/* ==========================================================================
   Funck IT — Kundenportal: Arbeitsflaeche (CRM-Schale)
   --------------------------------------------------------------------------
   Kopfzeile oben, Seitenmenue links, Inhalt rechts — dasselbe Grundmuster wie
   im LMS (dash-layout / dash-sidebar / dash-main), hier aber mit den Tokens
   des Portals statt denen des LMS.

   Wird NACH base.css und theme.css geladen und gewinnt deshalb bei gleicher
   Spezifitaet. base.css bleibt die geteilte Demo-Basis — hier nicht anfassen.

   Warum eine eigene Datei: Das Portal ist ein Arbeitswerkzeug, die Demoseiten
   sind Schaufenster. Beides in einer Datei zu mischen faellt beim naechsten
   Abgleich der Basis auf die Fuesse.
   ========================================================================== */

:root{
  --kp-side:264px;
  /* Gemeinsame Hoehe von Klappmenue und Fusszeile. Beide sitzen unten und
     tragen eine Oberkante — stehen sie unterschiedlich hoch, laufen die
     beiden Linien auseinander. Eine Variable haelt sie zusammen. */
  --kp-fussleiste:63px;
  --kp-side-bg:#eef0f4;
  --kp-tile-bg:#f4f6f9;
  /* 🔴 Deckende Fläche für alles, was ÜBER dem Inhalt schwebt (Filterkästen
     im Spaltenkopf). Nicht `--card` benutzen: Bei eingeschalteter Glasoptik
     ist das `rgba(255,255,255,.06)`, und durch einen Filterkasten scheinen
     dann die Tabellenzeilen darunter durch — unlesbar. Dieser Ton bleibt in
     jeder Darstellung deckend. */
  --kp-flyout:#ffffff;
  /* 🔴 Dieselbe Falle beim Diagramm-Tooltip (gefunden 10.08.2026). Dort stand
     `background:var(--text); color:var(--card)` — gemeint war „umgekehrte
     Farben". Mit eingeschalteter Glasoptik ist `--card` im Dunkeln aber
     `rgba(255,255,255,.06)`, also fast durchsichtiges Weiss auf hellem Grund:
     Die Beschriftung war unlesbar. Deshalb ein eigenes, deckendes Paar.
     ⚠️ `--card` ist eine FLAECHE, keine Schriftfarbe — sobald Glasoptik im
     Spiel ist, taugt sie fuer Text grundsaetzlich nicht. */
  --kp-tip-bg:#1f2937;
  --kp-tip-text:#ffffff;
  /* 🔴 Hinweisfarbe in ZWEI Tönen (11.08.2026). `--kp-warn` ist das Bernstein
     der Ampelpunkte und taugt als Fläche und als Symbol. Als kleine SCHRIFT
     taugt es nur im Dunkeln: Auf Weiß bringt #e0a12a rund 2:1 Kontrast, das
     ist für 0,8-rem-Text zu wenig. Deshalb ein zweiter Ton nur für Text —
     dieselbe Überlegung wie beim Tooltip-Paar darüber. */
  --kp-warn:#e0a12a;
  --kp-warn-text:#8a5300;
  /* 🔴 „Hat geklappt" ist eine AUSSAGE, keine Marke (16.08.2026).
     `.meldung.erfolg` lief bis dahin über `--brand-soft`/`--brand`. Bei einem
     Mandanten mit rotem Branding war die Erfolgsmeldung damit von der
     Fehlermeldung (`--danger`, ebenfalls rot) kaum zu unterscheiden — und
     ausgerechnet diese beiden dürfen nie zu verwechseln sein.
     Dieselbe Überlegung wie bei den Diagrammfarben: Sie folgen dem Branding
     bewusst nicht, weil ihre Bedeutung an der Farbe hängt.
     ⚠️ Zwei Töne wie bei `--kp-warn`: #3fae6b ist die Fläche und der
     Ampelpunkt, für Text auf Weiß reicht sein Kontrast nicht. */
  --kp-gut:#3fae6b;
  --kp-gut-text:#1c6b40;
  --kp-gut-soft:rgba(63,174,107,.12);
}
html[data-theme="dark"]{
  --kp-side-bg:#111726;
  --kp-tile-bg:#141a28;
  --kp-flyout:#161d2d;
  --kp-tip-bg:#e2e8f0;
  --kp-tip-text:#0f172a;
  --kp-warn-text:#e8b75a;
  --kp-gut-text:#6dd39b;
  --kp-gut-soft:rgba(63,174,107,.16);
}

/* --------------------------------------------------------------------------
   1. Kopfzeile — schlank, nur Marke und Konto
   Die Abschnittsnavigation sitzt im Seitenmenue, nicht mehr hier oben.
   -------------------------------------------------------------------------- */
body.kp header.site{border-bottom:1px solid var(--line)}
body.kp .brand-logo{height:36px}

/* Marke bündig zum Seitenmenü — wie im LMS.
   Der Kopf läuft dafür über die volle Breite (kein zentrierter Container),
   und der Markenblock ist exakt so breit wie das Menü darunter. Dadurch
   fluchten Logo, „Kundenportal" und die Menüpunkte auf einer Kante. */
body.kp header.site .container.nav{
  max-width:none;
  width:100%;
  padding:10px 0;
  gap:0;
}
body.kp .brand{
  width:var(--kp-side);
  flex:0 0 var(--kp-side);
  box-sizing:border-box;
  padding:0 18px;
  gap:12px;
}
body.kp .brand .brand-claim{padding-left:12px}

/* Kopfmenü: Bereichswechsel Portal ↔ Administration. Sitzt direkt neben der
   Marke, also am linken Rand des Inhaltsbereichs. */
.kp-kopfnav{margin-left:26px}
.kp-kopfnav ul{gap:6px}
.kp-kopfnav a{
  display:block;padding:7px 14px;border-radius:8px;
  font-size:.9rem;font-weight:600;opacity:1;text-decoration:none;
  color:var(--muted);transition:background .12s,color .12s;
}
.kp-kopfnav a:hover{background:var(--kp-tile-bg);color:var(--text);text-decoration:none}
.kp-kopfnav a.aktiv{background:var(--brand-soft);color:var(--brand)}

.kp-kopf-rechts{display:flex;align-items:center;gap:10px;margin-left:auto;padding-right:24px}

@media (max-width:980px){
  /* Ohne festes Menü darf die Marke wieder mitwachsen, sonst drückt sie den
     Umschalter auf schmalen Geräten aus dem Bild. */
  /* 🔴 Die Marke rückt an den RECHTEN Rand (Wunsch des Users, 15.08.2026:
     „kriegen wir mobil das hinterlegte logo nach rechts statt links neben den
     button?"). Im Markup steht der Menüknopf vor der Marke; ohne diese Regel
     kleben beide links aneinander. `margin-left:auto` schiebt die Marke ans
     Ende der Zeile, der Knopf bleibt links — die beiden Ecken, an denen der
     Daumen ohnehin liegt. */
  /* 🔴 Die Kopfzeile wird hier AUSDRÜCKLICH gesetzt (15.08.2026, im schmalen
     Chrome-Fenster des Users nachgemessen). Vorher hing die Anordnung daran,
     welches Geschwister gerade wie breit ist — die Marke stand dadurch
     „irgendwo über dem Papierkorb-Symbol" statt an der Kante.

     Zeile 1 trägt NUR den Menüknopf und die Marke, alles andere bekommt
     `flex-basis:100%` und damit eine eigene Zeile. Damit ist die Marke das
     letzte Element der ersten Zeile, und `margin-left:auto` schiebt sie
     zuverlässig an den rechten Rand — unabhängig davon, ob Suche oder
     Bereichsnavigation gerade sichtbar sind.
     ⚠️ Auch `padding-right:0`: Die 18 px der Desktopfassung hielten sie
     sonst von der Kante fern. */
  /* ⚠️ `justify-content:flex-start` statt des geerbten `space-between`
     aus `base.css`: Bei drei Elementen in der Zeile setzt `space-between`
     das mittlere in die MITTE — genau dort stand die Marke („irgendwo
     über dem Papierkorb-Symbol"). Mit `flex-start` zählt allein der
     automatische Rand der Marke, und der schiebt sie an die Kante. */
  body.kp header.site .container.nav{align-items:center;justify-content:flex-start}
  /* 🔴 JEDES weitere Kind bekommt eine eigene Zeile — nicht nur die, die ich
     namentlich kenne. Gemessen im schmalen Fenster: In der ersten Zeile lag
     noch ein unsichtbares Element von rund 150 px hinter der Marke und hielt
     sie von der Kante fern. Welches es ist, spielt für die Regel keine Rolle;
     entscheidend ist, dass die Marke das LETZTE Element ihrer Zeile ist. */
  body.kp header.site .container.nav > *{order:5;flex-basis:100%}
  /* ⚠️ Die Ausnahmen brauchen DIESELBE Selektorentiefe wie die Regel darüber.
     Kurz geschrieben (`body.kp .brand`) verlieren sie gegen sie — und dann
     steht auch der Menüknopf über die volle Breite. Einmal so passiert. */
  body.kp header.site .container.nav > .kp-side-btn{order:1;flex:0 0 auto}
  /* 🔴 `margin-right:0` ist der eigentliche Punkt. `theme.css` gibt der Marke
     unter 860 px ein `margin-right:auto` — dort steht das Logo LINKS und der
     Menüknopf rechts. Im Portal ist es umgekehrt, und zwei automatische
     Ränder teilen den freien Platz zu gleichen Teilen: Das Logo landete
     mittig, „irgendwo über dem Papierkorb-Symbol".
     ⚠️ Merksatz: Ein `margin-left:auto` wirkt nur, wenn auf der anderen Seite
     KEIN zweites `auto` steht. Beim Suchen nach so einer Verschiebung immer
     beide Seiten prüfen — und alle drei Stilvorlagen, nicht nur `crm.css`. */
  /* Die Suche teilt sich die erste Zeile mit Knopf und Marke. `flex:1 1 0`
     laesst ihr genau den Rest — auf 360 px sind das noch rund 120 px, genug
     fuer das Feld samt Lupe.
     ⚠️ `margin-left:0`: Ihre Grundregel traegt `margin-left:auto` (Desktop:
     sie schiebt sich dort selbst nach rechts). Hier waere das ein zweiter
     automatischer Rand neben dem der Marke — dieselbe Falle wie beim Logo. */
  body.kp header.site .container.nav > .kp-such-kopf{
    display:block;order:2;flex:1 1 0;min-width:0;
    margin:0 0 0 12px;
  }
  body.kp header.site .container.nav > .brand{
    order:3;width:auto;flex:0 0 auto;
    margin-left:12px;margin-right:0;padding:0;
  }
  body.kp header.site .container.nav > .kp-kopf-rechts{
    order:4;flex-basis:100%;margin-left:0;
  }
  /* Das Benutzermenue ans rechte Ende seiner Zeile (Wunsch des Users) — es
     ist das einzige Symbol mit einem Namen daneben und schliesst die Reihe
     damit sauber ab, statt mitten in der Zeile zu enden. */
  body.kp .kp-kopf-rechts > .kp-benutzer{margin-left:auto}
  body.kp header.site .container.nav{padding:10px 16px;flex-wrap:wrap}
  .kp-kopf-rechts{padding-right:0}

  /* base.css klappt nav.main normalerweise hinter den Menüknopf. Den gibt es
     hier nicht — es sind nur zwei Einträge, die bleiben sichtbar und rutschen
     bei Bedarf in die zweite Zeile. */
  .kp-kopfnav{order:9;flex-basis:100%;margin:8px 0 0}
  .kp-kopfnav ul{display:flex;flex-direction:row;gap:6px;padding:0}
  .kp-kopfnav ul li{border-top:0}
  .kp-kopfnav ul li a{padding:7px 12px}
}

/* 🔴 Der Zusatz neben dem Logo entfällt auf dem Handy (15.08.2026). Er stünde
   RECHTS vom Logo und wäre damit genau das, was das Logo von der Kante
   fernhält — und er wiederholt nur, was das Logo schon sagt. Auf dem Tablet
   bleibt er, dort ist Platz. */
@media (max-width:700px){
  body.kp .brand .brand-claim{display:none}
}

/* Umschalter fuer das Seitenmenue — nur schmal sichtbar */
.kp-side-btn{
  display:none;align-items:center;gap:8px;
  background:var(--brand);color:#fff;border:0;border-radius:10px;
  padding:7px 12px;font-size:.88rem;font-weight:600;cursor:pointer;
}
.kp-side-btn:hover{background:var(--accent)}

/* --------------------------------------------------------------------------
   1b. Band der Kundenansicht
   Muss auffallen: Wer das übersieht, hält die Ansicht für sein eigenes Portal
   und wundert sich, warum Daten fehlen.
   -------------------------------------------------------------------------- */
.kp-band{
  background:#8f231d;color:#fff;
  z-index:80;
  box-shadow:0 2px 10px rgba(0,0,0,.2);
}
.kp-band-inner{
  padding:9px 24px;
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  font-size:.88rem;line-height:1.35;
}
.kp-band-text{flex:1;min-width:220px}
.kp-band strong{font-weight:700}
.kp-band-meta{
  display:inline-block;margin-left:8px;padding:1px 9px;border-radius:999px;
  background:rgba(255,255,255,.18);font-size:.78rem;white-space:nowrap;
}
/* Mehrere Knöpfe am rechten Rand des Bandes (13.08.2026: „Mandant verlassen"
   neben „Abmelden"). Ohne eigene Regel bricht das Formular als Blockelement in
   die nächste Zeile und der zweite Knopf sitzt unter dem ersten. */
.kp-band-aktionen{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.kp-band .btn{background:#fff;color:#8f231d;border-color:#fff}
.kp-band .btn:hover{background:#f1f1f1;color:#8f231d}

/* Der Rand macht auch dann klar, dass etwas anders ist, wenn man weit
   nach unten gescrollt hat und das Band verlassen hat. */
body.kp-in-ansicht{box-shadow:inset 0 0 0 3px #8f231d}

/* Supportzugriff: eigene Farbe, NICHT die des Mandanten.
   🔴 Zwei Klassen im Selektor (.kp-band.kp-band-support), damit die Regel die
   Markenfarbe schlaegt — die kommt aus einem <style>-Block im Kopf und stuende
   sonst als spaetere Regel gleicher Staerke daueber. Ein Band in der Farbe des
   Kunden saehe nach seinem Auftritt aus; es ist aber eine Aussage ueber die
   Sitzung, nicht ueber ihn. */
.kp-band.kp-band-support{background:#7a4708;color:#fff}
.kp-band.kp-band-support .btn{background:#fff;color:#7a4708;border-color:#fff}
.kp-band.kp-band-support .btn:hover{background:#f1f1f1;color:#7a4708}

/* Mandanten-Kennung („M3 · kramm") im Seitenmenue und im Fuss.
   Schreibmaschinenschrift: Es ist eine Nummer, kein Name — und man liest sie
   vor oder tippt sie ab. */
.kp-side-kennung,.kp-fuss-kennung{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:.72rem;letter-spacing:.02em;
}
.kp-side-kennung{
  display:inline-block;margin:8px 0 0;padding:2px 8px;border-radius:6px;
  background:var(--kp-tile-bg,var(--hover,rgba(0,0,0,.05)));
  border:1px solid var(--line);color:var(--muted);
  cursor:default;
}
.kp-fuss-kennung{
  margin-right:10px;padding:1px 7px;border-radius:5px;
  border:1px solid var(--line);color:var(--muted);cursor:default;
}

/* --------------------------------------------------------------------------
   2. Schale
   -------------------------------------------------------------------------- */
/* App-Schale: Die Seite ist genau fensterhoch, Kopf und Band sind feste
   Zeilen, der Rest teilt sich den Platz. Vorher war .kp-side auf 100vh
   gesetzt, begann aber UNTER der Kopfzeile — sie ragte also um genau deren
   Höhe unten aus dem Bild, und das jeweils unterste Element verschwand.
   Erst war das die Fußzeile, dann das Klappmenü. Mit dieser Schale gibt es
   keine geratene Kopfhöhe mehr: Der Browser rechnet selbst. */
body.kp{height:100vh;display:flex;flex-direction:column;overflow:hidden}
body.kp > header.site,
body.kp > .kp-band{flex:0 0 auto}

/* Der „nach oben"-Knopf hört seit dem 08.08.2026 auf den aktiven
   Scrollbereich (in der App-Schale .kp-main-scroll, darunter das Fenster) und
   ist deshalb nicht mehr abgeschaltet — siehe zurueckNachOben() in portal.js.
   In der Schale klebt die Fußzeile am unteren Rand; der Knopf sitzt darüber,
   sonst deckt er sie ab. */
body.kp .to-top{bottom:calc(var(--kp-fussleiste) + 16px)}

.kp-shell{
  flex:1;min-height:0;          /* min-height:0 — sonst schrumpft es nicht */
  display:flex;align-items:stretch;
}

.kp-side{
  width:var(--kp-side);flex:0 0 var(--kp-side);
  background:var(--kp-side-bg);
  border-right:1px solid var(--line);
  height:100%;
  display:flex;flex-direction:column;
  /* NICHT overflow:hidden — das Untermenü von „Neu" fährt rechts aus der
     Spalte heraus und würde sonst abgeschnitten. Gescrollt wird ohnehin nur
     .kp-nav, die Spalte selbst läuft nie über.
     position/z-index, damit das Untermenü über dem Inhalt liegt: .kp-main
     kommt später im Dokument und würde sonst darüber gezeichnet. */
  overflow:visible;
  position:relative;z-index:10;
}

.kp-side-kopf{padding:20px 18px 16px;border-bottom:1px solid var(--line)}
.kp-side-label{
  font-size:.68rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted);margin:0 0 6px;
}
.kp-side-name{font-weight:700;line-height:1.3;margin:0;word-break:break-word}
.kp-side-meta{font-size:.8rem;color:var(--muted);margin:4px 0 0}

.kp-nav{
  flex:1;padding:10px 0;
  overflow-y:auto;
  /* Ohne min-height:0 weigert sich ein Flex-Kind zu schrumpfen und wächst
     stattdessen über den Container hinaus — der Klassiker. */
  min-height:0;
}
.kp-nav-gruppe{
  font-size:.68rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted);padding:14px 18px 6px;margin:0;
}
.kp-nav a{
  display:flex;align-items:center;gap:10px;
  padding:10px 18px;
  border-left:3px solid transparent;
  color:var(--text);text-decoration:none;
  font-size:.9rem;font-weight:500;line-height:1.3;
  transition:background .12s,border-color .12s;
}
.kp-nav a:hover{background:rgba(0,0,0,.05);text-decoration:none}
html[data-theme="dark"] .kp-nav a:hover{background:rgba(255,255,255,.05)}
.kp-nav a.aktiv{
  background:var(--card);border-left-color:var(--brand);
  font-weight:700;color:var(--brand);
}
.kp-nav-icon{width:18px;flex:0 0 18px;text-align:center;font-size:1rem;line-height:1}
.kp-nav-zahl{
  margin-left:auto;font-size:.72rem;font-weight:700;
  background:var(--line);color:var(--muted);
  border-radius:999px;padding:1px 8px;
}
.kp-nav a.aktiv .kp-nav-zahl{background:var(--brand-soft);color:var(--brand)}

/* Gesperrt: sichtbar, aber erkennbar nicht benutzbar (11.08.2026) --------
   🔴 Nicht ausblenden (Ansage des Users): Wer den Punkt sieht, weiß, dass es
   ihn gibt, und die Sperrseite erklärt den Rest. `pointer-events` wird NICHT
   abgeschaltet — der Klick soll zur Erklärung führen, nicht ins Leere. */
.kp-nav a.gesperrt{opacity:.45}
.kp-nav a.gesperrt:hover{opacity:.7}
.kp-nav-schloss{margin-left:auto;font-size:.9rem;line-height:1}
.kp-neu-liste a.gesperrt{opacity:.5}

/* Wochentage im Arbeitszeitkontingent (Punkt 26, 13.08.2026) --------------
   🔴 EIGENES Raster, nicht `.kp-felder`: Das dort ordnet nach Platz
   (`auto-fit`, mindestens 230 px je Spalte) — sieben Zahlenfelder rutschten
   damit je nach Fensterbreite in zwei oder drei Zeilen, und der Stichtag stand
   mitten zwischen ihnen. Eine Woche hat sieben Tage in EINER Reihe; das ist
   die Reihenfolge, in der man sie liest und ausfüllt. */
.az-woche{
  display:grid;gap:10px;
  grid-template-columns:repeat(7,minmax(58px,84px));
  justify-content:start;
}
.az-woche label{
  display:block;margin:0 0 5px;text-align:center;
  font-size:.74rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);
}
.az-woche input{width:100%;text-align:right;padding-left:6px;padding-right:6px}
/* Samstag und Sonntag stehen an derselben Stelle wie im Kalender, aber leiser:
   Sie sind der seltene Fall und sollen nicht wie ein leeres Pflichtfeld
   aussehen. */
.az-woche .az-frei label{opacity:.6}
.az-woche .az-frei input{background:var(--hover)}
.az-summe{margin:14px 0 0;font-size:.92rem;color:var(--muted)}
.az-summe strong{color:var(--text);font-size:1.05rem}
/* Auf schmalen Geräten zwei Reihen — vier Werktage, dann der Rest. Sieben
   Spalten à 58 px passen unter 460 px nicht mehr ohne Querlauf. */
@media (max-width:560px){
  .az-woche{grid-template-columns:repeat(4,minmax(58px,1fr))}
}

/* Anwesenheitsball in der Teamliste (Punkt 26b, 13.08.2026) ---------------
   🔴 Der Ball steht NIE allein: Rot und Grün liegen unter Deuteranopie dicht
   beieinander (ΔE 4,1) — daneben gehört das Wort. Dieselbe Regel wie beim
   Stimmungsbild der Betreuung, dort schon einmal teuer gelernt.
   Kein Emoji: `🟢` wird von jedem System anders und immer farbig gezeichnet
   → [[feedback_portal_oberflaeche_regeln]]. */
.kp-ball{
  display:inline-block;width:10px;height:10px;border-radius:50%;
  margin-right:8px;vertical-align:baseline;
  /* Ein Rand, damit der Ball auch auf gleichfarbigem Grund eine Kante hat. */
  box-shadow:0 0 0 1px rgba(0,0,0,.18) inset;
}
.kp-ball-gruen{background:#1f9d55}
.kp-ball-gelb {background:#d9a400}
.kp-ball-rot  {background:#c0392b}
.kp-ball-grau {background:#9aa3ad}
.kp-ball-wort{font-size:.92rem}
.kp-klein{font-size:.82rem}
/* Dieselbe Behandlung in der Kopfleiste (Briefumschlag, Papierkorb) —
   13.08.2026. Der Papierkorb hat seit dem 10.08. keinen anderen Einstieg mehr,
   ausblenden hieße hier: Die Funktion gibt es gar nicht. */
.kp-kopf-msg.gesperrt{opacity:.45}
.kp-kopf-msg.gesperrt:hover{opacity:.7}
/* Abgeblendeter Absendeknopf: sichtbar, erkennbar tot. Hängt an `:disabled`
   und nicht an einer eigenen Klasse — die Knöpfe tragen schon `class="btn"`,
   und zwei class-Attribute im selben Tag vertragen sich nicht. */
.btn:disabled,
.btn[disabled]{opacity:.45;cursor:not-allowed;filter:grayscale(.4)}
.btn:disabled:hover,
.btn[disabled]:hover{opacity:.45}

/* Klappmenü „Neu" ------------------------------------------------------- */
/* 🔴 Leerer Rahmen auf Reitern ohne Formularinhalt (vom User beanstandet,
   11.08.2026: leerer Bereich unten bei den Ticketeinstellungen). Die
   Einstellungen sind EIN grosses Formular; Reiter wie Tickets bringen aber
   eigene Formulare mit und liegen deshalb ausserhalb. Dann blieb der
   gestylte Rahmen leer stehen.
   Bedingung mit Bedacht: nur ausblenden, wenn das Formular ueberhaupt Reiter
   enthaelt UND keiner davon aktiv ist. Ohne den ersten Teil verschwaende
   jedes Formular ohne Reiter. */
/* 🔴 Am 15.08.2026 von `:has()` auf eine Klasse umgestellt (Fund des Users:
   „einstellungen öffnen -> zugänge öffnen -> super admin link Firma & Kontakt
   anklicken. die tabs bleiben leer … erst nach f5").

   Die alte Regel lautete
   `.kp-form:has(.kp-reiter-inhalt):not(:has(.kp-reiter-inhalt.aktiv))`.
   Sie musste neu greifen, sobald ein NACHFAHRE seine Klasse ändert — und zwar
   auch dann, wenn dieser Nachfahre gerade in einem `display:none`-Teilbaum
   liegt. Genau das passiert bei diesem Weg: Die vier Pflegereiter liegen
   AUSSERHALB des grossen Formulars, die neun Einstellungsreiter darin. Wer von
   aussen nach innen wechselt, setzt `aktiv` auf ein Element in einem
   ausgeblendeten Formular. Ob der Browser die `:has()`-Bedingung dann neu
   auswertet, ist nichts, worauf man bauen sollte.

   Jetzt setzt `portal.js` die Klasse selbst — dieselbe Stelle, die auch die
   Reiter umschaltet. Kein Ratespiel mehr über Stil-Invalidierung. */
.kp-form.kp-form-leer{display:none}

.kp-neu{
  position:relative;flex:0 0 auto;
  min-height:var(--kp-fussleiste);
  display:flex;align-items:center;
  padding:0 18px;border-top:1px solid var(--line);
}
.kp-neu > summary,
.kp-neu > .kp-neu-solo{flex:1}
.kp-neu > summary,
.kp-neu > .kp-neu-solo{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  list-style:none;cursor:pointer;
  padding:9px 14px;border-radius:10px;
  background:var(--brand);color:#fff;
  font-size:.9rem;font-weight:700;
}
.kp-neu > summary::-webkit-details-marker{display:none}
.kp-neu > summary::after{content:"⌃";font-size:.9rem;transform:translateY(2px)}
.kp-neu[open] > summary::after{content:"⌄";transform:translateY(-2px)}
.kp-neu > summary:hover,
.kp-neu > .kp-neu-solo:hover{background:var(--accent)}
/* Einzelner Eintrag: derselbe Knopf, nur ohne Klappzeichen. Deshalb mittig
   statt space-between — sonst klebte die Beschriftung ohne Gegenstück links. */
.kp-neu > .kp-neu-solo{
  justify-content:center;text-decoration:none;text-align:center;
}
.kp-neu > .kp-neu-solo:hover{color:#fff;text-decoration:none}

.kp-neu-liste{
  position:absolute;bottom:calc(100% - 6px);left:18px;right:18px;
  /* deckend — siehe .kp-benutzer-klapp */
  background:var(--kp-flyout);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  box-shadow:0 -6px 24px rgba(0,0,0,.16);
  /* Ebenfalls kein overflow:hidden: Es lag hier nur wegen der runden Ecken,
     hätte aber das seitlich ausfahrende Untermenü gekappt. Die Ecken
     erledigen jetzt die Ränder der ersten und letzten Gruppe. */
  overflow:visible;z-index:20;
}
.kp-neu-liste > .kp-neu-gruppe:first-child > summary{border-radius:var(--radius-sm) var(--radius-sm) 0 0}
.kp-neu-liste > .kp-neu-gruppe:last-child > summary{border-radius:0 0 var(--radius-sm) var(--radius-sm)}
/* Gruppen im Klappmenue. Die Untereintraege fahren nach RECHTS aus dem Menue
   heraus — nach unten waere am Fussende kein Platz, und nach oben wuerde die
   Gruppenliste selbst verdeckt. */
.kp-neu-gruppe{position:relative;border-bottom:1px solid var(--line)}
.kp-neu-gruppe:last-child{border-bottom:0}
.kp-neu-gruppe > summary{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  list-style:none;cursor:pointer;
  padding:11px 14px;font-size:.9rem;font-weight:600;color:var(--text);
}
.kp-neu-gruppe > summary::-webkit-details-marker{display:none}
.kp-neu-gruppe > summary::after{content:"\203A";font-size:1.1rem;color:var(--muted);line-height:1}
.kp-neu-gruppe > summary:hover{background:var(--brand-soft);color:var(--brand)}
.kp-neu-gruppe[open] > summary{background:var(--brand-soft);color:var(--brand)}
.kp-neu-gruppe[open] > summary::after{color:var(--brand)}

/* Punkt ohne Untermenue — sieht aus wie eine Gruppe, nur ohne Pfeil. */
.kp-neu-direkt{
  display:block;padding:11px 14px;
  font-size:.9rem;font-weight:600;color:var(--text);text-decoration:none;
  border-bottom:1px solid var(--line);
}
.kp-neu-liste > .kp-neu-direkt:last-child{
  border-bottom:0;border-radius:0 0 var(--radius-sm) var(--radius-sm);
}
.kp-neu-direkt:hover{background:var(--brand-soft);color:var(--brand);text-decoration:none}

.kp-neu-unter{
  position:absolute;left:calc(100% + 6px);bottom:0;
  min-width:210px;
  /* deckend — siehe .kp-benutzer-klapp */
  background:var(--kp-flyout);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  box-shadow:0 6px 24px rgba(0,0,0,.2);
  overflow:hidden;z-index:30;
}
.kp-neu-unter a{
  display:block;padding:10px 14px;white-space:nowrap;
  color:var(--text);text-decoration:none;font-size:.9rem;
  border-bottom:1px solid var(--line);
}
.kp-neu-unter a:last-child{border-bottom:0}
.kp-neu-unter a:hover{background:var(--brand-soft);color:var(--brand);text-decoration:none}

/* --------------------------------------------------------------------------
   3. Inhaltsflaeche
   -------------------------------------------------------------------------- */
.kp-main{
  flex:1;min-width:0;
  background:var(--bg);
  /* Zwei Zeilen: scrollender Inhalt oben, feste Fußzeile unten. Das Polster
     sitzt deshalb am Scrollbereich, nicht mehr hier. */
  display:flex;flex-direction:column;
  overflow:hidden;
}
.kp-main-scroll{
  flex:1;min-height:0;overflow-y:auto;
  padding:28px 34px 36px;
}
/* Keine Deckelung: Die Verwaltung zeigt breite Formulare und Tabellen, da ist
   Platz die knappe Ressource — nicht die Zeilenlänge. */
.kp-main > .kp-inner{max-width:none}

.kp-titel{font-size:1.55rem;line-height:1.2;margin:0 0 4px}
.kp-unter{color:var(--muted);margin:0 0 26px}

/* Auch .muted war überall in Gebrauch und nirgends definiert — base.css
   kennt nur .hint und .lead. */
.muted{color:var(--muted)}
small.muted{font-size:.85em}

.kp-abschnitt{margin-top:34px}
.kp-abschnitt > h2{font-size:1.12rem;margin:0 0 14px}

/* --------------------------------------------------------------------------
   4. Karten — die fehlende Klasse aus dashboard.php und leistungen.php
   -------------------------------------------------------------------------- */
.karte{
  background:var(--card);
  border:1px solid var(--line);
  border-radius:var(--radius);
  padding:20px 22px;
  box-shadow:var(--shadow);
}
.karte > :first-child{margin-top:0}
.karte > :last-child{margin-bottom:0}
.karte h2,.karte h3{margin:0 0 10px;line-height:1.25}
.karte h2{font-size:1.1rem}
.karte h3{font-size:1rem}

.kp-karten{
  display:grid;gap:18px;
  grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));
}

/* Preiszeile auf der Leistungskarte des Kunden. Der Betrag traegt die Zeile,
   Turnus und Steuerhinweis bleiben bewusst klein — sonst liest sich die Karte
   wie eine Rechnung. */
.kp-preis{
  margin:0 0 10px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  font-size:1.15rem;
}
.kp-preis .muted{font-size:.9rem}
/* 🔴 `align-items:stretch` (der Vorgabewert des Rasters), NICHT `start`
   (21.08.2026, Ansage des Users: „ich hätte die dashboard elemente gern so,
   dass wir keine freien Bereiche ohne Inhalt haben" — „bei Überblick z.B. Mein
   Konto und Hilfe gleich hoch").

   Mit `start` endete jede Spalte dort, wo ihr Inhalt aufhört, und neben der
   kürzeren stand ein Loch. Gemessen am 21.08.2026: Überblick 47 px, Umsatz
   151 px, Accounts 174 px, Betreuung 109 px, Betrieb 75 px — und Kündigungen
   880 px.

   Damit das wirkt, müssen zwei Dinge zusammenkommen: Die Spalte streckt sich
   (Raster), UND die letzte Karte darin füllt den Rest (Flex unten). Ohne den
   zweiten Teil wäre nur der unsichtbare Spaltenkasten hoch, die Karte bliebe
   kurz und das Loch sähe genauso aus wie vorher. */
.kp-zweispalt{display:grid;gap:20px;grid-template-columns:1.6fr 1fr;align-items:stretch}
.kp-zweispalt > div{display:flex;flex-direction:column}
/* ⚠️ Nur die LETZTE Karte wächst. Wachsen alle, verteilt sich der Rest über
   die ganze Spalte und jede Karte bekommt etwas Leerraum — dann sieht keine
   mehr nach ihrem Inhalt aus. Unten anzuwachsen ist die einzige Stelle, an der
   zusätzlicher Platz nicht wie ein Fehler wirkt. */
.kp-zweispalt > div > .karte:last-child{flex:1 1 auto}
/* Gestapelte Karten in einer Spalte brauchen Luft dazwischen — sonst kleben
   sie aneinander, sobald eine Spalte mehr als eine Karte traegt. */
.kp-zweispalt > div > .karte + .karte,
.kp-zweispalt > div > .karte + [class^="kp-"]{margin-top:18px}
/* Eine Karte über die VOLLE Breite unter den beiden Spalten (21.08.2026, die
   Gewinnprognose im Umsatzreiter). `.karte` bringt selbst keinen Rand mit —
   ohne diese Regel klebt sie an den Spalten darüber. Der Wert ist bewusst
   derselbe wie der `gap` des Rasters: Sonst sieht der Abstand zur Karte anders
   aus als der zwischen den Spalten, und die Seite wirkt schief. */
.kp-zweispalt + .karte{margin-top:20px}

/* --------------------------------------------------------------------------
   4b. Schaltflaechen
   Waren im ganzen Portal in Gebrauch (21 Stellen), aber nirgends definiert:
   base.css kennt nur .cta aus den Demoseiten. Deshalb sahen Formulare und
   Verwaltung bis 06.08.2026 nach unformatiertem HTML aus.
   -------------------------------------------------------------------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:9px 18px;border:1px solid transparent;border-radius:10px;
  background:var(--brand);color:#fff;
  font:inherit;font-size:.92rem;font-weight:600;line-height:1.2;
  text-decoration:none;cursor:pointer;white-space:nowrap;
  transition:background .15s,border-color .15s,color .15s;
}
.btn:hover{background:var(--accent);color:#fff;text-decoration:none}
.btn:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.btn[disabled],.btn.aus{opacity:.5;pointer-events:none}

.btn-outline{
  background:transparent;color:var(--text);border-color:var(--line);
}
.btn-outline:hover{background:var(--brand-soft);color:var(--brand);border-color:var(--brand)}

.btn-klein{padding:5px 11px;font-size:.82rem;border-radius:8px}

.btn-gefahr{background:var(--danger);border-color:var(--danger)}
.btn-gefahr:hover{background:var(--danger);filter:brightness(.9)}

/* Mehrere Schaltflaechen nebeneinander bekommen Luft, ohne dass jede Seite
   das per style-Attribut regeln muss. */
.btn + .btn{margin-left:8px}

/* 🔴 …ABER NICHT DORT, WO DER CONTAINER SEINEN ABSTAND SCHON PER `gap` REGELT.
   Die Regel darüber ist für Knöpfe gedacht, die einfach nebeneinander im Text
   stehen. In einem Flex- oder Rasterkasten mit `gap` kommt sie ein zweites Mal
   obendrauf — und richtet dort zwei Schäden an:

     * Nebeneinander: 8 px `gap` + 8 px Rand = 16 px. Nur unschön.
     * ⚠️ NACH EINEM UMBRUCH: Der erste Knopf der zweiten Zeile ist immer noch
       ein `.btn + .btn` und trägt den Rand — er schiebt die GANZE zweite Zeile
       um 8 px nach rechts. Auf dem Handy, wo jede Knopfreihe umbricht, steht
       dann Zeile 1 bündig und alles darunter eingerückt.

   Genau so gemeldet: 14.08.2026 an `.kp-stammliste` („abteilungen ist weiter
   links als alle anderen"), 21.08.2026 an `.kp-sichtwahl` („die filter bubbels
   sind nicht bündig, die erste reihe weicht ab auf dem handy" — „zieht sich
   durch alle seiten mit diesen elementen"). Zweimal derselbe Fehler, weil beim
   ersten Mal nur der eine Kasten geflickt wurde.

   📌 WER EINEN NEUEN CONTAINER MIT `gap` BAUT, DER KNÖPFE ENTHÄLT, TRÄGT IHN
   HIER EIN. Das ist die eine Stelle dafür; CSS kann nicht selbst erkennen, ob
   ein Elternteil `gap` gesetzt hat. */
.btn-row > .btn + .btn,
.kal-kopf > .btn + .btn,
.kp-aktionen > .btn + .btn,
.kp-ansicht-knopf > .btn + .btn,
.kp-ansicht-liste > .btn + .btn,
.kp-ansicht-name > .btn + .btn,
.kp-ansicht-pfeile > .btn + .btn,
.kp-ansicht-zeile > .btn + .btn,
.kp-band-aktionen > .btn + .btn,
.kp-band-inner > .btn + .btn,
.kp-blaettern > .btn + .btn,
.kp-check > .btn + .btn,
.kp-hinweis-aktionen > .btn + .btn,
.kp-hinweis-filter > .btn + .btn,
.kp-hinweis-leiste > .btn + .btn,
.kp-kopfleiste > .btn + .btn,
.kp-listenfuss > .btn + .btn,
/* ⚠️ Nachgetragen am 21.08.2026: `.kp-listenkopf` fehlte in dieser Liste, weil
   sie aus einer Markup-Suche entstand — der Listenkopf wird aber in PHP
   erzeugt (`Liste::steuerung()`) und stand deshalb in keiner Vorlage. Folge:
   Export und Zahnrad hatten 16 px Abstand statt 8, und das Knopfpaar war
   genau diese 8 px breiter als der Suchknopf darueber. */
.kp-listenkopf > .btn + .btn,
.kp-msg-kopf > .btn + .btn,
.kp-news-kopf > .btn + .btn,
.kp-recht-zeichen > .btn + .btn,
.kp-reiter > .btn + .btn,
.kp-schnellsuche > .btn + .btn,
.kp-sichtwahl > .btn + .btn,
.kp-spf > .btn + .btn,
.kp-spf-fuss > .btn + .btn,
.kp-stammliste > .btn + .btn,
.kp-stimmung > .btn + .btn,
.kp-suchleiste > .btn + .btn,
.kp-suchseite-form > .btn + .btn,
.kp-wahl-fuss > .btn + .btn,
.kp-wahl-knoepfe > .btn + .btn,
.kp-woche > .btn + .btn,
.kp-woche-kopf > .btn + .btn,
.kp-woche-nav > .btn + .btn{margin-left:0}

/* --------------------------------------------------------------------------
   4c. Formulare in der Verwaltung
   -------------------------------------------------------------------------- */

/* 🔴 base.css setzt input{width:100%} — das trifft auch Kästchen und
   Auswahlknöpfe. Die Box wird dann auf volle Spaltenbreite gedehnt, das
   Häkchen sitzt mittig darin und der Text rutscht weit nach rechts. base.css
   hat dafür zwar eine Ausnahme (.check-row), die greift aber nur dort, wo
   jemand daran gedacht hat. Deshalb hier global. */
input[type="checkbox"],
input[type="radio"]{
  width:auto;min-width:0;flex:0 0 auto;
  accent-color:var(--brand);
}

.kp-form{max-width:none;padding:24px 26px}

.kp-fieldset{border:0;padding:0;margin:0 0 28px}
/* ⚠️ Der Umkreisblock haengt hinter einer fremden Karte und nicht zwischen
   zwei Fieldsets — dort gibt es kein voriges Element, dessen unteres Mass den
   Abstand traegt. Er bringt ihn deshalb selbst mit (21.08.2026). */
.kp-umkreis-block{margin-top:24px}
.kp-fieldset > legend{
  font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);padding:0;margin-bottom:12px;
  width:100%;border-bottom:1px solid var(--line);padding-bottom:7px;
}

/* Felder in gleich breiten Spalten, aber mit Obergrenze.
   Ohne die Obergrenze (früher 1fr) zog ein breiter Bildschirm jedes Feld auf
   über 500 px — auch das für eine einstellige Zahl. Jetzt bleiben die Spalten
   bei 340 px stehen und der Rest der Zeile bleibt leer; das sieht aufgeräumt
   aus, statt Platz zu füllen, nur weil er da ist. */
/* 🔴 `min(230px,100%)` und nicht `230px` (15.08.2026, Fund des Users: „beim
   account anlegen ragen diverse felder aus dem bereich heraus in dem sie
   liegen"). Ein Raster mit fester Mindestspalte wird NICHT schmaler als diese
   Zahl — ist der Kasten darum enger (Overlay auf dem Handy: 360 px minus
   Fenster-, Karten- und Feldsatzrand), läuft die Spalte über den Rand hinaus.
   Mit `min()` ist die Untergrenze bei engem Platz die Kastenbreite selbst. */
.kp-felder{
  display:grid;gap:16px 20px;
  grid-template-columns:repeat(auto-fit,minmax(min(230px,100%),340px));
  justify-content:start;
  align-items:start;
}
.kp-felder > div{min-width:0}
.kp-felder label{margin-top:0}
.kp-felder small{display:block;margin-top:5px;font-size:.78rem;line-height:1.35}

/* Für Inhalte, die zwei Spalten brauchen — vor allem URLs. */
.kp-feld-breit{grid-column:span 2}
/* 🔴 Unter 700 px gibt es nur EINE Spalte. Ein Element, das zwei überspannt,
   erzeugt dann eine zweite Spalte, die es gar nicht geben soll — das Raster
   wird doppelt so breit wie sein Kasten.
   ⚠️ Genau deshalb darf `span 2` NIE als `style="…"` im Markup stehen: Eine
   Auszeichnung am Element schlägt jede Regel hier, auch diese. Neun solcher
   Stellen sind am 15.08.2026 auf die Klasse umgestellt worden. */
@media (max-width:700px){ .kp-feld-breit{grid-column:auto} }

/* 🔴 Datums- und Zeitfelder (15.08.2026, zweiter Anlauf).
   `min-width:0` allein genügte NICHT — der User meldete „Account seit ragt
   noch immer heraus" und dasselbe bei „Fällig am". Ursache ist die
   Standarddarstellung von WebKit: Solange `-webkit-appearance` auf dem
   eigenen Bedienelement steht, bemisst iOS das Feld nach seinem inneren
   Aufbau (Kalendersymbol plus TT.MM.JJJJ) und lässt `width:100%` links
   liegen. Erst `appearance:none` macht daraus ein gewöhnliches Feld, das sich
   an seine Spalte hält.
   ⚠️ Danach steht der Wert auf iOS mittig — `::-webkit-date-and-time-value`
   holt ihn nach links, wie in jedem anderen Eingabefeld auch. */
input[type="date"],
input[type="month"],
input[type="time"],
input[type="datetime-local"]{
  -webkit-appearance:none;appearance:none;
  display:block;box-sizing:border-box;
  width:100%;min-width:0;max-width:100%;
}
input[type="date"]::-webkit-date-and-time-value,
input[type="month"]::-webkit-date-and-time-value,
input[type="time"]::-webkit-date-and-time-value,
input[type="datetime-local"]::-webkit-date-and-time-value{
  text-align:left;
}

/* Und für das Gegenteil: Zahlen brauchen keine 340 px. */
.kp-feld-kurz input{max-width:130px}

/* 🔴 …ein DATUM aber schon (17.08.2026, Meldung des Users: „die datums box ist
   viel zu schmal ich kann das jahr nicht richtig tippen", Formular „Leistung
   erfassen").
   Die 130 px oben sind für Zahlenfelder gedacht. Ein Datumsfeld zeigt seit dem
   `appearance:none`-Fix darüber „31.12.2026" als gewöhnlichen Text plus
   Kalendersymbol — das sind rund 145 px, der Jahresblock wird also
   abgeschnitten und lässt sich nicht mehr sauber tippen.
   ⚠️ `min()` statt eines festen Wertes: Auf einem schmalen Schirm gilt wieder
   die Spaltenbreite, sonst ragt das Feld dort heraus — dieselbe Falle wie bei
   `minmax(<px>,…)` in den Rastern. */
.kp-feld-kurz input[type="date"],
.kp-feld-kurz input[type="month"],
.kp-feld-kurz input[type="time"],
.kp-feld-kurz input[type="datetime-local"]{max-width:min(190px,100%)}

/* Kästchen: Box links, fette Bezeichnung, Erklärung darunter. Vorher stand
   die Erklärung in einer Zeile neben der Box und trieb die Zeile auseinander. */
.kp-checks{
  display:grid;gap:12px;
  grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));
  margin-bottom:20px;
}
.kp-check{
  display:flex;align-items:flex-start;gap:11px;
  margin:0;font-weight:400;
  padding:13px 15px;
  background:var(--kp-tile-bg);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  cursor:pointer;
}
.kp-check:hover{border-color:var(--brand)}
.kp-check input{margin-top:2px}
.kp-check > span{display:block;min-width:0}
.kp-check b{display:block;font-weight:700;font-size:.92rem;margin-bottom:3px}
.kp-check small{display:block;color:var(--muted);font-size:.8rem;line-height:1.4}
.kp-check:has(input:checked){border-color:var(--brand);background:var(--brand-soft)}

/* 🔴 Einzeilige Kästchen mittig ausrichten (vom User beanstandet, 10.08.2026:
   „die checkbox bei moderne ansicht sitzt höher als der text").
   `align-items:flex-start` oben ist für die KACHELN gedacht — dort stehen
   eine fette Überschrift und ein Erklärtext, und das Kästchen gehört auf die
   erste Zeile. Wo nur eine Zeile steht (kein <b>), ist genau das falsch: Das
   Kästchen klebt an der Oberkante einer höheren Zeilenbox.
   Erkannt am fehlenden <b> statt an einer neuen Klasse — so greift es
   automatisch bei jedem einzeiligen Kästchen, auch bei künftigen. */
.kp-check:not(:has(b)){align-items:center}
.kp-check:not(:has(b)) input{margin-top:0}

.kp-aktionen{
  display:flex;gap:10px;flex-wrap:wrap;align-items:center;
  padding-top:6px;
}

/* Typ der Beziehung: kompakte Schalter in einer Reihe, keine Erklärkacheln —
   „Kunde" und „Lieferant" erklären sich selbst. */
.kp-feldlabel{font-weight:600;margin:0 0 8px;font-size:.9rem}
/* Feldüberschrift mit Knopf ganz rechts (etwa „Neu" beim Beziehungstyp). */
.kp-feldlabel-mit-knopf{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
}
.kp-typen{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:20px}
.kp-typ{
  display:inline-flex;align-items:center;gap:8px;margin:0;
  padding:7px 14px;font-weight:600;font-size:.88rem;
  background:var(--kp-tile-bg);
  border:1px solid var(--line);border-radius:999px;cursor:pointer;
}
.kp-typ:hover{border-color:var(--brand)}
.kp-typ:has(input:checked){background:var(--brand-soft);border-color:var(--brand);color:var(--brand)}

/* „Neu" als eigene Bubble in derselben Reihe (11.08.2026, Ansage des Users:
   „vielleicht einfach neben die auswahl bubbels eine farblich abgesetzte
   bubbel mit Neu"). Vorher saß der Knopf am rechten Rand der Label-Zeile —
   getrennt von dem, was er anlegt, mit einer breiten Lücke dazwischen.
   Gestrichelter Rand: Es ist kein Wert, den man auswählt, sondern ein Weg
   hinaus. */
.kp-typ-neu{
  border-style:dashed;border-color:var(--brand);color:var(--brand);
  background:transparent;text-decoration:none;
}
.kp-typ-neu:hover{background:var(--brand-soft);text-decoration:none}

/* Rechtematrix: Auge = sehen, Auge+Stift = bearbeiten (11.08.2026) --------
   Der Haken war irreführend — in einer Tabelle liest er sich als „erledigt".
   Zwei Arten von Zugriff brauchen zwei unterscheidbare Zeichen. */
.kp-recht-zeichen{
  display:inline-flex;align-items:center;gap:4px;color:var(--muted);
  vertical-align:-3px;
}
.kp-recht-zeichen.darf{color:var(--brand)}

/* Kästchen in der Rechtematrix: ohne Kachelrahmen. `.kp-check` ist für
   Einstellungskacheln gedacht und füllt die Spalte — bei zwei verschieden
   breiten Spalten sah man zwei verschieden breite Rahmen. */
.kp-recht-box{
  display:inline-flex;align-items:center;justify-content:center;
  margin:0;padding:6px;cursor:pointer;
}
.kp-recht-box input{width:17px;height:17px;margin:0;cursor:pointer}
.kp-recht-box input:disabled{cursor:not-allowed;opacity:.5}

/* Suchleiste über der Liste */
.kp-suchleiste{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:18px;align-items:center}
.kp-suchleiste input{max-width:380px}
.kp-suchleiste select{max-width:190px}
.kp-suchleiste input,.kp-suchleiste select{padding:9px 12px}
/* 🔴 Ein Feld MIT Symbol behält seinen Einzug (13.08.2026, vom User beanstandet:
   „die suchtextbox ist gequetscht, der text ragt unter die lupe"). Die Regel
   darüber ist mit `.kp-suchleiste input` stärker als `.kp-feld-eingerueckt`
   und setzte den linken Abstand auf 12 px zurück — der Text lief unter das
   Symbol. Gilt für JEDE Suchleiste mit Symbolfeld, nicht nur für die eine. */
.kp-suchleiste .kp-feld-eingerueckt{padding-left:38px}
.kp-suchleiste .kp-feld-symbolisch{max-width:380px;flex:1 1 220px}

/* --------------------------------------------------------------------------
   5. Kennzahlen-Kacheln
   -------------------------------------------------------------------------- */
.kp-kacheln{
  display:grid;gap:14px;
  grid-template-columns:repeat(auto-fit,minmax(min(190px,100%),1fr));
  margin-bottom:8px;
}
.kp-kachel{
  background:var(--kp-tile-bg);
  border:1px solid var(--line);
  border-radius:var(--radius-sm);
  padding:16px 18px;
}
.kp-kachel-wert{font-size:1.7rem;font-weight:800;line-height:1.1;color:var(--text)}
.kp-kachel-wert.klein{font-size:1.12rem;font-weight:700}
.kp-kachel-lbl{font-size:.78rem;color:var(--muted);margin-top:7px}
a.kp-kachel{display:block;color:inherit;text-decoration:none;transition:border-color .15s,transform .15s}
a.kp-kachel:hover{text-decoration:none;border-color:var(--brand);transform:translateY(-2px)}

/* Ampel fuer den Vertrags- bzw. Datenstand */
.kp-ampel{display:inline-flex;align-items:center;gap:7px}
.kp-ampel::before{content:"";width:9px;height:9px;border-radius:50%;flex:0 0 auto;background:var(--muted)}
.kp-ampel.gut::before{background:var(--kp-gut)}
.kp-ampel.warn::before{background:var(--kp-warn)}
.kp-ampel.stop::before{background:var(--danger)}

/* --------------------------------------------------------------------------
   6. Listen und Tabellen
   -------------------------------------------------------------------------- */
.kp-liste{list-style:none;margin:0;padding:0}
.kp-liste li{
  display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  padding:11px 0;border-bottom:1px solid var(--line);
}
.kp-liste li:last-child{border-bottom:0;padding-bottom:0}
.kp-liste li:first-child{padding-top:0}
.kp-liste-name{font-weight:600}
.kp-liste-meta{margin-left:auto;font-size:.84rem;color:var(--muted);white-space:nowrap}

/* --------------------------------------------------------------------------
   Diagramme

   🔴 Die Serienfarbe ist NICHT die Markenfarbe des Mandanten — bewusst.
   --brand ist je Mandant frei einstellbar; eine hellgelbe oder blassgraue
   Marke ergaebe unlesbare Balken, und unser eigenes Rot ist von der
   Warnfarbe kaum zu unterscheiden. Deshalb ein festes, geprueftes Blau.
   Geprueft heisst: gegen die echten Kartenfarben (#ffffff hell, #1a2030
   dunkel) durch den Palettenvalidator gelaufen — Helligkeitsband, Chroma,
   Kontrast alle bestanden.

   Ebenfalls geprueft und deshalb VERWORFEN: ein gestapelter Balken in den
   Statusfarben. Status-Rot und Status-Gruen liegen unter Deuteranopie nur
   4,1 auseinander (noetig waeren 8) — fuer Rotgrunblinde nicht zu trennen.
   Alle Verteilungen tragen daher EINE Farbe; die Aussage steckt in der
   Laenge, nicht im Farbton.
   -------------------------------------------------------------------------- */
/* ⚠️ Diese Werte sind nur die VORGABE. Hat der Mandant einen Farbsatz gewählt,
   überschreibt `_layout.php` sie im Kopf → src/Diagrammfarben.php.
   `--viz-serie-2` ist die zweite KATEGORIE (nicht dieselbe Farbe heller): Sie
   trägt dort, wo zwei Dinge nebeneinanderstehen, etwa im Vollkreis. */
:root{
  --viz-serie:#2a78d6;
  --viz-serie-2:#eb6834;
  --viz-serie-hell:#5598e7;
  --viz-flaeche:rgba(42,120,214,.10);
  --viz-grid:#e5e7eb;
  --viz-achse:#c3c2b7;
  --viz-text:#6b7280;
}
html[data-theme="dark"]{
  --viz-serie:#3987e5;
  --viz-serie-2:#d95926;
  --viz-serie-hell:#6da7ec;
  --viz-flaeche:rgba(57,135,229,.14);
  --viz-grid:rgba(255,255,255,.10);
  --viz-achse:rgba(255,255,255,.20);
  --viz-text:#94a3b8;
}

.kp-chart{margin:0;position:relative}
.kp-chart-flaeche{position:relative;min-height:40px}
.kp-chart svg{display:block;overflow:visible}
/* Beschriftung traegt Text-, nie Datenfarben. */
.kp-chart-tick{font-size:.72rem;font-variant-numeric:tabular-nums}
.kp-chart-name{font-size:.82rem}
.kp-chart-wert{font-size:.78rem;font-variant-numeric:tabular-nums}
.kp-chart-stab{transition:fill .15s}
.kp-chart-stab.hell{fill:var(--viz-serie-hell)}
.kp-chart rect[tabindex]:focus-visible{outline:2px solid var(--viz-serie);outline-offset:1px}

.kp-chart-tip{
  position:absolute;z-index:5;pointer-events:none;
  background:var(--kp-tip-bg);color:var(--kp-tip-text);
  padding:7px 10px;border-radius:8px;font-size:.8rem;line-height:1.35;
  box-shadow:0 6px 20px rgba(0,0,0,.22);white-space:nowrap;
}
.kp-chart-tip strong{display:block;font-variant-numeric:tabular-nums}
.kp-chart-tip span{opacity:.75;font-size:.74rem}

.kp-chart-fuss{
  margin:10px 0 0;font-size:.78rem;color:var(--muted);
}

/* Gesamtzahl unter einem Diagramm. Gebraucht beim VOLLKREIS: Beim Ring steht
   sie in der freien Mitte, beim Kreis gibt es die nicht — und im Fließtext
   ginge sie unter. Absichtlich allgemein benannt, nicht „umsatz". */
.kp-chart-summe{
  display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;
  margin:14px 0 0;padding-top:12px;border-top:1px solid var(--line);
}
.kp-chart-summe strong{
  font-size:1.3rem;font-weight:700;color:var(--text);
  font-variant-numeric:tabular-nums;line-height:1.2;
}
.kp-chart-summe span{color:var(--muted);font-size:.85rem}

/* Ueberschrift ueber einer einzelnen Flaeche — noetig, sobald zwei kleine
   Diagramme nebeneinander stehen: Ohne Beschriftung waere nicht zu sehen,
   welche Reihe welche ist. */
.kp-chart-titel{
  margin:0 0 6px;font-size:.82rem;font-weight:600;color:var(--muted);
  text-transform:none;
}

/* Die Tabelle unter den Diagrammen — zugleich die barrierefreie Zweitfassung:
   jeder Wert aus einer Grafik ist hier als Text zu lesen. */
.kp-tabelle-klapp summary{
  cursor:pointer;font-size:.84rem;color:var(--muted);
  padding:8px 0;list-style:none;
}
.kp-tabelle-klapp summary::-webkit-details-marker{display:none}
.kp-tabelle-klapp summary::before{content:"▸ ";display:inline-block;transition:transform .15s}
.kp-tabelle-klapp[open] summary::before{content:"▾ "}
.kp-tabelle-klapp summary:hover{color:var(--text)}

/* Ringdiagramm (Stimmungsbarometer).
   🔴 Die Legende ist hier keine Zugabe, sondern Pflicht: Status-Rot und
   Status-Gruen sind fuer Rotgruenblinde kaum zu trennen, und im Kreis
   beruehren sich alle Segmente. Wort und Zahl tragen die Aussage. */
.kp-ring-box{display:flex;gap:22px;align-items:center;flex-wrap:wrap}
.kp-ring-summe{font-size:1.5rem;font-weight:800}
.kp-ring-lbl{font-size:.72rem}
.kp-ring-teil{cursor:pointer;transition:stroke-width .15s}
.kp-ring-teil:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

.kp-ring-legende{list-style:none;margin:0;padding:0;flex:1 1 190px;min-width:180px}
.kp-ring-legende li{
  display:flex;align-items:center;gap:9px;
  padding:7px 0;border-bottom:1px solid var(--line);font-size:.9rem;
}
.kp-ring-legende li:last-child{border-bottom:0}
.kp-ring-punkt{width:10px;height:10px;border-radius:50%;flex:0 0 auto}
.kp-ring-name{flex:1 1 auto}
.kp-ring-wert{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.kp-ring-anteil{
  font-weight:400;color:var(--muted);font-size:.8rem;margin-left:7px;
}

/* Stimmungsmarke in Listen und Tabellen */
.kp-stimmung{display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
.kp-stimmung::before{content:"";width:9px;height:9px;border-radius:50%;flex:0 0 auto}
.kp-stimmung.gruen::before{background:#0ca30c}
.kp-stimmung.gelb::before {background:#fab219}
.kp-stimmung.rot::before  {background:#d03b3b}
.kp-stimmung.ohne::before {background:#9ca3af}

/* --------------------------------------------------------------------------
   Nachrichten — Aufbau nach dem Vorbild des LMS: Gespraechsliste links,
   Verlauf als Sprechblasen, eigene rechts in der Markenfarbe.
   -------------------------------------------------------------------------- */
/* Avatarkreis fuer Personen, aus Profil::avatar().
   Groesse und Farbe kommen als Inline-Stil mit: Sie haengen an der Person und
   an der Stelle, nicht am Thema. Hier steht nur, was immer gilt. */
.kp-avatar-kreis{
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:50%;overflow:hidden;flex:0 0 auto;vertical-align:middle;
  background:var(--kreis,var(--brand));color:#fff;
  font-weight:700;letter-spacing:.02em;line-height:1;
  user-select:none;
}
.kp-avatar-kreis img{width:100%;height:100%;object-fit:cover;display:block}

/* Gespraechsliste: Bild und Name in einer Zeile. */
.kp-msg-eintrag .kp-liste-name{display:flex;align-items:center;gap:10px;min-width:0}
.kp-msg-eintrag .kp-liste-name > span{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* Benutzermenue oben rechts (Vorbild LMS).
   <details>/<summary> statt eigener Klapplogik: schliesst beim Klick nach
   aussen von selbst und ist ohne JavaScript bedienbar. */
.kp-benutzer{position:relative}
.kp-benutzer > summary{
  display:flex;align-items:center;gap:9px;cursor:pointer;
  padding:5px 10px 5px 5px;border-radius:999px;
  /* Der Rahmen steht IMMER (Ansage des Users 08.08.2026): Ohne ihn sieht der
     Knopf nicht nach Bedienelement aus, und beim Ueberfahren sprang vorher
     die Umrandung ins Bild. */
  border:1px solid var(--line);list-style:none;
  transition:background .15s ease, border-color .15s ease;
}
.kp-benutzer > summary::-webkit-details-marker{display:none}
.kp-benutzer > summary::marker{content:""}
.kp-benutzer > summary:hover{background:var(--brand-soft);border-color:var(--brand)}
.kp-benutzer > summary:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* Aufgeklappt deutlich abgesetzt — der Knopf gehoert dann sichtbar zum
   Kasten darunter. */
.kp-benutzer[open] > summary{
  background:var(--brand-soft);
  border-color:var(--brand);
}

.kp-benutzer-bild{
  width:30px;height:30px;border-radius:50%;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;overflow:hidden;
  background:var(--kreis,var(--brand));color:#fff;
  font-size:.72rem;font-weight:700;letter-spacing:.02em;
}
.kp-benutzer-bild img{width:100%;height:100%;object-fit:cover;display:block}
.kp-benutzer-name{
  font-size:.86rem;font-weight:600;max-width:190px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.kp-benutzer-pfeil{color:var(--muted);flex:0 0 auto;transition:transform .15s}
.kp-benutzer[open] .kp-benutzer-pfeil{transform:rotate(180deg)}

.kp-benutzer-klapp{
  position:absolute;right:0;top:calc(100% + 8px);z-index:60;
  min-width:230px;padding:6px;
  /* 🔴 `--kp-flyout`, nicht `--card` (vom User beanstandet, 10.08.2026:
     „abmelden ist so schlechter lesbar"). Bei eingeschalteter Glasoptik ist
     `--card` = `rgba(255,255,255,.06)`; der Kasten war fast durchsichtig und
     der Seiteninhalt las sich hindurch. Dieselbe Falle wie beim Filterkasten
     und beim Diagramm-Tooltip. **Merksatz: Jeder Kasten, der ÜBER dem Inhalt
     schwebt, braucht eine deckende Fläche.** */
  background:var(--kp-flyout);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 14px 40px rgba(0,0,0,.22);
}
.kp-benutzer-kopf{
  margin:0;padding:8px 10px 10px;border-bottom:1px solid var(--line);
  display:flex;flex-direction:column;gap:2px;
}
.kp-benutzer-kopf strong{font-size:.88rem}
.kp-benutzer-kopf span{
  font-size:.76rem;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.kp-benutzer-klapp a{
  display:flex;align-items:center;gap:10px;
  padding:9px 11px;border-radius:8px;
  font-size:.88rem;color:var(--text);text-decoration:none;
  /* Der Streifen links entsteht aus dem Rahmen — so springt beim Ueberfahren
     nichts, weil die Breite von Anfang an steht. */
  border-left:2px solid transparent;
  transition:background .14s ease, color .14s ease, border-color .14s ease;
}
.kp-benutzer-symbol{
  color:var(--muted);flex:0 0 auto;
  transition:color .14s ease, transform .14s ease;
}
.kp-benutzer-klapp a > span{flex:1 1 auto}

.kp-benutzer-klapp a:hover,
.kp-benutzer-klapp a:focus-visible{
  background:var(--brand-soft);
  color:var(--brand);
  border-left-color:var(--brand);
  outline:none;
}
.kp-benutzer-klapp a:hover .kp-benutzer-symbol,
.kp-benutzer-klapp a:focus-visible .kp-benutzer-symbol{
  color:var(--brand);
  transform:translateX(1px);
}

/* Zahl der ungelesenen Nachrichten in der Zeile. */
.kp-benutzer-zahl{
  flex:0 0 auto;min-width:20px;padding:1px 6px;border-radius:999px;
  background:var(--brand);color:#fff;
  font-size:.7rem;font-weight:700;text-align:center;
}

/* Abmelden abgesetzt: Es ist die einzige Zeile mit Folgen. */
.kp-benutzer-aus{
  margin-top:5px;padding-top:11px !important;
  border-top:1px solid var(--line);
  color:var(--danger) !important;
}
.kp-benutzer-aus .kp-benutzer-symbol{color:var(--danger);opacity:.7}
.kp-benutzer-aus:hover,
.kp-benutzer-aus:focus-visible{
  background:color-mix(in srgb, var(--danger) 10%, transparent);
  border-left-color:var(--danger);
}
.kp-benutzer-aus:hover .kp-benutzer-symbol,
.kp-benutzer-aus:focus-visible .kp-benutzer-symbol{
  color:var(--danger);opacity:1;
}

/* Wer die Bewegung abbestellt hat, bekommt nur den Farbwechsel. */
@media (prefers-reduced-motion:reduce){
  .kp-benutzer-klapp a,
  .kp-benutzer-symbol{transition:none}
  .kp-benutzer-klapp a:hover .kp-benutzer-symbol{transform:none}
}

/* Auf schmalen Schirmen bleibt nur das Bild — der Name frisst die Kopfzeile. */
@media (max-width:640px){
  .kp-benutzer-name{display:none}
  .kp-benutzer-klapp{min-width:200px}
}

/* Profil: Bild, Initialen und die Vorlagen.
   Der Initialenkreis bekommt seine Farbe ueber --kreis aus dem Markup — sie
   haengt an der Person, nicht am Thema. */
.kp-profil-bild{display:flex;align-items:center;gap:16px;margin-bottom:14px}
.kp-profil-bild img{
  width:96px;height:96px;border-radius:50%;object-fit:cover;
  border:2px solid var(--line);flex:0 0 auto;
}
.kp-initialen{
  width:96px;height:96px;border-radius:50%;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  background:var(--kreis,#2a5c8f);color:#fff;
  font-size:2rem;font-weight:700;letter-spacing:.02em;
  /* Die Palette in Profil::farbe() ist auf weisse Schrift ausgelegt. */
}

/* 🔴 Fünf je Reihe statt freiem Umbruch (Ansage des Users, 11.08.2026:
   „jetzt sind erste reihe 7 zweite reihe 3 bilder"). Mit `flex-wrap` hing die
   Zahl je Reihe an der Fensterbreite, und die letzte Reihe blieb angebrochen.
   Ein Raster mit fester Spaltenzahl bricht immer gleich. */
.kp-avatare{
  display:grid;grid-template-columns:repeat(5, max-content);
  gap:10px;margin-top:6px;justify-content:start;
}
@media (max-width:520px){
  .kp-avatare{grid-template-columns:repeat(4, max-content)}
}
.kp-avatar{
  padding:0;border:2px solid transparent;border-radius:50%;
  background:none;cursor:pointer;line-height:0;
}
.kp-avatar img{width:48px;height:48px;border-radius:50%;object-fit:cover;display:block}
.kp-avatar:hover{border-color:var(--line)}
.kp-avatar.aktiv{border-color:var(--brand)}
.kp-avatar:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* Eingabefelder mit Symbol (Vorbild LMS).
   Der Wrapper ist die Bezugsflaeche fuer beide Overlays; das Symbol nimmt
   keine Klicks an, sonst laesst sich das Feld an seiner linken Kante nicht
   fokussieren. */
.kp-feld-symbolisch{position:relative;display:block}
.kp-feld-symbol{
  position:absolute;left:12px;top:50%;transform:translateY(-50%);
  color:var(--muted);pointer-events:none;display:flex;align-items:center;
}
.kp-feld-eingerueckt{padding-left:38px}
.kp-feld-mit-auge{padding-right:40px}

/* Fehlende Angabe (11.08.2026) — dasselbe Feld mit Symbol wie bei der Suche,
   nur in der Warnfarbe. Der Kunde kommt vom Dashboard („Für Ihre Rechnungen
   fehlt noch: …") hierher und muss sehen, WELCHES Feld gemeint ist; eine
   Meldung allein über dem Formular beantwortet das nicht.
   Der Rahmen ist bewusst nur getönt und nicht rot wie ein Fehler: Es ist
   nichts falsch eingegeben, es steht nur noch nichts drin. */
.kp-feld-fehlt .kp-feld-symbol{color:var(--kp-warn)}
.kp-feld-fehlt input{border-color:var(--kp-warn)}
.kp-feld-fehlt input:focus{border-color:var(--brand)}
.kp-felder small.kp-feld-fehlt-text,
small.kp-feld-fehlt-text{
  display:block;margin-top:5px;color:var(--kp-warn-text);
  font-size:.8rem;line-height:1.35;
}

/* Abwesenheitskalender, Monatsansicht (13.08.2026) ------------------------
   Der erste Entwurf war ein Jahresraster mit 6-px-Spalten — technisch dicht,
   praktisch unlesbar (vom User beanstandet). Jetzt Wochen als Zeilen, Tage als
   Kacheln, Namen im Klartext. */
.kal-kopf{
  display:flex;gap:16px;flex-wrap:wrap;align-items:center;
  justify-content:space-between;margin-bottom:14px;
}
.kal-wahl{display:flex;gap:10px;align-items:center;margin:0}
.kal-wahl .kp-auswahl{width:auto;min-width:140px}
.kal-titel{margin:0 0 12px;font-size:1.15rem}

.kal-monat{
  display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:6px;
}
.kal-wt{
  font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);padding:0 0 4px 2px;
}
.kal-tag{
  min-height:104px;padding:6px;
  border:1px solid var(--line);border-radius:8px;
  background:var(--card);
  display:flex;flex-direction:column;gap:3px;
}
.kal-leer{background:transparent;border-color:transparent}
.kal-zahl{
  font-weight:700;font-size:.9rem;line-height:1;
  display:flex;align-items:center;justify-content:space-between;gap:4px;
}
/* Klappmenü in der Kachel: „＋" erscheint erst beim Überfahren, sonst stünden
   31 Pluszeichen im Raster und der Blick fände die Namen nicht mehr.
   ⚠️ Beim Tastaturfokus und im geöffneten Zustand bleibt es sichtbar — sonst
   wäre es ohne Maus unauffindbar. */
.kal-menu{position:relative}
.kal-menu > summary{
  list-style:none;cursor:pointer;line-height:1;
  padding:1px 5px;border-radius:5px;color:var(--muted);
  opacity:0;transition:opacity .12s;
}
.kal-menu > summary::-webkit-details-marker{display:none}
.kal-tag:hover .kal-menu > summary,
.kal-menu[open] > summary,
.kal-menu > summary:focus-visible{opacity:1}
.kal-menu > summary:hover{background:var(--hover);color:var(--text)}
.kal-menu-liste{
  position:absolute;z-index:30;top:calc(100% + 4px);right:0;min-width:190px;
  padding:6px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--kp-flyout);box-shadow:0 14px 40px rgba(0,0,0,.35);
  font-weight:400;
}
.kal-menu-liste a{
  display:block;padding:7px 10px;border-radius:6px;
  font-size:.85rem;text-decoration:none;color:var(--text);white-space:nowrap;
}
.kal-menu-liste a:hover{background:var(--hover)}
/* Betriebsfrei: eigene Kennzeichnung neben dem gesetzlichen Feiertag. */
.kal-tag.kal-betriebsfrei{background:rgba(224,161,42,.16);border-color:#e0a12a}
.kal-betrieb{
  font-size:.72rem;line-height:1.2;color:var(--kp-warn-text);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.kal-legende .kal-betriebsfrei{background:rgba(224,161,42,.5);border-color:#e0a12a}
.kal-tag.kal-frei{background:var(--hover)}
/* Feiertag eigen gekennzeichnet — er ist eine Auskunft, kein bloßes „frei",
   und er gilt je nach Bundesland verschieden. */
.kal-tag.kal-feier{background:rgba(138,180,216,.22);border-color:#8ab4d8}
.kal-tag.kal-heute{box-shadow:inset 0 0 0 2px var(--brand)}
.kal-feiername{
  font-size:.72rem;line-height:1.2;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* Ein Name je Zeile, abgeschnitten statt umgebrochen: Sonst wachsen die
   Kacheln je nach Namenslänge unterschiedlich hoch und das Raster wackelt. */
.kal-person{
  font-size:.76rem;line-height:1.25;padding:2px 5px;border-radius:5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#fff;
}
.kal-person.kal-weg{background:#c0392b}
.kal-person.kal-offen{
  background:repeating-linear-gradient(45deg,#c0392b 0 5px,#a33328 5px 10px);
}
.kal-legende{
  display:flex;gap:18px;flex-wrap:wrap;align-items:center;
  margin:0 0 14px;font-size:.85rem;color:var(--muted);
}
.kal-legende i{
  display:inline-block;width:12px;height:12px;margin-right:6px;
  vertical-align:-2px;border:1px solid var(--line);border-radius:3px;
}
.kal-legende .kal-weg{background:#c0392b}
.kal-legende .kal-offen{background:repeating-linear-gradient(45deg,#c0392b 0 3px,#a33328 3px 6px)}
.kal-legende .kal-feier{background:rgba(138,180,216,.5);border-color:#8ab4d8}
.kal-legende .kal-frei{background:var(--hover)}

/* Auf schmalen Geräten kippt die Woche in zwei Blöcke — sieben Kacheln
   nebeneinander sind unter 700 px nicht mehr lesbar. */
@media (max-width:700px){
  .kal-monat{grid-template-columns:repeat(4,minmax(0,1fr))}
  .kal-wt{display:none}
  .kal-tag{min-height:86px}
  .kal-leer{display:none}
}

/* Urlaubsanträge: Liste links, Detail rechts (13.08.2026) -----------------
   Der erste Entwurf war eine breite Tabelle — dort war ausgerechnet die
   wichtigste Angabe (wer sonst noch weg ist) die schmalste Spalte. */
.an-zwei{display:grid;grid-template-columns:minmax(260px,340px) 1fr;gap:20px;align-items:start}
.an-liste{padding:16px}
.an-eintrag{
  display:block;padding:10px 12px;border-radius:var(--radius);
  text-decoration:none;color:var(--text);border:1px solid transparent;
}
.an-eintrag:hover{background:var(--hover)}
/* Der gewählte Eintrag trägt einen Balken in der Markenfarbe UND einen Rahmen:
   Auf der Fläche allein wäre er bei eingeschalteter Glasoptik kaum zu sehen. */
.an-eintrag.aktiv{
  background:var(--hover);border-color:var(--line);
  box-shadow:inset 3px 0 0 var(--brand);
}
.an-name{display:block;font-weight:600}
.an-zeit{display:block;font-size:.84rem}
.an-art{display:block;font-size:.78rem}

.an-fakten,
.an-konto{display:grid;gap:12px 22px;grid-template-columns:repeat(auto-fit,minmax(min(130px,100%),1fr));margin:0 0 16px}
.an-fakten span,
.an-konto span{display:block;font-size:.76rem;letter-spacing:.04em;text-transform:uppercase}
.an-fakten strong,
.an-konto strong{font-size:1rem}
.an-konto strong{font-size:1.25rem}
.an-plus{color:var(--text)}
.an-minus{color:var(--danger)}
.an-notiz{margin:0 0 16px}
.an-koll{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.an-koll li{line-height:1.35}

@media (max-width:900px){
  .an-zwei{grid-template-columns:1fr}
}

/* Onlinestatus in der Kopfleiste (13.08.2026) — NUR das Symbol, kein Text
   (Ansage des Users). Der Ball ist etwas größer als in Listen: Er steht allein
   zwischen zwei Strichzeichnungen und wäre mit 10 px kaum zu treffen.
   Das Wort liegt in `title` und `aria-label`. */
.kp-kopf-status{display:inline-flex;align-items:center;justify-content:center}
.kp-kopf-status .kp-ball{
  width:14px;height:14px;margin:0;
  box-shadow:0 0 0 1px rgba(0,0,0,.18) inset, 0 0 0 3px var(--hover);
}

/* Stempeluhr auf dem Dashboard, zweigeteilt (13.08.2026) ------------------
   Links „Zeit erfassen", rechts „Nächste Abwesenheit" (Ansage des Users).
   Eine Trennlinie statt zweier Karten: Es bleibt eine Auskunft über den
   eigenen Stand, nur mit zwei Fragen darin. */
.kp-stempel-zwei{
  display:grid;grid-template-columns:1fr 1fr;gap:0;
}
.kp-stempel-halb{padding:0 22px}
.kp-stempel-halb:first-child{padding-left:0}
.kp-stempel-halb:last-child{padding-right:0;border-left:1px solid var(--line)}
.kp-stempel-halb > h2{margin:0 0 10px;font-size:1rem}
.kp-stempel-gross{font-size:1.6rem;font-weight:700;line-height:1;color:var(--text)}
.kp-stempel-naechste{margin:0 0 4px}
/* ⚠️ Unter 720 px gestapelt: Zwei Spalten mit Knöpfen nebeneinander sind auf
   dem Handy unbedienbar, und die Trennlinie läge quer. */
@media (max-width:720px){
  .kp-stempel-zwei{grid-template-columns:1fr}
  .kp-stempel-halb{padding:0}
  .kp-stempel-halb:last-child{
    border-left:0;border-top:1px solid var(--line);margin-top:16px;padding-top:16px;
  }
}

/* Band bei laufender Pause (13.08.2026) — eigene Farbe, damit es nicht mit
   dem Kundenansichts-Band (Markenfarbe) und nicht mit dem Supportband
   verwechselt wird. Bernstein wie die Ampel: Es ist kein Fehler, nur ein
   Zustand, den man beenden sollte.
   ⚠️ ZWEI Klassen im Selektor, wie beim Supportband: Die Markenfarbe kommt aus
   einem <style>-Block im Kopf und stünde sonst als spätere Regel gleicher
   Stärke darüber. */
.kp-band.kp-band-pause{background:#7a5a08}
.kp-band.kp-band-pause .btn{color:#7a5a08}

/* Pflicht-Auswahlfeld ohne Wert (13.08.2026) — dieselbe Farbe wie ein leeres
   Pflicht-Eingabefeld. Die Hülle liegt AUSSERHALB von `.kp-auswahl`, weil
   `portal.js` dessen Klassenattribut beim Bauen überschreibt. Getroffen werden
   beide Fassungen: das native <select> (ohne JavaScript) und der eigene Knopf. */
.kp-pflicht-leer select,
.kp-pflicht-leer .kp-auswahl-knopf{border-color:var(--kp-warn)}
.kp-pflicht-leer select:focus,
.kp-pflicht-leer .kp-auswahl-knopf:focus-visible{border-color:var(--brand)}

.kp-feld-auge{
  position:absolute;right:10px;top:50%;transform:translateY(-50%);
  background:none;border:0;padding:4px;cursor:pointer;color:var(--muted);
  display:flex;align-items:center;line-height:1;border-radius:6px;
  transition:color .15s;
}
.kp-feld-auge:hover{color:var(--text)}
.kp-feld-auge:focus-visible{outline:2px solid var(--brand);outline-offset:1px}

/* Chromes und Edges eigene Passwort-Symbole doppeln unser Auge. */
.kp-feld-mit-auge::-ms-reveal,
.kp-feld-mit-auge::-ms-clear{display:none}

/* Tickets: Prioritaet und Verlauf.
   Die Prioritaet traegt Farbe UND Wort — Farbe allein waere fuer
   Rotgruenblinde nicht lesbar. */
.kp-prio{
  display:inline-block;padding:2px 9px;border-radius:20px;
  font-size:.75rem;font-weight:700;border:1px solid;
}
.kp-prio.niedrig {color:var(--muted); border-color:var(--line)}
.kp-prio.normal  {color:#2a78d6; border-color:#2a78d6}
.kp-prio.hoch    {color:#c07800; border-color:#e0a12a}
.kp-prio.dringend{color:#d03b3b; border-color:#d03b3b; background:rgba(208,59,59,.08)}

.kp-verlauf{list-style:none;margin:0;padding:0}
.kp-verlauf li{
  padding:12px 0 12px 14px;border-left:2px solid var(--line);
  margin-bottom:2px;
}
.kp-verlauf li.intern{border-left-color:var(--brand);background:rgba(127,127,127,.05)}
.kp-verlauf-kopf{
  display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;
  font-size:.8rem;color:var(--muted);margin-bottom:5px;
}
.kp-verlauf-kopf strong{color:var(--text);font-size:.86rem}
.kp-verlauf-text{font-size:.92rem;line-height:1.55}

/* reCAPTCHA-Kaestchen: Googles iframe ist 302px breit und laesst sich nicht
   verkleinern — auf schmalen Anmeldekarten deshalb zentrieren statt strecken. */
.kp-captcha{margin:16px 0 0;display:flex;justify-content:center}
.kp-captcha > div{max-width:100%}

/* Dezenter Verweis auf die Mitarbeiteranmeldung — soll nicht mit dem
   Kundenzugang konkurrieren. */
.kp-mitarbeiter-link{color:var(--muted);text-decoration:none;font-size:.84rem}
.kp-mitarbeiter-link:hover{color:var(--brand);text-decoration:underline}

/* Briefumschlag in der Kopfzeile, mit Zaehler wie im LMS. */
.kp-kopf-msg{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;border-radius:10px;color:var(--text);
  border:1px solid var(--line);text-decoration:none;transition:border-color .15s,color .15s;
}
.kp-kopf-msg:hover{color:var(--brand);border-color:var(--brand);text-decoration:none}
.kp-kopf-msg:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.kp-kopf-msg-zahl{
  position:absolute;top:-6px;right:-6px;
  background:var(--brand);color:#fff;border-radius:20px;
  min-width:18px;height:18px;padding:0 5px;
  font-size:.68rem;font-weight:700;line-height:18px;text-align:center;
  border:2px solid var(--card);
}

.kp-msg-layout{display:grid;gap:20px;grid-template-columns:300px 1fr;align-items:start}
@media (max-width:900px){ .kp-msg-layout{grid-template-columns:1fr} }

.kp-msg-liste .kp-liste-name.aktiv{color:var(--brand)}
.kp-msg-zahl{
  background:var(--brand);color:#fff;border-radius:20px;
  padding:1px 8px;font-size:.72rem;font-weight:700;
}
.kp-msg-kopf{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding-bottom:14px;margin-bottom:14px;border-bottom:1px solid var(--line)}

.kp-msg-verlauf{
  display:flex;flex-direction:column;gap:12px;
  min-height:180px;max-height:56vh;overflow-y:auto;margin-bottom:18px;
}
.kp-msg-leer{color:var(--muted);text-align:center;padding:36px 0;font-size:.88rem}

.kp-msg-zeile{display:flex;gap:9px;align-items:flex-end;max-width:74%}
/* Der Textblock in der Zeile bleibt eine Spalte — Blase ueber Zeitangabe. */
.kp-msg-zeile > div{display:flex;flex-direction:column;min-width:0}
.kp-msg-bild{flex:0 0 auto;margin-bottom:18px}   /* auf Hoehe der Blase, nicht der Meta */
.kp-msg-zeile.meine{align-self:flex-end}
.kp-msg-zeile.meine > div{align-items:flex-end}
.kp-msg-zeile.fremde{align-self:flex-start}
.kp-msg-zeile.fremde > div{align-items:flex-start}
.kp-msg-blase{
  padding:10px 14px;border-radius:16px;font-size:.92rem;line-height:1.5;
  word-break:break-word;
}
.kp-msg-zeile.meine .kp-msg-blase{
  background:var(--brand);color:#fff;border-bottom-right-radius:4px;
}
.kp-msg-zeile.fremde .kp-msg-blase{
  background:var(--bg);border:1px solid var(--line);border-bottom-left-radius:4px;
}
.kp-msg-meta{font-size:.72rem;color:var(--muted);margin-top:4px}
.kp-msg-antwort{border-top:1px solid var(--line);padding-top:16px}
.kp-msg-antwort textarea{resize:vertical;min-height:72px}

/* Schnellerfassung: Suchzeile und Trefferliste */
.kp-schnellsuche{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.kp-schnellsuche input{flex:1 1 260px;min-width:200px}
.kp-schnellliste li{padding:12px 0}
.kp-schnellliste .kp-liste-name{font-size:1rem}
/* Der ganze Eintrag ist ein Ziel — die Zeile lädt sich sonst zum Danebentippen ein. */
.kp-schnellliste li:hover{background:var(--hover, rgba(127,127,127,.06))}
.kp-schnellliste li:hover .kp-liste-name{text-decoration:underline}

/* Jahresfilter ueber dem Gesamtumsatz */
.kp-jahrfilter{display:flex;align-items:center;gap:10px;margin:0 0 16px}
.kp-jahrfilter label{margin:0;font-size:.84rem;color:var(--muted)}
.kp-jahrfilter select{width:auto;min-width:120px}

/* Der Zeitraum ueber dem ganzen Umsatzreiter (18.08.2026). Ein eigener Kasten,
   damit er nicht wie die Ueberschrift der ersten Karte darunter aussieht — er
   steuert ja alle.
   ⚠️ `flex-wrap` ist Pflicht: Auf dem Telefon steht der erklaerende Satz sonst
   in derselben Zeile wie die Auswahl und drueckt sie aus dem Bild. */
.kp-jahrfilter-oben{
  flex-wrap:wrap;
  margin:0 0 18px;padding:12px 16px;
  background:var(--kp-flyout);border:1px solid var(--line);
  border-radius:var(--radius);
}
.kp-jahrfilter-oben small{flex:1 1 240px;font-size:.8rem;line-height:1.45}

/* Die grosse Summe. Proportionale Ziffern, nicht tabular — bei einer einzelnen
   grossen Zahl laesst tabular-nums die Ziffern auseinanderfallen. */
.kp-summe{margin:0 0 16px}
.kp-summe-wert{font-size:2rem;font-weight:800;line-height:1.1;color:var(--text)}
.kp-summe-lbl{font-size:.8rem;color:var(--muted);margin-top:5px}

/* Hilfeartikel: Klapptexte. <details> statt JavaScript — die Seite muss auch
   dann bedienbar sein, wenn sonst nichts laedt. */
.kp-hilfe-artikel{border-bottom:1px solid var(--line)}
.kp-hilfe-artikel:last-of-type{border-bottom:0}
.kp-hilfe-artikel summary{
  cursor:pointer;padding:12px 0;font-weight:600;list-style:none;
  display:flex;align-items:baseline;gap:9px;
}
.kp-hilfe-artikel summary::-webkit-details-marker{display:none}
.kp-hilfe-artikel summary::before{
  content:"+";color:var(--brand);font-weight:700;flex:0 0 auto;width:12px;
}
.kp-hilfe-artikel[open] summary::before{content:"–"}
.kp-hilfe-artikel summary:hover{color:var(--brand)}
.kp-hilfe-artikel summary:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.kp-hilfe-text{padding:0 0 14px 21px;font-size:.94rem;line-height:1.62}
.kp-hilfe-text p{margin:0 0 10px}
.kp-hilfe-text ul{margin:0 0 10px;padding-left:20px}
.kp-hilfe-text li{margin-bottom:5px}
.kp-hilfe-text > :last-child{margin-bottom:0}

/* Sortierbare Spaltenkoepfe */
.kp-sort-kopf{cursor:pointer;user-select:none;white-space:nowrap}
.kp-sort-kopf:hover{color:var(--brand)}
.kp-sort-kopf::after{content:"";opacity:.35;margin-left:6px}
.kp-sort-kopf.sort-auf::after{content:"▲";opacity:.8}
.kp-sort-kopf.sort-ab::after{content:"▼";opacity:.8}
.kp-sort-kopf:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}

@media (prefers-reduced-motion:reduce){
  .kp-chart-stab{transition:none}
}

/* Handlungsbedarf auf der Uebersicht: Der Punkt traegt die Dringlichkeit, die
   Zahl steht rechts. Eigene Klasse statt .kp-ampel, weil der Punkt hier VOR
   einem Link steht und nicht Teil seines Textes ist. */
.kp-ampel-punkt{
  width:9px;height:9px;border-radius:50%;flex:0 0 auto;
  background:var(--muted);align-self:center;
}
.kp-ampel-punkt.gut{background:var(--kp-gut)}
.kp-ampel-punkt.warn{background:var(--kp-warn)}
.kp-ampel-punkt.stop{background:var(--danger)}
.kp-tuwas li{gap:10px}
.kp-tuwas .kp-liste-meta strong{
  font-size:1rem;color:var(--text);
  font-variant-numeric:tabular-nums;
}

table.tabelle{width:100%;border-collapse:collapse;font-size:.92rem}
table.tabelle th,table.tabelle td{
  padding:11px 12px;text-align:left;border-bottom:1px solid var(--line);vertical-align:top;
}
table.tabelle thead th{
  font-size:.74rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);font-weight:700;border-bottom:2px solid var(--line);
}
table.tabelle tbody tr:hover{background:var(--kp-tile-bg)}

/* --------------------------------------------------------------------------
   Filter im Spaltenkopf (Punkt 15, src/Spaltenfilter.php)
   Aufklappen macht <details>, abgeschickt wird ein GET-Formular — der Filter
   funktioniert also ohne JavaScript.
   -------------------------------------------------------------------------- */
/* Band über der Tabelle: gesetzte Filter als Bubbles, dazu die beiden
   Zurücksetzen-Knöpfe (Ansage des User 08.08.2026). Ohne das Band sieht man
   einen Filter nur am gefärbten Spaltenkopf und muss jede Spalte aufklappen,
   um ihn loszuwerden. */
.kp-filterband{
  display:flex;flex-wrap:wrap;gap:8px;align-items:center;
  margin:0 0 14px;
}
.kp-bubble{
  display:inline-flex;align-items:center;gap:7px;
  padding:5px 12px;border-radius:999px;
  background:var(--brand-soft);border:1px solid var(--brand);
  color:var(--text);font-size:.84rem;line-height:1.3;
}
.kp-bubble-feld{color:var(--muted);font-weight:600}
.kp-bubble > a{
  color:var(--muted);text-decoration:none;font-size:1.05rem;line-height:1;
  padding:0 2px;border-radius:4px;
}
.kp-bubble > a:hover{color:var(--brand);background:var(--hover,rgba(0,0,0,.06))}
/* Die Zurücksetzen-Bubbles sind selbst der Verweis, nicht die Anzeige eines
   Zustands — deshalb neutral und nicht in der Markenfarbe. Sonst sähen sie aus
   wie ein weiterer gesetzter Filter. */
a.kp-bubble-weg{
  background:none;border:1px solid var(--line);color:var(--muted);
  text-decoration:none;font-weight:600;
}
a.kp-bubble-weg:hover{color:var(--text);border-color:var(--muted)}

/* Dieselbe Überlegung für die Meldung „Punkt ist erledigt" (Punkt 30,
   12.08.2026): Sie zeigt keinen gesetzten Filter an, sondern erklärt, warum
   die Liste ungefiltert dasteht. In der Markenfarbe sähe sie aus wie eine
   Einschränkung, die noch wirkt. */
.kp-bubble-neutral{background:none;border:1px solid var(--line);color:var(--muted)}
/* ⚠️ Der Verweis darin ist Text, kein ✕ — die Regel `.kp-bubble > a` macht
   daraus sonst ein großes, graues Zeichen. */
.kp-bubble-neutral > a{
  font-size:inherit;color:var(--brand);text-decoration:underline;padding:0;
}
.kp-bubble-neutral > a:hover{background:none;color:var(--brand)}

/* Sortier-Link im Spaltenkopf (src/Sortierung.php). Trägt den Spaltennamen;
   der Trichter daneben ist der Filter. */
.kp-sort{
  display:inline-flex;align-items:center;gap:5px;
  color:inherit;text-decoration:none;
}
.kp-sort:hover{color:var(--text)}
.kp-sort.an{color:var(--text)}
.kp-sort-pfeil{font-size:.9em;color:var(--brand)}
/* Sortierte und gefilterte Spalte stehen nebeneinander im selben Kopf —
   etwas Luft, sonst kleben Name und Trichter aneinander. */
th > .kp-sort + .kp-spf{margin-left:6px}
/* ⚠️ Ohne das bricht der Trichter in die zweite Zeile, sobald die Spalte
   schmal ist (bei „Portalzugang" und „Aktiv" gesehen) — er sieht dann aus wie
   ein zweites, leeres Kopffeld. */
th:has(> .kp-sort){white-space:nowrap}

.kp-spf{position:relative;display:inline-block;vertical-align:middle}
.kp-spf > details > summary{
  display:inline-flex;align-items:center;gap:6px;
  cursor:pointer;list-style:none;
  /* Der Spaltenkopf erbt seine Auszeichnung — der Filter soll wie eine
     Überschrift aussehen, nicht wie ein Knopf. */
  color:inherit;font:inherit;letter-spacing:inherit;text-transform:inherit;
}
.kp-spf > details > summary::-webkit-details-marker{display:none}
.kp-spf > details > summary:hover{color:var(--text)}
.kp-spf-trichter{
  width:11px;height:11px;flex:0 0 auto;
  fill:currentColor;opacity:.35;
}
.kp-spf > details > summary:hover .kp-spf-trichter{opacity:.7}
/* Greift der Filter, muss man das der Spalte ansehen, ohne sie aufzuklappen. */
.kp-spf.an > details > summary{color:var(--brand)}
.kp-spf.an .kp-spf-trichter{opacity:1}

.kp-spf-kasten{
  position:absolute;z-index:40;top:calc(100% + 8px);left:0;
  min-width:240px;max-width:320px;
  padding:14px;
  background:var(--kp-flyout);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:0 14px 40px rgba(0,0,0,.35);
  /* Zurück zur normalen Textauszeichnung: Der Kopf ist versal und gesperrt,
     die Bedienelemente darin sollen das nicht erben. */
  text-transform:none;letter-spacing:normal;font-size:.9rem;color:var(--text);
}
/* Die letzten Spalten öffnen nach links, sonst schiebt der Kasten die Tabelle
   in die Breite (und wird von .table-wrap abgeschnitten). */
table.tabelle th:nth-last-child(-n+3) .kp-spf-kasten{left:auto;right:0}
.kp-spf-kasten input[type="text"],
.kp-spf-kasten input:not([type]),
.kp-spf-kasten select{width:100%}
.kp-spf-haken{display:grid;gap:6px;max-height:230px;overflow-y:auto}
.kp-spf-haken label{
  display:flex;align-items:center;gap:8px;
  font-weight:500;cursor:pointer;
}
.kp-spf-haken input{margin:0;flex:0 0 auto}
.kp-spf-fuss{display:flex;gap:8px;margin-top:12px}

/* Zeitraumfilter (09.08.2026): von und bis untereinander. Nebeneinander
   bleiben von einem Datumsfeld im 240 px schmalen Kasten nur noch die Pfeile
   der Jahreszahl übrig — der Kalenderknopf drängt es zusammen. */
.kp-spf-zeitraum{display:grid;gap:10px}
.kp-spf-zeitraum label{display:grid;gap:4px}
.kp-spf-zeitraum label > span{
  font-size:.78rem;font-weight:600;color:var(--muted);
  /* Der Kasten erbt die Auszeichnung des Spaltenkopfes — ohne das Zurücksetzen
     stünde „von" in Kapitälchen mit Sperrung wie eine zweite Überschrift. */
  letter-spacing:normal;text-transform:none;
}
/* input[type=date] fällt nicht unter die Breitenregel oben (die trifft nur
   text/typlos/select) und bliebe sonst auf seiner Eigenbreite stehen. */
.kp-spf-kasten input[type="date"]{width:100%}

/* 🔴 .table-wrap scrollt waagerecht (overflow-x:auto) und schneidet damit
   ALLES ab, was aus dem Kasten herausragt — auch nach unten. Solange kein
   Filter offen ist, bleibt das Scrollen; ist einer offen, wird der Deckel
   kurz aufgehoben. Ohne diese Regel wäre der Filterkasten bei einer kurzen
   Tabelle unten abgeschnitten. */
.table-wrap:has(.kp-spf details[open]){overflow:visible}

/* Adressblock so, wie er auf der Rechnung steht */
.kp-adresse{font-style:normal;line-height:1.55}
.kp-adresse .fehlt{color:var(--muted);font-style:italic}

.kp-marke{
  display:inline-block;font-size:.72rem;font-weight:700;
  border-radius:999px;padding:2px 9px;
  background:var(--brand-soft);color:var(--brand);
}
.kp-marke.ruhig{background:var(--line);color:var(--muted)}

/* Abgeschlossene Leistungen in der Kundenansicht (17.08.2026). Sie bleiben
   vollständig lesbar — es ist die eigene Vertragshistorie — treten aber
   zurück, damit das Laufende beim Überfliegen vorne steht.
   ⚠️ Nur ein leiser Ton, KEIN `opacity` auf der ganzen Karte: Das zöge auch
   den Text mit und ginge auf Kosten der Lesbarkeit. Der Stand steht ohnehin
   als Wort in der Marke, nicht nur als Farbe. */
.karte.kp-leist-beendet{border-style:dashed}
.karte.kp-leist-beendet h3{color:var(--muted)}

/* Die Filterleiste der Kundenansicht nutzt `.kp-reiter`, hat aber keine
   Registerkarten darunter — die untere Kante würde ins Leere zeigen. */
.kp-leist-filter{border-bottom:0}

/* --------------------------------------------------------------------------
   7. Fusszeile — im Portal deutlich schlanker als auf den Demoseiten
   -------------------------------------------------------------------------- */
.kp-fuss{
  flex:0 0 auto;
  margin:0;padding:0 34px;
  min-height:var(--kp-fussleiste);
  border-top:1px solid var(--line);
  background:var(--bg);
  display:flex;gap:16px;flex-wrap:wrap;align-items:center;
  font-size:.82rem;color:var(--muted);
}
.kp-fuss a{color:var(--muted)}
.kp-fuss .rechts{margin-left:auto}

/* --------------------------------------------------------------------------
   8. Schmal — Seitenmenue wird zur Schublade
   -------------------------------------------------------------------------- */
.kp-backdrop{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:399}
.kp-backdrop.offen{display:block}
.kp-side-zu{display:none}

@media (max-width:980px){
  .kp-side-btn{display:inline-flex}

  /* Schmale Geräte scrollen wieder ganz normal: Die Seitenspalte ist hier
     eine Schublade, und eine fensterhohe Seite mit eigenem Scrollbereich
     macht auf dem Handy mehr kaputt als sie hilft. */
  /* 🔴 `overflow-y:visible` und NICHT `overflow:visible` (15.08.2026, Fund des
     Users: „scrolle ich da nach rechts verschwindet auch der hintergrund").
     Die Kurzform setzte beide Achsen — und damit das `overflow-x:clip` aus
     `base.css` außer Kraft. Ein zu breiter Inhalt ließ dann die GANZE Seite
     zur Seite scrollen; Kopfzeile, Fußzeile und Hintergrund enden aber bei der
     Fensterbreite, weshalb rechts das Nichts erschien.
     ⚠️ `clip` und nicht `hidden`: `hidden` erzeugt einen Scrollcontainer und
     bricht `position:sticky` der Kopfzeile — steht so schon in `base.css`. */
  body.kp{height:auto;display:block;overflow-y:visible;overflow-x:clip}
  .kp-shell{display:flex}
  .kp-main{overflow:visible;display:block}
  .kp-main-scroll{overflow:visible;padding:20px 18px 28px}
  .kp-fuss{padding:12px 18px;min-height:0}
  .kp-neu{min-height:0;padding:12px 18px 16px;display:block}
  /* Hier läuft die Fußzeile im normalen Fluss mit — kein Platz freihalten. */
  body.kp .to-top{bottom:20px}

  /* Schmale Geraete: Untermenues klappen untereinander auf statt zur Seite —
     rechts waere kein Platz, das Menue ist dort eine Schublade. */
  .kp-neu-unter{
    position:static;min-width:0;margin:0 0 6px;
    box-shadow:none;border-radius:0;border-left:0;border-right:0;
  }

  .kp-side{
    position:fixed;top:0;left:0;z-index:400;
    height:100dvh;width:290px;max-width:88vw;
    transform:translateX(-100%);
    transition:transform .26s cubic-bezier(.4,0,.2,1);
    box-shadow:4px 0 28px rgba(0,0,0,.22);
    border-right:0;overscroll-behavior:contain;
  }
  .kp-side.offen{transform:translateX(0)}

  .kp-side-zu{
    display:flex;align-items:center;justify-content:center;
    position:absolute;top:10px;right:10px;
    width:32px;height:32px;border-radius:50%;
    background:rgba(0,0,0,.08);border:0;cursor:pointer;
    color:var(--text);font-size:1rem;z-index:1;
  }
  html[data-theme="dark"] .kp-side-zu{background:rgba(255,255,255,.1)}

  .kp-main{padding:20px 18px 44px}
  .kp-zweispalt{grid-template-columns:1fr}
}

@media (prefers-reduced-motion:reduce){
  .kp-side{transition:none}
  a.kp-kachel:hover{transform:none}
}

/* Trenner im Seitenmenü — setzt die „+ Neu"-Einträge von den Listen ab. */
.kp-nav-trenner{
  border:0;border-top:1px solid var(--line);
  margin:10px 18px 8px;
}


/* --------------------------------------------------------------------------
   Reiter auf Detailseiten
   Die Leiste klebt oben im Scrollbereich, damit man beim Blättern nicht
   erst zurückscrollen muss. Ohne JavaScript sind alle Bereiche sichtbar —
   das ist zwar lang, aber nie kaputt.
   -------------------------------------------------------------------------- */
/* 🔴 KEIN `position:sticky` (vom User verworfen, 10.08.2026: „im tab möchte
   ich da aber kein sticky das sieht scheisse aus").
   Woran es lag: Der Scrollbereich `.kp-main-scroll` hat `padding-top:28px`.
   Die Leiste blieb deshalb 28 px unterhalb seiner Oberkante stehen, und in
   diesem Streifen lief der Inhalt sichtbar an ihr vorbei — es sah aus, als
   schwebe die Leiste willkürlich im Text. Nicht wieder einbauen, ohne diesen
   Streifen zu lösen. */
.kp-reiter{
  display:flex;gap:2px;flex-wrap:wrap;
  margin:0 0 22px;padding-top:2px;
  background:var(--bg);
  border-bottom:1px solid var(--line);
}
/* Reiter sind meist Knöpfe (JS schaltet um). Die Stammdaten nutzen LINKS —
   jede Liste hat eigene Blätterung und wird einzeln geladen. Gleiche Optik,
   deshalb dieselben Regeln; `text-decoration` muss beim Link weg. */
.kp-reiter button,
.kp-reiter a{
  display:inline-flex;align-items:center;gap:8px;
  border:0;border-bottom:3px solid transparent;background:none;
  padding:10px 16px;margin-bottom:-1px;
  font:inherit;font-size:.92rem;font-weight:600;color:var(--muted);
  cursor:pointer;text-decoration:none;
}
.kp-reiter button:hover,
.kp-reiter a:hover{color:var(--text)}
.kp-reiter button.aktiv,
.kp-reiter a.aktiv{color:var(--brand);border-bottom-color:var(--brand)}
.kp-reiter-zahl{
  font-size:.72rem;font-weight:700;border-radius:999px;padding:1px 8px;
  background:var(--line);color:var(--muted);
}
/* Trenner in der Reiterleiste: Was dahinter steht, wechselt die SEITE und
   nicht nur den Reiter (Einstellungen → Stammdaten/Hilfe/Zugänge). Ohne diese
   Kante sähe ein Seitenwechsel wie ein Reiterwechsel aus — und ungespeicherte
   Eingaben im Formular gingen unbemerkt verloren. */
.kp-reiter-trenner{
  align-self:center;width:1px;height:20px;margin:0 10px;
  background:var(--line);flex:0 0 auto;
}
.kp-reiter button.aktiv .kp-reiter-zahl,
.kp-reiter a.aktiv .kp-reiter-zahl{background:var(--brand-soft);color:var(--brand)}

/* 🔴 Punkt am Reiter mit UNGESPEICHERTEN Eingaben (17.08.2026, Meldung des
   Users: Leistung eingetippt, Reiter gewechselt, dort gespeichert — Leistung
   weg). Jeder Reiter trägt sein eigenes Formular; abgeschickt wird immer nur
   eines. Der Punkt macht sichtbar, wo noch etwas offen ist, `portal.js` fragt
   zusätzlich vor dem Absenden nach.
   ⚠️ Als `::after` und nicht als zusätzliches Element: Die Knöpfe entstehen im
   Markup an acht Stellen, ein Element müsste überall mitgepflegt werden.
   ⚠️ Die Farbe kommt aus `--kp-warn` und nicht aus der Markenfarbe — es ist
   ein Hinweis, keine Auszeichnung. */
.kp-reiter button.kp-offen::after,
.kp-reiter a.kp-offen::after{
  content:"";display:inline-block;width:7px;height:7px;margin-left:7px;
  border-radius:999px;background:var(--kp-warn,#c47f17);vertical-align:middle;
}

/* Stammdatenlisten als RASTER (14.08.2026, Ansage des Users: „die darstellung
   noch etwas schöner"). Sechzehn Knöpfe in einer flexiblen Reihe brechen
   ausgefranst um — jede Zeile endet woanders, und das Auge findet den
   gesuchten Eintrag nicht.

   `auto-fill` mit fester Mindestbreite füllt die Zeile stattdessen mit gleich
   breiten Feldern; bei schmalem Fenster werden es von selbst weniger Spalten.
   Der Name steht links, die Anzahl rechts — dadurch stehen alle Zahlen
   untereinander und lassen sich vergleichen. */
.kp-stammliste{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(215px, 1fr));
  gap:8px;margin:0 0 22px;
}
.kp-stammliste .btn{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  width:100%;text-align:left;
  /* 🔴 `.btn + .btn{margin-left:8px}` gilt global für jeden Knopf AUSSER dem
     ersten — gedacht für Knöpfe nebeneinander in einer Reihe. Im Raster ist
     das falsch: Der Abstand kommt hier von `gap`, und der zusätzliche Rand
     schob alle Felder außer dem ersten um 8 px nach rechts. Genau so vom User
     gesehen (14.08.2026): „abteilungen ist weiter links als alle anderen und
     hat rechts etwas mehr abstand". */
  margin-left:0;
  /* Lange Namen („Beschäftigungsarten") dürfen den Knopf nicht sprengen. */
  overflow:hidden;
}
.kp-stammliste .btn > span:first-child{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* Die Zahl im ausgewählten Knopf steht auf gefülltem Grund — dort trägt der
   graue Kasten nicht, er verschwindet fast. Deshalb durchscheinendes Weiß. */
.kp-stammliste .btn:not(.btn-outline) .kp-reiter-zahl{
  background:rgba(255,255,255,.22);color:#fff;
}

/* Erst wenn JavaScript da ist, wird ausgeblendet. */
/* ⚠️ `html.js`, nicht `body.js` (12.08.2026, Punkt 4b). Die Klasse setzt
   portal.js im KOPF der Seite, bevor der Browser zeichnet — am <body> ginge
   das nicht, den gibt es zu dem Zeitpunkt noch nicht. Vorher fiel sie erst
   bei `DOMContentLoaded`, und bis dahin standen alle Reiter untereinander.
   🔴 Ohne Klasse bleiben sie sichtbar: Eine Detailseite ohne JavaScript wäre
   sonst unbedienbar — man käme an zehn von elf Reitern nicht heran. */
html.js .kp-reiter-inhalt{display:none}
html.js .kp-reiter-inhalt.aktiv{display:block}

/* --------------------------------------------------------------------------
   Kopfzeile über Tabellen: Zahl der Zeilen und Blätterung
   -------------------------------------------------------------------------- */
.kp-listenkopf{
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  margin-bottom:12px;font-size:.86rem;
}
.kp-pro{display:flex;align-items:center;gap:8px;margin:0;font-weight:600;font-size:.86rem}
.kp-pro select{width:auto;padding:6px 10px;font-size:.86rem}
.kp-blaettern{display:flex;align-items:center;gap:10px;margin-left:auto}
.kp-blaettern .aus{opacity:.4;pointer-events:none}

/* Dieselbe Leiste noch einmal UNTER der Liste (18.08.2026, Ansage des Users).
   Wer zwanzig Zeilen durchgesehen hat, steht am Ende der Tabelle — zum
   Weiterblaettern erst wieder hochzuscrollen ist bei jeder Seite derselbe
   unnoetige Weg.
   ⚠️ Abgesetzt durch eine Linie OBEN statt durch Abstand allein: Ohne sie haengt
   sie an der letzten Tabellenzeile und liest sich wie deren Fortsetzung. */
/* ⚠️ Der obere Rand war bis zum 21.08.2026 NEGATIV (-14px) und zog die
   Leiste an die Tabelle heran — Ansage des Users: „die vor / zurück buttons
   unter den listen bitte etwas mehr abstand zur liste selbst, sie kleben
   direkt an der liste". Der Wert stammte aus einer Zeit, in der die Hülle
   `.table-wrap` einen eigenen Abstand nach unten mitbrachte; den hat sie nicht
   mehr, und so klebte die Leiste an der letzten Zeile.
   Die Trennlinie bleibt: Sie sagt, dass hier die Liste endet und die Bedienung
   anfängt — nur eben mit Luft davor. */
.kp-listenfuss{
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  margin:14px 0 26px;padding-top:14px;
  border-top:1px solid var(--line);
  font-size:.86rem;
}

/* --------------------------------------------------------------------------
   Dateiauswahl
   Der Browser zeichnet sonst eine graue Systemschaltfläche mitten in ein
   sonst durchgestaltetes Formular — und schneidet den Dateinamen ab.
   -------------------------------------------------------------------------- */
input[type=file]{
  padding:8px 10px;font-size:.86rem;cursor:pointer;line-height:1.6;
}
input[type=file]::file-selector-button{
  margin-right:12px;padding:6px 13px;
  border:1px solid var(--line);border-radius:8px;
  background:var(--kp-tile-bg);color:var(--text);
  font:inherit;font-size:.83rem;font-weight:600;cursor:pointer;
  transition:border-color .15s,color .15s;
}
input[type=file]::file-selector-button:hover{border-color:var(--brand);color:var(--brand)}

/* --------------------------------------------------------------------------
   Dateiauswahl in einer Tabellenzelle (Beleg-Spalte der Zahlliste)
   🔴 Fund des Users am 21.08.2026: „der durchsuchen button bei den belegen
   rutscht aus seiner bubble". Das Feld stand auf `max-width:150px` und war
   damit SCHMALER als sein eigener Knopf — und weil ein Dateifeld seinen Inhalt
   abschneidet, wurde der Knopf rechts gekappt.

   Die Lösung ist nicht ein breiteres Feld, sondern gar kein Feld: Neben einem
   „Hochladen" in derselben Zelle ist für Kasten, Knopf UND Dateinamen kein
   Platz. Ohne Rahmen und Grund ist der KNOPF das äußerste Element — es gibt
   dann nichts mehr, woraus er rutschen könnte.

   ⚠️ Der Dateiname bleibt sichtbar (das Feld zeigt ihn nach der Auswahl an) und
   wird nur mit Auslassungspunkten gekürzt. Ihn wegzublenden wäre bequemer und
   falsch: Wer eine Datei wählt, will lesen können, welche.
   -------------------------------------------------------------------------- */
/* ⚠️ `input[type=file]` davor ist SPEZIFISCHER als eine Klasse (Element +
   Attribut schlaegt Klasse). Ohne den Typ im Selektor blieben Polsterung und
   Hoehe von dort stehen, und die Zeile waere weiter zu hoch — an genau dieser
   Stelle einmal hereingefallen und im Browser nachgemessen. */
input[type=file].kp-beleg-wahl{
  border:0;background:transparent;padding:0;
  width:auto;max-width:none;
  /* Volle Zeilenbreite, damit der Dateiname lesbar bleibt: Der „Hochladen"
     rutscht dadurch in die zweite Zeile. Nebeneinander blieben nach dem Knopf
     rund 70 px fuer den Namen — daraus wird „K…", und das ist keine Auskunft,
     sondern Schutt. */
  flex:1 1 100%;
}
input[type=file].kp-beleg-wahl::file-selector-button{margin-right:8px}
.kp-beleg-form{flex-wrap:wrap}

/* Datumsfelder in einer Suchleiste (21.08.2026).
   ⚠️ `base.css` setzt `input{width:100%}`. In einem Flex-Kasten wird daraus
   eine Wunschbreite, die sich das Feld auch nimmt: Die beiden Datumsfelder der
   Eingangsrechnungen standen bei je 380 px und drueckten das Suchfeld auf 275.
   Ein Datum braucht rund 150 — gemessen im Browser, nicht geschaetzt. */
/* ⚠️ Auch Zahlenfelder: Das km-Feld im Umkreisblock zog sich sonst ueber die
   halbe Leiste, obwohl `size="4"` daran steht — `size` gilt nur, solange
   keine Breite gesetzt ist, und `base.css` setzt eine. Gefunden am
   Erinnerungs-Umkreis (21.08.2026). */
.kp-suchleiste input[type=date],
.kp-suchleiste input[type=number]{width:auto;min-width:0;flex:0 0 auto}

/* --------------------------------------------------------------------------
   Laufbalken des Geo-Sammellaufs (21.08.2026)
   Der Lauf zerfaellt in Haeppchen; dieser Balken zeigt, wie weit er ist.

   ⚠️ Die Schiene hat eine feste Hoehe und der Fuellstand waechst per `width`.
   Eine Skalierung ueber `transform` waere fluessiger, verzerrt aber die
   abgerundeten Enden — bei 3 % saehe die Fuellung aus wie ein Strich mit
   Delle.
   -------------------------------------------------------------------------- */
.kp-geo-stand{margin-top:12px}
.kp-geo-schiene{
  height:8px;border-radius:999px;overflow:hidden;
  background:var(--kp-tile-bg);border:1px solid var(--line);
}
.kp-geo-fuellung{
  height:100%;width:0;border-radius:999px;
  background:var(--brand);
  transition:width 320ms ease;
}
/* Abgebrochen: Der Balken bleibt stehen, wo er war, und wechselt die Farbe.
   Ihn zurueckzusetzen wuerde verschweigen, dass die halbe Arbeit getan ist —
   und sie IST getan, jede Anschrift ist einzeln gespeichert. */
.kp-geo-fuellung.fehler{background:var(--danger)}
.kp-geo-text{margin:8px 0 0;font-size:.82rem;color:var(--muted)}

/* Solange der Lauf laeuft, ist der Knopf gesperrt — ein zweiter Lauf wuerde
   dieselben Anschriften parallel anfragen. */
.kp-geo button[disabled]{opacity:.55;cursor:default}



/* Anklickbare Diagrammzeile (21.08.2026). Der Zeiger ist der einzige Hinweis,
   dass hinter der Zeile etwas liegt — ohne ihn probiert es niemand aus.
   Der Fokusrahmen gehoert an den Anker und nicht an die durchsichtige
   Trefferflaeche: Auf transparentem Grund saehe man ihn nicht. */
.kp-chart-verweis{cursor:pointer}
.kp-chart-verweis:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.kp-chart-verweis:hover .kp-chart-stab{filter:brightness(1.15)}



/* --------------------------------------------------------------------------
   Logo-Upload: Vorschau statt Pfad
   Zwei gleich hohe Karten nebeneinander. Das helle Logo wird auf hellem, das
   dunkle auf dunklem Grund gezeigt — sonst sieht man bei einem von beiden
   schlicht nichts.
   -------------------------------------------------------------------------- */
.kp-logos{
  display:grid;gap:18px;
  grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),380px));
  justify-content:start;
}
.kp-logo{
  border:1px solid var(--line);border-radius:var(--radius);
  padding:16px;background:var(--kp-tile-bg);
}
.kp-logo-kopf{display:flex;align-items:baseline;gap:8px;margin-bottom:12px}
.kp-logo-kopf strong{font-size:.95rem}
.kp-logo-kopf .muted{font-size:.82rem}
.kp-logo-vorschau{
  height:104px;margin-bottom:12px;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:var(--radius-sm);padding:12px;
}
.kp-logo-vorschau.hell{background:#fff}
.kp-logo-vorschau.dunkel{background:#1b1e24}
.kp-logo-vorschau img{max-width:100%;max-height:78px;height:auto;display:block}

/* Kleine Marke, die sagt, woran man gerade ist: Vorgabe oder eigenes Bild. */
.kp-logo-marke{
  display:inline-block;margin:0 0 8px;
  font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  background:var(--line);color:var(--muted);border-radius:999px;padding:3px 10px;
}
.kp-logo input[type=file]{width:100%}
.kp-logo small{display:block;margin-top:6px}
.kp-check-schmal{margin-top:12px;padding:9px 12px;font-size:.86rem}

/* --------------------------------------------------------------------------
   Farbwähler
   input[type=color] erbt sonst width:100% aus base.css und wird zu einem
   dünnen Balken quer über die Spalte — im Bild kaum als Bedienelement
   erkennbar. Hier: quadratische Fläche, Beschriftung daneben.
   -------------------------------------------------------------------------- */
.kp-farben{display:flex;gap:26px;flex-wrap:wrap}
.kp-farbe{display:flex;align-items:center;gap:12px}
.kp-farbe label{margin:0;font-size:.92rem}
.kp-farbe small{display:block;font-weight:400;margin-top:2px}
.kp-farbe input[type=color]{
  width:56px;height:46px;flex:0 0 auto;padding:4px;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--input-bg);
}
.kp-farbe input[type=color]::-webkit-color-swatch-wrapper{padding:0}
.kp-farbe input[type=color]::-webkit-color-swatch{border:0;border-radius:6px}
.kp-farbe input[type=color]::-moz-color-swatch{border:0;border-radius:6px}

/* --------------------------------------------------------------------------
   Dokumente (Modul Dateiverwaltung)
   -------------------------------------------------------------------------- */
.kp-datei-name{display:flex;align-items:center;gap:8px}
.kp-datei-art{
  font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;
  background:var(--line);color:var(--muted);border-radius:4px;padding:2px 6px;
}

/* Reiter, auf denen es nichts zu speichern gibt (etwa die Modulübersicht),
   blenden die Knopfreihe des Formulars aus. Ohne JavaScript sind ohnehin
   alle Karten sichtbar, dann bleibt die Reihe stehen — richtig so. */
.kp-reiter-inhalt[data-ohne-aktionen].aktiv ~ .kp-form-aktionen{display:none}
/* Dasselbe fuer Reiter, die VOR dem Formular stehen muessen, weil sie eigene
   Formulare enthalten (Ticketverteiler) — ein <form> im <form> ist ungueltig. */
.kp-reiter-inhalt[data-ohne-aktionen].aktiv ~ form .kp-form-aktionen{display:none}

/* Freigabecode fürs Vorlesen am Telefon: groß, monospace, gesperrt. */
.kp-code{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:1.8rem;font-weight:700;letter-spacing:.12em;
  margin:6px 0 12px;color:var(--brand);
}


/* --------------------------------------------------------------------------
   Suche ueber alles (Kopfzeile der Verwaltung + Trefferseite)
   Vorbild ist das LMS: Feld im Kopf, Vorschlaege darunter, vollstaendige
   Treffer auf einer eigenen Seite.
   -------------------------------------------------------------------------- */
/* Das Feld waechst beim Anklicken (Vorbild LMS, dort 160 → 220 px).
   Im Ruhezustand soll es nicht die halbe Kopfzeile belegen; wer tippt,
   braucht dagegen Platz — Firmennamen sind laenger als ein Suchwort.

   🔴 Aufgeklappt bleibt es breit, auch wenn der Fokus schon weg ist
   (Klasse `offen` aus portal.js). Sonst schrumpft der Kasten in dem Moment,
   in dem die Maus auf einen Vorschlag zusteuert — und man klickt daneben. */
.kp-such-kopf{
  position:relative;margin-left:auto;flex:0 1 280px;min-width:0;
  transition:flex-basis .2s ease;
}
.kp-such-kopf:focus-within,
.kp-such-kopf.offen{flex-basis:460px}
.kp-such-kopf form{margin:0}

@media (prefers-reduced-motion:reduce){
  .kp-such-kopf{transition:none}
}

.kp-such-feld{
  width:100%;height:38px;padding:5px 40px 5px 16px;
  border-radius:999px;background:var(--card);
  font-size:.9rem;
}
.kp-such-feld::-webkit-search-cancel-button{-webkit-appearance:none}

/* Lupe rechts im Feld — wie im LMS. Sie sitzt IM Feld und nicht daneben,
   damit die Kopfzeile eine Zeile bleibt. */
.kp-such-knopf{
  position:absolute;right:6px;top:50%;transform:translateY(-50%);
  background:none;border:0;padding:6px;cursor:pointer;color:var(--muted);
  display:flex;align-items:center;line-height:1;border-radius:999px;
  transition:color .15s ease, background .15s ease;
}
.kp-such-knopf:hover{color:var(--brand);background:var(--brand-soft)}
.kp-such-knopf:focus-visible{outline:2px solid var(--brand);outline-offset:1px}

/* Vorschlagsliste. Sie liegt ueber allem anderen im Kopf — sonst schoebe
   sich die Kopfzeile beim Tippen auseinander. */
.kp-such-klapp{
  position:absolute;left:0;right:0;top:calc(100% + 8px);z-index:70;
  max-height:min(70vh,560px);overflow-y:auto;
  /* deckend — siehe .kp-benutzer-klapp */
  background:var(--kp-flyout);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 16px 44px rgba(0,0,0,.24);
  padding:6px;
}
.kp-such-klapp[hidden]{display:none}

.kp-such-gruppenkopf{
  display:flex;align-items:center;gap:7px;
  margin:8px 8px 4px;
  font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);
}
.kp-such-gruppenkopf:first-child{margin-top:4px}

.kp-such-treffer{
  display:block;padding:8px 10px;border-radius:9px;
  color:var(--text);text-decoration:none;
}
.kp-such-treffer:hover,
.kp-such-treffer.aus{background:var(--brand-soft);text-decoration:none}
.kp-such-treffer.aus{outline:2px solid var(--brand);outline-offset:-2px}

.kp-such-treffer b{display:block;font-size:.9rem;font-weight:600}
.kp-such-treffer small{
  display:block;font-size:.78rem;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.kp-such-treffer mark{background:var(--brand-soft);color:inherit;font-weight:700}

.kp-such-leer{padding:14px 10px;color:var(--muted);font-size:.88rem}
.kp-such-alle{
  display:block;margin-top:6px;padding:9px 10px;
  border-top:1px solid var(--line);
  font-size:.84rem;font-weight:600;color:var(--brand);text-align:center;
}
.kp-such-alle:hover{background:var(--brand-soft);text-decoration:none}

/* 🔴 Die Suche stand auf schmalen Geraeten bis zum 15.08.2026 auf
   `display:none` — begruendet mit fehlendem Platz neben Marke und Konto.
   Der User hat das beanstandet: „mir faellt grad auf, dass wir mobile unsere
   suche komplett unterschlagen." Zu Recht: Die Suche ist der schnellste Weg
   durch das Portal, und gerade auf dem Handy will man nicht erst ein Menue
   aufklappen.
   Sie sitzt jetzt zwischen Menueknopf und Marke und teilt sich die Zeile mit
   beiden — die Anordnung dafuer steht oben im Block ab `max-width:980px`. */

/* ---- Trefferseite -------------------------------------------------------- */
.kp-suchseite-form{
  display:flex;gap:10px;align-items:center;
  margin:0 0 20px;max-width:640px;
}
.kp-suchseite-form .kp-feld-symbolisch{flex:1 1 auto}

.kp-such-zahl{margin:0 0 16px;color:var(--muted)}
.kp-such-zahl strong{color:var(--text)}

.kp-such-chips{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 22px}
.kp-such-chip{
  display:inline-flex;align-items:center;gap:7px;
  padding:6px 12px;border:1px solid var(--line);border-radius:999px;
  font-size:.85rem;font-weight:600;color:var(--text);text-decoration:none;
  background:var(--card);
}
.kp-such-chip:hover{border-color:var(--brand);color:var(--brand);text-decoration:none}
.kp-such-chip-zahl{
  font-size:.72rem;font-weight:700;border-radius:999px;padding:1px 7px;
  background:var(--line);color:var(--muted);
}

.kp-such-gruppe{margin-bottom:18px}
.kp-such-gruppe-titel{
  display:flex;align-items:center;gap:9px;
  margin:0 0 12px;font-size:1rem;
}
.kp-such-icon{color:var(--brand)}
.kp-such-gruppe-zahl{
  font-size:.74rem;font-weight:700;border-radius:999px;padding:1px 8px;
  background:var(--brand-soft);color:var(--brand);
}

.kp-such-liste{list-style:none;margin:0;padding:0}
.kp-such-liste > li{padding:11px 0;border-top:1px solid var(--line)}
.kp-such-liste > li:first-child{border-top:0}

.kp-such-titel{font-weight:600}
.kp-such-kunde{
  font-size:.8rem;color:var(--muted);
  margin-left:8px;
}
.kp-such-schnipsel{
  margin:4px 0 0;font-size:.86rem;color:var(--muted);
  overflow-wrap:anywhere;
}
.kp-such-liste mark{background:var(--brand-soft);color:inherit;font-weight:700}
.kp-such-mehr{margin:14px 0 0;font-size:.88rem}


/* --------------------------------------------------------------------------
   Glocke (Benachrichtigungen)
   Sieht aus wie der Briefumschlag daneben — es sind zwei Anzeigen derselben
   Art, und sie sollen nicht wie zwei verschiedene Bedienelemente wirken.
   <details>/<summary> wie beim Benutzermenue.
   -------------------------------------------------------------------------- */
.kp-glocke{position:relative}
.kp-glocke > summary{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;border-radius:10px;color:var(--text);
  border:1px solid var(--line);cursor:pointer;list-style:none;
  transition:border-color .15s, color .15s;
}
.kp-glocke > summary::-webkit-details-marker{display:none}
.kp-glocke > summary::marker{content:""}
.kp-glocke > summary:hover{color:var(--brand);border-color:var(--brand)}
.kp-glocke > summary:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.kp-glocke[open] > summary{color:var(--brand);border-color:var(--brand)}

.kp-glocke-zahl{
  position:absolute;top:-6px;right:-6px;
  background:var(--brand);color:#fff;border-radius:20px;
  min-width:18px;height:18px;padding:0 5px;
  font-size:.68rem;font-weight:700;line-height:18px;text-align:center;
  border:2px solid var(--card);
}

.kp-glocke-klapp{
  position:absolute;right:0;top:calc(100% + 8px);z-index:60;
  width:min(380px,calc(100vw - 32px));
  max-height:min(70vh,520px);overflow-y:auto;
  padding:6px;
  /* deckend — siehe .kp-benutzer-klapp */
  background:var(--kp-flyout);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 14px 40px rgba(0,0,0,.22);
}

.kp-glocke-kopf{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:8px 10px 10px;border-bottom:1px solid var(--line);margin-bottom:4px;
}
.kp-glocke-kopf form{margin:0}
.kp-glocke-alle{
  background:none;border:0;padding:0;cursor:pointer;
  font:inherit;font-size:.8rem;font-weight:600;color:var(--brand);
}
.kp-glocke-alle:hover{text-decoration:underline}

.kp-glocke-leer{padding:16px 10px;margin:0;color:var(--muted);font-size:.86rem}

.kp-glocke-eintrag{
  display:flex;gap:10px;align-items:flex-start;
  padding:9px 10px;border-radius:9px;color:var(--text);text-decoration:none;
}
.kp-glocke-eintrag:hover{background:var(--brand-soft);text-decoration:none}

/* Ungelesen traegt einen Balken links UND fettere Schrift: Farbe allein
   traegt die Unterscheidung nicht, wenn jemand sie nicht sieht. */
.kp-glocke-eintrag.neu{border-left:3px solid var(--brand);padding-left:7px}
.kp-glocke-eintrag.neu b{font-weight:700}

.kp-glocke-icon{flex:0 0 auto;color:var(--brand);line-height:1.4}
.kp-glocke-text{min-width:0;display:block}
.kp-glocke-text b{display:block;font-size:.88rem;font-weight:600}
.kp-glocke-text small{
  display:block;font-size:.79rem;color:var(--muted);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.kp-glocke-text time{display:block;font-size:.72rem;color:var(--muted);margin-top:3px}

.kp-glocke-mehr{
  display:block;margin-top:6px;padding:9px 10px;
  border-top:1px solid var(--line);
  font-size:.84rem;font-weight:600;color:var(--brand);text-align:center;
}
.kp-glocke-mehr:hover{background:var(--brand-soft);text-decoration:none}

/* ---- Seite „Hinweise" ---------------------------------------------------- */
.kp-hinweis-leiste{
  display:flex;flex-wrap:wrap;gap:12px;align-items:center;
  justify-content:space-between;margin-bottom:14px;
}
.kp-hinweis-filter,.kp-hinweis-aktionen{display:flex;gap:8px;flex-wrap:wrap}
.kp-hinweis-filter .btn.aktiv{
  border-color:var(--brand);color:var(--brand);background:var(--brand-soft);
}

.kp-hinweis-liste{list-style:none;margin:0;padding:0}
.kp-hinweis-liste > li{
  display:flex;gap:12px;align-items:flex-start;
  padding:12px 0;border-top:1px solid var(--line);
}
.kp-hinweis-liste > li:first-child{border-top:0}
.kp-hinweis-liste > li.neu{
  border-left:3px solid var(--brand);padding-left:11px;
}
.kp-hinweis-icon{flex:0 0 auto;color:var(--brand);line-height:1.5}
.kp-hinweis-text{flex:1 1 auto;min-width:0}
.kp-hinweis-titel{font-weight:600}
.kp-hinweis-liste > li.neu .kp-hinweis-titel{font-weight:700}
.kp-hinweis-schnipsel{
  margin:3px 0 0;font-size:.86rem;color:var(--muted);overflow-wrap:anywhere;
}
.kp-hinweis-wann{display:block;font-size:.75rem;color:var(--muted);margin-top:4px}

.kp-hinweis-weg{margin:0;flex:0 0 auto}
.kp-hinweis-weg button{
  background:none;border:0;padding:4px 8px;cursor:pointer;
  color:var(--muted);font:inherit;font-size:.9rem;border-radius:8px;
}
.kp-hinweis-weg button:hover{color:var(--danger,#c8362e);background:var(--brand-soft)}

/* ==========================================================================
   Auswahlfeld mit eigenem Klappteil (12.08.2026)

   Ansage des Users: „kannst du die optik der dropdown nochmal überarbeiten?
   es hat einen runden rahmen aber eckige einträge, beim lms hast du das
   schöner hinbekommen (ich arbeite im dunkel modus)" — und als Vorbild „im
   lms z.b. das admin menü".

   🔴 Die Liste eines nativen <select> zeichnet das BETRIEBSSYSTEM. Rand,
   Ecken und Farben dieser Liste lassen sich mit CSS nicht anfassen; deshalb
   sitzt unter einem runden Feld ein eckiger Kasten, im dunklen Design
   obendrein oft ein heller. Das ist kein Stylesheet-Fehler, sondern die
   Grenze des Bauteils.

   Deshalb dasselbe Muster wie beim Benutzermenü und der Suche: ein eigener
   Klappteil auf `--kp-flyout` mit Innenabstand, dessen Einträge selbst
   gerundet sind und beim Überfahren die Markenfarbe bekommen.

   ⚠️ Das echte <select> BLEIBT im Markup und trägt weiterhin den Wert — ohne
   JavaScript ist das Feld also unverändert bedienbar, und das Formular
   schickt dasselbe wie vorher. Erst `auswahlfelder()` in portal.js blendet es
   aus und setzt den Knopf davor.
   ========================================================================== */
.kp-auswahl{position:relative;width:100%}

/* 🔴 Das echte Feld wird DURCHSICHTIG gelegt, nicht ausgeblendet.
   Fünf Auswahlfelder im Portal sind `required`. Ein ungültiges Pflichtfeld,
   das der Browser nicht anspringen kann (`display:none`, `visibility:hidden`,
   `hidden`), bricht das Absenden mit „An invalid form control is not
   focusable" ab — und zwar STILL: Der Nutzer klickt auf Speichern und es
   passiert nichts. Durchsichtig hinter dem Knopf bleibt es fokussierbar, die
   Prüfblase erscheint an der richtigen Stelle. */
.kp-auswahl-echt{
  position:absolute;left:0;top:0;width:100%;height:100%;
  opacity:0;pointer-events:none;margin:0;padding:0;border:0;
}
.kp-auswahl-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Ohne JavaScript sieht man nur das native Feld — der Knopf entsteht erst
   dort. Umgekehrt verschwindet das Feld erst, wenn der Knopf steht. */
/* 🔴 Dieselben Werte wie `input,select,textarea` in base.css — Polsterung,
   Radius, Grund und Rand. Der Knopf steht neben echten Eingabefeldern; weicht
   er auch nur um zwei Pixel ab, sieht die Zeile schief aus. */
.kp-auswahl-knopf{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  width:100%;padding:12px;
  background:var(--input-bg);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  color:var(--text);font-family:inherit;font-size:.95rem;text-align:left;
  cursor:pointer;
}
.kp-auswahl-knopf:hover{border-color:var(--brand)}
.kp-auswahl-knopf:focus-visible{outline:2px solid var(--brand);outline-offset:1px}
.kp-auswahl.offen > .kp-auswahl-knopf{border-color:var(--brand)}
/* Der Pfeil dreht sich beim Aufklappen — dasselbe Zeichen wie im „Neu"-Menü. */
/* ⚠️ Deutlich größer als im LMS-Menü (dort .68rem): Dieser Pfeil ersetzt den
   Pfeil eines Auswahlfeldes und steht am Ende einer breiten Zeile. Klein und
   gedämpft war er im Dunkelmodus praktisch unsichtbar — nachgemessen. */
.kp-auswahl-pfeil{
  flex:0 0 auto;font-size:.95rem;line-height:1;
  color:var(--text);opacity:.65;transition:transform .15s;
}
.kp-auswahl-knopf:hover .kp-auswahl-pfeil{opacity:1}
.kp-auswahl.offen .kp-auswahl-pfeil{transform:rotate(180deg)}
/* „— keine Angabe —" steht gedämpft: Es ist die Abwesenheit eines Werts. */
.kp-auswahl-knopf.leer{color:var(--muted)}

.kp-auswahl-klapp{
  position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:80;
  max-height:min(50vh,320px);overflow-y:auto;
  /* 🔴 deckend über `--kp-flyout`, nicht `--card` — dieselbe Regel wie bei
     allen Klappteilen des Portals. */
  background:var(--kp-flyout);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 16px 44px rgba(0,0,0,.24);
  padding:6px;
}
.kp-auswahl-klapp[hidden]{display:none}

.kp-auswahl-eintrag{
  display:block;padding:8px 10px;border-radius:9px;
  color:var(--text);font-size:.92rem;cursor:pointer;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.kp-auswahl-eintrag:hover,
.kp-auswahl-eintrag.aus{background:var(--brand-soft)}
/* Der GEWÄHLTE Eintrag trägt die Markenfarbe, der gerade angesteuerte nur den
   weichen Grund — sonst sieht man beim Blättern mit den Pfeiltasten nicht
   mehr, was eigentlich gesetzt ist. */
.kp-auswahl-eintrag[aria-selected="true"]{font-weight:600;color:var(--brand)}
.kp-auswahl-eintrag.leer{color:var(--muted)}

/* Der rote Rahmen des Pflichtfeldes — das durchsichtige <select> kann ihn
   nicht zeigen, also übernimmt ihn der Knopf. */
.kp-auswahl-knopf.fehlt{border-color:var(--danger,#c8362e)}

/* Der Pflegeverweis unter dem Feld — wie beim Kündigungsgrund. */
.kp-feld-pflege{display:block;margin-top:4px;font-size:.82rem}

/* ⚠️ Wo das <select> bisher schmal war, muss es der Umschlag auch sein: Die
   bestehenden Regeln treffen `select`, und das ist jetzt das unsichtbare Feld
   in der Ecke. Ohne diese vier Zeilen sprengte die Blätterauswahl ihre Zeile. */
/* 🔴 Die Zeilenzahl-Auswahl war zu schmal (17.08.2026, Meldung des Users:
   „die dropdown box mit 10, 20 … ist zu klein und zeigt nur A.. statt Alle").

   Ursache: `width:auto` bemisst sie nach ihrem INHALT — beim Wert „20" sind
   das 59 px. Sie sitzt aber in einem flexiblen Listenkopf, und dort schrumpft
   sie mit, sobald es eng wird; `white-space:normal` bricht „Alle" dann um und
   es bleibt „A.." sichtbar.

   Drei Dinge dagegen: eine Mindestbreite, die auch den längsten Wert samt
   Pfeil trägt, kein Umbruch, und kein Schrumpfen im Flex-Kopf.
   ⚠️ `nowrap` nur hier und nicht am Bauteil allgemein — dieselbe Auswahl
   trägt anderswo lange Katalognamen, die umbrechen dürfen. */
.kp-pro{flex:0 0 auto}
.kp-pro .kp-auswahl{width:auto;min-width:92px}
.kp-pro .kp-auswahl-knopf{padding:6px 10px;font-size:.86rem;white-space:nowrap}
.kp-pro select{min-width:92px}
.kp-jahrfilter .kp-auswahl{width:auto;min-width:120px}
.kp-suchleiste .kp-auswahl{max-width:190px}
.kp-suchleiste .kp-auswahl-knopf{padding:9px 12px}

/* In der Tabellenzeile sitzt das Feld eng — dort keine 100 %. */
table.tabelle .kp-auswahl{width:auto;min-width:140px}
/* ⚠️ Der Spaltenfilter steht AUCH in `table.tabelle` (im `<th>`), soll aber
   die volle Breite seines Klappkastens haben — sonst stünde ein 140 px
   schmales Feld in einem 300 px breiten Kasten. Diese Regel muss deshalb
   hinter der Tabellenregel stehen und die spezifischere sein. */
table.tabelle .kp-spf-kasten .kp-auswahl{width:100%;min-width:0}

/* ---- Newsfeed (Punkt 3b, 12.08.2026) --------------------------------------
   Meldungen auf der Übersicht — in der Verwaltung die des Anbieters, im
   Kundenbereich die des Mandanten. Bewusst schlicht: Der Kasten steht ganz
   oben und darf die Arbeit darunter nicht verdrängen. */
.kp-news{padding:12px 0;border-top:1px solid var(--line)}
.kp-news:first-of-type{padding-top:0;border-top:0}
.kp-news-titel{margin:0;font-size:1rem;font-weight:600}
.kp-news-meta{font-size:.78rem;color:var(--muted);margin:2px 0 6px}
/* Hervorgehoben heißt: ein Balken in der Markenfarbe, keine gefärbte Fläche.
   Eine volle Farbfläche zöge mehr Aufmerksamkeit als der Handlungsbedarf
   darunter, und der ist dringlicher. */
.kp-news.wichtig{
  border-left:3px solid var(--brand);padding-left:11px;
  border-top-color:transparent;
}
.kp-news.wichtig .kp-news-titel{color:var(--brand)}
/* 🔴 Rechtstexte kommen aus der Datenbank und enthalten lange Adressen,
   E-Mails und Aufsichtsbehörden-Links (15.08.2026, Fund des Users: „die
   datenschutzerklärung rutscht auch ausserhalb des bildes"). Ein Wort ohne
   Trennstelle ist so breit, wie es ist — auf dem Handy schiebt es den ganzen
   Kasten über den Rand. `anywhere` erlaubt den Umbruch notfalls mitten im
   Wort; das ist bei einer URL richtig und bei Fließtext folgenlos, weil dort
   Leerzeichen die günstigere Trennstelle sind.
   ⚠️ Eine Tabelle im Rechtstext (Aufbewahrungsfristen) bricht davon nicht um —
   sie bekommt ihren eigenen Scrollbereich. */
.kp-rechtstext{overflow-wrap:anywhere}
.kp-rechtstext table{display:block;width:100%;overflow-x:auto}

/* 🔴 Die ÜBERSCHRIFT war der eigentliche Grund (15.08.2026, Verdacht des
   Users: „ich vermute mal es liegt an der schriftgröße der überschrift" —
   er hatte recht). „Datenschutzerklärung" ist EIN Wort mit 20 Zeichen; bei
   rund 32 px ist es etwa 350 px breit. Auf einem 390-px-Schirm bleiben nach
   Seiten- und Kartenrand aber nur ungefähr 290 px übrig, und ein Wort ohne
   Trennstelle ist so breit, wie es ist — es schiebt die Karte auf.
   ⚠️ Die Überschrift steht AUSSERHALB von `.kp-rechtstext` (sie kommt aus
   `recht.php`, nicht aus dem Text der Datenbank). Die Umbruchregel darüber
   hat sie deshalb nie erfasst — deswegen blieb der Fehler nach dem ersten
   Anlauf bestehen.

   Zwei Maßnahmen, in dieser Reihenfolge wirksam:
   1. `clamp()` — auf schmalen Geräten ist die Zeile kleiner und passt ohne
      Trennung. Das ist die schönere Lösung, deshalb steht sie zuerst.
   2. Silbentrennung als Netz für noch längere Komposita
      („Verantwortlichkeit", „Aufsichtsbehörde"). Deutsch trennt sauber, weil
      `<html lang="de">` gesetzt ist; ohne `lang` täte `hyphens:auto` nichts.
   ⚠️ `-webkit-hyphens` mitschreiben — Safari kennt die kurze Form nicht.
   `overflow-wrap:anywhere` bleibt als letzte Rückfallebene: Es greift erst,
   wenn auch die Trennung nicht reicht. */
.karte-schmal h1{
  font-size:clamp(1.35rem,5.2vw,2rem);
  line-height:1.2;
}
.karte-schmal h1,
.karte-schmal h2,
.kp-rechtstext h2,
.kp-rechtstext h3{
  overflow-wrap:anywhere;
  -webkit-hyphens:auto;hyphens:auto;
}
/* Auf dem Handy zählt jeder Millimeter Textbreite mehr als das Polster:
   34/30 px Innenrand kosten bei 390 px Schirmbreite ein Sechstel der Zeile. */
@media (max-width:560px){
  .karte-schmal{padding:22px 18px}
}
/* ⚠️ `.schmalseite` ist ein Raster mit `place-items:center` (theme.css). Ein
   zentriertes Rasterelement bekommt KEINE volle Breite, sondern richtet sich
   nach seinem Inhalt — bei einem langen Rechtstext kann das breiter werden
   als der Bildschirm. Auf den Anmeldekarten fällt das nicht auf, die sind
   schmal. */
.schmalseite > .container{width:100%}

.kp-news .kp-rechtstext{font-size:.92rem}
.kp-news .kp-rechtstext p:last-child{margin-bottom:0}

/* ---- „Bereits gelesen" (12.08.2026) ---------------------------------------
   Kopfzeile der Karte: Überschrift links, der Archivschalter rechts. Er sitzt
   dort und nicht unter den Meldungen — sonst wandert er mit jeder neuen
   Meldung weiter nach unten und ist einmal ganz aus dem Blick. */
.kp-news-kopf{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;flex-wrap:wrap;margin-bottom:10px;
}
.kp-news-kopf h2{margin:0}
/* Der Knopf gehört zur Meldung, nicht zum Text — deshalb rechtsbündig darunter
   und mit Abstand. Neben dem Titel bräche er bei langen Überschriften um. */
.kp-news-aktion{margin-top:8px;text-align:right}
/* Gelesenes bleibt lesbar, tritt aber zurück: Es steht nur im Archiv, und dort
   sucht man Bekanntes. Kein Durchstreichen — das wäre „erledigt", und eine
   Meldung erledigt sich nicht durchs Lesen. */
.kp-news.erledigt .kp-news-titel{color:var(--muted);font-weight:500}
.kp-news.erledigt .kp-rechtstext{color:var(--muted)}
/* ⚠️ Auch im Archiv behält eine wichtige Meldung ihren Balken, aber in
   Grau — sonst leuchtet eine längst gelesene Wartungsmeldung so kräftig wie
   eine neue. */
.kp-news.wichtig.erledigt{border-left-color:var(--line)}
.kp-news.wichtig.erledigt .kp-news-titel{color:var(--muted)}

/* ==========================================================================
   Mein Arbeitsplatz: Wochenkalender auf dem Dashboard (13.08.2026)
   --------------------------------------------------------------------------
   Ansage des Users: „vielleicht ein kleiner wochenkalender auf dem überblick
   des dashboards?" — Montag bis Sonntag, sieben gleich breite Felder.

   🔴 `grid-template-columns:repeat(7,minmax(0,1fr))` und nicht `1fr`: Ohne
   `minmax(0,…)` bestimmt der längste Inhalt (ein Feiertagsname) die Spalte,
   und aus sieben gleichen Feldern werden sieben verschieden breite.
   ========================================================================== */
.kp-woche-kopf{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;flex-wrap:wrap;margin-bottom:12px;
}
.kp-woche-kopf h2{margin:0}
.kp-woche-nav{display:flex;align-items:center;gap:8px}
.kp-woche-spanne{font-size:.92rem;white-space:nowrap}

.kp-woche{
  display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;
}
.kp-woche-tag{
  /* Deckende Fläche, kein `--card`: Bei eingeschalteter Glasoptik schiene der
     Hintergrund durch und die Tage verlören ihre Kante. */
  background:var(--kp-tile-bg);
  border:1px solid var(--line);border-radius:var(--radius);
  padding:8px;min-height:78px;
  display:flex;flex-direction:column;gap:4px;
}
/* Wochenende, Feiertag, Abwesenheit: derselbe zurückgenommene Ton. Sie haben
   verschiedene Gründe, aber dieselbe Aussage — an diesem Tag wird nicht
   gearbeitet. Der Grund steht als Text darin. */
.kp-woche-tag.ruhig{background:transparent}
.kp-woche-tag.heute{border-color:var(--brand);box-shadow:0 0 0 1px var(--brand) inset}
.kp-woche-datum{display:flex;align-items:baseline;gap:6px;line-height:1}
.kp-woche-wt{font-weight:700;font-size:.86rem}
.kp-woche-nr{font-size:.8rem;color:var(--muted)}
.kp-woche-zeit{font-size:.86rem;margin-top:auto}
/* Marke für Abwesenheit und Feiertag — schmaler Text, umbruchfähig: „Tag der
   Deutschen Einheit" muss in 90 px passen, ohne die Spalte zu sprengen. */
.kp-woche-marke{
  font-size:.78rem;line-height:1.2;font-weight:600;color:var(--kp-warn-text);
  overflow-wrap:anywhere;
}
.kp-woche-marke.frei{color:var(--muted);font-weight:500}
/* Beantragt ist noch nicht entschieden — gestrichelt, wie im Jahreskalender. */
.kp-woche-marke.offen{border-bottom:1px dashed var(--kp-warn)}
.kp-woche-klein{font-size:.72rem;line-height:1.2}
.kp-woche-summe{
  margin:12px 0 0;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  font-size:.92rem;
}
.kp-woche-saldo{margin-left:auto;font-weight:700}
.kp-woche-saldo.minus{color:var(--kp-warn-text)}

/* ⚠️ Unter 900 px vier Spalten, unter 560 px zwei: Sieben Felder nebeneinander
   werden auf dem Handy zu Streifen, in denen keine Uhrzeit mehr steht. Die
   Reihenfolge bleibt dieselbe, nur der Umbruch ändert sich. */
@media (max-width:900px){
  .kp-woche{grid-template-columns:repeat(4,minmax(0,1fr))}
}
@media (max-width:560px){
  .kp-woche{grid-template-columns:repeat(2,minmax(0,1fr))}
  .kp-woche-saldo{margin-left:0}
}

/* Karte „Mein Konto" (13.08.2026) — Avatar neben Name, darunter die beiden
   Anmeldezeiten. Der Avatar bringt seine eigene Größe mit (Profil::avatar),
   hier steht nur die Anordnung. */
.kp-konto{display:flex;align-items:center;gap:12px;margin-bottom:12px}
.kp-konto-text{display:flex;flex-direction:column;gap:2px;min-width:0}
/* ⚠️ `min-width:0` und Umbruch: Eine lange Adresse sprengt sonst die Karte —
   Flex-Kinder schrumpfen ohne das nicht unter ihre Inhaltsbreite. */
.kp-konto-text > *{overflow-wrap:anywhere}
.kp-konto-text .muted{font-size:.86rem}

/* Erinnerung im Wochenkalender (13.08.2026) — ein Verweis, kein Absatz: Er
   muss in eine 90-px-Spalte passen und darf die Zeilenhöhe der Woche nicht
   sprengen. Deshalb zweizeilig abgeschnitten statt umbrechend. */
.kp-woche-er{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;
  font-size:.76rem;line-height:1.25;color:var(--brand);text-decoration:none;
}
.kp-woche-er:hover{text-decoration:underline}
.kp-woche-er.muted{color:var(--muted)}

/* Eigene Erinnerung in der Kalenderkachel (13.08.2026) — wie ein Name
   abgeschnitten statt umgebrochen, damit das Raster nicht wackelt. Kein
   farbiger Balken: Sie ist kein Zustand des Tages wie eine Abwesenheit,
   sondern ein Verweis. */
.kal-er{
  display:block;font-size:.74rem;line-height:1.25;padding:1px 3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--brand);text-decoration:none;
}
.kal-er:hover{text-decoration:underline}
.kal-er.muted{color:var(--muted)}

/* „2 abwesend" im Wochenkalender (13.08.2026) — Zahl statt Namen: In eine
   90-px-Spalte passt kein Name, und die Frage lautet ohnehin „fehlt heute
   jemand?". Wer wissen will, wer, klickt in den Kalender. */
.kp-woche-koll{
  font-size:.74rem;line-height:1.2;color:var(--muted);text-decoration:none;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.kp-woche-koll:hover{text-decoration:underline;color:var(--text)}

/* „Mein Arbeitsplatz" auf dem Dashboard (13.08.2026) — Abstand nach oben und
   zwischen den eigenen Bausteinen. Vom User beanstandet: Die Kachelreihe klebte
   an der Karte darüber. `.kp-kacheln` bringt nur einen Rand nach unten mit.
   ⚠️ Der Abstand sitzt an der Hülle, nicht an den einzelnen Bausteinen — die
   stehen auch anderswo und sollen dort ihr gewohntes Maß behalten. */
.kp-arbeitsplatz{margin-top:34px}
.kp-arbeitsplatz > .kp-kacheln{margin-bottom:18px}
.kp-arbeitsplatz > .karte + .karte,
.kp-arbeitsplatz > .karte + .kp-zweispalt,
.kp-arbeitsplatz > .kp-kacheln + .karte{margin-top:18px}

/* ==========================================================================
   Auswahl-Overlay (13.08.2026)
   --------------------------------------------------------------------------
   Breiter als im LMS (Ansage des Users): bis 1120 px, damit Nummer, Titel,
   Kunde und Status nebeneinander lesbar bleiben. Auf schmalen Geräten füllt
   es die Fläche.
   ========================================================================== */
.kp-wahl-hintergrund{
  position:fixed;inset:0;z-index:1200;
  background:rgba(15,23,42,.55);
  display:flex;align-items:center;justify-content:center;padding:24px;
}
.kp-wahl-hintergrund[hidden]{display:none}
/* Der Seiteninhalt darf nicht mitscrollen, solange das Fenster offen ist. */
body.kp-wahl-offen{overflow:hidden}

.kp-wahl-fenster{
  /* 🔴 Deckend, nicht `--card`: Bei eingeschalteter Glasoptik ist das im
     Dunkeln fast durchsichtig, und die Tabelle läge über dem Seiteninhalt. */
  background:var(--kp-flyout);
  color:var(--text);
  border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:0 24px 60px rgba(0,0,0,.35);
  width:min(1120px,100%);max-height:min(760px,90vh);
  display:flex;flex-direction:column;overflow:hidden;
}
.kp-wahl-kopf{
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  padding:16px 20px;border-bottom:1px solid var(--line);
}
.kp-wahl-kopf h2{margin:0;font-size:1.1rem}
.kp-wahl-suche{flex:1 1 240px;min-width:180px}
.kp-wahl-filter{
  display:flex;gap:16px;flex-wrap:wrap;align-items:center;
  padding:10px 20px;border-bottom:1px solid var(--line);
}
.kp-wahl-filter:empty{display:none}
.kp-wahl-filterfeld{display:flex;align-items:center;gap:8px;font-size:.9rem}
.kp-wahl-filterfeld select{width:auto}

/* Die Liste ist der einzige Bereich, der scrollt — Kopf und Fuß bleiben
   stehen, damit „Übernehmen" immer erreichbar ist. */
.kp-wahl-liste{overflow:auto;flex:1 1 auto;padding:0 8px}
.kp-wahl-liste table{margin:0}
.kp-wahl-zeile{cursor:pointer}
.kp-wahl-zeile:hover{background:var(--hover)}
.kp-wahl-zeile.gewaehlt{background:var(--hover);box-shadow:inset 3px 0 0 var(--brand)}
.kp-wahl-sort{
  background:none;border:0;padding:0;font:inherit;font-weight:700;
  color:inherit;cursor:pointer;
}
.kp-wahl-sort:hover{text-decoration:underline}

.kp-wahl-fuss{
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  padding:12px 20px;border-top:1px solid var(--line);
}
.kp-wahl-pro{display:flex;align-items:center;gap:8px;font-size:.9rem}
.kp-wahl-pro select{width:auto}
.kp-wahl-blaettern{display:flex;align-items:center;gap:8px}
.kp-wahl-knoepfe{margin-left:auto;display:flex;gap:8px}

/* Das Feld im Formular: Knopfreihe oben, gewählter Eintrag darunter (Ansage
   des Users, 13.08.2026). Nebeneinander schob ein langer Tickettitel den
   Knopf „entfernen" aus der Zeile. */
/* Das Feld im Formular: Anzeige links, daneben ＋ ✕ ⚙ (Ansage des Users,
   13.08.2026). Vorher standen zwei flache Knöpfe über dem Text und der
   Pflege-Link darunter — drei Zeilen für eine Angabe.
   🔴 Die Anzeige übernimmt Polsterung, Rand und Grund von `input` aus
   base.css: Das Feld steht neben echten Eingabefeldern, und schon zwei Pixel
   Abweichung lassen die Zeile schief aussehen. */
.kp-wahl-feld{display:flex;align-items:stretch;gap:6px}
.kp-wahl-anzeige{
  flex:1 1 auto;min-width:0;
  display:flex;align-items:center;
  padding:12px;
  background:var(--input-bg);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  font-size:.95rem;line-height:1.2;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* Ohne Auswahl gedämpft — es ist die Abwesenheit eines Werts, kein Wert. */
.kp-wahl-anzeige.leer{color:var(--muted)}
/* Die drei Zeichenknöpfe: quadratisch, so hoch wie das Feld daneben. */
.kp-wahl-sym{
  flex:0 0 auto;width:44px;
  display:flex;align-items:center;justify-content:center;
  background:var(--input-bg);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  color:var(--text);font-size:1rem;line-height:1;text-decoration:none;
  cursor:pointer;transition:border-color .15s,color .15s;
}
.kp-wahl-sym:hover{border-color:var(--brand);color:var(--brand)}
.kp-wahl-sym:focus-visible{outline:2px solid var(--brand);outline-offset:1px}
/* ⚠️ Unter 560 px bricht die Reihe um: Ein Feld mit drei Knöpfen daneben
   lässt auf dem Handy sonst zwei Zeichen für den Wert übrig. */
@media (max-width:560px){
  .kp-wahl-feld{flex-wrap:wrap}
  .kp-wahl-anzeige{flex:1 1 100%}
}

/* ==========================================================================
   Overlays auf dem Handy (15.08.2026)
   --------------------------------------------------------------------------
   🔴 Fund des Users: „im overlay hab ich auch keine ,x button' oben, muss also
   immer bis zum abbrechen runterscrollen."

   Ursache war NICHT ein fehlender Knopf — er stand die ganze Zeit im Markup.
   Die Schale ist `position:fixed;inset:0` und zentriert ihr Fenster
   (`align-items:center`), das Fenster durfte `100vh` hoch werden. Auf dem
   Handy ist `100vh` die Höhe OHNE die eingeblendete Adressleiste des Browsers:
   Das Fenster wurde höher als der sichtbare Bereich und stand zentriert
   darin — oben und unten ragte es heraus, und was oben herausragte, war die
   Kopfzeile mit ✕.

   Deshalb hier zweierlei:
   1. `align-items:stretch` — das Fenster beginnt oben, statt zu schweben.
   2. `100dvh` (dynamische Sichthöhe) statt `100vh`. Ältere Browser kennen es
      nicht und bleiben beim bisherigen Verhalten; ein Rückschritt entsteht
      dadurch nicht.
   ⚠️ Der Kopf darf nicht schrumpfen (`flex:0 0 auto`) — sonst gibt er unter
   Druck des scrollenden Inhalts nach und der Knopf wandert doch aus dem Bild.
   ========================================================================== */
@media (max-width:720px){
  .kp-wahl-hintergrund{padding:0;align-items:stretch;height:100dvh}
  .kp-wahl-fenster{width:100%;max-height:none;height:100%;
                   border-radius:0;border:0}
  .kp-wahl-kopf{flex:0 0 auto}
  .kp-wahl-knoepfe{margin-left:0;width:100%}
  .kp-wahl-knoepfe .btn{flex:1 1 auto}
}

/* Pflichtfeld-Zeichen (13.08.2026) — portalweit von `portal.js` angehängt.
   ⚠️ `--kp-warn-text` statt `--danger`: Ein Pflichtfeld ist kein Fehler,
   sondern ein Hinweis. Rot bekommt das Feld erst, wenn es leer bleibt. */
.kp-pflicht{color:var(--kp-warn-text);margin-left:3px;font-weight:700}
.kp-pflicht-hinweis{font-size:.82rem;margin:14px 0 0}

/* Spaltenfilter im Auswahl-Overlay (13.08.2026) — die Kästen kommen aus
   derselben Familie wie in den Arbeitslisten (`.kp-spf`), sie brauchen hier
   nur zwei Anpassungen: Der Kopf trägt Sortierknopf UND Trichter
   nebeneinander, und der Kasten darf nicht unter dem Tabellenrand
   verschwinden. */
.kp-wahl-liste th{white-space:nowrap}
.kp-wahl-liste th .kp-spf{display:inline-block;vertical-align:middle;margin-left:6px}
/* ⚠️ `overflow:auto` am Listenbereich schneidet aufgeklappte Kästen ab.
   Deshalb liegt der Kasten hier fest über der Tabelle statt im Fluss. */
.kp-wahl-liste .kp-spf-kasten{position:absolute;z-index:5}
.kp-wahl-liste .kp-spf details[open]{position:relative}
.kp-wahl-filterweg{
  background:none;border:0;padding:0;font:inherit;color:var(--brand);
  cursor:pointer;text-decoration:underline;
}

/* Bearbeiten-Overlay (13.08.2026) — dieselbe Schale wie die Auswahl, nur mit
   einem Formular darin statt einer Tabelle. Etwas schmaler: Ein Formular liest
   sich in einer breiten Spalte schlechter als eine Tabelle. */
.kp-maske-fenster{width:min(860px,100%)}
.kp-maske-inhalt{overflow:auto;padding:20px;flex:1 1 auto}
/* Die Maske bringt ihre eigene Überschrift mit — im Fenster steht sie schon
   im Kopf, deshalb hier weg. Dasselbe gilt für „Zur Übersicht". */
.kp-maske-inhalt .kp-titel{display:none}
.kp-maske-inhalt > .kp-maske > .kp-aktionen:first-of-type{margin-bottom:14px}
.kp-maske-inhalt .kp-unter{margin-top:0}

/* Der Schließen-Knopf gehört an den rechten Rand, nicht neben den Titel
   (13.08.2026 im Browser gesehen). Im Auswahl-Overlay schiebt ihn das
   Suchfeld dorthin, im Bearbeiten-Overlay gibt es keines. */
.kp-maske-fenster .kp-wahl-kopf > h2{margin-right:auto}

/* Im Fenster gezeigte LISTEN (Stammdaten) brauchen etwas mehr Breite als ein
   Formular — Tabellen mit fünf Spalten sind sonst gequetscht. Die Schale
   entscheidet nach Inhalt: Steht eine Tabelle darin, wird sie breiter. */
.kp-maske-fenster:has(.kp-maske-inhalt table){width:min(1120px,100%)}
/* Der Zurück-Pfeil sitzt vor dem Titel und erscheint erst ab dem zweiten
   Schritt. */
.kp-maske-fenster .kp-wahl-kopf{gap:10px}

/* ⚠️ Der Unterstrich kommt von der allgemeinen Regel `a:hover` — beim ⚙ ist
   er falsch: Es ist ein Knopf, der zufällig ein Verweis ist (vom User
   beanstandet, 13.08.2026). Der Rahmen zeigt schon, dass er anspricht. */
.kp-wahl-sym:hover,
.kp-wahl-sym:focus-visible{text-decoration:none}

/* Der Block um Feld und Pflege-Verweis (13.08.2026): Die Reihe mit Anzeige
   und Knöpfen oben, der dezente Verweis darunter — kein Zahnrad in der Reihe
   (Entscheidung des Users). */
.kp-wahl-block{display:flex;flex-direction:column;gap:6px}
.kp-wahl-block .kp-feld-pflege{margin:0}

/* ==========================================================================
   Flackern im Hintergrund abstellen (13.08.2026)
   --------------------------------------------------------------------------
   Fund des Users: „im dunkelmodus ist mir schon öfters ein flackern
   aufgefallen … die portal maske im hintergrund flackert, während das andere
   Fenster im Vordergrund nicht flackert."

   🔴 Ursache sind die Farbwolken aus `base.css`: `.blob` trägt
   `filter:blur(90px)` UND eine endlose Animation (`blob-drift`, 20–28 s). Ein
   700-px-Kreis mit 90 px Weichzeichner muss damit in JEDEM Bild neu gerastert
   werden — dauerhaft, auch wenn das Fenster im Hintergrund liegt. Im dunklen
   Design fällt das besonders auf, weil die Abstufungen dort größer sind.

   Die Wolken BLEIBEN, nur stehen sie still. Im Portal ist die Bewegung
   ohnehin fehl am Platz: Es ist ein Arbeitswerkzeug, keine Schaufensterseite —
   und die Demoseiten (dieselbe `base.css`) behalten ihre Bewegung.
   ========================================================================== */
body.kp .blob{animation:none}

/* Mehrfachauswahl im Overlay (13.08.2026): schmale Hakenspalte ganz links. */
.kp-wahl-liste th.kp-wahl-haken,
.kp-wahl-liste td.kp-wahl-haken{width:44px;text-align:center}
.kp-wahl-liste td.kp-wahl-haken input{cursor:pointer}

/* ==========================================================================
   Dashboard anpassen (Punkt 19c, 15.08.2026)
   --------------------------------------------------------------------------
   Eine Zeile je Registerkarte und Baustein: links Haken und Name, rechts die
   beiden Pfeile. Bewusst eine Liste und kein Ziehen mit der Maus — Ziehen
   braucht Zeigegerät und ruhige Hand, zwei Knöpfe kommen auch mit Tastatur
   und auf dem Handy aus.
   ========================================================================== */
/* Zweite Ebene der Maske: eine Reiterleiste je Registerkarte (15.08.2026).
   🔴 `.kp-dash-tabinhalt` ist im Grundzustand SICHTBAR — erst `kp-tabs-an`
   (von `portal.js` gesetzt) blendet aus. Ohne Skript bleibt die Maske damit
   vollständig bedienbar; andersherum wäre sie leer. */
.kp-dash-tabs:not(.kp-tabs-an) .kp-leiste-schiebe{display:none}
.kp-dash-tabbar{display:flex;gap:2px;flex-wrap:wrap}
.kp-dash-tabbar button{
  border:0;border-bottom:3px solid transparent;background:none;
  padding:10px 16px;margin-bottom:-1px;white-space:nowrap;
  font:inherit;font-size:.92rem;font-weight:600;color:var(--muted);
  cursor:pointer}
.kp-dash-tabbar button:hover{color:var(--text)}
.kp-dash-tabbar button.aktiv{color:var(--brand);border-bottom-color:var(--brand)}
.kp-dash-tabs.kp-tabs-an .kp-dash-tabinhalt{display:none}
.kp-dash-tabs.kp-tabs-an .kp-dash-tabinhalt.aktiv{display:block}
/* Mit Leiste trägt die Karte den Namen schon oben — die Überschrift bliebe
   eine Dopplung. Ohne Leiste ist sie die einzige Orientierung. */
.kp-dash-tabs.kp-tabs-an .kp-dash-tabinhalt > .karte > h2{display:none}
.kp-dash-tabs.kp-tabs-an .kp-dash-tabinhalt > .karte{margin-top:0}

.kp-dash-liste{list-style:none;margin:12px 0 0;padding:0;
               display:flex;flex-direction:column;gap:2px}
.kp-dash-zeile{display:flex;align-items:center;gap:12px;
               padding:8px 10px;border-radius:var(--radius);
               border:1px solid transparent}
.kp-dash-zeile:hover{background:var(--hover);border-color:var(--border)}

.kp-dash-name{display:flex;align-items:flex-start;gap:10px;flex:1 1 auto;
              margin:0;cursor:pointer;font-weight:500}
.kp-dash-name input{margin-top:3px;flex:0 0 auto;cursor:pointer}
/* Ein abgeschalteter Haken („Überblick") ist keine Einladung zum Klicken. */
.kp-dash-name input:disabled{cursor:default;opacity:.55}
.kp-dash-name input:disabled + span{opacity:.75}
.kp-dash-name small{display:block;font-weight:400;font-size:.82rem;
                    margin-top:1px}

/* Die Spalte bleibt auch bei festen Zeilen stehen — sonst rutschen deren
   Namen nach rechts und die Liste franst aus. */
.kp-dash-pfeile{flex:0 0 auto;display:flex;gap:4px;min-width:62px;
                justify-content:flex-end}
.kp-dash-pfeile button{width:29px;height:29px;line-height:1;padding:0;
                       border:1px solid var(--border);border-radius:8px;
                       background:var(--card);color:var(--text);
                       cursor:pointer;font-size:.78rem}
.kp-dash-pfeile button:hover{background:var(--hover)}
.kp-dash-pfeile button:focus-visible{outline:2px solid var(--primary);
                                     outline-offset:1px}

@media (max-width:560px){
  /* Namen wie „Verantwortung je Mitarbeiter" brauchen die Breite; die Pfeile
     rücken enger zusammen, statt den Text zweizeilig zu machen. */
  .kp-dash-zeile{gap:8px;padding:8px 6px}
  .kp-dash-pfeile{min-width:auto}

  /* 🔴 Aktionsknöpfe stehen auf dem Handy untereinander und gleich breit
     (Fund des Users, 15.08.2026: „ticket erstellen und abbrechen nicht exakt
     untereinander"). Ohne die Regel behält jeder Knopf beim Umbruch seine
     Textbreite, und zwei gleichrangige Aktionen sehen aus wie zwei
     verschiedene Dinge.
     ⚠️ Nur die großen Knöpfe. `.btn-klein` steht in Listenzeilen und in
     Werkzeugreihen — die gehören nebeneinander, nicht gestapelt. */
  .kp-aktionen > .btn:not(.btn-klein){flex:1 1 100%}
}

/* ==========================================================================
   Schiebbare Reiterleisten (15.08.2026)
   --------------------------------------------------------------------------
   Ansage des Users: dieselbe Darstellung wie in „Dashboard anpassen" fuer
   alle Reiterleisten, „damit das portal wie aus einem guss wirkt".

   Die Huelle `.kp-leiste-schiebe` steht im MARKUP — `leisteAuf()` und
   `leisteZu()` in `index.php` geben sie an den acht Stellen aus, an denen
   eine Leiste entsteht. Ein erster Anlauf liess sie vom Skript um die Leiste
   herum bauen; das verschob sie im DOM und brach die Umschaltung der
   Stammdaten. **Bestehendes Markup nicht nachtraeglich umbauen.**

   Auf dem DESKTOP aendert sich nichts: Die Leiste bricht weiter um, nichts
   liegt ausserhalb, `portal.js` findet nichts zu schieben und die Pfeile
   bleiben unsichtbar.
   ========================================================================== */
.kp-leiste-schiebe{display:flex;align-items:stretch}
.kp-leiste-schiebe > .kp-reiter,
.kp-leiste-schiebe > .kp-dash-tabbar{flex:1 1 auto;min-width:0}

.kp-leiste-pfeil{
  display:none;flex:0 0 auto;width:30px;align-self:stretch;
  border:0;background:none;color:var(--muted);
  font-size:1.2rem;line-height:1;cursor:pointer;
}
.kp-leiste-schiebe.kp-schiebbar .kp-leiste-pfeil{display:block}
.kp-leiste-pfeil:hover:not(:disabled){color:var(--brand)}
/* Am Ende angekommen abgeblendet STEHEN LASSEN — verschwaende der Knopf,
   spraenge die Leiste bei jedem Schieben um 30 px zur Seite. */
.kp-leiste-pfeil:disabled{opacity:.3;cursor:default}

/* 🔴 Umgeschaltet wird nach BEDARF, nicht nach Bildschirmbreite (Ansage des
   Users, 15.08.2026: „bau es so, dass es bei zwei zeilen auf die buttons
   springt"). `portal.js` rechnet die natuerliche Breite der Reiter zusammen;
   passt sie nicht in eine Zeile, setzt es `kp-eng` — und erst dann scrollt
   die Leiste. Das gilt auf dem Handy wie am Schreibtisch: Zwei Zeilen Reiter
   sehen ueberall unruhig aus.
   ⚠️ `overflow-y:hidden` gegen die zweite, senkrechte Bildlaufleiste: Der
   aktive Reiter ragt mit `margin-bottom:-1px` ueber den Rand, und bei
   `overflow-x:auto` zaehlt dieses eine Pixel in der Senkrechten. */
.kp-leiste-schiebe.kp-eng{margin:0 0 22px;border-bottom:1px solid var(--line)}
.kp-leiste-schiebe.kp-eng > .kp-reiter,
.kp-leiste-schiebe.kp-eng > .kp-dash-tabbar{
  margin:0;border-bottom:0;
  flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;
}
.kp-leiste-schiebe.kp-eng > .kp-reiter::-webkit-scrollbar,
.kp-leiste-schiebe.kp-eng > .kp-dash-tabbar::-webkit-scrollbar{display:none}

/* ⚠️ Muss IMMER gelten, nicht nur im engen Zustand: Die Messung im Skript
   zaehlt die Breiten der Reiter zusammen. Duerfte ein Reitertext umbrechen,
   waere seine Breite von der Fensterbreite abhaengig und die Rechnung
   liefe im Kreis. */
.kp-reiter button,.kp-reiter a,.kp-dash-tabbar button{white-space:nowrap}

@media (max-width:720px){
  .kp-reiter button,.kp-reiter a,.kp-dash-tabbar button{padding:10px 13px}
}

/* ==========================================================================
   Klappfenster der Kopfleiste auf dem Handy (15.08.2026)
   --------------------------------------------------------------------------
   🔴 Fund des Users: „klicke ich oben die glocke an verschwindet der overlay
   links aus dem bild." Die Fenster hängen mit `right:0` an ihrem eigenen
   Knopf und sind bis zu 380 px breit — sitzt der Knopf nicht ganz rechts,
   ragen sie nach links über den Bildrand hinaus.

   Auf schmalen Geräten hängen sie deshalb nicht mehr am Knopf, sondern an der
   Kopfzeile: `position:static` am Knopf gibt den Bezugsrahmen an die Zeile ab,
   und `left`/`right` spannen das Fenster über die volle Breite.
   ⚠️ Dafür MUSS die Zeile positioniert sein — sonst wäre der nächste Bezug
   das Fenster selbst und die Fenster stünden ganz oben auf der Seite.
   ========================================================================== */
@media (max-width:720px){
  body.kp header.site .container.nav{position:relative}
  .kp-glocke,.kp-benutzer{position:static}
  .kp-glocke-klapp,.kp-benutzer-klapp{
    left:12px;right:12px;width:auto;min-width:0;max-width:none;
    top:calc(100% + 6px);
  }
}

/* ==========================================================================
   Sprachauswahl in der Kopfleiste (Punkt 18, 15.08.2026)
   --------------------------------------------------------------------------
   Sitzt zwischen Hell/Dunkel-Umschalter und Glocke (Ansage des Users). Sie
   ist ein `<details>` wie Glocke und Benutzermenue — damit klappt sie ohne
   JavaScript auf, und `portal.js` muss sich um nichts kuemmern.

   🔴 Deckende Flaeche (`--kp-flyout`), nicht `--card`: Jeder Kasten, der
   UEBER dem Inhalt schwebt, braucht sie — bei eingeschalteter Glasoptik ist
   `--card` fast durchsichtig. Derselbe Merksatz wie beim Benutzermenue.
   ========================================================================== */
.kp-sprache{position:relative}
.kp-sprache > summary{
  list-style:none;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;
  height:42px;padding:0 12px;
  border:1px solid var(--line);border-radius:999px;
  background:var(--input-bg);color:var(--text);
}
.kp-sprache > summary::-webkit-details-marker{display:none}
.kp-sprache > summary::marker{content:""}
.kp-sprache > summary:hover{color:var(--brand);border-color:var(--brand)}
.kp-sprache > summary:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.kp-sprache[open] > summary{color:var(--brand);border-color:var(--brand)}
.kp-sprache-kurz{font-size:.8rem;font-weight:700;letter-spacing:.03em}
.kp-flagge{flex:0 0 auto;display:block;border-radius:50%}

.kp-sprache-klapp{
  position:absolute;right:0;top:calc(100% + 8px);z-index:60;
  min-width:190px;padding:6px;
  background:var(--kp-flyout);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 14px 40px rgba(0,0,0,.22);
}
.kp-sprache-klapp form{margin:0}
.kp-sprache-klapp button{
  width:100%;display:flex;align-items:center;gap:10px;
  padding:9px 10px;border:0;border-radius:8px;
  background:none;color:var(--text);font:inherit;font-size:.92rem;
  cursor:pointer;text-align:left;
}
.kp-sprache-klapp button:hover{background:var(--hover)}
.kp-sprache-klapp button.aktiv{color:var(--brand);font-weight:600}

/* Auf dem Handy haengt das Fenster an der Kopfzeile statt am Knopf — dieselbe
   Regel wie bei Glocke und Benutzermenue, begruendet dort. */
@media (max-width:720px){
  .kp-sprache{position:static}
  .kp-sprache-klapp{left:12px;right:12px;min-width:0}
}

/* 🔴 Briefumschlag raus auf schmalen Geraeten (16.08.2026, Fund des Users:
   „durch die uebersetzung bricht es auf dem iphone auf eine dritte zeile
   um"). Mit der Sprachauswahl ist die Symbolreihe eine Stelle zu lang.

   Warum ausgerechnet der Umschlag: Er ist die einzige Abkuerzung der Reihe,
   die es doppelt gibt — „Nachrichten" steht im Seitenmenue, und die Glocke
   meldet neue Nachrichten ohnehin. Hell/Dunkel, Sprache, Status, Papierkorb
   und das Benutzermenue haben keinen zweiten Weg.
   ⚠️ `display:none` und nicht abblenden: Es geht um PLATZ, nicht um ein
   fehlendes Recht. Ein abgeblendetes Symbol braucht denselben Platz. */
@media (max-width:720px){
  body.kp .kp-kopf-mail{display:none}
}

/* 🔴 Zahl der ungelesenen Nachrichten am Profilbild — NUR auf schmalen
   Geraeten (16.08.2026). Dort ist der Briefumschlag ausgeblendet; ohne diese
   Marke verschwaende der Hinweis mit ihm. Auf dem Desktop bleibt sie am
   Umschlag, zweimal dieselbe Zahl waere verwirrend.
   ⚠️ Sie sitzt am `<summary>`, das `position:relative` bekommt — nicht am
   Bild: Das Bild ist rund und beschnitten, eine Marke daran wuerde
   angeschnitten. */
.kp-benutzer-zahl{display:none}
@media (max-width:720px){
  .kp-benutzer > summary{position:relative}
  .kp-benutzer-zahl{
    display:block;position:absolute;top:-2px;left:-4px;z-index:2;
    min-width:18px;padding:0 5px;border-radius:999px;
    background:var(--brand);color:#fff;
    font-size:.68rem;font-weight:700;line-height:18px;text-align:center;
    box-shadow:0 0 0 2px var(--kp-kopf-bg, var(--bg));
  }
}

/* --------------------------------------------------------------------------
   Einrichtungsassistent (Punkt 24, 17.08.2026)
   -------------------------------------------------------------------------- */

/* Die Schrittleiste. Bewusst KEINE `.kp-reiter`: Reiter sind gleichrangig und
   in beliebiger Reihenfolge erreichbar, Schritte haben eine Richtung und einen
   Stand. Sie teilen sich deshalb weder Aussehen noch Mechanik.

   🔴 Der Stand haengt an drei Klassen und nicht allein an der Farbe: `fertig`
   traegt ein Haekchen als Textzeichen, `hier` den Rahmen in der Markenfarbe,
   `offen` bleibt blass. Wer Rot und Gruen nicht unterscheidet, sieht trotzdem,
   wo er steht — dieselbe Ueberlegung wie bei den Erfolgsmeldungen. */
.kp-schritte{
  display:flex;flex-wrap:wrap;gap:8px;
  list-style:none;margin:0 0 22px;padding:0;
}
.kp-schritte li{
  display:flex;align-items:center;gap:8px;
  padding:8px 13px;
  background:var(--kp-tile-bg);
  border:1px solid var(--line);border-radius:999px;
  font-size:.88rem;color:var(--muted);
}
.kp-schritte li a{
  display:flex;align-items:center;gap:8px;
  color:inherit;text-decoration:none;
}
.kp-schritte li a:hover{color:var(--text)}
.kp-schritt-nr{
  display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;flex:0 0 22px;
  border-radius:999px;
  background:var(--line);color:var(--text);
  font-size:.78rem;font-weight:700;
}
.kp-schritte li.fertig{
  background:var(--kp-gut-soft);
  border-color:var(--kp-gut);
  color:var(--kp-gut-text);
}
.kp-schritte li.fertig .kp-schritt-nr{background:var(--kp-gut);color:#fff}
/* 🔴 Das Haekchen steht im MARKUP neben dem Namen, nicht als `::after` an der
   Nummer. Erster Anlauf war genau das — zusammen mit `font-size:0` an der
   Nummer, damit beides nicht uebereinanderliegt. Damit war die Nummer weg,
   und die ist der Weg zurueck („Schritt 2"), nicht bloss Zierrat. Ein Zeichen,
   das ein anderes verdraengt, ist keine zweite Unterscheidung. */
.kp-schritte li.hier{
  background:var(--brand-soft, var(--kp-tile-bg));
  border-color:var(--brand);
  color:var(--text);font-weight:600;
}
.kp-schritte li.hier .kp-schritt-nr{background:var(--brand);color:#fff}
.kp-schritte li.offen{opacity:.6}

/* Der Einrichtungslink des ersten Zugangs. Eigener Kasten und keine
   `.meldung`: Die ist eine Zeile Rueckmeldung, hier steht eine Adresse, die
   jemand herauskopieren soll — sie braucht Platz und einen Umbruch. */
.kp-linkkasten{
  margin:0 0 20px;padding:14px 16px;
  background:var(--kp-gut-soft);
  border:1px solid var(--kp-gut);border-radius:var(--radius-sm);
}
.kp-linkkasten code{
  display:block;padding:9px 11px;margin-top:4px;
  background:var(--kp-flyout);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  font-size:.85rem;
}

/* --------------------------------------------------------------------------
   Rechnungsliste (18.08.2026)
   -------------------------------------------------------------------------- */

/* Der Haken ist ein KNOPF, kein Kaestchen — ohne JavaScript muesste ein
   Kaestchen erst abgeschickt werden, und ein Haken, der nichts tut, ist
   schlimmer als keiner. Er soll aber wie ein Kaestchen aussehen. */
.kp-haken{
  width:22px;height:22px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border:2px solid var(--line);border-radius:6px;
  background:var(--kp-flyout);color:var(--brand);
  font-size:.9rem;font-weight:800;line-height:1;cursor:pointer;
}
.kp-haken:hover{border-color:var(--brand)}
.kp-haken.an{background:var(--brand);border-color:var(--brand);color:#fff}
/* Tastaturbedienung muss sichtbar bleiben — der Knopf traegt sonst keinen
   eigenen Rahmen, an dem man den Fokus erkennen wuerde. */
.kp-haken:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* Ueberfaellige Zeile: ein Streifen am linken Rand statt einer Flaechenfarbe.
   ⚠️ KEIN eingefaerbter Hintergrund ueber die ganze Zeile — der zieht den Text
   mit und geht auf Kosten der Lesbarkeit; dieselbe Ueberlegung wie bei den
   beendeten Karten der Kundenansicht. */
/* ⚠️ `--warn` gibt es im Portal nicht — nur `--danger`. Ueberfaellig ist
   aber kein Fehler, sondern eine Faelligkeit, deshalb der Markenton
   statt Rot. Rot bliebe fuer echte Stoerungen reserviert. */
.kp-zeile-warn td:first-child{box-shadow:inset 3px 0 0 var(--brand)}

/* Die Positionen unter einer Rechnung. Schmal gesetzt, damit die Zeile trotz
   mehrerer Posten nicht auseinanderfaellt. */
.kp-liste-schmal{margin:0;padding:0;list-style:none}
.kp-liste-schmal li{padding:1px 0;font-size:.92rem}
.kp-liste-schmal li + li{border-top:1px dashed var(--line)}
.kp-liste-schmal .muted{margin-left:6px;font-size:.85rem}

/* Knopfleiste ueber dem Titel einer Detailseite (18.08.2026, Meldung des Users:
   „bei sehr langen titeln brechen die buttons um").
   🔴 Eigene Zeile statt neben der Ueberschrift: Ein Accountname kann beliebig
   lang werden, und in derselben Zeile zerfiel die Leiste dann in einzelne
   umgebrochene Knoepfe. Getrennt ist die Breite des Titels egal.
   ⚠️ `flex-wrap` bleibt trotzdem — auf dem Telefon passen fuenf Knoepfe auch in
   einer eigenen Zeile nicht nebeneinander. Der Unterschied ist, dass sie dann
   ALS GRUPPE umbrechen und nicht mehr um den Titel herum. */
.kp-kopfleiste{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-bottom:14px;
}
.kp-kopfleiste form{margin:0}

/* Sichtwahl ueber einer Liste — „Alle / Wiederkehrend / Einmalig" (18.08.2026).
   Dieselbe Sprache wie die Filterknoepfe auf der Hinweisseite: Der gewaehlte
   Knopf traegt den Markenton, die uebrigen bleiben Umrisse.
   ⚠️ Das ist bewusst KEIN Spaltenfilter. Die Trichter im Tabellenkopf
   verfeinern, was man sieht; diese Leiste wechselt die SICHT. Zwei
   Bedienelemente, die man nicht verwechseln soll, duerfen nicht gleich
   aussehen. */
.kp-sichtwahl{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px}
.kp-sichtwahl .btn.aktiv{
  border-color:var(--brand);color:var(--brand);background:var(--brand-soft);
}
.kp-sichtwahl .kp-reiter-zahl{margin-left:6px}

/* Kennzahlenzeile ueber einer Arbeitsliste (Rechnungen).
   🔴 Der erklaerende Satz steht UNTER den Zahlen, nicht daneben (Ansage des
   Users, 18.08.2026). Rechts neben „8 offen · 818,87 € gesamt" konkurriert er
   mit ihnen um dieselbe Zeile und dieselbe Aufmerksamkeit — dabei ist das eine
   die Auskunft und das andere ihre Erlaeuterung. */
.kp-kopfzahlen{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 0 18px;padding:12px 16px;
  background:var(--kp-flyout);border:1px solid var(--line);
  border-radius:var(--radius);
}
.kp-kopfzahlen > small{flex:0 0 100%;font-size:.8rem;line-height:1.45;margin-top:2px}

/* Ein Knopf in der Sichtwahl, der von sich aus auffallen soll — „Überfällig",
   solange dort etwas steht. Warnton statt Markenton: Der Markenton markiert die
   GEWAEHLTE Sicht, hier geht es um den Inhalt.
   ⚠️ Der aktive Zustand gewinnt: Wer die Sicht offen hat, sieht sie als
   gewaehlt, nicht als Warnung. Deshalb steht `.aktiv` in der Datei danach. */
.kp-sichtwahl .btn.kp-warnton{
  border-color:#e0a12a;color:#c07800;
}
.kp-sichtwahl .btn.kp-warnton.aktiv{
  border-color:var(--brand);color:var(--brand);background:var(--brand-soft);
}

/* --------------------------------------------------------------------------
   Barrierefreiheit: hoher Kontrast (18.08.2026)
   --------------------------------------------------------------------------
   Ansage des Users: „im LMS haben wir fuer die barrierefreiheit noch ,hoher
   kontrast' der fehlt hier im crm noch."

   🔴 Ueber die FARBTOKEN, nicht ueber Einzelregeln je Bauteil. Das Portal
   zeichnet alles aus `--text`, `--muted`, `--line`, `--card` und `--bg` — wer
   diese fuenf verschaerft, erreicht jede Karte, jede Tabelle und jedes Feld
   auf einmal. Eine Liste einzelner Selektoren waere ab der naechsten neuen
   Seite unvollstaendig.

   ⚠️ Die Markenfarbe bleibt unangetastet: Sie ist das Erkennungszeichen des
   Mandanten (Whitelabel). Verschaerft werden Text, Linien und Flaechen.
   -------------------------------------------------------------------------- */
html[data-kontrast="hoch"]{
  --text:#000000;
  --muted:#333333;
  --line:#4a4a4a;
  --card:#ffffff;
  --bg:#f4f4f4;
  --input-bg:#ffffff;
}
html[data-kontrast="hoch"][data-theme="dark"]{
  --text:#ffffff;
  --muted:#d4d4d4;
  --line:#9a9a9a;
  --card:#0a0a0a;
  --bg:#000000;
  --input-bg:#0a0a0a;
}

/* Raender kraeftiger — Farbe allein traegt bei schwachem Sehen nicht. */
html[data-kontrast="hoch"] .karte,
html[data-kontrast="hoch"] .kp-kachel,
html[data-kontrast="hoch"] table.tabelle{border:2px solid var(--line)}
html[data-kontrast="hoch"] .btn{border-width:2px;font-weight:600}
html[data-kontrast="hoch"] input,
html[data-kontrast="hoch"] select,
html[data-kontrast="hoch"] textarea{border-width:2px}

/* 🔴 Verweise werden unterstrichen. Ein Link, der sich nur durch die Farbe
   vom Text unterscheidet, ist fuer Farbfehlsichtige kein Link.
   ⚠️ Nicht bei Knoepfen und Menuepunkten — die sind schon als Flaeche
   erkennbar, und die Unterstreichung machte sie unruhig. */
html[data-kontrast="hoch"] a{text-decoration:underline}
html[data-kontrast="hoch"] a.btn,
html[data-kontrast="hoch"] a.kp-kachel,
html[data-kontrast="hoch"] .kp-reiter a,
html[data-kontrast="hoch"] .kp-seite a,
html[data-kontrast="hoch"] a.kp-sort{text-decoration:none}

/* Der Knopf selbst: gedrueckt = Markenfarbe, damit man den Zustand sieht. */
.kontrast-toggle.an{color:var(--brand);border-color:var(--brand)}

/* Sichtbarer Fokusring — Tastaturbedienung darf nicht raten lassen. */
html[data-kontrast="hoch"] :focus-visible{
  outline:3px solid var(--brand);outline-offset:2px;
}

/* Interne Notiz der Leistung im Zuweisungsformular (18.08.2026).
   Abgesetzt, damit sie nicht wie eine Feldbeschriftung wirkt — sie ist eine
   Information zum Nachschlagen, kein Hinweis zur Eingabe. */
.kp-leist-notiz{
  margin:8px 0 0;padding:8px 10px;
  border-left:3px solid var(--brand);
  background:var(--kp-flyout);
  font-size:.86rem;line-height:1.45;white-space:pre-line;
}

/* Punkt im Handlungsbedarf ausblenden (18.08.2026). Zurueckhaltend: Das × soll
   erreichbar sein, aber nicht mit der Zahl daneben um Aufmerksamkeit ringen. */
.kp-tuwas-weg{
  border:0;background:none;padding:0 2px;cursor:pointer;
  color:var(--muted);font-size:1.05rem;line-height:1;opacity:.55;
}
.kp-tuwas-weg:hover{opacity:1;color:var(--text)}
.kp-tuwas-weg:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:4px}

/* Knopf, der wie ein dezenter Verweis aussieht — fuer Aktionen, die per POST
   laufen muessen (CSRF), aber keine Aufmerksamkeit verlangen.
   🔴 Vorbild ist „⚙ Ansicht anpassen" auf dem LMS-Dashboard (Ansage des Users,
   18.08.2026: „kriegen wir den Link etwas kleiner und dezenter hin? im LMS
   haben wir das auch schoen dezent"). Dieselben Werte: 0,78 rem, gedaempfte
   Farbe, erst beim Ueberfahren Markenton mit leiser Flaeche.
   ⚠️ KEINE Unterstreichung im Ruhezustand — sie machte den Knopf zum zweiten
   Blickfang neben den Zahlen darueber, und genau das war der Fund. */
.kp-textknopf{
  border:0;background:none;cursor:pointer;
  font-family:inherit;font-size:.78rem;line-height:1.4;
  color:var(--muted);text-decoration:none;
  display:inline-flex;align-items:center;gap:3px;
  padding:2px 6px;border-radius:4px;
  transition:color .15s, background .15s;
}
.kp-textknopf:hover{color:var(--brand);background:var(--hover,var(--kp-flyout))}
.kp-textknopf:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* Eigene Zeile fuer den Weg zurueck, rechtsbuendig unter dem Erklaertext. */
.kp-tuwas-zurueck{display:flex;justify-content:flex-end;margin:6px 0 0}


/* ---------------------------------------------------------------------------
   Abweichende Rechnungsadresse (20.08.2026)
   ---------------------------------------------------------------------------
   🔴 Ein- und Ausblenden OHNE JavaScript. Die CSP des Portals blockt
   Inline-Skripte (Befund A″-8, 16.08.2026), und für einen einzigen Haken
   lohnt kein Eintrag in `portal.js`.

   ⚠️ Der Geschwister-Selektor `~` verlangt, dass `.kp-abw` NACH dem Label
   mit dem Kästchen steht und beide DASSELBE Elternelement haben. Wer den
   Block später in ein weiteres <div> wickelt, schaltet ihn damit still ab.
   Ein `:has()` wäre unempfindlicher, wird aber von älteren Browsern nicht
   verstanden — und dort wäre das Feld dann dauerhaft unsichtbar. */
.kp-abw { display: none; }
.kp-abw-schalter:has(input:checked) ~ .kp-abw { display: block; }

/* Rückfall für Browser ohne `:has()`: Dort bleibt der Block immer sichtbar.
   Sichtbar zu viel ist harmlos, unsichtbar zu wenig wäre ein verlorenes
   Formularfeld. */
@supports not (selector(:has(*))) {
  .kp-abw { display: block; }
}


/* ---------------------------------------------------------------------------
   Blättern in der Detailansicht (20.08.2026)
   ---------------------------------------------------------------------------
   🔴 Die Klasse heißt `kp-satzblaettern` und NICHT `kp-blaettern`. Letztere
   gehört der Seitenblätterung UNTER den Listen. Als hier zuerst derselbe Name
   stand, machte `display:flex` aus deren <span> einen Flex-Kasten — „‹ Zurück"
   und „Weiter ›" standen daraufhin versetzt. Der User hat es sofort gesehen.
   Vor einem neuen Klassennamen im Stylesheet nachsehen, ob es ihn schon gibt.

   ⚠️ Der abgeblendete Knopf ist ein <span> und kein <button disabled>: Er soll
   den Platz halten, damit „Nächster" nicht springt, sobald man am Ende der
   Liste ankommt. */
.kp-satzblaettern {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  flex-wrap: wrap;
}


/* ---------------------------------------------------------------------------
   Export-Knopf über den Listen (20.08.2026)
   ---------------------------------------------------------------------------
   Ansage des Users: „der csv button klebt an der liste, kriegen wir den etwas
   höher und auf die rechte seite der listen?"

   ⚠️ `float` und nicht Flex: Der Knopf steht im Markup als einzelnes Element
   zwischen Steuerung und Tabelle, ohne umschließenden Kasten. Ein Flex-Elter
   müsste in jede der über zwanzig Listen eingezogen werden; `float: right`
   holt ihn ohne Eingriff in den Seiten nach rechts. Das `clear` an der Tabelle
   darunter verhindert, dass sie unter ihn rutscht. */
/* ⚠️ KEIN `float` mehr (20.08.2026): Der Knopf steht seit heute IM Flex-Kasten
   der Steuerungszeile, ausgegeben von `Liste::steuerung()`. Ein Float daneben
   hätte ihn wieder herausgelöst. */
.kp-export {
  margin: 0;
}

/* ⚠️ Gemessen statt geschätzt (20.08.2026): Mit »1em« war das Symbol 14×14 px
   und der ganze Knopf 37×25 — in der Größe ist ein Blatt mit Pfeil nicht mehr
   zu deuten. Feste 18 px und ein quadratischer Knopf: gut sichtbar und auf
   dem Touchscreen zu treffen. Der Knopf trägt nur noch ein Symbol, deshalb
   braucht er keine Textbreite mehr. */
.kp-export {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  min-height: 34px;
  padding: 6px;
}

/* Die Größe kommt aus `symbolSvg('export', '18px')` — sie steht inline und
   ließe sich von hier ohnehin nicht überschreiben. */

/* Trägt der Knopf ausnahmsweise doch eine Beschriftung (zwei Listen auf einer
   Seite), darf er wieder in die Breite gehen. */
.kp-export:not(:has(.sr-only)) {
  min-width: 0;
  padding: 5px 11px;
  gap: 6px;
}


/* ==========================================================================
   Listenansicht-Overlay (20.08.2026)
   --------------------------------------------------------------------------
   Hintergrund und Fenster kommen aus dem Auswahl-Overlay (`kp-wahl-*`) — es
   ist derselbe Dialog, nur mit anderem Inhalt. Zwei eigene Sätze Regeln für
   dasselbe Fenster wären die Stelle, an der eines Tages nur noch eines von
   beiden zur Glasoptik passt.
   ========================================================================== */
.kp-ansicht-fenster{width:min(520px,100%);max-height:min(680px,90vh)}

/* Der einzige Bereich, der scrollt: Kopf und Fuß bleiben stehen, damit
   „Speichern" bei einer Liste mit fünfzehn Spalten erreichbar bleibt. */
.kp-ansicht-inhalt{overflow:auto;flex:1 1 auto;padding:16px 20px}
.kp-ansicht-hinweis{margin:0 0 12px;font-size:.86rem}

.kp-ansicht-liste{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:6px}

.kp-ansicht-zeile{
  display:flex;align-items:center;gap:12px;
  padding:8px 10px;
  border:1px solid var(--line);border-radius:var(--radius);
  background:var(--card);
}
.kp-ansicht-name{display:flex;align-items:center;gap:10px;flex:1 1 auto;
  margin:0;cursor:pointer;min-width:0}
.kp-ansicht-name span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Eine abgewählte Spalte bleibt lesbar, tritt aber zurück — sonst sieht die
   Zeile aus wie ein Fehler und nicht wie eine Entscheidung. */
.kp-ansicht-name:has(input:not(:checked)) span{opacity:.5}

.kp-ansicht-pfeile{display:flex;gap:4px;flex:0 0 auto}
/* ⚠️ Feste Breite: Ohne sie werden die Knöpfe von „↑" und „↓" verschieden
   breit, und die Zeilen stehen um ein bis zwei Pixel versetzt. */
.kp-ansicht-pfeile .btn{min-width:32px;padding-left:0;padding-right:0;
  text-align:center}
.kp-ansicht-pfeile .btn[disabled]{opacity:.35;cursor:default}

.kp-ansicht-sortierung{
  display:flex;gap:16px;flex-wrap:wrap;
  margin-top:18px;padding-top:16px;border-top:1px solid var(--line);
}
.kp-ansicht-sortierung label{display:flex;flex-direction:column;gap:4px;
  flex:1 1 180px;font-size:.9rem}
.kp-ansicht-sortierung select{width:100%}

/* Der Fuß trägt links „Zurücksetzen", rechts Abbrechen und Speichern —
   `kp-wahl-knoepfe` bringt das `margin-left:auto` mit. */
.kp-ansicht-fenster .kp-wahl-fuss{gap:10px}

/* ---------------------------------------------------------------------------
   Die beiden Symbolknöpfe in der Steuerungszeile (21.08.2026)
   ---------------------------------------------------------------------------
   🔴 Sie standen unterschiedlich hoch: 34 px der Export, 29,6 px das
   Zahnrad (Ansage des Users). Der Grund ist die Bauart — der Export ist ein
   `<a>`, das Zahnrad ein `<button>`, und beide bekommen von Browser und
   Stylesheet verschiedene Polsterung. Nebeneinander in einer Zeile fällt schon
   ein Pixel auf.

   ⚠️ Deshalb feste Maße statt Polsterung: Zwei quadratische Flächen von
   34×34 sind unabhängig davon gleich groß, wie das Symbol darin gerechnet
   wird. Eine Angleichung über `padding` hält nur, solange keiner der beiden
   Knöpfe je eine andere Grundregel erbt.

   ⚠️ NICHT für die beschriftete Fassung (`kp-export-text`): Wo zwei Listen
   auf einer Seite stehen, tragen die Knöpfe einen Namen, und 34 px schnitten
   ihn ab. */
.kp-listenkopf .kp-export:not(.kp-export-text),
.kp-listenkopf .kp-ansicht-knopf{
  display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;padding:0;flex:0 0 auto;
}

.kp-ansicht-knopf{display:inline-flex;align-items:center;gap:6px}
.kp-ansicht-knopf svg,
.kp-listenkopf .kp-export svg{width:18px;height:18px}

@media (max-width: 640px){
  .kp-ansicht-fenster{width:100%;max-height:none;height:100%;border-radius:0}
}

/* ==========================================================================
   Listen als Kaertchen auf dem Telefon (21.08.2026)

   Ansage des Users vom 20.08.: „die mobile darstellung der listen muss auch
   nochmal ueberarbeitet werden. ich denke wir fahren da mit einer anderen
   darstellung besser" — ausdruecklich eine ANDERE Darstellung, keine schmalere
   Tabelle.

   🔴 Nur Tabellen mit `.kp-liste-karten`. Die Klasse setzt `portal.js`, und zwar erst
   nachdem es die Zellen beschriftet hat. Eine Tabelle ohne Beschriftung wuerde
   hier zu einer Saeule nackter Werte — schlechter als die Tabelle, die sie
   vorher war.

   ⚠️ Der Name ist mit Bedacht `kp-liste-karten` und NICHT `kp-karten`: Das gab
   es schon (`display:grid` fuer die Leistungskaertchen des Kunden, Zeile 573).
   Beim Bauen habe ich genau das uebersehen — die Tabelle bekam dadurch am
   DESKTOP `display:grid`, und Kopf, Koerper und Summenzeile lagen uebereinander.
   Aufgefallen ist es nur, weil ich die Desktopansicht gegengeprueft habe; auf
   dem Telefon sah alles richtig aus. **Vor einer neuen Klasse einmal danach
   greppen.**

   ⚠️ 720 px und nicht 480: Eine Liste mit neun Spalten ist auf einem Tablet
   quer schon nicht mehr lesbar. Wer bis zur Telefonbreite wartet, laesst den
   unbrauchbaren Zustand genau dort stehen, wo er am haeufigsten auftritt.
   ========================================================================== */
@media (max-width:720px){

  /* Der Rahmen gehoert jetzt an die Kaertchen, nicht mehr um die Tabelle. Der
     waagerechte Bildlauf entfaellt — genau der war das Problem. */
  .table-wrap:has(table.kp-liste-karten){
    overflow:visible;border:0;background:none;box-shadow:none;border-radius:0;
  }

  table.tabelle.kp-liste-karten,
  table.tabelle.kp-liste-karten tbody,
  table.tabelle.kp-liste-karten tbody > tr,
  table.tabelle.kp-liste-karten tbody > tr > td{display:block;width:auto}

  /* 🔴 Der Kopf wird NICHT ausgeblendet, sondern zur Bedienleiste.
     Blendete man ihn aus, waeren Sortierung und Spaltenfilter auf dem Telefon
     ersatzlos weg — beides steckt in den Kopfzellen. Uebrig bleiben nur die
     Zellen, die wirklich etwas zu bedienen haben; die reinen Titel fallen raus,
     ihre Beschriftung steht ja jetzt im Kaertchen. */
  table.tabelle.kp-liste-karten thead{display:block}
  table.tabelle.kp-liste-karten thead tr{
    display:flex;flex-wrap:wrap;gap:6px;
    padding:0 0 10px;border-bottom:1px solid var(--line);margin-bottom:12px;
  }
  table.tabelle.kp-liste-karten thead th{display:none;border:0;padding:0}
  /* Als abgesetzte Plaettchen und nicht als Fliesstext: Nebeneinander gesetzt
     verschwimmen „BEZEICHNUNG GLAEUBIGER BETRAG" zu einer Zeile, in der man
     nicht sieht, was ein einzelnes Bedienelement ist. */
  table.tabelle.kp-liste-karten thead th:has(a.kp-sort),
  table.tabelle.kp-liste-karten thead th:has(details){
    display:block;font-size:.72rem;
    padding:5px 9px;border:1px solid var(--line);border-radius:999px;
    background:var(--kp-tile-bg);
    /* 🔴 `!important` mit Grund (Fund des Users am Telefon, 21.08.2026:
       „bei den Sortier Feldern oben ragt ‚nr' aus seiner bubble'').
       Schmale Spalten tragen inline `style="width:1%"` — der uebliche
       Tabellenkniff fuer „so schmal wie moeglich". In einer Tabelle heisst das
       „nimm die Mindestbreite", als Flex-Element aber ein Prozent der
       Zeilenbreite: Das Plaettchen war 20 px breit, sein Inhalt 37, und „Nr."
       stand rechts daneben im Freien. Ein Inline-Stil laesst sich nur so
       ueberschreiben.
       ⚠️ `flex:0 0 auto` dazu, damit kein Plaettchen unter seinen Inhalt
       gedrueckt wird — umgebrochen wird ohnehin (`flex-wrap:wrap`). */
    width:auto !important;flex:0 0 auto;white-space:nowrap;
  }

  /* Ein Datensatz, ein Kaestchen. */
  table.tabelle.kp-liste-karten tbody > tr{
    border:1px solid var(--line);border-radius:var(--radius);
    background:var(--card);box-shadow:var(--shadow);
    padding:12px 14px;margin-bottom:12px;
  }
  /* ⚠️ Der Zeilen-Hover aus der Tabellenansicht muss hier weg: Auf dem Telefon
     gibt es keinen Zeiger, und die Faerbung bliebe nach einer Beruehrung
     stehen — dann sieht ein beliebiges Kaertchen aus wie ausgewaehlt. */
  table.tabelle.kp-liste-karten tbody > tr:hover{background:var(--card)}

  /* Beschriftung links, Wert rechts. Zwei Spalten und kein Umbruch untereinander:
     Ein Kaertchen mit acht Angaben waere sonst sechzehn Zeilen hoch. */
  /* 🔴 Beschriftung in einem festen linken Streifen, NICHT als Rasterspalte
     (Fund am Telefon, 21.08.2026). Mit `display:grid` wird JEDES Kind der Zelle
     ein eigenes Rasterfeld — eine Zelle mit zwei Kennzeichen („Kunde",
     „Partner") warf das zweite in die naechste Zeile unter die Beschriftung.
     Als Block fliesst der Zellinhalt wieder normal: ein Wert, zwei Kennzeichen,
     ein Auswahlfeld, ein ganzes Formular — alles gleich. */
  /* 🔴 Beschriftung ÜBER dem Wert, nicht daneben (Ansage des Users am Telefon,
     21.08.2026: „die email adresse rutscht raus, vielleicht machen wir Bezug
     etc. nicht neben den inhalt sondern als überschrift darüber").

     Der linke Streifen war 10em breit und nahm auf einem 390-px-Telefon rund
     40 % der Karte. Was übrig blieb, reichte für „Christian Funck", aber nicht
     für `bestellungen@wollberg.de` — die Adresse lief über den Rand, und
     mehrzeilige Texte brachen nach drei Wörtern um. Über dem Wert steht die
     Beschriftung einmal kurz, und der Wert bekommt die GANZE Kartenbreite.

     ⚠️ Die Karte wird dadurch höher. Das ist der Tausch: lieber scrollen als
     raten, was da abgeschnitten steht. */
  table.tabelle.kp-liste-karten tbody > tr > td{
    display:block;
    padding:7px 0 0;border:0;text-align:left;
  }
  table.tabelle.kp-liste-karten tbody > tr > td[data-spalte]{
    /* 🔴 Lange Werte ohne Leerzeichen brechen um, statt herauszulaufen. Eine
       E-Mail-Adresse hat keine Trennstelle, an der der Browser von sich aus
       umbräche — `anywhere` ist hier kein Schönheitsfehler, sondern die
       einzige Stelle, an der er es darf. */
    overflow-wrap:anywhere;
  }
  table.tabelle.kp-liste-karten tbody > tr > td[data-spalte]::before{
    content:attr(data-spalte);
    display:block;margin-bottom:1px;
    /* ⚠️ 10em und nicht 8: Die Einrueckung der Zelle betraegt 8,5em ihrer
       eigenen (groesseren) Schrift — in der kleineren Schrift der Beschriftung
       sind das rund 10,5em. Bei 8em brach „Portalzugang" mitten im Wort um
       („PORTALZUGA / NG"), obwohl daneben Platz war. */

    color:var(--muted);font-size:.74rem;letter-spacing:.04em;
    text-transform:uppercase;font-weight:700;line-height:1.4;
    /* Lange Beschriftungen brechen im Streifen um, statt in den Wert zu
       laufen — „Portalzugang" passt sonst nicht. */
    overflow-wrap:anywhere;
    /* ⚠️ Eigene Ausrichtung: Geldspalten tragen `style="text-align:right"`
       direkt im Markup, und ein Inline-Stil schlaegt jeden Selektor. Ohne
       diese Zeile rutscht die BESCHRIFTUNG mit nach rechts und klebt am Wert.
       Der Wert selbst darf rechts bleiben — Betraege liest man rechtsbuendig. */
    text-align:left;
  }

  /* Die Ueberschrift des Kaertchens: volle Breite, groesser, ohne Beschriftung.
     Welche Zelle das ist, entscheidet `portal.js` — es ist die erste MIT
     Beschriftung, nicht die erste ueberhaupt. */
  table.tabelle.kp-liste-karten tbody > tr > td.kp-karte-titel{
    font-size:1.02rem;font-weight:600;line-height:1.35;
    padding:0 0 8px;margin-bottom:6px;border-bottom:1px solid var(--line);
  }
  table.tabelle.kp-liste-karten tbody > tr > td.kp-karte-titel::before{content:none}
  /* Der Nachsatz unter dem Titel (Notiz, Belegnummern) bleibt klein und leise. */
  table.tabelle.kp-liste-karten tbody > tr > td.kp-karte-titel small{
    display:block;margin-top:4px;font-weight:400;
  }

  /* Zellen ohne Beschriftung sind die festen Spalten: vorn der Statuspunkt,
     hinten die Knoepfe. Sie bekommen die volle Breite statt einer leeren
     Beschriftungsspalte. */
  /* Zellen ohne Beschriftung sind die festen Spalten: vorn der Statuspunkt,
     hinten die Knöpfe. */
  table.tabelle.kp-liste-karten tbody > tr > td:not([data-spalte]){
    padding-top:4px;
  }
  /* Die Knopfspalte sitzt am Fuss des Kaertchens, abgesetzt. */
  table.tabelle.kp-liste-karten tbody > tr > td:last-child:not([data-spalte]){
    margin-top:8px;padding-top:10px;border-top:1px solid var(--line);
  }

  /* Zeilen ohne Spaltenstruktur — „keine Eintraege", Zwischensummen — bleiben
     Tabellenzeilen: `portal.js` hat sie bewusst nicht beschriftet. */
  table.tabelle.kp-liste-karten tbody > tr:not(:has(td[data-spalte])){
    border:0;background:none;box-shadow:none;padding:0;
  }

  /* Die Summenzeile unter der Tabelle traegt ihre eigene Struktur. */
  table.tabelle.kp-liste-karten tfoot{display:block}
  table.tabelle.kp-liste-karten tfoot tr{display:flex;justify-content:space-between;gap:10px}
  table.tabelle.kp-liste-karten tfoot td{border:0;padding:8px 0}
}

/* ==========================================================================
   Mobil: bis zu den Daten scrollen (21.08.2026)
   --------------------------------------------------------------------------
   Ansage des Users: „mobile muss ich erst mal scrollen bis daten kommen,
   kriegen wir das (auf allen ansichten) kompakter hin? ggf. die bubbles als
   dropdown und alles etwas näher beieinander."

   Gemessen an der Accountliste bei 390 px Breite, vorher **673 px** bis zur
   ersten Datenzeile:

     Tabellenkopf   117 px   ← überflüssig, siehe unten
     Listenkopf     124 px   ← fünf Elemente untereinander
     Filterreihe     98 px   ← drei Reihen Bubbles
     Suchleiste      85 px   ← Feld und Knopf übereinander
     Untertitel      79 px

   🔴 Alles hier gilt NUR unter 720 px. Am Schreibtisch ändert sich nichts —
   dort ist Platz, und die Knopfreihe war eine ausdrückliche Entscheidung
   („das system soll wie aus einem guss wirken", 21.08.2026).
   ========================================================================== */
@media (max-width:720px){
  /* Eine Groesse fuer alle Knoepfe, die untereinander buendig stehen sollen. */
  :root{--kp-mobil-knopf:96px;--kp-mobil-knopfhoehe:38px}

  /* ---- 1. Tabellenkopf in der Kartenansicht: weg -----------------------
     🔴 Der größte Einzelposten und schlicht ein Fehler: In der Kartenansicht
     trägt JEDE Zelle ihre Beschriftung selbst (`td::before` aus `data-spalte`).
     Der Tabellenkopf stand daneben und wiederholte dieselben Wörter — als
     Block untereinander, 117 px hoch.
     ⚠️ Damit wandern Sortierpfeile und Trichter am Handy in die Ansicht
     hinter dem Zahnrad. Das Filterband über der Liste bleibt sichtbar, ein
     gesetzter Filter lässt sich also weiterhin sehen und entfernen. */
  table.tabelle.kp-liste-karten > thead{display:none}

  /* ---- 2. Kopfbereich der Seite enger ---------------------------------- */
  .kp-titel{font-size:1.5rem;margin-bottom:4px}
  /* Der Untertitel erklärt die Seite — das liest man einmal. Jeden Aufruf
     daran vorbeizuscrollen kostet mehr, als er einbringt. */
  .kp-unter{display:none}
  .kp-inner > .kp-aktionen{margin-bottom:10px}
  /* Ein Knopf über die volle Breite sieht nach Formularabschluss aus; hier
     ist er ein Einstieg neben anderen. */
  .kp-aktionen .btn{width:auto}

  /* ---- 3. Filterreihe als Auswahlfeld ----------------------------------
     Das Feld baut `portal.js` aus derselben Knopfreihe (Beschriftung + Zahl).
     Beide stehen im Markup, die Breite entscheidet, welches man sieht — so
     muss beim Wechsel der Bildschirmgröße nichts umgebaut werden. */
  .kp-sichtwahl{display:none}
  .kp-sichtwahl-klein{display:block;margin:0 0 12px}
  .kp-sichtwahl-klein select{width:100%}

  /* ---- 4. Suchleiste einzeilig ------------------------------------------
     ⚠️ `base.css` setzt `input{width:100%}` — deshalb rutschte der Knopf in
     die nächste Zeile. Das Feld darf schrumpfen, der Knopf nicht. */
  .kp-suchleiste{gap:8px;margin-bottom:12px}
  .kp-suchleiste input[type=text],
  .kp-suchleiste input[type=search],
  .kp-suchleiste input:not([type]){flex:1 1 0;min-width:0;width:auto}
  .kp-suchleiste .btn{flex:0 0 auto}

  /* ---- 5. Listenkopf zusammenrücken ------------------------------------
     Zählzeile, Zeilenzahl, Export, Zahnrad und Blätterknöpfe standen
     untereinander. Sie gehören nebeneinander und dürfen umbrechen. */
  .kp-listenkopf{gap:8px;margin-bottom:10px;align-items:center}
  /* ⚠️ Die Zaehlzeile bekommt eine EIGENE Zeile. Zwischenzeitlich teilte sie
     sich die Reihe mit den Bedienelementen — das ging nur, solange die beiden
     Knoepfe 34 px schmal waren. Seit sie so breit sind wie der Suchknopf
     (96 px), passt die Reihe nicht mehr: Zaehlzeile + Zeilenwahl + zwei
     Knoepfe sind ueber 430 px. Dann bricht sie an einer beliebigen Stelle um,
     und die zwei Knoepfe stehen NICHT mehr nebeneinander — auf den Tickets
     landete das Zahnrad allein in der naechsten Zeile, 310 px vom rechten
     Rand. Mit einer festen Aufteilung ist die Lage auf jeder Seite dieselbe. */
  .kp-listenkopf > .muted{flex:0 1 auto;font-size:.82rem}
  .kp-listenkopf .kp-pro{margin:0}
  /* 🔴 Blaetterknoepfe OBEN weg: Unter der Liste stehen dieselben noch
     einmal (`Liste::steuerungUnten`). Am Schreibtisch sind zwei Stellen
     bequem, am Handy kosten sie eine ganze Reihe, bevor die erste Zeile
     kommt — und wer blaettern will, ist ohnehin am Ende der Liste. */
  .kp-listenkopf .kp-blaettern{display:none}
  /* ---- Knopfbreiten angleichen (Ansage des Users, 21.08.2026) ----------
     „toll waere es wenn der zahnrad button und der export button genau so
     breit waeren wie suchen und sie buendig mit dem suchen button rechts
     abschliessen."

     🔴 Ueber eine gemeinsame Groesse, NICHT ueber eine abgeschriebene
     Zahl: „Suchen" ist im Deutschen 91 px breit, im Englischen („Search")
     schmaler. Wer 91 px festschreibt, hat die Buendigkeit in genau einer
     Sprache. So sind alle drei per Definition gleich breit — in jeder.

     ⚠️ Auch die Hoehe angeglichen: Drei gleich breite Knoepfe in zwei
     verschiedenen Hoehen sehen nicht nach Absicht aus, sondern nach Zufall.
     Die beiden Listenknoepfe sind `btn-klein`, der Suchknopf nicht. */
  .kp-suchleiste .btn{
    width:var(--kp-mobil-knopf);
    min-width:var(--kp-mobil-knopf);
    height:var(--kp-mobil-knopfhoehe);
    justify-content:center;
  }
  /* 🔴 Die BEIDEN Listenknoepfe ZUSAMMEN so breit wie der Suchknopf darueber,
     nicht jeder einzeln (Praezisierung des Users, 21.08.2026). Also je die
     Haelfte, abzueglich des Zwischenraums — dann steht der rechte Rand des
     Zahnrads genau unter dem rechten Rand von „Anzeigen".
     ⚠️ Der Abzug MUSS dem `gap` der Reihe entsprechen. Steht dort spaeter ein
     anderer Wert, verschiebt sich die Buendigkeit um genau diese Differenz —
     deshalb beides hier beieinander. */
  .kp-listenkopf{gap:8px}
  /* 🔴 DIESELBEN Selektoren wie die Grundregel weiter oben
     (`.kp-listenkopf .kp-export:not(.kp-export-text), .kp-listenkopf
     .kp-ansicht-knopf`), nicht `.kp-listenkopf .btn`. Die Grundregel hat beim
     Export DREI Klassen und schlaegt zwei; beim Zahnrad steht es zwei zu zwei,
     und dort gewann meine, weil sie spaeter steht. Ergebnis war genau das,
     was der User gesehen hat: Export 34 px, Zahnrad 44 px.
     Merksatz: Wer eine bestehende Regel ueberschreibt, nimmt ihren Selektor —
     nicht einen bequemeren. */
  .kp-listenkopf .kp-export:not(.kp-export-text),
  .kp-listenkopf .kp-ansicht-knopf,
  .kp-listenkopf .btn{
    /* ⚠️ `flex:0 0 auto` ist hier entscheidend. Ohne das schrumpft Flexbox den
       ERSTEN Knopf, sobald die Reihe eng wird — auf den Tickets stand der
       Export dann mit 34 px neben einem Zahnrad mit 44, und das Paar war
       schmaler als der Suchknopf. Eine gesetzte Breite ist in einer Flexreihe
       nur ein Wunsch, solange das Schrumpfen erlaubt bleibt. */
    flex:0 0 auto;
    width:calc((var(--kp-mobil-knopf) - 8px) / 2);
    min-width:0;
    height:var(--kp-mobil-knopfhoehe);
    justify-content:center;
    padding-left:0;padding-right:0;
  }
  /* Damit die Reihe nicht an der Zaehlzeile scheitert: sie darf schrumpfen. */
  .kp-listenkopf > .muted{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* Alles vor den Knoepfen bekommt den Rest — damit stehen sie rechts und
     der letzte schliesst mit dem Suchknopf darueber ab. */
  .kp-listenkopf .kp-pro{margin-right:auto}

  /* Das Wort hinter der Zahl weg (Ansage des Users): „1–20 von 50" statt
     „1–20 von 50 Accounts". Damit passt das Zahnrad in dieselbe Reihe und
     eine ganze Zeile faellt weg. Unter der Liste bleibt das Wort stehen. */
  .kp-listenkopf .kp-einheit{display:none}

  /* ---- 6. Luft zwischen den Karten ------------------------------------- */
  table.tabelle.kp-liste-karten tbody > tr{margin-bottom:10px}
}

/* ---- 7. Reiterleisten scrollen, statt umzubrechen -----------------------
   Auf den Eingangsrechnungen brach die Reiterleiste am Handy in DREI Zeilen
   und kostete 144 px, bevor die Seite ueberhaupt anfing.

   \U0001f4cc Fuer manche Leisten gibt es schon die Schiebehuelle mit Pfeilen
   (`leisteAuf()`/`leisteZu()`, 15.08.2026) — diese hier steckt nicht darin.
   Statt die Huelle an acht Stellen nachzuruesten, scrollt die Leiste am Handy
   selbst: gleiche Wirkung, eine Regel, und sie greift auch bei jeder Leiste,
   die spaeter dazukommt.

   ⚠️ Innerhalb der Huelle KEIN eigenes Scrollen — sonst schieben zwei
   Behaelter ineinander und die Pfeile bewegen den falschen. */
@media (max-width:720px){
  .kp-reiter{
    flex-wrap:nowrap;
    overflow-x:auto;
    scrollbar-width:none;
    -webkit-overflow-scrolling:touch;
  }
  .kp-reiter::-webkit-scrollbar{display:none}
  .kp-reiter > *{flex:0 0 auto}
  .kp-leiste-schiebe .kp-reiter{overflow-x:visible}

  /* ---- 8. Suchleisten mit Zeitraum ---------------------------------------
     Suchfeld, zwei Datumsfelder und der Knopf standen in drei Zeilen. Das
     Suchfeld darf die erste Zeile behalten, die drei schmalen Felder teilen
     sich die zweite. */
  .kp-suchleiste input[type=search],
  .kp-suchleiste input[type=text]{flex:1 1 100%}
  .kp-suchleiste input[type=date]{flex:1 1 0;min-width:0;width:auto}
}

/* Marke ohne Logo: der Name als Text (21.08.2026). Ein Mandant, der noch kein
   Logo hochgeladen hat, zeigt seinen Namen — nicht das Logo des Betreibers.
   Groesse und Gewicht an die Kopfzeile angepasst, damit die Zeile gleich hoch
   bleibt, ob dort ein Bild oder Text steht. */
.brand-name{
  font-size:1.05rem;font-weight:700;letter-spacing:-.01em;
  color:var(--text);white-space:nowrap;
}

/* ---- Demoanmeldung (21.08.2026) -------------------------------------------
   🔴 NICHT `.kp-haken` benutzen. Das ist der runde Haken-KNOPF aus der
   Rechnungsliste (ein `<button>`), kein Ankreuzfeld. Auf einem `<label>` mit
   `<input type=checkbox>` sah die Modulauswahl kaputt aus — der User hat es
   sofort gemeldet: „die auswahl der module ist kaputt".

   ⚠️ Zwei Spalten ab 520px, darunter eine. Neun Module untereinander sind
   auf dem Telefon eine halbe Bildschirmlaenge Scrollweg vor dem Absenden. */
.kp-modulwahl{border:0;padding:0;margin:20px 0 0}
/* ⚠️ Kein Rahmen mehr: Seit die Formularspalte selbst eine Flaeche ist, waere
   das ein Kasten im Kasten. Zwei ineinandergeschachtelte Rahmen sehen nach
   Versehen aus, nicht nach Gliederung. Die Ueberschrift traegt die Gruppe. */
.kp-modulwahl legend{padding:0;font-weight:600;font-size:1.02rem}
.kp-wahlliste{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(205px,1fr));
  gap:9px 18px;margin-top:10px;
}
.kp-wahl{
  display:flex;align-items:flex-start;gap:10px;
  cursor:pointer;line-height:1.35;
  padding:11px 13px;border:1px solid var(--line);border-radius:12px;
  background:var(--card);
  transition:transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.kp-wahl input{
  margin:1px 0 0;flex:0 0 auto;width:17px;height:17px;
  accent-color:var(--brand);cursor:pointer;
}
/* ⚠️ `min-width:0` am Text: Ein Flex-Kind hat als Vorgabe `min-width:auto`
   und schrumpft deshalb NICHT unter seine Inhaltsbreite — ein langer Name wie
   „Mitarbeiterverwaltung" schob sich aus der Kachel heraus, statt umzubrechen.
   Vom User gemeldet, sobald die Kacheln standen. */
.kp-wahl > span{min-width:0;overflow-wrap:anywhere}

/* Anheben und ein sehr weicher Schatten mit stark negativer Streuung. Genau
   das unterscheidet das Schweben von einem Schlagschatten: Der Schatten liegt
   weit unter dem Element und hat kaum eine Kante.
   Vorbild: dealpilot.immo, dort `0 30px 56px -30px` bei 4px Anhebung. */
.kp-wahl:hover{
  transform:translateY(-3px);
  border-color:color-mix(in srgb, var(--brand) 45%, var(--line));
  box-shadow:0 22px 44px -28px rgba(0,0,0,.55);
}

/* Gewaehlt: Rahmen und ein Hauch Markenfarbe im Ruecken. `:has()` erspart
   eine JavaScript-Klasse — das Ankreuzfeld selbst bleibt die Wahrheit, und
   ohne Skript sieht es trotzdem richtig aus. */
.kp-wahl:has(input:checked){
  border-color:var(--brand);
  background:color-mix(in srgb, var(--brand) 8%, var(--card));
}
.kp-wahl:focus-within{outline:2px solid var(--brand);outline-offset:2px}

/* ⚠️ Wer Bewegung abgestellt hat, bekommt nur die Farbe — kein Anheben.
   Ein Effekt, der sich nicht abschalten laesst, ist keine Verzierung mehr. */
@media (prefers-reduced-motion:reduce){
  .kp-wahl{transition:border-color .16s ease}
  .kp-wahl:hover{transform:none}
}

/* Die Zugangsdaten nach dem Einloesen: Beschriftung und Wert nebeneinander,
   der Wert umbrechbar — ein Kennwort mit Sonderzeichen sprengt sonst die
   Karte auf dem Telefon. */
.kp-zugangsdaten{display:grid;grid-template-columns:auto 1fr;gap:7px 18px;margin:18px 0}
.kp-zugangsdaten dt{font-weight:600;color:var(--muted)}
.kp-zugangsdaten dd{margin:0;overflow-wrap:anywhere}
.kp-zugangsdaten code{font-size:1.05rem;letter-spacing:.02em}

@media (max-width:520px){
  .kp-wahlliste{grid-template-columns:1fr}
  .kp-zugangsdaten{grid-template-columns:1fr;gap:2px 0}
  .kp-zugangsdaten dd{margin-bottom:10px}
}

/* ---- Demoanmeldung: zwei Spalten am Rechner (21.08.2026) ------------------
   Frage des Users: „wieso konzentrieren wir das immer so sehr auf die mitte
   und gehen nicht mehr in die breite (zumindest am desktop)?"

   Es steckte keine Entscheidung dahinter — `.karte-schmal` stammt von der
   Anmeldeseite und ist mit 560px fuer ZWEI Eingabefelder richtig bemessen.
   Ein Formular mit fuenf Feldern, neun Modulen und Captcha wird darin zu
   einer schmalen Schlucht mit langem Scrollweg.

   ⚠️ Die schmale Karte bleibt, wo sie hingehoert: bei den Anmeldungen. Ein
   breites Anmeldeformular sieht falsch aus, weil zwei Felder die Breite nicht
   fuellen. Deshalb eine eigene Klasse und keine Aenderung an `.karte-schmal`.

   ⚠️ Umbruchpunkt bei 900px, nicht bei 768px: Bei zwei Spalten braucht die
   Formularspalte allein schon rund 420px, sonst stehen Vor- und Nachname
   wieder untereinander und der Gewinn ist weg. */
/* ⚠️ Eigenes Innenmass: `.karte-schmal` hat 30px seitlich, und was bei
   560px Breite luftig wirkt, klebt bei 1000px am Rand — der User hat es
   sofort gesehen: „die textboxen rechts sind jetzt direkt am rand ihres
   bereiches“. Die Eingabefelder gehen ueber die volle Spaltenbreite,
   also muss der Abstand aus der Karte kommen. */
/* 🔴 1240px, nicht 1000 (21.08.2026). Der User hat viermal dasselbe
   gemeldet, und ich habe es dreimal als Abstandsproblem behandelt. Es war
   ein BREITENproblem: „unverändert nur dass der generelle bereich mit text
   und eingabefeldern erneut kleiner geworden ist“ — mein groesserer
   Innenabstand hat den nutzbaren Bereich weiter verkleinert, also genau das
   Gegenteil.
   Seine erste Frage war schon die richtige: „wieso konzentrieren wir das
   immer so sehr auf die mitte und nicht mehr in die breite?“
   1240px ist das Containermass von dealpilot.immo, das ihm gefaellt. */
/* ⚠️ 21px seitlich statt 42 (21.08.2026). Die Glasflaeche des Formulars
   sass mit 42px Luft in der Karte; auf Wunsch des Users die Haelfte —
   nah genug, dass es zusammengehoert, weit genug, dass die innere Flaeche
   nicht mit der aeusseren verschmilzt.
   Oben und unten bleibt es groesser: Dort steht keine zweite Flaeche
   daneben, sondern die Ueberschrift, und die braucht Luft. */
.karte-breit{max-width:1240px;padding:38px 42px}

.kp-demo-raster{
  display:grid;grid-template-columns:1fr;gap:26px;
}
.kp-demo-text h1{margin-top:0}
.kp-demo-liste{margin:14px 0;padding-left:20px;line-height:1.7}
.kp-demo-liste li{margin-bottom:4px}

/* Zwei Felder nebeneinander — Vor-/Nachname und Mail/Telefon gehoeren
   zusammen und sind einzeln schmal genug. */
.kp-demo-paar{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.kp-demo-paar > div{min-width:0}
.kp-demo-paar label{display:block}

/* 🔴 Die Formularspalte ist eine eigene FLAECHE, keine Trennlinie
   (21.08.2026, dritte Rueckmeldung des User zur selben Sache: „textboxen und
   bereiche liegen bei der servuno demo anmeldung immer noch an den grenzen
   ihrer äußeren container“).

   Gemessen stimmte der Abstand die ganze Zeit — 47px bis zum Kartenrand. Das
   Auge sieht aber etwas anderes: Links steht Text mit Flattersatz, rechts
   stehen harte Rechtecke, deren Kanten exakt auf der Spaltengrenze enden.
   Ohne eine sichtbare Flaeche dahinter wirkt jedes Feld angeschoben.
   Mit Flaeche und Innenabstand hat das Feld einen Rand, zu dem es gehoert.

   Die Flaeche ist bewusst kaum sichtbar — `--line` zu 22% gemischt. Vorbild
   ist dealpilot.immo, wo die Glasflaechen bei rgba(255,255,255,.03) bis .08
   liegen: Man soll sie spueren, nicht sehen. */
@media (min-width:900px){
  /* Die Formularspalte bekommt den groesseren Anteil — sie traegt Felder,
     die Textspalte nur Fliesstext, der ohnehin nicht breiter als rund 60
     Zeichen laufen sollte. */
  .kp-demo-raster{grid-template-columns:minmax(0,1fr) minmax(480px,1.3fr);gap:40px}
  /* 🔴 Die Flaeche ist das FORMULAR, nicht die Spalte (21.08.2026).
     Vorher trug die Spalte eine Flaeche UND das Formular eine zweite aus
     dem Glaseffekt von base.css — die Felder klebten an der inneren. Jetzt
     gibt es genau eine, und die hat ihren Innenabstand. */
  /* 🔴 ZWEI Flaechen, und zwischen ihnen 21px (21.08.2026).
     Der User wollte die Glasflaeche behalten, aber sie soll nicht bis an
     den Rand ihres Bereichs laufen. Vorher waren es 40px, gewuenscht die
     Haelfte. Ich hatte das zuerst am Kartenmass gedreht — falsch: Dadurch
     rueckte auch die Textspalte an den Kartenrand.
     Die Staffelung von aussen nach innen:
       Karte -> 42px -> aeussere Flaeche -> 21px -> Glas -> 34px -> Feld */
  .kp-demo-form{
    background:color-mix(in srgb, var(--line) 14%, transparent);
    border:1px solid var(--line);border-radius:20px;
    padding:21px;
  }
  /* ⚠️ `.karte-schmal .form` (zwei Klassen) schlaegt `.kp-demo-form form`
     (eine Klasse, ein Element) — die Regel darunter blieb wirkungslos, das
     Innenmass stand weiter auf 0. Mit der Karte im Selektor gewinnt sie. */
  .karte-schmal .kp-demo-form form{
    background:color-mix(in srgb, var(--line) 22%, transparent);
    border:1px solid var(--line);border-radius:16px;
    padding:32px 34px 34px;
  }
}
@media (max-width:560px){
  .kp-demo-paar{grid-template-columns:1fr}
  .karte-breit{padding:26px 20px}
}
