:root {
  --accent-ink: #ffffff;   /* Schrift AUF dem Akzent, siehe html.call weiter unten */
  --bg: #f4f6fb;
  --bg2: #ffffff;
  --bg3: #f0f3fa;
  --bg4: #e8edf8;
  --border: rgba(99,120,200,0.1);
  --border2: rgba(99,120,200,0.22);
  --text: #141830;
  --text2: #5a6490;
  /* --text3 (08.10.2026, Paket Farben, Durchsicht vom 04.10. W1): #7c8496 hatte als Schrift 3,20–3,75:1 —
     Hinweise, Metazeilen, Tabellenkoepfe, Unterzeilen in fast jeder Ansicht (auf Weiss 3,75, auf --bg3 3,38,
     auf --bg4 3,20). #5f677a: im Bild gemessen 5,6:1 auf Weiss, 5,1 auf --bg3, 4,8 auf --bg4 (Werte und Probe:
     intern/werkzeuge/lokal/pruef-farben-app.js). Farbton bleibt blaugrau. Der Dialer setzt je Design eigene
     Werte (glass.css Abschnitt 26 (3)) — die bleiben. */
  --text3: #5f677a;
  --accent: #051C2C;
  --accent2: #3451c7;
  --accent-light: #eef1fd;
  --green: #0ea579;
  --green-bg: #e8f8f3;
  --green-text: #0a7a59;
  --red: #e53e5e;
  /* Rot als SCHRIFT (08.10.2026, W2): --red auf Weiss 4,05:1, auf --red-bg 3,61:1, auf dem Testphasen-Streifen
     3,37:1. --red bleibt die Farbe der Flaechen und Raender; wer Rot SCHREIBT, nimmt --red-text. */
  --red-text: #b91c3c;
  --red-bg: #fdeef2;
  --amber: #d97706;
  /* Bernstein als SCHRIFT (W6): --amber auf --amber-bg 2,90:1. Der Wert ist der von .login-hinweis (10.08.2026). */
  --amber-text: #92400e;
  --amber-bg: #fef3e2;
  --purple: #C8A44D;
  /* --purple ist seit dem Markenwechsel GOLD und traegt Flaechen und Raender. Als SCHRIFT auf Hell hat es
     2,15–2,20:1 (W6) — dafuer --purple-text. #7a5f1c wie im Dialer (glass.css 26 (4)): auf den getoenten
     Plaketten haelt #8a6d22 nur 4,4–4,6:1. */
  --purple-text: #7a5f1c;
  --purple-bg: #eff8fe;
  /* Platzhalter in Feldern (W3): ohne Regel nimmt jeder Browser sein eigenes Grau — WebKit (jedes iPhone) hell
     2,1–2,4:1, Chromium dunkel 3,2–3,6:1. Eine eigene Farbe, in beiden gleich. */
  --platzhalter: #646c80;
  --radius: 16px;
  --radius-sm: 10px;
  --shadow: 0 2px 12px rgba(5,28,44,0.07), 0 1px 3px rgba(0,0,0,0.05);
  --shadow-lg: 0 8px 30px rgba(5,28,44,0.12), 0 2px 8px rgba(0,0,0,0.06);
  /* Motion-Tokens (Design-Standard, siehe intern/docs/design-motion.md) */
  --dur-fast: 140ms;
  --dur: 200ms;
  --dur-slow: 300ms;
  --ease-out: cubic-bezier(.2,.8,.2,1);
  --ease-in: cubic-bezier(.4,0,1,1);
}

/* DARK MODE */
body.dark {
  /* Navy statt Fast-Schwarz (22.07.2026, Wunsch des Betreibers): die Navigation traegt
     EXAKT das Marken-Navy #051C2C, die Inhaltsflaeche liegt eine Spur tiefer, die Karten
     steigen darueber auf. Dadurch fliesst es von der Leiste in die Flaeche, statt hart
     abzusetzen — der Uebergang betraegt nur 1,07:1.
     Die Helligkeits-Abstufung des alten Entwurfs ist erhalten, gewechselt hat nur die
     Farbfamilie: die Tiefe traegt die Helligkeit, nicht der Farbton.
     Alle Textfarben sind gegen die HELLSTE dieser Flaechen (--bg4) nachgerechnet. */
  --bg: #0a2038;
  --bg2: #12293f;
  --bg3: #17324a;
  --bg4: #21405c;
  --border: rgba(99,120,200,0.15);
  --border2: rgba(99,120,200,0.25);
  --text: #e8eaf6;
  /* Gedaempfter Text im Dunkelmodus muss HELLER werden, nicht dunkler.
     Bis zum 22.07.2026 stand hier --text3: #4a5490 — nach derselben Ueberlegung wie im
     Hellmodus gebildet ("gedaempft = weiter weg vom Haupttext"), nur in die falsche
     Richtung: auf dunklem Grund heisst gedaempft NAEHER am Hintergrund, also heller.
     Ergebnis waren 1,8:1 bis 2,7:1 — gemessen an 61 Stellen quer durch die App, u.a.
     saemtliche Tabellenkoepfe und die Zaehl-Plaketten.
     Die neuen Werte sind gerechnet, nicht geschaetzt, und gegen die HELLSTE dunkle
     Flaeche (--bg4) geprueft, wo es am schwersten ist:
       --text2  mindestens 7,0:1   --text3  mindestens 4,65:1
     Farbfamilie bleibt blaugrau, damit der Entwurf nicht kippt. */
  --text2: #cbd0e2;
  --text3: #a5b2cf;
  --accent: #5b7fff;
  --accent2: #C8A44D;
  --accent-light: #1a2040;
  --green: #0ea579;
  --green-bg: #0a2a20;
  --green-text: #0ea579;
  --red: #ff5577;
  /* 08.10.2026: --red #ff5577 haelt als Schrift auf --bg und --bg2 (4,9:1), auf den helleren dunklen Flaechen nicht:
     „Konto löschen" auf --bg3 im Bild 4,28:1. #ff8a9f: gerechnet 5,9:1 auf --bg3, 4,8:1 auf --bg4. */
  --red-text: #ff8a9f;
  --red-bg: #2a0a14;
  --amber: #f59e0b;
  --amber-text: #f59e0b;
  --amber-bg: #2a1a00;
  --purple: #E4C878;
  --purple-text: #E4C878;
  --purple-bg: #102230;
  --platzhalter: #a5b2cf;   /* = --text3 dunkel: auch auf der hellsten dunklen Flaeche (--bg4) ueber 4,5:1 */
  --shadow: 0 2px 12px rgba(0,0,0,0.3), 0 1px 3px rgba(0,0,0,0.2);
  --shadow-lg: 0 8px 30px rgba(0,0,0,0.4), 0 2px 8px rgba(0,0,0,0.3);
}

/* DARK MODE TOGGLE */
.theme-toggle { display: flex; align-items: center; gap: 6px; padding: 7px 12px; border-radius: var(--radius-sm); border: 1.5px solid var(--border2); background: var(--bg2); cursor: pointer; font-size: 13px; font-weight: 500; font-family: inherit; color: var(--text2); transition: all 0.15s; box-shadow: var(--shadow); }
.theme-toggle:hover { background: var(--bg3); color: var(--text); }
* { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 12px; }
body { font-family: system-ui, -apple-system, 'Segoe UI Variable Text', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; min-height: -webkit-fill-available; }
/* Die SEITE scrollt nie. Gescrollt wird ausschliesslich im Inhaltsbereich (.main) und
   auch dort nur, wenn wirklich mehr Inhalt da ist. Vorher schob jede Seite die ganze
   Flaeche und es erschien rechts eine Leiste, selbst wenn alles gepasst haette. */
html, body { height: 100%; }
body { overflow: hidden; }
html { height: -webkit-fill-available; }

/* LOGIN */
.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #eef1fd 0%, #f4f6fb 50%, #eff8fe 100%); }
.login-card { max-height: calc(100dvh - 40px); overflow-y: auto; background: var(--bg2); border-radius: 24px; box-shadow: var(--shadow-lg); padding: 2.5rem; width: 100%; max-width: 420px; border: 1.5px solid var(--border); position: relative; z-index: 1; }
/* Login-Wow: driftende Aurora-Blobs + Partikel-Canvas (self-hosted, CSP/DSGVO-safe, hell+dunkel) */
/* Bildschirmfeste Ebene statt normalem Block: so verlaengert die Anmeldung das Dokument
   NIE und es kann dort gar keine Seiten-Rollleiste entstehen (Betreiber: "man soll rechts
   nichts vom Scrollen sehen"). Nebenwirkung geloest: eine auftauchende Rollleiste hatte die
   zentrierte Karte seitlich verschoben — genau das war der Wackler beim Splash-Uebergang.
   Ist das Fenster zu niedrig, scrollt die KARTE in sich (siehe .login-card), nicht die Seite. */
/* HOEHE FEST AM GROSSEN FENSTER, nicht am aktuellen (Betreiber-Fund 24.07.2026:
   "zuckt runter — hat das was mit Face ID zu tun?"). Mit inset:0 folgte die Hoehe dem
   Fenster. Legt iOS ein System-Blatt darueber — Face ID, Passkey-Vorschlag, Tastatur —,
   schrumpft das Fenster, die zentrierte Karte sitzt hoeher; verschwindet das Blatt,
   waechst das Fenster und die Karte FAELLT wieder nach unten. Gemessen am iPhone 16 Pro:
   298 -> 152 -> 298, also 146px Ausschlag. Genau dieser Fall trifft den Start, weil der
   Passkey-Vorschlag beim Oeffnen kommt.
   --iq-fenster wird EINMAL gesetzt (siehe index.html) und danach nur noch beim Drehen
   erneuert. Eine feste Zahl kann nicht mitwandern - anders als 100lvh, dessen Wirkung
   sich in keinem Pruefstand belegen laesst, weil Testbrowser keine ein- und ausfahrenden
   Systemleisten haben. Was man nicht messen kann, soll hier nicht die Loesung sein.
   100vh bleibt der Rueckfall, bis die Zahl steht. */
.login-wrap { position: fixed; top: 0; left: 0; right: 0; height: var(--iq-fenster, 100vh); overflow: hidden; }
#auth-fx { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
.login-wrap::before, .login-wrap::after { content: ""; position: absolute; border-radius: 50%; filter: blur(90px); pointer-events: none; z-index: 0; }
/* Blau oben rechts von .34 auf .16 zurueckgenommen (Betreiber 2026-07-16: "oben rechts ist
   mir zu viel blau"). Der Fleck war mit 620px + .34 kraeftiger als sein violettes Gegenstueck
   unten links (.30 bei 540px) und zog das Auge von der Anmelde-Karte weg. Die Tiefe bleibt,
   die Lautstaerke geht - der Held ist die Karte, nicht der Hintergrund. */
.login-wrap::before { width: 46vw; height: 46vw; max-width: 620px; max-height: 620px; top: -14%; right: -8%; background: radial-gradient(circle, rgba(5,28,44,.16), transparent 68%); animation: authAurora1 24s ease-in-out infinite alternate; }
.login-wrap::after { width: 42vw; height: 42vw; max-width: 540px; max-height: 540px; bottom: -16%; left: -8%; background: radial-gradient(circle, rgba(92,172,246,.30), transparent 68%); animation: authAurora2 30s ease-in-out infinite alternate; }
@keyframes authAurora1 { from { transform: translate(0,0) scale(1); } to { transform: translate(-40px,50px) scale(1.15); } }
@keyframes authAurora2 { from { transform: translate(0,0) scale(1); } to { transform: translate(50px,-40px) scale(1.12); } }
@media (prefers-reduced-motion: reduce) { .login-wrap::before, .login-wrap::after { animation: none; } }
.login-logo { display: flex; align-items: center; gap: 12px; margin-bottom: 2rem; justify-content: center; }
.login-logo .icon { width: 52px; height: 52px; background: linear-gradient(135deg, #0e3a63, #051C2C); border-radius: 14px; display: flex; align-items: center; justify-content: center; font-size: 24px; box-shadow: 0 4px 14px rgba(5,28,44,0.3); }
.login-logo div h1 { font-size: 20px; font-weight: 700; }
.login-logo div p { font-size: 12px; color: var(--text3); }
.login-title { font-size: 22px; font-weight: 700; margin-bottom: 6px; }
.login-sub { font-size: 14px; color: var(--text2); margin-bottom: 1.5rem; }
.form-group { margin-bottom: 1rem; }
.form-group label { display: block; font-size: 13px; font-weight: 500; color: var(--text2); margin-bottom: 6px; }
.form-group input, .form-group select, .form-group textarea { width: 100%; padding: 11px 14px; border: 1.5px solid var(--border2); border-radius: var(--radius-sm); font-size: 16px; font-family: inherit; background: var(--bg); color: var(--text); outline: none; transition: border-color 0.15s; box-sizing: border-box; }
.form-group textarea { resize: vertical; min-height: 80px; line-height: 1.5; }
.form-group input:focus, .form-group select:focus, .form-group textarea:focus { border-color: var(--accent); background: var(--bg2); }
.btn-login { width: 100%; padding: 12px; background: linear-gradient(135deg, #0e3a63, #051C2C); color: #fff; border: none; border-radius: var(--radius-sm); font-size: 15px; font-weight: 600; font-family: inherit; cursor: pointer; margin-top: 0.5rem; box-shadow: 0 4px 14px rgba(5,28,44,0.3); transition: all 0.2s; }
.btn-login:hover { box-shadow: 0 6px 18px rgba(5,28,44,0.22); }
.login-error { background: var(--red-bg); color: var(--red); border: 1.5px solid rgba(229,62,94,0.2); border-radius: var(--radius-sm); padding: 10px 14px; font-size: 13px; margin-top: 1rem; display: none; }
/* STOERUNGSHINWEIS auf der Anmeldemaske (10.08.2026) — ausdruecklich NICHT .login-error.
   Der rote Kasten sagt "du hast etwas falsch gemacht"; hier ist der Server weg und der
   Benutzer hat alles richtig gemacht. Ein freundlicher Satz in einem roten Kasten liest
   sich weiter wie ein Vorwurf, deshalb eine eigene Farbe statt nur eines anderen Textes.
   Amber ist dieselbe Farbe wie der Verbindungsstreifen in der angemeldeten App
   (#verbindung-weg, #D97706) — dieselbe Lage soll ueberall gleich aussehen.
   .bereit = gruen: der Zustand hat gewechselt, es geht weiter. */
/* SCHRIFTFARBE: im HELLMODUS ein dunkleres Amber statt var(--amber) — gemessen, nicht
   geschaetzt (10.08.2026, im Browser ueber getComputedStyle, hell und dunkel):
       var(--amber) #d97706 auf #fef3e2   2,90:1   ← unter AA (4,5:1 bei 13px)
       #92400e      auf #fef3e2           6,46:1
   Der Rahmen und die Flaeche bleiben, wie sie waren; die Farbfamilie also auch.
   Das Token selbst wird bewusst NICHT angefasst — es haengt an ~10 weiteren Stellen
   (Plaketten, Zaehl-Chips, Verbindungsstreifen), und eine Aenderung dort waere eine
   Marken-Aenderung durch die Hintertuer.
   Warum es hier schwerer wiegt als anderswo: waehrend eines Ausfalls ist dieser Satz die
   EINZIGE Auskunft auf der Seite — der rote Kasten bleibt dann absichtlich leer. Und kein
   bestehender Pruefer sieht ihn: pruef-marke.js und pruef-marke-flaeche.js messen nur,
   was sichtbar ist, und sichtbar ist er nur im Ausfall.
   Im DUNKELMODUS bleibt var(--amber) (#f59e0b, 7,85:1) — dort ist nichts zu reparieren. */
.login-hinweis { background: var(--amber-bg); color: #92400e; border: 1.5px solid rgba(217,119,6,0.25); border-radius: var(--radius-sm); padding: 10px 14px; font-size: 13px; line-height: 1.5; margin-top: 12px; display: none; }
body.dark .login-hinweis { color: var(--amber); }
.login-hinweis.bereit { background: var(--green-bg); color: var(--green-text); border-color: rgba(14,165,121,0.28); }
/* Reihenfolge zaehlt: `.bereit` steht NACH der Dunkelmodus-Zeile, sonst gewaenne
   `body.dark .login-hinweis` (hoehere Spezifitaet) und der gruene Satz waere amber. */
body.dark .login-hinweis.bereit { color: var(--green-text); }
/* Testphasen-Karte (05.09.2026): der gruene Hinweiskasten mit einem Knopf darin.
   Links ausgerichtet, weil es drei Saetze sind und kein Einzeiler. */
.login-weiter { text-align: left; }
.login-weiter p { margin: 0 0 8px; }
.login-weiter p.klein { margin: 8px 0 0; font-size: 12.5px; opacity: .8; }
.login-weiter a.weiter-knopf { display: block; text-align: center; margin: 12px 0 0; padding: 12px 14px;
  border-radius: 10px; background: #051C2C; color: #fff; font-weight: 700; text-decoration: none; }
.login-weiter a.weiter-knopf:hover { background: #0B2A40; }


/* APP */
.app-wrap { display: none; }

/* SIDEBAR — always dark (HubSpot / Pipedrive style) */
.sidebar { position: fixed; left: 0; top: 0; bottom: 0; width: 240px; background: #152735; border-right: none; display: flex; flex-direction: column; padding: 1.5rem 1rem; z-index: 100; box-shadow: 3px 0 24px rgba(0,0,0,0.22); }
/* Im Dunkelmodus muss die Leiste DUNKLER sein als im Hellmodus — sonst wirkt das
   dunkle Bild heller als das helle. Genau das war am 22.07.2026 der Fall: hell 15 %,
   dunkel 22 % Helligkeit. Jetzt hell 22 % (McKinsey-Blau), dunkel 10 %.
   Gleiche Farbfamilie, nur tiefer; der Uebergang zur Inhaltsflaeche betraegt 1,06:1
   und fliesst dadurch. */
body.dark .sidebar { background: #071b2e; }
.sidebar-logo { display: flex; align-items: center; gap: 12px; padding: 0.5rem 0.75rem 1.5rem; border-bottom: 1px solid rgba(255,255,255,0.07); margin-bottom: 1.5rem; }
.logo-icon { width: 42px; height: 42px; background: linear-gradient(135deg, #0e3a63, #051C2C); border-radius: 24.5%; display: flex; align-items: center; justify-content: center; font-size: 20px; box-shadow: 0 4px 16px rgba(200,164,77,0.5); }
.logo-text h1 { font-size: 16px; font-weight: 700; color: #fff; }
/* DER MARKENPUNKT "Ruf·on" (12.09.2026, Betreiber: "in der App steht nur Rufon").
   Gezeichnet, nicht getippt — dieselbe Technik wie in der H1 der Werbeseite: ein Kreis
   in em, damit er jede Schriftgroesse mitgeht, und `aria-hidden` am <i>, damit ein
   Screenreader weiter "Rufon" liest (Wortmarke, Domain und alt-Text bleiben ohne Punkt).
   DREI ZAHLEN WEICHEN BEWUSST VON DER WERBESEITE AB:
   · 0,19em statt 0,13em. Dort ist die H1 36-64px, hier 16-20px — mit 0,13em waere der
     Punkt 2,1px und von einem Strichende nicht zu unterscheiden. Das ist der Fehler vom
     11.09.2026: den Punkt bei 120px beurteilt, benutzt wird er bei 30px. 0,19em ergibt
     3,0px (Seitenleiste) und 3,8px (Anmeldung), also mindestens die Stegbreite der 700er.
   · GOLD statt weiss. Auf der Werbeseite steht er in einer goldenen Zeile, dort waere
     Gold auf Gold unsichtbar. Hier sind die Ueberschriften dunkel (Anmeldekarte) oder
     weiss (Seitenleiste auf Navy) — Gold ist der Gegensatz und dieselbe Paarung wie im
     Logo.
   · vertical-align .25em statt .27em: die App laeuft in system-ui, nicht in Inter
     (gemessen: kein @font-face in der App), und dessen x-Hoehe ist etwas niedriger.
   Angesehen wurde es in beiden Groessen, nicht nur gerechnet.
   .login-title .mp (19.09.2026): "Willkommen bei Ruf·on" ueber der Einladungs-Maske, 22px
   dunkel auf der hellen Anmeldekarte — dieselbe Paarung wie in der Anmeldung (4,2px Punkt). */
.login-logo h1 .mp, .logo-text h1 .mp, .login-title .mp {
  display: inline-block; width: .19em; height: .19em; border-radius: 50%;
  background: #C8A44D; vertical-align: .25em; margin: 0 .06em;
}
.logo-text p { font-size: 11px; color: rgba(255,255,255,0.42); }
.nav-section { font-size: 10px; font-weight: 700; color: rgba(255,255,255,0.28); text-transform: uppercase; letter-spacing: 1.2px; padding: 0 0.75rem; margin-bottom: 6px; margin-top: 4px; }
/* min-height: pruef-mobil.js mass 44 px knapp unterschritten (gerundet 44, gerechnet
   darunter) — und die Regel fuer schmale Schirme weiter unten kuerzt das Polster sogar
   auf 8 px. Ein Fingerziel unter 44 px trifft der Daumen beim Telefonieren daneben. */
.nav-item { display: flex; align-items: center; gap: 10px; padding: 11px 14px; min-height: 44px; border-radius: var(--radius-sm); font-size: 14px; font-weight: 500; color: rgba(255,255,255,0.62); cursor: pointer; transition: all 0.15s; margin-bottom: 2px; border: none; background: none; width: 100%; text-align: left; font-family: inherit; }

/* Rechtsverweise in der Navigation: 10 px Schrift ergibt ein 14 px hohes Ziel — auf dem
   Handy praktisch nicht zu treffen, ausgerechnet bei den Pflichtangaben nach § 5 DDG.
   Das Polster vergroessert die Trefferflaeche auf 44 px, ohne die Schrift aufzublasen:
   die Zeile bleibt zurueckhaltend, der Finger trifft trotzdem. */
.legal-link { display: inline-block; padding: 14px 8px; min-width: 44px; text-align: center; color: inherit; text-decoration: none; }
.legal-link:hover { color: rgba(255,255,255,0.7); text-decoration: underline; }
/* Hover NUR fuer Maus-Geraete: auf Touch (Handy/Tablet) wuerde iOS den ersten Tap als "Hover"
   werten (Highlight) und erst der zweite loest den Klick aus -> alles muss mit EINEM Tap gehen. */
@media (hover: hover) { .nav-item:hover { background: rgba(255,255,255,0.08); color: #fff; } }
.nav-item.active { background: rgba(200,164,77,0.28); color: #E4C878; font-weight: 600; }
.nav-item.active .nav-icon { filter: none; }
.nav-item.nav-locked { opacity: 0.38; }
@media (hover: hover) { .nav-item.nav-locked:hover { background: rgba(255,255,255,0.05); color: rgba(255,255,255,0.55); } }
.nav-lock-badge { margin-left: auto; font-size: 11px; flex-shrink: 0; }
.nav-icon { font-size: 17px; width: 22px; text-align: center; }
/* Unterpunkt (z.B. Wettbewerb unter Rufon): eingerueckt + kleiner, mit zarter Fuehrungslinie */
.nav-sub { padding-left: 30px; font-size: 13px; margin-left: 8px; border-left: 1px solid rgba(255,255,255,0.10); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.nav-sub .nav-icon { font-size: 14px; width: 18px; }
/* Verwaltung am Sidebar-Ende verankern (Tagesarbeit oben, Admin unten), klar abgesetzt */
.nav-verwaltung { margin-top: auto; border-top: 1px solid var(--border); padding-top: 8px; }
.sidebar-bottom { margin-top: auto; border-top: 1px solid rgba(255,255,255,0.07); padding-top: 1rem; }
/* Kleine/niedrige Notebook-Screens: Sidebar IMMER scrollbar -> unterer Nav-Teil (Verwaltung + User/Logout)
   wird nie mehr abgeschnitten (Bug: Nav unsichtbar, User musste rauszoomen). */
.sidebar { overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scrollbar-width: thin; }
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); border-radius: 3px; }
@media (max-height: 760px) {
  .sidebar { padding-top: 1rem; }
  .sidebar-logo { padding-bottom: 1rem; margin-bottom: 1rem; }
  .nav-item { padding: 8px 14px; margin-bottom: 1px; }
  .nav-section { margin-top: 2px; margin-bottom: 4px; }
  .nav-verwaltung { padding-top: 6px; }
  .sidebar-bottom { padding-top: 0.6rem; }
}
.user-pill { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--radius-sm); background: rgba(255,255,255,0.07); margin-bottom: 8px; }
.user-avatar { width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg, #0e3a63, #051C2C); display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; color: #fff; flex-shrink: 0; }
.user-info { flex: 1; min-width: 0; }
.user-name { font-size: 14px; font-weight: 600; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-role { font-size: 10px; color: rgba(255,255,255,0.42); }
.btn-logout { width: 100%; padding: 8px; border-radius: var(--radius-sm); background: none; border: 1.5px solid rgba(255,255,255,0.12); font-size: 12px; font-weight: 500; font-family: inherit; color: rgba(255,255,255,0.52); cursor: pointer; transition: all 0.15s; }
@media (hover: hover) { .btn-logout:hover { background: rgba(229,62,94,0.18); color: #fca5a5; border-color: rgba(229,62,94,0.3); } }

/* Rechtliches am Fuss der Seitenleiste — bewusst leise (Betreiber 20.08.2026: "klein").
   Es muss auffindbar sein, nicht auffallen: Anbieterkennzeichnung nach § 5 DDG gehoert
   staendig verfuegbar, aber sie ist kein Bedienelement. Deshalb kleiner als der
   Abmelden-Knopf, gedaempft, und erst beim Ueberfahren deutlich. Umbruch erlaubt, damit
   drei Verweise auch in der schmalen Sidebar nicht ueber den Rand laufen. */
.sidebar-legal { display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: 4px 6px; margin-top: 10px; font-size: 10.5px; line-height: 1.5;
  color: rgba(255,255,255,0.24); }
.sidebar-legal a { color: rgba(255,255,255,0.34); text-decoration: none; }
.sidebar-legal a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
@media (hover: hover) { .sidebar-legal a:hover { color: rgba(255,255,255,0.72); text-decoration: underline; } }

.main { margin-left: 240px; padding: 2rem 3rem; height: 100dvh; overflow-y: auto; display: flex; flex-direction: column; }
/* Breite Schirme: der Inhalt streckte sich sonst randlos ueber die ganze Breite (bei 1280px
   ~968px breit) -> "alles zu weit am Rand". Deckel + zentriert gibt ueberall in Klassik einen
   ruhigen Rahmen statt Kante-an-Kante (Betreiber 30.07.). Der Modern/Glass-Dialer hat seinen
   eigenen, breiteren Rahmen und wird ausgenommen. Greift nur ueber 900px Inhaltsbreite. */
.main > * { max-width: 900px; margin-left: auto; margin-right: auto; width: 100%; }
#page-dialer.skin-modern, #page-dialer.skin-glass { max-width: none; }
/* Anti-Flacker: aktive Seite füllt die Höhe, Footer bleibt unten angepinnt.
   Ohne das rutscht der Footer beim Seitenaufbau erst hoch und springt nach dem
   Daten-Laden wieder runter (= sichtbares "Zucken", per Layout-Shift-API gemessen). */
.page.active { flex: 1 0 auto; }
/* `position: relative; z-index: 1` ist hier PFLICHT, nicht Kosmetik: ohne das war die
   Fusszeile in den Skins "glass" (dem STANDARD) und "modern" unsichtbar — gemessene
   Kontrastspanne klassik 114, glass 3, modern 0. Ursache ist dieselbe wie beim
   Testphasen-Streifen: #page-dialer.skin-glass::before ist `position:fixed; inset:0` mit
   deckendem Grund, #page-dialer ist positioniert und isoliert, also malt der ganze Block
   ueber jedes statische Geschwister in .main.
   Aufgefallen erst, als die Herkunftsangabe "ein Produkt von FL-ITSERVICE" hier hinein
   sollte (03.09.2026) — eine Zuordnung an unsichtbarer Stelle waere schlimmer als keine
   gewesen, weil sie erledigt aussieht. */
/* pointer-events (07.10.2026, Gegenpruefung Erstbesuch): der Fuss traegt nur das Datum, liegt aber mit z-index 1
   ueber der Seite — mit einem Wartungsbanner fing er am PC den Klick auf „Weiter" der Startseite ab (Modern und
   Glass, 1366×768 und 1280×900; am Handy lag er ueber der festen Leiste). Er nimmt jetzt keine Klicks mehr an. */
footer { margin-top: auto; position: relative; z-index: 1; pointer-events: none; }
.topbar { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 1.5rem; gap: 1rem; }
.topbar-left h2 { font-size: 28px; font-weight: 700; color: var(--text); letter-spacing: -0.5px; }
.topbar-left p { font-size: 14px; color: var(--text2); margin-top: 3px; }
.topbar-right { display: flex; gap: 10px; align-items: center; flex-shrink: 0; }
.search-wrap { display: flex; align-items: center; gap: 8px; background: var(--bg2); border: 1.5px solid var(--border2); border-radius: var(--radius-sm); padding: 8px 14px; box-shadow: var(--shadow); transition: border-color 0.15s; }
.search-wrap:focus-within { border-color: var(--accent); }
.search-wrap input { background: none; border: none; outline: none; font-size: 16px; font-family: inherit; color: var(--text); width: 200px; }
.search-wrap input::placeholder { color: var(--text3); }
.btn { display: flex; align-items: center; gap: 6px; padding: 9px 18px; border-radius: var(--radius-sm); font-size: 13px; font-weight: 500; font-family: inherit; cursor: pointer; border: none; transition: all 0.15s; }
.btn-primary { background: var(--accent); color: #fff; box-shadow: 0 4px 12px rgba(5,28,44,0.3); }
.btn-primary:hover { background: var(--accent2); }
/* Sekundaer-Button (dezent, fuer Nebenaktionen wie "Rundgang starten") — war nie definiert -> Browser-Default */
.btn-secondary { background: var(--bg3); color: var(--text); border: 1px solid var(--border2); box-shadow: var(--shadow); }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-light); }
.btn-ghost { background: var(--bg2); color: var(--text2); border: 1.5px solid var(--border2); box-shadow: var(--shadow); }
.btn-ghost:hover { background: var(--bg3); color: var(--text); }
.btn-danger { background: var(--red-bg); color: var(--red); border: 1.5px solid rgba(229,62,94,0.2); }
.btn-sm { padding: 6px 12px; font-size: 12px; }
.btn-block { width: 100%; }
.btn-danger-ghost { background: var(--bg2); color: var(--red); border: 1.5px solid rgba(229,62,94,0.3); box-shadow: var(--shadow); }
.btn-danger-ghost:hover { background: var(--red-bg); color: var(--red); }

/* ── KNOPFZUSTAENDE (07.10.2026, Paket Fenster und Knoepfe; Durchsicht Handy „Quer ueber alle Ansichten") ──
   (1) Der Bestaetigen-Knopf einer ZERSTOERENDEN Rueckfrage (iqConfirm mit danger, core.js): Rot als Klasse.
       Weiss auf #dc2626 = 4,8:1; beim Ueberfahren dunkler, nie Gold (die Hover-Regel von btn-primary greift
       hier nicht, weil der Knopf btn-primary gar nicht traegt). */
.btn-gefahr { background: #dc2626; color: #fff; box-shadow: 0 4px 12px rgba(220,38,38,.28); }
.btn-gefahr:hover { background: #b91c1c; }

/* (2) Abgeschaltet sieht abgeschaltet aus. Fuer .btn:disabled gab es KEINE Regel — „Speichern" im Kasten
       „Neuer Leitfaden" war gesperrt und sah aus wie an (Deckkraft 1, Gold, Schatten); eine einzige Ausnahme
       stand hier fuer den Aufheben-Knopf der Sperrliste (#sfg-ok, 19.09.2026, mit opacity .45).
       „Aus" heisst in diesem Projekt: graue Flaeche, gedaempfte Schrift, kein Schatten, kein Zeiger — NICHT
       Deckkraft (glass.css Abschnitt 26 (6), .dflow-aus): ein halb durchsichtiger Knopf mischt Schrift UND
       Flaeche mit dem Grund, das Wort ist dann kaum zu lesen, und lesen muss man es, um zu verstehen, was fehlt.
       !important, weil viele Knoepfe ihre Farbe am Element tragen (style="color:var(--amber)") und html.call
       .btn-primary hoeher wiegt als jede Regel hier. Gilt auch fuer #sfg-ok — seine eigene Regel ist entfallen. */
.btn:disabled {
  /* --text3, nicht --text2: der Nebenknopf (btn-ghost) traegt --text2 auf Weiss — mit derselben Schrift saehe ein
     abgeschalteter Knopf aus wie ein eingeschalteter Nebenknopf. --text3 auf --bg3: 3,4:1 hell, 5,6:1 dunkel (im Foto). */
  background: var(--bg3) !important; color: var(--text3) !important; border-color: var(--border) !important;
  box-shadow: none !important; cursor: not-allowed; transform: none !important; filter: none !important;
}
/* --bg3 ist in der glass-Sitzung durchscheinend (.48) — dort deckend, sonst traegt der Knopf den Verlauf dahinter. */
#page-dialer.skin-glass .btn:disabled { background: rgba(255,255,255,.72) !important; }

/* (3) Der Druck hat eine Antwort. Fuer keinen Knopf gab es :active (18 von 18 gemessen) — am Handy gibt es kein
       Ueberfahren, der Finger bekam also gar keine Rueckmeldung. Knoepfe, Ergebnis-Knoepfe und Tabs geben nach
       (kleiner) und werden dunkler; bei „Bewegung reduzieren" nur dunkler. Abgeschaltete antworten nicht.
       brightness statt einer zweiten Farbe je Knopfart: die Regel gilt fuer jede Flaeche, auch fuer die, an die
       niemand gedacht hat. Die Tabs haben keine Flaeche — sie bekommen eine (--bg3), solange der Finger drauf ist. */
.btn:active:not(:disabled), .kal-knopf:active:not(:disabled),
.bu-wahl:active:not(:disabled), .kal-wahl:active, .dflow-next:active:not(:disabled), .dflow-back:active:not(:disabled) {
  transform: scale(.97); filter: brightness(.9);
}
/* Die Ergebnis-Knoepfe: ihre Hover-Regeln haengen an bis zu drei Kennungen (glass.css: translateY(-2px),
   brightness(1.1)) — ohne !important bliebe der Druck dort ohne Bild (gemessen: 0,00 % der Pixel anders).
   Gesperrte (aria-disabled, vor dem Anruf) antworten nicht; fuer sie gilt die Regel in pages/dialer.html. */
#dialer-outcome-section .oc:active:not([aria-disabled="true"]) { transform: scale(.97) !important; filter: brightness(.9) !important; }
.mtab-btn:active { background: var(--bg3); transform: scale(.97); }
@media (prefers-reduced-motion: reduce) {
  .btn:active:not(:disabled), .kal-knopf:active:not(:disabled),
  .bu-wahl:active:not(:disabled), .kal-wahl:active, .dflow-next:active:not(:disabled), .dflow-back:active:not(:disabled),
  .mtab-btn:active { transform: none; }
  #dialer-outcome-section .oc:active:not([aria-disabled="true"]) { transform: none !important; }
}


/* METRICS */
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
/* Feste Spaltenzahlen gegen "Waisen-Karte": 7 Karten -> 7 bzw. 4+3; 5 Karten -> 5 bzw. 3+2 (nie eine allein) */
@media (min-width: 1200px) { .metrics-7 { grid-template-columns: repeat(7, 1fr); } .metrics-5 { grid-template-columns: repeat(5, 1fr); } }
@media (min-width: 860px) and (max-width: 1199px) { .metrics-7 { grid-template-columns: repeat(4, 1fr); } .metrics-5 { grid-template-columns: repeat(3, 1fr); } }
.metric-card { background: var(--bg2); border: 1.5px solid var(--border); border-radius: var(--radius); padding: 1.25rem 1.5rem; box-shadow: var(--shadow); transition: border-color 0.2s ease, box-shadow 0.2s ease; position: relative; overflow: hidden; }
.metric-card:hover { box-shadow: var(--shadow-lg); border-color: var(--border2); }
.metric-card .accent-bar { position: absolute; top: 0; left: 0; right: 0; height: 3px; border-radius: 16px 16px 0 0; }
.blue .accent-bar { background: linear-gradient(90deg, #0e3a63, #051C2C); }
.green .accent-bar { background: linear-gradient(90deg,#0ea579,#06b6d4); }
.amber .accent-bar { background: linear-gradient(90deg,#d97706,#f59e0b); }
.purple .accent-bar { background: linear-gradient(90deg, #C8A44D, #E4C878); }
.teal .accent-bar { background: linear-gradient(90deg, #0e3a63, #C8A44D); }
.red2 .accent-bar { background: linear-gradient(90deg,#e53e5e,#f59e0b); }
.metric-icon-wrap { width: 34px; height: 34px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; font-size: 17px; margin-bottom: 10px; }
.blue .metric-icon-wrap { background: var(--accent-light); }
.green .metric-icon-wrap { background: var(--green-bg); }
.amber .metric-icon-wrap { background: var(--amber-bg); }
.purple .metric-icon-wrap { background: var(--purple-bg); }
.teal .metric-icon-wrap { background: #e0f7fa; }
.red2 .metric-icon-wrap { background: var(--red-bg); }
.metric-label { font-size: 13px; color: var(--text3); font-weight: 500; margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.5px; }
.metric-value { font-size: 32px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -1px; }

/* GRID LAYOUTS */
.grid-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 1rem; margin-bottom: 1.25rem; }

/* CARDS */
.card { background: var(--bg2); border: 1.5px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; margin-bottom: 1.25rem; }
.card-header { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.5rem; border-bottom: 1px solid var(--border); background: var(--bg3); }
.card-header h3 { font-size: 16px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 8px; }
.card-body { padding: 1.25rem 1.5rem; }
.chart-wrap { position: relative; height: 180px; }
.chart-wrap-lg { position: relative; height: 220px; }
.chart-empty { display: none; align-items: center; justify-content: center; height: 100%; min-height: 140px; color: var(--text3); font-size: 13px; font-weight: 500; text-align: center; padding: 1rem; }
.count-chip { font-size: 12px; padding: 3px 10px; background: var(--accent-light); color: var(--accent); border-radius: 20px; font-weight: 600; font-variant-numeric: tabular-nums; }
/* Alle Plätze belegt — der Chip sagt es, bevor jemand vergeblich auf "Anlegen" klickt. */
.count-chip.voll { background: var(--amber-bg); color: var(--amber); }

/* CALL ITEMS */
.call-item { padding: 1rem 1.5rem; border-bottom: 1px solid var(--border); transition: background 0.15s ease; }
@keyframes fadeUp { from{opacity:0;transform:translateY(4px);}to{opacity:1;transform:translateY(0);} }
.call-item:hover { background: var(--bg3); }
.call-item:last-child { border-bottom: none; }
.call-row3 { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.call-transcript-preview { font-size: 12px; color: var(--text3); margin-bottom: 6px; font-style: italic; line-height: 1.5; border-left: 2px solid var(--border2); padding-left: 8px; }
.badge { font-size: 13px; padding: 4px 11px; border-radius: 20px; font-weight: 600; }
.badge-in { background: var(--green-bg); color: var(--green-text); }
.badge-out { background: var(--accent-light); color: var(--accent); }
.badge-missed { background: var(--red-bg); color: var(--red); }
.badge-voicemail { background: var(--purple-bg); color: var(--purple); }
.call-name { font-size: 16px; font-weight: 600; color: var(--text); flex: 1; }
.call-dur { font-size: 11px; padding: 2px 8px; background: var(--bg4); border-radius: 20px; color: var(--text2); font-weight: 500; }
.sentiment { font-size: 11px; padding: 3px 9px; border-radius: 20px; font-weight: 600; }
.action-btn { font-size: 11px; padding: 3px 9px; border-radius: 20px; cursor: pointer; font-family: inherit; font-weight: 500; border: 1.5px solid; transition: all 0.15s; }
.btn-audio { background: var(--amber-bg); color: var(--amber); border-color: rgba(217,119,6,0.2); }
.btn-transcript { background: var(--bg3); color: var(--text2); border-color: var(--border2); }
.btn-transcript:hover { background: var(--bg4); }
.transcript-box { display: none; margin-top: 10px; background: var(--bg3); border: 1.5px solid var(--border2); border-radius: var(--radius-sm); padding: 10px 14px; font-size: 12px; color: var(--text2); line-height: 1.8; max-height: 180px; overflow-y: auto; font-variant-numeric: tabular-nums; }
.audio-player { display: none; margin-top: 8px; }
.audio-player audio { width: 100%; border-radius: var(--radius-sm); }

/* FILTER */
.filter-row { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-bottom: 1rem; }
.filter-chip { padding: 7px 16px; border-radius: 20px; font-size: 14px; font-weight: 500; font-family: inherit; cursor: pointer; border: 1.5px solid var(--border2); background: var(--bg2); color: var(--text2); transition: all 0.15s; box-shadow: var(--shadow); }
.filter-chip.active { background: var(--accent-light); color: var(--accent); border-color: rgba(5,28,44,0.25); }
.sort-select { padding: 5px 13px; border-radius: 20px; font-size: 12px; font-family: inherit; font-weight: 500; border: 1.5px solid var(--border2); background: var(--bg2); color: var(--text2); outline: none; cursor: pointer; }

/* ============================================================
   MODERNES PERSONEN-DROPDOWN (.psel) — kein natives 90er-Aussehen
   eigener Chevron-Pfeil, Rundung, Fokus-Ring; light + dark
   ============================================================ */
.psel {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  font-size: 13px; font-weight: 500; font-family: inherit;
  padding: 7px 32px 7px 12px;
  border-radius: 10px;
  border: 1.5px solid var(--border2);
  background-color: var(--bg2);
  color: var(--text);
  min-width: 168px; max-width: 200px;
  cursor: pointer; outline: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239ba4c8' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.psel:hover { background-color: var(--bg3); }
.psel:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-light); }
.psel option { color: var(--text); background: var(--bg2); font-weight: 500; }

/* ============================================================
   EIGENES DROPDOWN (.dd) — komplett gestaltbar (auch im offenen Zustand)
   Menü ist position:fixed -> wird nicht von overflow:hidden abgeschnitten
   ============================================================ */
.dd { position: relative; display: inline-block; }
.dd-toggle { display: flex; align-items: center; gap: 8px; min-width: 168px; max-width: 210px; padding: 7px 12px; border-radius: 10px; border: 1.5px solid var(--border2); background: var(--bg2); color: var(--text); font-size: 13px; font-weight: 500; font-family: inherit; cursor: pointer; outline: none; transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease; }
.dd-toggle:hover { background: var(--bg3); }
.dd.open .dd-toggle { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-light); }
.dd-label { flex: 1; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dd-arrow { width: 14px; height: 14px; flex-shrink: 0; color: var(--text3); transition: transform 0.18s ease; }
.dd.open .dd-arrow { transform: rotate(180deg); }
.dd-menu { position: fixed; display: none; width: max-content; min-width: 168px; max-width: 260px; max-height: 264px; overflow-y: auto; background: var(--bg2); border: 1.5px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-lg); padding: 6px; z-index: 9500; animation: ddIn 0.15s ease; }
.dd.open .dd-menu { display: block; }
@keyframes ddIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
.dd-option { padding: 8px 12px; border-radius: 8px; font-size: 13px; font-weight: 500; color: var(--text); cursor: pointer; white-space: nowrap; transition: background-color 0.12s ease; }
.dd-option:hover { background: var(--bg3); }
.dd-option.sel { background: var(--accent-light); color: var(--accent); font-weight: 600; }
.dd-search { position: sticky; top: 0; background: var(--bg2); padding: 0 0 6px; margin-bottom: 2px; }
.dd-search-input { width: 100%; padding: 8px 11px; border: 1.5px solid var(--border2); border-radius: 8px; font-size: 13px; font-family: inherit; background: var(--bg); color: var(--text); outline: none; transition: border-color 0.15s ease; }
.dd-search-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-light); }
.dd-empty { padding: 12px; text-align: center; font-size: 12px; color: var(--text3); }

/* USER TABLE */
.user-table { width: 100%; border-collapse: collapse; }
.user-table th { padding: 10px 16px; text-align: left; font-size: 11px; font-weight: 600; color: var(--text3); text-transform: uppercase; letter-spacing: 0.5px; background: var(--bg3); border-bottom: 1px solid var(--border); }
.user-table td { padding: 12px 16px; font-size: 13px; color: var(--text); border-bottom: 1px solid var(--border); }
/* Rolle und Team gibt es im Rufon nicht (Produktdefinition 2.3). Sie werden HIER
   ausgeblendet, nicht erst zur Laufzeit.

   Vorgeschichte in zwei Schritten, beide am 01.08.2026:
   1. Der Betreiber fotografierte die PWA: beim Oeffnen von "Benutzer" standen kurz die
      Spalten ROLLE und TEAM da. callAssistBenutzerZuschnitt() blendet sie aus — aber erst
      hinter `await loadTeams()`, also nach einem echten Netzaufruf.
   2. Ich habe daraufhin nur die KOPFZEILEN (<th> in users.html) versteckt. Das machte den
      Zwischenzustand schlimmer: die Datenzellen (<td>) schreibt cx-users.js:386 weiterhin
      ohne Startlage — sechs sichtbare Ueberschriften ueber acht sichtbaren Zellen, die
      Tabelle also um zwei Spalten verschoben. Am Handy setzt `td::before{content:attr(
      data-label)}` zusaetzlich woertlich "ROLLE" und "TEAM" in jede Karte.

   Eine CSS-Regel trifft Kopf UND Zellen, sofort beim ersten Zeichnen, und auch jede Zeile,
   die spaeter nachgerendert wird. Das JavaScript darf weiterhin dasselbe tun — doppelt
   schadet nicht, aber verlassen muss man sich darauf nicht mehr. */
.user-table .sp-rolle, .user-table .sp-team { display: none; }
.user-table tr:last-child td { border-bottom: none; }
.user-table tr:hover td { background: var(--bg3); }
/* Rolle am Namen und Wort am Knopf (Durchsicht 17.10.2026, cx-users.js loadUsers): Admin hervorgehoben, Benutzer leise;
   das Wort neben dem Symbol nur am PC — am Handy stehen die Zeilen als Karten, dort reicht das Symbol (aria-label). */
.ua-rolle { display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: 20px; font-size: 12px; font-weight: 600; line-height: 1.5;
  white-space: nowrap; vertical-align: 1px; background: var(--bg3); color: var(--text2); }
.ua-rolle-admin { background: var(--accent-light); color: var(--accent); }
.ua-knopf { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.ua-wort { font-size: 12px; font-weight: 600; }
@media (max-width: 768px) { .ua-wort { display: none; } }
/* Am Handy EIN Knopf „⋯ Aktionen" statt fuenf Symbole (17.10.2026, cx-users.js uaAktionenBlatt); am PC bleiben Wort und
   Symbol in der Zeile, der Knopf „⋯" fehlt dort. */
.ua-mehr { display: none; }
@media (max-width: 768px) {
  .user-table .ua-knopf { display: none !important; }
  .user-table .ua-mehr { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 44px; min-width: 44px; padding: 0 16px; font-size: 14px; font-weight: 600; }
}
.ua-blatt-kopf { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; padding-right: 40px; }
.ua-blatt-titel { margin: 0; font-size: 17px; font-weight: 700; color: var(--text); overflow-wrap: anywhere; }
.ua-blatt-rolle { font-size: 12px; font-weight: 600; color: var(--text2); }
.ua-blatt-liste { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.ua-blatt-knopf { display: flex; align-items: center; justify-content: flex-start; gap: 12px; width: 100%; min-height: 48px; padding: 8px 14px; text-align: left; }
.modal .ua-blatt-knopf { min-height: 48px; }        /* „.modal button" (44 px, Handy) wiegt sonst schwerer */
.ua-blatt-knopf.btn-ghost { color: var(--text); }   /* das Wort in voller Schrift; Pausieren/Aktivieren tragen ihre Farbe inline */
.ua-bk-zeichen { font-size: 18px; line-height: 1; width: 24px; text-align: center; flex-shrink: 0; }
.ua-bk-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ua-bk-wort { font-size: 15px; font-weight: 700; }
.ua-bk-satz { font-size: 12px; font-weight: 400; color: var(--text2); line-height: 1.35; white-space: normal; }
.ua-blatt-satz { font-size: 12px; color: var(--text2); margin: 4px 2px 0; line-height: 1.45; }
.ua-blatt-abbrechen { display: block; width: 100%; min-height: 44px; margin-top: 16px; }
.role-badge { font-size: 11px; padding: 3px 9px; border-radius: 20px; font-weight: 600; }
.role-user { background: var(--accent-light); color: var(--accent); }

/* MODAL */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.25); backdrop-filter: blur(4px); z-index: 1000; display: none; align-items: center; justify-content: center; }
.modal-overlay.open { display: flex; }
.modal { background: var(--bg2); border-radius: 20px; padding: 2rem; width: 100%; max-width: 440px; max-height: 92vh; overflow-y: auto; box-shadow: var(--shadow-lg); border: 1.5px solid var(--border); animation: modalIn 0.2s ease; }
@keyframes modalIn { from{opacity:0;transform:scale(0.96);}to{opacity:1;transform:scale(1);} }
.modal h3 { font-size: 18px; font-weight: 700; margin-bottom: 1.5rem; color: var(--text); }
.modal-actions { display: flex; gap: 10px; margin-top: 1.5rem; justify-content: flex-end; }
/* Die Ankuendigung der aktualisierten Bedingungen (core.js ankuendigungZeigen, 17.10.2026): die Verweise der vier Zeilen
   tragen die Farbe der Vertragswand (--accent) am Element — im Fenster der App ist das je Design Gold auf hellem Grund
   (unter 3:1). Hier deshalb Schrift in --text mit Unterstrich. */
.zust-fenster a { color: var(--text) !important; text-decoration: underline; text-underline-offset: 3px; }
/* Das Fenster selbst nimmt den Fokus, wenn es kein Feld und keinen Knopf als Ziel gibt (core.js, fensterFokus) —
   ohne Ring um das ganze Fenster: der Ring gehoert an Knoepfe und Felder (07.10.2026). */
.modal-overlay .modal:focus, .modal-overlay .modal:focus-visible { outline: none; }

/* ── FENSTER AM HANDY: EIN BLATT VON UNTEN (07.10.2026, Apple-Abgleich V8, Durchsicht vom 04.10. W16) ──────────
   Gemessen am 01.10. (390×844): ein schwebendes Fenster, das links und rechts den Rand beruehrt, Radius 20 an
   allen vier Ecken, oben und unten 68 px Luft — weder Blatt noch Dialog; „Speichern" lag unter dem Inhalt.
   Jetzt bis 768 px (dieselbe Grenze wie die Tab-Leiste und das Buchungsblatt):
     · randstaendig unten, volle Breite, nur OBEN runde Ecken, ein Griff als Zeichen „das ist ein Blatt",
     · ueber der Tab-Leiste (der Schleier hat z-index 1000, die Leiste 250) — ein Fenster ist modal,
     · hoechstens bis 28 px unter den oberen Rand: man sieht, dass die Seite dahinter noch da ist;
       dvh, weil vh in Safari die Adressleiste mitrechnet (vh bleibt als Rueckfall davor),
     · der Inhalt rollt IM Blatt, der Fuss mit den Knoepfen bleibt unten stehen (am Daumen),
     · unten der sichere Rand (Home-Balken).
   Die Bewegung (von unten herein) schaltet „Bewegung reduzieren" ueber die allgemeine Regel weiter unten ab.
   max-width traegt !important: iqModal schreibt die PC-Breite ans Element (opts.width). */
@keyframes blattHoch { from { transform: translateY(28px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (max-width: 768px) {
  .modal-overlay { align-items: flex-end; }
  .modal-overlay > .modal {
    width: 100%; max-width: none !important;
    max-height: calc(100vh - 28px); max-height: calc(100dvh - 28px - env(safe-area-inset-top));
    border-radius: 20px 20px 0 0; border-width: 1.5px 0 0;
    padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    box-shadow: 0 -8px 30px rgba(0,0,0,.22);
    animation: blattHoch .24s cubic-bezier(.32,.72,0,1);
  }
  /* Der Griff. Er ist ein Zeichen, kein Bedienelement (Ziehen schliesst nicht — der Ausgang ist der Knopf). */
  .modal-overlay > .modal::before { content: ""; display: block; width: 36px; height: 5px; border-radius: 3px; background: rgba(120,130,150,.45); margin: 0 auto 12px; }
  /* Der Fuss bleibt beim Rollen unten stehen — deckend, sonst scheint der Inhalt durch die Knoepfe. bottom: 0
     meint die Kante des INHALTS, nicht die des Blatts (gemessen: mit bottom 16px rutschte der Fuss 16 px zu hoch
     und lag 4 px auf dem Passwort-Feld) — der Fuss haelt so von selbst den Innenabstand samt sicherem Rand.
     Den Streifen darunter deckt sein Schatten in der Farbe des Blatts, sonst liefe dort der Inhalt durch. */
  .modal-overlay > .modal .modal-actions, .modal-overlay > .modal #kal-blatt > .kal-fuss {
    position: sticky; bottom: 0; z-index: 2; background: var(--bg2); padding-top: 12px; margin-top: 12px;
    box-shadow: 0 calc(17px + env(safe-area-inset-bottom)) 0 var(--bg2);
  }
  /* Der eine Ausgang eines Fensters ohne eigene Knoepfe („Schließen", core.js): ueber die ganze Breite, 44 px. */
  .modal-overlay > .modal .modal-fuss .btn { flex: 1 1 auto; justify-content: center; min-height: 44px; }
}
/* Karten am Handy nicht bis an den Rand (W16): Anmeldung, Vertragswand, Tour und Einrichtung sind KARTEN — sie
   stehen eingerueckt (12 px), das Blatt oben ist randstaendig. Vorher beruehrten beide Sorten beide Raender. */
@media (max-width: 480px) { .login-card { width: calc(100% - 24px); } }
/* Tour und Einrichtung sind am Handy modal (W8): die Huelle .login-wrap hatte keinen z-index — Fusszeile (1),
   Tab-Leiste (250) und die Lampe lagen DARUEBER, bei 360×740 die Fusszeile auf dem Knopf „Weiter". 900: ueber
   allem der Seite, unter einem Fenster (1000) und der Meldung oben (10000).
   NUR bis 768 px (dort wurde es gemessen, dort gibt es die Tab-Leiste). Am PC liegt die Seitenleiste (z-index 100)
   weiter ueber der Huelle: ein Versuch ohne die Grenze deckte sie zu, und der Klick auf „Kalender" kam nicht mehr an
   (pruef-kalender-tempo.js brach ab — dort steht die Tour im Hintergrund offen). Ob die Tour auch am PC die
   Seitenleiste verdecken soll, ist eine Entscheidung fuer sich; sie aendert das Bild der Tour. */
@media (max-width: 768px) { #tour-wrap, #einr-wrap { z-index: 900; } }

/* Schwebender Toast — kein Layout-Shift (verhindert das ruckartige Springen) */
/* Meldungen stehen OBEN, nicht unten.
   Bis zum 21.07. lagen sie am unteren Bildschirmrand — technisch sichtbar, praktisch
   uebersehen: gearbeitet wird im oberen Drittel (Kontakt, Knoepfe, Leitfaden), und
   eine Meldung 850 Pixel darunter nimmt niemand wahr. Der Betreiber suchte sie oben
   und meldete sie als fehlend — genau das ist der Beleg, wo sie hingehoert.
   z-index 10000, damit sie auch ueber der Berichtsleiste (9999) liegt. */
#status-box { position: fixed; left: 50%; top: calc(16px + env(safe-area-inset-top)); transform: translateX(-50%); z-index: 10000; pointer-events: none; }
/* Am PC oben LINKS ueber dem Seitentitel, hoechstens 420 px breit, umbrechend (02.10.2026, Apple-Abgleich V6):
   seit Fehler und Anweisungen stehen bleiben, darf die Meldung nicht ueber den Knoepfen der Kopfzeile liegen —
   und die stehen rechts (Design-Umschalter, Konfiguration, Spielregeln, Anruf-Weg, Sitzung beenden), links
   steht nur der Titel. Gemessen 04.10.: mittig ueber dem Fenster und einzeilig (bis 900 px) lag „Nur 1 🔥 — …"
   in Klassik bei 1366 px ueber „Anruf-Weg"; mittig ueber dem Inhalt und 460 px breit noch ueber dem
   Design-Umschalter (1366, 1280, 1600). 420 px passen links neben den Umschalter auch bei 1280 px.
   276 px = Seitenleiste 240 + Polster von .main 36 (3rem). */
@media (min-width: 769px) {
  #status-box { left: 276px; transform: none; width: max-content; max-width: min(420px, calc(100vw - 276px - 24px)); }
  #status-box .status-bar { white-space: normal; line-height: 1.4; }
}
@media (max-width: 768px) { #status-box { top: calc(10px + env(safe-area-inset-top)); width: max-content; max-width: 90vw; } }
/* Schwebt oben die Erinnerung (kalender.js; seit 09.10.2026 als Mitteilung wie bei Apple, vorher als Streifen im
   Inhalt), erscheint die Meldung UNTER ihr: die Mitteilung meldet ihre Unterkante als --kal-karte-oben. Ohne
   Mitteilung gilt die Zeile darueber.
   · Am Handy, solange die schmale Tafel oder die aufgeklappte Liste steht: sie stehen oben ueber die ganze Breite,
     genau am Platz der Meldung.
   · Am PC nur in schmalen Fenstern (769–1080 px): die Meldung reicht von links bis 696 px, die Mitteilung (360 px,
     12 px vom rechten Rand) beginnt bei Fensterbreite − 372 px — ab 1068 px liegen sie nebeneinander, darunter
     laege die eine auf der anderen. In breiten Fenstern bleibt die Meldung oben links.
   · Steht nur der MINI-KNOPF, meldet kalender.js keine Unterkante (kalKarteHoeheMelden) — am PC und am Handy: die
     Meldung bleibt, wo sie ohne Erinnerung steht. Am PC beruehren sie sich in keinem Fenster; am Handy liegt die
     Meldung (bis 90 % der Breite, z-index 10000) fuer ihre Dauer UEBER dem Knopf in der Ecke (z-index 240). Unter
     ihn gerueckt verdeckte sie Knoepfe, die ohne Erinnerung frei waren (Gegenpruefung 09.10.2026, 27 von 60 Faellen). */
@media (max-width: 768px) { #status-box { top: max(calc(10px + env(safe-area-inset-top)), calc(var(--kal-karte-oben, 0px) + 8px)); } }
@media (min-width: 769px) and (max-width: 1080px) { #status-box { top: max(calc(16px + env(safe-area-inset-top)), calc(var(--kal-karte-oben, 0px) + 8px)); } }
/* Eingeklappt (05.10.2026, core.js statusEinklappen): eine stehende Meldung nach ihrer Lesezeit als Marke oben links
   ueber dem Seitentitel — 44 px hoch (bis 48 px vom Rand: dort beginnt der Design-Umschalter bei 50 px), hoechstens
   180 px breit (rechts oben steht im Kalender „+ Neuer Eintrag"). Ein Tipp klappt sie wieder auf. */
@media (max-width: 768px) {
  #status-box.eingeklappt { left: 12px; transform: none; top: max(calc(4px + env(safe-area-inset-top)), calc(var(--kal-karte-oben, 0px) + 4px)); width: auto; max-width: 180px; }
  #status-box.eingeklappt .status-bar { white-space: nowrap; height: 44px; padding: 0 0 0 12px; cursor: pointer; animation: none; box-sizing: border-box; }
  #status-box.eingeklappt .status-text { overflow: hidden; text-overflow: ellipsis; }
  /* Die Marke ist samt Rand 44 px hoch (endet bei 48 px); das ✕ ragt mit -1,5 px ueber den Rand und bleibt 44 × 44. */
  #status-box.eingeklappt .status-zu { margin: -1.5px -1.5px -1.5px 0; height: 44px; }
}
/* Der Einrichtungs-Hinweis steht IM FLUSS ganz oben in .main, VOR #page-dialer. Die Modern-
   und Glass-Skins legen einen fixierten Vollbild-Verlauf als #page-dialer.skin-*::before
   (position:fixed; inset:0; z-index:-1). Weil #page-dialer erst NACH dem Banner im DOM kommt
   und keinen eigenen Stacking-Context bildet, wandert dieses z-index:-1 in den Wurzel-Kontext
   und malt UEBER den frueher stehenden Hinweis — er wurde in Modern/Glass komplett unsichtbar
   (am lebenden DOM gemessen 2026-07-30: Banner top=12/h=153/sichtbar, aber im Bild leer).
   Klassik hat diesen Verlauf nicht, dort war nie etwas zu sehen. Fix: den Hinweis mit eigenem
   Stapelplatz ueber den Verlauf heben — in Klassik voellig folgenlos (nichts ueberlappt ihn).
   #status-box (fixed, z 10000) und .nc-banner (fixed, z 9000) liegen bereits darueber. */
#einrichtung-hinweis { position: relative; z-index: 1; }
/* Von OBEN hereinfahren, seit die Meldung oben sitzt — sonst schiebt sie sich von
   unten ins Bild und wirkt, als gehoere sie woanders hin. */
@keyframes statusIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
.status-bar { padding: 10px 14px; border-radius: var(--radius-sm); font-size: 13px; margin: 0; font-weight: 500; border: 1.5px solid; display: none; box-shadow: var(--shadow-lg); pointer-events: auto; animation: statusIn 0.2s ease; white-space: nowrap; }
.status-bar.ok { background: var(--green-bg); color: var(--green-text); border-color: rgba(14,165,121,0.2); display: flex; align-items: center; gap: 8px; }
.status-bar.err { background: var(--red-bg); color: var(--red); border-color: rgba(229,62,94,0.2); display: flex; align-items: center; gap: 8px; }
.status-bar.info { background: var(--accent-light); color: var(--accent); border-color: rgba(5,28,44,0.2); display: flex; align-items: center; gap: 8px; }
/* Fehlertext lesbar (02.10.2026, Apple-Abgleich V6): ausgerechnet die Fehlermeldung war die blasseste —
   --red #e53e5e auf --red-bg #fdeef2 sind 3,6:1 bei 13 px (verlangt 4,5:1). Ein dunkleres Rot nur fuer
   den TEXT der Meldung; --red selbst bleibt (Raender, Knoepfe). Im Dunklen besteht --red auf --red-bg schon. */
.status-bar.err { color: #b91c3c; }
body.dark .status-bar.err { color: var(--red); }
/* „✕" an jeder Meldung (02.10.2026): 44 × 44 px Trefferflaeche; die negativen Raender holen sie in das
   Polster der Meldung, damit die Meldung dadurch kaum hoeher wird. Farbe = die der Meldung. */
.status-text { flex: 1 1 auto; min-width: 0; }
.status-zu { flex: 0 0 auto; width: 44px; height: 44px; margin: -10px -12px -10px 0; border: 0; background: none; color: inherit; font: inherit;
  font-size: 15px; line-height: 1; cursor: pointer; border-radius: var(--radius-sm); }
.status-zu::before { content: '✕'; }
.status-zu:hover { background: rgba(0,0,0,.06); }
body.dark .status-zu:hover { background: rgba(255,255,255,.08); }
.status-zu:focus-visible { outline: 2px solid currentColor; outline-offset: -4px; }
/* Am Handy bricht die Meldung um (01.10.2026): mit nowrap ragte jeder laengere Satz ueber die 90vw der
   Box hinaus und war rechts abgeschnitten — gemessen bei 390 px an „Nur 1 🔥 — das Gespräch dauerte …"
   und am Hinweis auf eine Doppelbelegung; auch Fehlermeldungen. Am PC bleibt sie einzeilig. */
@media (max-width: 768px) { .status-bar { white-space: normal; line-height: 1.35; text-align: left; } }
.empty { text-align: center; padding: 2.5rem; color: var(--text3); font-size: 14px; }
.empty-state { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px; padding:3rem 1.5rem; text-align:center; animation:esFade .25s ease; }
.empty-state .es-icon { font-size:40px; line-height:1; opacity:.9; margin-bottom:4px; }
.empty-state .es-title { font-size:15px; font-weight:700; color:var(--text); }
.empty-state .es-hint { font-size:13px; color:var(--text3); max-width:360px; line-height:1.5; }
.empty-state .es-action { margin-top:10px; }
@keyframes esFade { from{opacity:0;transform:translateY(4px);} to{opacity:1;transform:none;} }
/* Tastatur-Fokus sichtbar (a11y) — erscheint nur bei Tastatur-Navigation,nicht bei Maus-Klick */
button:focus-visible,a:focus-visible,.btn:focus-visible,[role="button"]:focus-visible,[tabindex]:focus-visible{
  outline: 2px solid var(--accent); outline-offset: 2px;
}
/* Bewegung reduzieren: respektiert OS-Einstellung (a11y) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}
.spinner { width: 22px; height: 22px; border: 2px solid var(--border2); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; margin: 0 auto 10px; }
@keyframes spin { to{transform:rotate(360deg);} }
.page { display: none; }
/* Seitenwechsel: SETZEN, nicht einblenden.
   Bis zum 01.08.2026 lief hier 0.3s ab opacity:0 — und weil die alte Seite in dem Moment
   schon weg ist, war der Schirm dazwischen gemessen ~55 ms voellig leer und danach ~250 ms
   fast unsichtbar. Der Betreiber beschrieb es als "in Millisekunden ist eine andere
   Webseite davor". Es war keine fremde Seite, es war GAR KEINE.
   Jetzt beginnt die Bewegung bei 0.65 — der Inhalt ist ab dem ersten Bild lesbar und setzt
   sich nur noch. Bei einem Arbeitswerkzeug, in dem jemand 200-mal am Tag die Seite
   wechselt, ist Wartezeit kein Genuss, sondern Reibung.
   (prefers-reduced-motion schaltet es weiter oben ganz ab.) */
.page.active { display: block; animation: pageIn 0.14s cubic-bezier(0.2, 0, 0, 1); }
/* KEIN transform in dieser Einblendung — nur Deckkraft. Bis zum 09.09.2026 stand hier
   `translateY(3px)`, drei Pixel, die niemand sieht. Aber ein `transform` macht das Element
   fuer 140 ms zum Bezugsrahmen aller `position: fixed`-Nachfahren: die Handy-Leiste
   Zurueck/Weiter (.dflow-nav, fixed ueber den Tabs) sass solange am unteren Ende des
   SEITENINHALTS statt am unteren Rand des Fensters und sprang beim Ende der Animation um
   130 px nach unten — genau waehrend der Splash halb durchsichtig war (gemessen bei
   390x844 ab dem ersten Frame: 807 ms top 586, 991 ms top 718). Der Betreiber hatte es als
   "Fussleiste springt 110 px" gemeldet. Deckkraft allein bildet keinen Bezugsrahmen. */
@keyframes pageIn { from { opacity: .65; } to { opacity: 1; } }

/* Neue-Anrufe-Toast: schwebt oben mittig, schiebt NICHTS im Layout (kein Ruckeln) */
.nc-banner {
  position: fixed; top: 18px; left: 50%;
  transform: translateX(-50%) translateY(-16px);
  z-index: 9000; display: none; align-items: center; gap: 10px;
  background: var(--accent); color: #fff;
  padding: 9px 18px; border-radius: 999px; font-size: 13px; font-weight: 600;
  box-shadow: var(--shadow-lg); cursor: pointer; opacity: 0;
  transition: opacity .3s ease, transform .35s cubic-bezier(0.4, 0, 0.2, 1);
}
.nc-banner.nc-show { opacity: 1; transform: translateX(-50%) translateY(0); }
footer { text-align: center; font-size: 11px; color: var(--text3); padding: 1.5rem 0 0.5rem; }

/* MOBILE */
@media (max-width: 768px) {
  /* Sidebar wird zum Bottom-Sheet: per "Mehr" hochgeschoben, sonst versteckt.
     So bleibt die komplette Rollen-/Plan-Logik erhalten (alle Nav-Punkte im Sheet). */
  .sidebar { width: 100%; max-width: 100%; height: auto; max-height: 82vh; position: fixed;
    left: 0; right: 0; bottom: 0; top: auto; flex-direction: column;
    overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
    padding: 0.75rem 0.9rem calc(0.9rem + 66px + env(safe-area-inset-bottom));
    border-right: none; border-top: 1px solid var(--border); border-radius: 22px 22px 0 0;
    z-index: 300;   /* Hintergrund bleibt der dunkle Sidebar-Look (#152735) -> weisse Schrift sichtbar */
    transform: translateY(106%); transition: transform .3s cubic-bezier(.32,.72,0,1);
    box-shadow: 0 -14px 44px rgba(0,0,0,.28); }
  .app-wrap.nav-open .sidebar { transform: translateY(0); }
  .sidebar-logo { display: flex; }        /* im Sheet sichtbar */
  .nav-section { display: block; }
  .sidebar-bottom { display: block; }
  /* Polster unten fuer die feste Leiste (.mtab).
     Gemessen am 23.07.: die Leiste ist 59 px hoch, das Polster war 64 px — macht
     5 px Luft. Der `env()`-Anteil hebt sich auf, weil die Leiste denselben Wert
     selbst schon aufschlaegt. Fuenf Pixel reichen nicht: der Weiter-Knopf im Dialer
     wirkte dadurch angeschnitten, und auf jeder anderen Seite kann das letzte
     Element genauso hinter der Leiste verschwinden.
     96 px lassen ueberall gut 35 px echte Luft. Lieber ein Stueck leerer Raum am
     Ende als ein Knopf, den man nicht trifft. */
  .main { margin-left: 0; padding: 1rem; padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
  .topbar { flex-wrap: wrap; gap: 8px; }
  .topbar-left h2 { font-size: 18px; }
  .grid-2 { grid-template-columns: 1fr; }
  .grid-equal { grid-template-columns: 1fr; }
  .metrics { grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .metric-value { font-size: 22px; }
  .cx-user-grid { grid-template-columns: 1fr; }
  .topbar-right { width: 100%; justify-content: flex-end; }
  .topbar-right .search-wrap { flex: 1 1 auto; }
  .search-wrap input { width: 100%; }
  .filter-row { gap: 4px; }
  .filter-chip { padding: 4px 10px; }
  /* CTI-Popup ueber der unteren Nav-Leiste, volle Breite */
  .cti-popup { left: 10px; right: 10px; width: auto; bottom: calc(74px + env(safe-area-inset-bottom)); }
  /* Toast nicht hinter Nav-Leiste */
  /* Inline-Grids auf Mobil entstapeln (schlagen inline styles via !important) */
  .metrics { grid-template-columns: repeat(3,1fr) !important; }
  #cx-stats-row { grid-template-columns: repeat(3,1fr) !important; }
  #dialer-step-indicator, #dialer-mapping-grid { grid-template-columns: 1fr !important; }
  .m-stack { grid-template-columns: 1fr !important; }
  /* Breite Benutzer-Tabelle auf Mobil als Karten stapeln (statt Seitwaerts-Scroll) */
  .user-table, .user-table tbody, .user-table tr { display: block; }
  .user-table thead { display: none; }
  .user-table tr { background: var(--bg2); border: 1px solid var(--border); border-radius: 12px; padding: 4px 14px; margin-bottom: 12px; }
  .user-table tr:hover td { background: transparent; }
  .user-table td { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--border); white-space: normal; text-align: right; }
  .user-table tr td:last-child { border-bottom: none; }
  .user-table td::before { content: attr(data-label); font-weight: 600; color: var(--text3); font-size: 11px; text-transform: uppercase; letter-spacing: .5px; text-align: left; flex-shrink: 0; }
  .user-table td[colspan] { justify-content: center; text-align: center; }
  .user-table td[colspan]::before { content: none; }
}

/* 3CX NUTZER SEITE */
.cx-user-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 1rem; }
.cx-user-card { background: var(--bg2); border: 1.5px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 1.25rem 1.5rem; transition: border-color 0.2s ease, box-shadow 0.2s ease; position: relative; overflow: hidden; }
.cx-user-card:hover { box-shadow: var(--shadow-lg); border-color: var(--border2); }
.cx-user-card-top { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 1rem; }
.cx-avatar { width: 44px; height: 44px; border-radius: 12px; background: linear-gradient(135deg, #0e3a63, #051C2C); display: flex; align-items: center; justify-content: center; font-size: 16px; font-weight: 700; color: #fff; flex-shrink: 0; }
.cx-user-info { flex: 1; min-width: 0; }
.cx-user-name { font-size: 14px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cx-user-email { font-size: 12px; color: var(--text3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.cx-role-badge { font-size: 10px; padding: 2px 8px; border-radius: 20px; font-weight: 600; margin-top: 4px; display: inline-block; }
.cx-role-owner { background: var(--purple-bg); color: var(--purple); }
.cx-role-manager { background: var(--amber-bg); color: var(--amber); }
.cx-role-user { background: var(--accent-light); color: var(--accent); }
.cx-ext-badge { display: flex; align-items: center; gap: 6px; background: var(--bg3); border-radius: var(--radius-sm); padding: 6px 10px; margin-bottom: 10px; }
.cx-ext-num { font-size: 18px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -0.5px; }
.cx-ext-label { font-size: 10px; color: var(--text3); font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px; }
.cx-status-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; margin-left: auto; }
.cx-status-online { background: var(--green); box-shadow: 0 0 0 3px rgba(14,165,121,0.18); }
.cx-status-away { background: var(--amber); box-shadow: 0 0 0 3px rgba(245,158,11,0.2); }
.cx-status-dnd { background: #ef4444; box-shadow: 0 0 0 3px rgba(239,68,68,0.2); }
.cx-status-offline { background: #cbd5e1; }
.cx-field { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 6px; }
.cx-field-label { font-size: 10px; color: var(--text3); font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; width: 65px; flex-shrink: 0; padding-top: 1px; }
.cx-field-val { font-size: 12px; color: var(--text2); flex: 1; line-height: 1.5; }
.cx-phone-row { display: flex; align-items: center; gap: 8px; background: var(--bg3); border-radius: 8px; padding: 7px 10px; margin-top: 8px; }
.cx-phone-icon { font-size: 16px; }
.cx-phone-info { flex: 1; min-width: 0; }
.cx-phone-model { font-size: 12px; font-weight: 600; color: var(--text); }
.cx-no-phone { display: flex; align-items: center; gap: 6px; background: var(--bg3); border-radius: 8px; padding: 7px 10px; margin-top: 8px; font-size: 12px; color: var(--text3); }
.cx-stats-row { display: grid; grid-template-columns: repeat(3,1fr); gap: 8px; margin-bottom: 1rem; }
.cx-stat { background: var(--bg2); border: 1.5px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; text-align: center; }
/* .cx-filter-chip nutzt jetzt den Standard .filter-chip (cx-filter-chip bleibt nur JS-Haken) */

/* KI-ZENTRALE */
.task-card { background: var(--bg2); border: 1.5px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 1.25rem 1.5rem; margin-bottom: 0.75rem; transition: border-color 0.2s ease, box-shadow 0.2s ease; }
.task-card:hover { box-shadow: var(--shadow-lg); border-color: var(--border2); }
.task-card.erledigt { opacity: 0.55; }
.task-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 0.75rem; }
.task-caller { display: flex; align-items: center; gap: 10px; }
.task-avatar { width: 40px; height: 40px; border-radius: 12px; background: linear-gradient(135deg, #0e3a63, #051C2C); display: flex; align-items: center; justify-content: center; font-size: 16px; font-weight: 700; color: #fff; flex-shrink: 0; }
.task-caller-info { flex: 1; }
.task-caller-name { font-size: 15px; font-weight: 700; color: var(--text); }
.task-caller-number { font-size: 12px; color: var(--text3); font-variant-numeric: tabular-nums; margin-top: 2px; }
.task-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.task-time { font-size: 11px; color: var(--text3); }
.task-summary { font-size: 13px; color: var(--text2); line-height: 1.6; margin-bottom: 1rem; padding: 10px 14px; background: var(--bg3); border-radius: var(--radius-sm); border-left: 3px solid var(--accent); }
.task-footer { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.task-assign-wrap { display: flex; align-items: center; gap: 6px; flex: 1; }
.task-assign-label { font-size: 12px; color: var(--text3); white-space: nowrap; }
.task-status-badge { font-size: 11px; padding: 4px 10px; border-radius: 20px; font-weight: 600; cursor: pointer; border: none; font-family: inherit; transition: all 0.15s; }
.status-offen { background: var(--amber-bg); color: var(--amber); }
.status-bearbeitung { background: var(--accent-light); color: var(--accent); }
.status-erledigt { background: var(--green-bg); color: var(--green-text); }
.task-check-btn { width: 34px; height: 34px; border-radius: 50%; border: 2px solid var(--border2); background: var(--bg2); font-size: 16px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; flex-shrink: 0; }
.task-check-btn:hover { border-color: var(--green); background: var(--green-bg); }
.task-check-btn.done { border-color: var(--green); background: var(--green-bg); }
@keyframes slideUp { from{opacity:0;transform:translateY(12px);}to{opacity:1;transform:translateY(0);} }

/* REGELN */
.rule-card { transition: background 0.15s, opacity 0.15s; }
.drag-handle:hover { color: var(--accent) !important; }

/* UHRZEIT WIDGET */
.clock-widget { background: linear-gradient(135deg, #0e3a63 0%, #C8A44D 100%); border-radius: var(--radius); padding: 1.5rem 2rem; box-shadow: 0 8px 32px rgba(5,28,44,0.25); color: #fff; display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.25rem; position: relative; overflow: hidden; }
.clock-widget::before { content:''; position:absolute; right:-30px; top:-30px; width:120px; height:120px; background: rgba(255,255,255,0.06); border-radius:50%; }
.clock-widget::after { content:''; position:absolute; right:30px; bottom:-40px; width:80px; height:80px; background: rgba(255,255,255,0.04); border-radius:50%; }
.clock-time { font-size: 52px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -2px; line-height: 1; }
.clock-time .clock-seconds { font-size: 28px; color: rgba(255,255,255,0.6); vertical-align: super; margin-left: 4px; }
.clock-date-wrap { text-align: right; }
.clock-date { font-size: 16px; font-weight: 600; opacity: 0.9; }
.clock-weekday { font-size: 12px; opacity: 0.65; margin-top: 4px; text-transform: uppercase; letter-spacing: 1px; }
.clock-greeting { font-size: 13px; opacity: 0.75; margin-top: 8px; }

/* MOBILE IMPROVEMENTS */
@media (max-width: 768px) {
  /* Clock */
  .clock-widget { padding: 0.85rem 1rem; }
  .clock-time { font-size: 34px; }
  .clock-time .clock-seconds { font-size: 18px; }
  .clock-date { font-size: 12px; }

  /* Metrics: 3 columns, compact */
  .metrics { grid-template-columns: repeat(3, 1fr); gap: 6px; }
  .metric-card { padding: 0.7rem 0.5rem; }
  .metric-icon-wrap { font-size: 18px; margin-bottom: 3px; }
  .metric-value { font-size: 20px; }
  .metric-label { font-size: 10.5px; }

  /* Filter chips: horizontal scroll */
  .filter-row { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 4px; scrollbar-width: none; gap: 5px; }
  .filter-row::-webkit-scrollbar { display: none; }
  .filter-chip, .ki-filter { white-space: nowrap; flex-shrink: 0; font-size: 11px; padding: 4px 10px; }

  /* Topbar */
  .topbar { margin-bottom: 0.75rem; flex-wrap: wrap; gap: 6px; }
  .topbar-left h2 { font-size: 16px; }
  .topbar-right { gap: 5px; flex-wrap: wrap; }
  .topbar-right .btn, .theme-toggle, .notif-btn { padding: 6px 8px; font-size: 11px; }

  /* Call item — stack vertically on mobile */
  .call-item { padding: 0.75rem; }
  .call-item > div:first-child { flex-direction: column !important; gap: 8px !important; }
  .call-item > div:first-child > div:last-child {
    text-align: left !important;
    align-items: flex-start !important;
    min-width: unset !important;
    flex-direction: row !important;
    flex-wrap: wrap !important;
    gap: 6px !important;
  }
  .call-item > div:first-child > div:last-child select {
    width: 100% !important;
    max-width: 100% !important;
    min-width: unset !important;
  }
  .call-row3 { flex-wrap: wrap; gap: 5px; }
  .call-transcript-preview, .call-row2 { word-break: break-word; overflow-wrap: break-word; }

  /* Task cards */
  .task-card { padding: 0.85rem; }
  .task-summary { font-size: 12px; }
  .task-footer { flex-wrap: wrap; gap: 6px; }

  /* Grid */
  .grid-2, .grid-equal { grid-template-columns: 1fr; }

  /* Search: mobil volle Breite (Platzhalter passt rein) */
  .topbar-right .search-wrap { flex: 1 1 auto; }
  .search-wrap input { width: 100%; }
}

@media (min-width: 769px) and (max-width: 1100px) {
  /* iPad: Anruf-Karte stapelt Aktionen unter den Content */
  .call-item > div:first-child { flex-wrap: wrap !important; }
  .call-item > div:first-child > div:first-child { flex: 1 1 100% !important; min-width: 0 !important; }
  .call-item > div:first-child > div:last-child {
    flex: 1 1 100% !important;
    min-width: unset !important;
    text-align: left !important;
    align-items: flex-start !important;
    flex-direction: row !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
    margin-top: 8px !important;
  }
  .call-item > div:first-child > div:last-child select {
    flex: 1 1 160px !important;
    max-width: 220px !important;
  }
}

@media (max-width: 480px) {
  /* Very small phones */
  .metrics { grid-template-columns: repeat(2, 1fr) !important; gap: 5px; }
  #cx-stats-row { grid-template-columns: repeat(2, 1fr) !important; }
  .metric-value { font-size: 18px; }
  .clock-time { font-size: 28px; }
}

/* ============================================================
   RUHIGES, ELEGANTES BILD
   Einheitliche, sanfte Übergänge auf interaktiven Elementen +
   Respekt vor "weniger Bewegung" (Barrierefreiheit / ruhigeres Gefühl)
   ============================================================ */
.btn, .filter-chip, .nav-item, .action-btn, .theme-toggle, .card,
.task-card, .metric-card, .cx-user-card, .cx-filter-chip, .sort-select,
.user-table tr, .search-wrap, input, select, button, a {
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

/* ============================================================
   KALENDER — Microsoft-365/Outlook-Optik (FullCalendar 6 Theming)
   ============================================================ */
.fc {
  --fc-border-color: var(--border);
  --fc-today-bg-color: rgba(5,28,44,0.06);
  --fc-neutral-bg-color: var(--bg3);
  --fc-page-bg-color: var(--bg2);
  --fc-event-border-color: transparent;
  font-family: inherit;
}
/* Mobil: KW-Nummer ausblenden (ueberlappte sonst die Tageszahl, schwer lesbar/tippbar) */
@media (max-width: 768px) { .fc .fc-daygrid-week-number { display: none; } }
/* Toolbar */
.fc .fc-toolbar.fc-header-toolbar { margin-bottom: 1rem; gap: 8px; flex-wrap: wrap; }
.fc .fc-toolbar-title { font-size: 19px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.fc .fc-button {
  background: var(--bg3); border: 1.5px solid var(--border2); color: var(--text2);
  border-radius: 9px; font-weight: 600; font-size: 13px; padding: 7px 13px;
  text-transform: none; box-shadow: none; transition: all .15s; font-family: inherit;
}
.fc .fc-button:hover { background: var(--bg4); color: var(--text); }
.fc .fc-button-primary:not(:disabled).fc-button-active,
.fc .fc-button-primary:not(:disabled):active {
  background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 2px 8px rgba(5,28,44,0.25);
}
.fc .fc-button:focus { box-shadow: none; }
.fc .fc-button-group { gap: 4px; }
.fc .fc-today-button:disabled { opacity: .5; }
/* Spaltenköpfe (Wochentage) */
.fc .fc-col-header-cell-cushion {
  color: var(--text3); font-weight: 700; font-size: 11px; text-transform: uppercase;
  letter-spacing: .4px; padding: 10px 4px; text-decoration: none;
}
/* Tageszahlen */
.fc .fc-daygrid-day-number { color: var(--text2); font-size: 13px; font-weight: 500; padding: 6px 8px; text-decoration: none; }
.fc .fc-daygrid-day.fc-day-today { background: var(--fc-today-bg-color); }
.fc .fc-day-today .fc-daygrid-day-number {
  background: var(--accent); color: #fff; border-radius: 50%; width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center; margin: 3px;
}
/* Events als saubere Pillen */
.fc .fc-event { border: none; border-radius: 7px; padding: 1px 2px; font-size: 12px; font-weight: 500; cursor: pointer; }
.fc .fc-daygrid-event { padding: 2px 7px; margin: 1px 3px; }
.fc .fc-event-title, .fc .fc-event-time { font-weight: 500; }
.fc .fc-daygrid-event:hover { filter: brightness(1.06); }
.fc .fc-h-event .fc-event-main { color: #fff; }
/* Zeit-Achse (Woche/Tag) */
.fc .fc-timegrid-slot-label-cushion, .fc .fc-list-day-text { color: var(--text3); font-size: 12px; }
.fc .fc-scrollgrid { border-radius: 12px; overflow: hidden; }
.fc .fc-highlight { background: rgba(5,28,44,0.10); }
/* "+ mehr" Link */
.fc .fc-daygrid-more-link { color: var(--accent); font-weight: 600; font-size: 11px; }

/* M365-Feinschliff Monats-/Wochenansicht */
.fc .fc-col-header { background: var(--bg3); }
.fc .fc-col-header-cell { border-bottom: 1.5px solid var(--border); }
.fc .fc-daygrid-day.fc-day-sat, .fc .fc-daygrid-day.fc-day-sun { background: rgba(99,120,200,0.035); }
.fc .fc-daygrid-day { transition: background .12s; }
.fc .fc-daygrid-day:hover { background: rgba(5,28,44,0.05); }
.fc .fc-daygrid-day.fc-day-today:hover { background: rgba(5,28,44,0.10); }
.fc .fc-daygrid-day-frame { min-height: 96px; }
.fc .fc-day-other { background: var(--bg3); }
.fc .fc-day-other .fc-daygrid-day-number { opacity: .4; }
.fc .fc-daygrid-week-number { color: var(--text3); font-size: 10px; font-weight: 700; background: transparent; padding: 4px 6px; }
/* Events als solide Pillen mit weißer Schrift */
.fc .fc-daygrid-block-event, .fc .fc-timegrid-event { box-shadow: none; }
.fc .fc-daygrid-block-event .fc-event-title, .fc .fc-daygrid-block-event .fc-event-time { color: #fff; }
.fc .fc-event:hover { filter: brightness(1.07); }
.fc .fc-scrollgrid { box-shadow: var(--shadow); }

/* M365-Feinschliff Wochen-/Tagesansicht (timeGrid) */
.fc .fc-timegrid-col.fc-day-today { background: rgba(5,28,44,0.05); }
.fc .fc-timegrid-now-indicator-line { border-color: #ef4444; border-width: 2px; }
.fc .fc-timegrid-now-indicator-arrow { border-color: #ef4444; color: #ef4444; }
.fc .fc-timegrid-slot { height: 2.4em; }
.fc .fc-timegrid-slot-label-cushion, .fc .fc-timegrid-axis-cushion { color: var(--text3); font-size: 11px; font-weight: 600; }
.fc .fc-timegrid-axis, .fc .fc-timegrid-slot-minor { border-color: var(--border); }
.fc .fc-timegrid-event { border-radius: 7px; padding: 2px 6px; box-shadow: 0 1px 3px rgba(0,0,0,0.12); }
.fc .fc-timegrid-event .fc-event-title { font-weight: 600; }
/* Listenansicht moderner */
.fc .fc-list { border-radius: 12px; overflow: hidden; }
.fc .fc-list-day-cushion { background: var(--bg3); }
.fc .fc-list-event:hover td { background: rgba(5,28,44,0.05); }
.fc .fc-list-event-time { color: var(--text3); }

/* #3 Politur: Aufgabe "Erledigen" — smoother Erfolgs-Flash + Rausgleiten */
.task-card.task-completing {
  animation: task-done 0.36s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  pointer-events: none;
  overflow: hidden;
}
@keyframes task-done {
  0%   { opacity: 1; transform: translateX(0) scale(1); box-shadow: 0 0 0 0 rgba(34,197,94,0); }
  25%  { box-shadow: 0 0 0 2px rgba(34,197,94,0.55); background: rgba(34,197,94,0.12); }
  100% { opacity: 0; transform: translateX(36px) scale(0.97); }
}

/* Mein Tag — Tages-Cockpit */
.meintag-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; align-items: start; }

/* ============================================================
   FEEDBACK & IDEEN — 💡-Button (FAB) + Einmal-Hinweis (Coachmark)
   ============================================================ */
#feedback-fab { position:fixed; right:22px; bottom:22px; width:52px; height:52px; border-radius:50%; border:none; background:var(--accent); color:var(--accent-ink); font-size:22px; cursor:pointer; z-index:850; box-shadow:0 6px 20px rgba(5,28,44,0.35); display:flex; align-items:center; justify-content:center; transition:transform .18s ease, box-shadow .18s ease; touch-action:none; -webkit-user-select:none; user-select:none; }
#feedback-fab:hover { transform:translateY(-2px) scale(1.05); box-shadow:0 10px 26px rgba(5,28,44,0.45); }
#feedback-fab.fb-pulse { animation:fbPulse 2.6s ease-out infinite; }
@keyframes fbPulse {
  0%   { box-shadow:0 6px 20px rgba(5,28,44,0.35), 0 0 0 0 rgba(5,28,44,0.35); }
  60%  { box-shadow:0 6px 20px rgba(5,28,44,0.35), 0 0 0 14px rgba(5,28,44,0); }
  100% { box-shadow:0 6px 20px rgba(5,28,44,0.35), 0 0 0 0 rgba(5,28,44,0); }
}
.fb-intro-backdrop { position:fixed; inset:0; background:rgba(15,23,42,0.38); z-index:860; }
.fb-intro-card { position:fixed; right:22px; bottom:90px; width:min(280px, calc(100vw - 44px)); background:var(--bg2, #fff); color:var(--text); border:1px solid var(--border); border-radius:14px; padding:16px; z-index:861; box-shadow:0 18px 50px rgba(15,23,42,0.28); animation:fbIntroIn .35s cubic-bezier(.2,.8,.3,1); }
.fb-intro-arrow { position:absolute; right:24px; bottom:-8px; width:14px; height:14px; background:inherit; border-right:1px solid var(--border); border-bottom:1px solid var(--border); transform:rotate(45deg); }
.fb-intro-title { font-weight:700; font-size:14px; margin-bottom:6px; }
.fb-intro-text { font-size:13px; color:var(--text2); line-height:1.5; margin-bottom:12px; }
.fb-intro-btn { border:none; background:var(--accent); color:#fff; font-family:inherit; font-size:13px; font-weight:600; padding:7px 16px; border-radius:8px; cursor:pointer; }
@keyframes fbIntroIn { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:none; } }
.fb-cats { display:flex; gap:8px; margin-bottom:12px; }
.fb-cat { flex:1; padding:8px 6px; border-radius:10px; border:1.5px solid var(--border); background:var(--bg3); color:var(--text2); font-family:inherit; font-size:13px; font-weight:600; cursor:pointer; transition:all .15s ease; }
.fb-cat.active { border-color:var(--accent); background:var(--accent-light); color:var(--accent); }
#fb-text { border:1px solid var(--border); border-radius:10px; background:var(--bg3); color:var(--text); font-family:inherit; font-size:14px; padding:10px 12px; resize:vertical; }
#fb-text:focus { outline:2px solid var(--accent); outline-offset:0; border-color:transparent; }
@media (max-width:768px) {
  /* +safe-area: sonst ueberlappt die Lampe auf Notch-iPhones die Tab-Leiste (die selbst um den
     Home-Indikator waechst). So bleibt sie immer sauber ueber den Tabs. */
  #feedback-fab { right:14px; bottom:calc(76px + env(safe-area-inset-bottom)); }
  .fb-intro-card { right:14px; bottom:calc(140px + env(safe-area-inset-bottom)); }
  /* Update-Banner mobil: ueber die Tab-Leiste heben + kompakt (war zu wuchtig auf dem iPhone) */
  #iq-update-banner { bottom: calc(80px + env(safe-area-inset-bottom)) !important; padding:8px 10px 8px 13px !important; gap:9px !important; border-radius:12px !important; }
  #iq-update-banner .iqub-title { font-size:12.5px !important; }
  #iq-update-banner .iqub-sub { display:none !important; }   /* Untertitel weg — der "Neu laden"-Knopf sagt's schon */
  #iq-update-banner #iq-update-reload { padding:7px 12px !important; font-size:12px !important; }
}
@media (prefers-reduced-motion:reduce) { #feedback-fab.fb-pulse, .fb-intro-card { animation:none; } }
/* Spotlight: solange der Einmal-Hinweis offen ist, liegt der FAB ÜBER dem Backdrop (klickbar + hell) */
#feedback-fab.fb-intro-hero { z-index: 862; }

/* ============================================================
   SKELETON-KARTEN (Shimmer) — reservieren die Listenhöhe beim Laden,
   damit nichts "poppt"/zuckt, wenn die echten Daten eintreffen.
   ============================================================ */
.skel-card { height: 92px; border-radius: 14px; border: 1px solid var(--border); background: var(--bg2); margin-bottom: 0.75rem; padding: 16px; display: flex; gap: 14px; align-items: center; }
.skel-el { border-radius: 8px; background: linear-gradient(90deg, var(--bg3) 25%, var(--border) 50%, var(--bg3) 75%); background-size: 200% 100%; animation: skelShimmer 1.4s ease-in-out infinite; }
.skel-av { width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0; }
@keyframes skelShimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skel-el { animation: none; } }

/* ============================================================
   RECHTS-FUSS — Impressum/Datenschutz/AGB
   §5 DDG verlangt "leicht erkennbar, unmittelbar erreichbar, staendig verfuegbar".
   Darum unter jeder Login-Karte UND in der Seitenleiste der App.
   ============================================================ */
.legal-foot {
  display: flex; justify-content: center; gap: 14px;
  margin-top: 18px; font-size: 12px;
}
.legal-foot a {
  color: var(--text3); text-decoration: none;
  transition: color .15s;
}
.legal-foot a:hover { color: var(--accent); text-decoration: underline; }
.legal-foot-app {
  margin-top: 10px; gap: 10px; font-size: 11px;
  opacity: .55; transition: opacity .15s;
}
.legal-foot-app:hover { opacity: 1; }
.legal-foot-app a { color: rgba(255,255,255,0.55); }
.legal-foot-app a:hover { color: #fff; }

/* ============================================================
   WILLKOMMENS-TOUR (tour.js)
   Der Spotlight ist ein einziger, riesiger box-shadow um ein leeres Kästchen —
   damit braucht es kein Canvas, kein SVG und keine vier Overlay-Streifen.
   ============================================================ */
#tour-overlay {
  position: fixed; inset: 0; z-index: 9000;
  opacity: 0; transition: opacity .22s ease;
}
#tour-overlay.an { opacity: 1; }

#tour-hole {
  position: fixed; border-radius: 12px;
  box-shadow: 0 0 0 9999px rgba(9, 12, 20, 0.74);
  transition: left .28s cubic-bezier(.4,0,.2,1), top .28s cubic-bezier(.4,0,.2,1),
              width .28s cubic-bezier(.4,0,.2,1), height .28s cubic-bezier(.4,0,.2,1), opacity .2s;
  pointer-events: none;
}
/* Anfangs-/Schlusskarte: kein Loch, aber der Schleier muss bleiben */
#tour-hole[style*="opacity: 0"] { box-shadow: 0 0 0 9999px rgba(9, 12, 20, 0.74); opacity: 1 !important; width: 0; height: 0; }

.tour-ziel {
  position: relative; z-index: 9001;
  box-shadow: 0 0 0 2px var(--accent), 0 0 22px rgba(66, 99, 235, 0.55) !important;
  border-radius: 10px;
}

#tour-card {
  position: fixed; z-index: 9002;
  width: min(360px, calc(100vw - 32px));
  background: var(--bg2); color: var(--text);
  border: 1px solid var(--border); border-radius: 16px;
  padding: 20px 20px 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  transition: left .28s cubic-bezier(.4,0,.2,1), top .28s cubic-bezier(.4,0,.2,1);
}
.tour-h { font-size: 17px; font-weight: 700; margin-bottom: 8px; text-wrap: balance; }
.tour-t { font-size: 13.5px; line-height: 1.6; color: var(--text2); }
.tour-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 18px;
}
.tour-dots { display: flex; gap: 5px; }
.tour-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--border); transition: background .2s, width .2s;
}
.tour-dot.an { background: var(--accent); width: 16px; border-radius: 3px; }
.tour-btns { display: flex; align-items: center; gap: 8px; }
.tour-btns button {
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  border-radius: 9px; padding: 7px 13px; cursor: pointer;
  border: 1px solid transparent; transition: all .15s;
}
.tour-skip { background: none; color: var(--text3); }
.tour-skip:hover { color: var(--text); }
.tour-back { background: none; border-color: var(--border); color: var(--text2); }
.tour-back:hover { background: var(--bg3); }
.tour-next { background: var(--accent); color: #fff; }
.tour-next:hover { filter: brightness(1.08); }

@media (prefers-reduced-motion: reduce) {
  #tour-overlay, #tour-hole, #tour-card { transition: none; }
}
@media (max-width: 700px) {
  #tour-card { left: 12px !important; right: 12px; width: auto;
               top: auto !important; bottom: 16px; transform: none !important; }
}

/* ============================================================================
   MOBILE SHELL — 5 Prioritäts-Tabs + "Mehr"-Sheet (statt überladener Leiste)
   Desktop/Tablet ab 769px: unsichtbar (Sidebar links regiert).
   Handy ≤768px: feste Bottom-Tabs; "Mehr" schiebt die Sidebar als Sheet hoch.
   ============================================================================ */
.mtab { display: none; }
.nav-scrim { display: none; }
#mehr-zu { display: none; }   /* Ausgang des „Mehr"-Blatts — nur am Handy (core.js mtabAusgang) */

@media (max-width: 768px) {
  /* Ausgang des „Mehr"-Blatts (02.10.2026, Apple-Abgleich V7c): oben rechts im Blatt, mit Wort, 44 px hoch.
     Die negative Unterkante holt die Zeile mit dem Markenzeichen neben den Knopf, statt sie nach unten zu
     schieben. Weiss auf dem dunklen Blatt (#152735). Nicht „sticky": beim Rollen im Blatt laege er sonst
     ueber dem rechten Rand der Menuepunkte (dort steht die Zahl am Kalender); unten bleiben Tab „Mehr",
     der Tipp daneben und Escape. */
  #mehr-zu { display: inline-flex; align-items: center; justify-content: center; align-self: flex-end; position: relative; z-index: 1;
    min-height: 44px; min-width: 44px; padding: 0 16px; margin: 0 0 -44px; border-radius: 22px;
    border: 1px solid rgba(255,255,255,.28); background: rgba(255,255,255,.10); color: #fff;
    font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer; }
  #mehr-zu:focus-visible { outline: 2px solid #C8A44D; outline-offset: 2px; }
  /* Die Tab-Leiste bleibt ueber dem offenen Blatt (Blatt 300, Schleier 290): „Mehr" schliesst, was es
     geoeffnet hat, die anderen Tabs fuehren direkt weiter. Das Blatt haelt unten 66 px fuer sie frei. */
  .app-wrap.nav-open .mtab { z-index: 310; }
  .mtab {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 250;
    background: var(--bg2); border-top: 1px solid var(--border);
    padding: 4px 4px calc(4px + env(safe-area-inset-bottom));
    justify-content: space-around; align-items: stretch;
    box-shadow: 0 -2px 14px rgba(0,0,0,.06);
  }
  body.dark .mtab { background: #101f2a; }
  .mtab-btn {
    flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 3px;
    border: 0; background: none; font-family: inherit; font-size: 10px; font-weight: 600;
    color: var(--text2); padding: 6px 2px; min-height: 50px; cursor: pointer; border-radius: 12px;
    transition: color .15s, background .15s;
  }
  .mtab-btn.active { color: var(--accent); }
  .mtab-btn.active .mtab-i { transform: translateY(-1px); }
  .mtab-i { font-size: 21px; line-height: 1; transition: transform .15s; }

  .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 290;
    background: rgba(10,18,25,.42); opacity: 0; pointer-events: none;
    -webkit-backdrop-filter: blur(2px);
    transition: opacity .3s ease; backdrop-filter: blur(2px);
  }
  .app-wrap.nav-open .nav-scrim { opacity: 1; pointer-events: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .sidebar, .nav-scrim { transition: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CALLASSIST — die Marke ist orange, nicht blau
   ---------------------------------------------------------------------------
   Rufon und das Altprodukt sind zwei Produkte auf einer Codebasis (siehe index.html:
   der Hostname setzt html.call). Ein blauer "Anmelden"-Knopf unter einem orangen
   Logo verraet, dass es dieselbe App ist — genau das soll es nicht.
   Warum so viele Zeilen fuer eine Farbe: --accent ist eine Variable (eine Zeile), aber
   Knopf-Verlauf, Schatten, Hintergrund und die zwei Lichtflecken sind fest verdrahtetes
   Blau. Die kann man nur einzeln umhaengen.
   `html.call body.dark` MUSS mit: body.dark setzt --accent selbst und hat dieselbe
   Spezifitaet wie html.call -> ohne diese Zeile waere Rufon im Dunkeln wieder blau.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Rufon — Navy #051C2C + Gold #C8A44D (McKinsey). --accent = Navy
   (Nav/Links/Text, hoher Kontrast), Buttons = Gold-Flaeche + Navy-Text (Marken-CTA).
   Status-Farben (rot/gruen) bleiben unveraendert. */
/* --accent-ink = die Schriftfarbe AUF dem Akzent. Muss mitwechseln, weil der Akzent
   selbst wechselt: Navy im Hellmodus (helle Schrift), Gold im Dunkelmodus (dunkle
   Schrift). Vorher stand an mehreren Knoepfen fest color:#fff — auf Gold sind das
   2,37:1, gemessen im Dunkelmodus. */
html.call           { --accent: #051C2C; --accent2: #0a3352; --accent-light: #eef2f6; --accent-ink: #ffffff; }
html.call body.dark { --accent: #C8A44D; --accent2: #E4C878; --accent-light: #13212c; --accent-ink: #051C2C; }

html.call .login-wrap { background: linear-gradient(135deg, #eef1f5 0%, #f7f8fb 50%, #e9edf2 100%); }
html.call .login-wrap::before { background: radial-gradient(circle, rgba(200,164,77,.16), transparent 68%); }
html.call .login-wrap::after  { background: radial-gradient(circle, rgba(5,28,44,.12), transparent 68%); }
/* Login-Knopf in McKinsey-Blau (Betreiber-Wunsch), nicht Gold. */
html.call .btn-login          { background: linear-gradient(135deg, #0e3a63, #082740); color: #fff; box-shadow: 0 4px 14px rgba(5,28,44,.35); }
html.call .btn-login:hover    { background: linear-gradient(135deg, #124a7e, #0a3352); box-shadow: 0 6px 18px rgba(5,28,44,.3); }
html.call .btn-primary        { background: #C8A44D; color: #051C2C; box-shadow: 0 4px 12px rgba(200,164,77,.3); }
html.call .btn-primary:hover  { background: #E4C878; }
/* Logo-Kachel enthaelt jetzt das Rufon-Icon (img, randlose Squircle-SVG) -> Hintergrund weg,
   weicher Navy-Schatten. border-radius exakt auf die Squircle-Ecke (24.5%) -> KEIN heller Rand. */
html.call .login-logo .icon   { background: transparent; box-shadow: 0 4px 14px rgba(5,28,44,.22); border-radius: 24.5%; }
html.call .logo-icon          { background: transparent; box-shadow: 0 4px 16px rgba(5,28,44,.28); }

/* Unter-Navigation der zusammengelegten Seite "Einstellungen" (Persönlich | Firma) */
.mk-subnav { display:flex; gap:8px; margin:0 0 20px; flex-wrap:wrap; }
.mk-subnav-btn { appearance:none; border:1px solid var(--border2); background:var(--bg2); color:var(--text2);
  font:inherit; font-size:14px; font-weight:600; padding:9px 18px; border-radius:999px; cursor:pointer;
  transition:background .15s, color .15s, border-color .15s; }
.mk-subnav-btn:hover { background:var(--bg3); color:var(--text); }
.mk-subnav-btn.active { background:var(--accent); color:#fff; border-color:var(--accent); }

/* ============================================================
   ROLLLEISTEN — schlanke, schwebende Pille (macOS-Stil) statt der klobigen
   System-Leiste. Sie erscheint NUR, wenn der Inhalt wirklich laenger ist.
   Der 3px-Rand in Verbindung mit background-clip:content-box macht den Balken
   schmal und laesst ihn schweben; die Spur bleibt unsichtbar.
   Firefox kann kein ::-webkit-scrollbar -> scrollbar-width/-color deckt ihn ab.
   ============================================================ */
.main, .modal, .dd-menu, .transcript-box {
  scrollbar-width: thin;
  scrollbar-color: rgba(120,120,140,.38) transparent;
}
.main::-webkit-scrollbar, .modal::-webkit-scrollbar, .dd-menu::-webkit-scrollbar,
.transcript-box::-webkit-scrollbar { width: 11px; height: 11px; }
.main::-webkit-scrollbar-track, .modal::-webkit-scrollbar-track, .dd-menu::-webkit-scrollbar-track,
.transcript-box::-webkit-scrollbar-track { background: transparent; }
.main::-webkit-scrollbar-thumb, .modal::-webkit-scrollbar-thumb, .dd-menu::-webkit-scrollbar-thumb,
.transcript-box::-webkit-scrollbar-thumb {
  background: rgba(120,120,140,.38);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: 999px;
}
.main::-webkit-scrollbar-thumb:hover, .modal::-webkit-scrollbar-thumb:hover,
.dd-menu::-webkit-scrollbar-thumb:hover, .transcript-box::-webkit-scrollbar-thumb:hover {
  background: rgba(120,120,140,.62);
  background-clip: content-box;
}
body.dark .main, body.dark .modal, body.dark .dd-menu, body.dark .transcript-box {
  scrollbar-color: rgba(210,223,235,.30) transparent;
}
body.dark .main::-webkit-scrollbar-thumb, body.dark .modal::-webkit-scrollbar-thumb,
body.dark .dd-menu::-webkit-scrollbar-thumb, body.dark .transcript-box::-webkit-scrollbar-thumb {
  background: rgba(210,223,235,.30);
  background-clip: content-box;
}

/* ── "Konfiguration" im Dialer pulsiert dezent ──────────────────────────────────
   Betreiber-Wunsch 20.07.: der Knopf soll auffallen, ohne zu drängeln. Deshalb ein
   ruhiger Schein am Rand statt Groessenaenderung — Letzteres laesst die Kopfzeile
   zappeln und wirkt nach Fehler, nicht nach Hinweis.
   Wer weniger Bewegung eingestellt hat, bekommt sie nicht (Barrierefreiheit). */
@keyframes cfgPuls {
  0%, 100% { box-shadow: 0 0 0 0 rgba(200,164,77,0.00); }
  50%      { box-shadow: 0 0 0 4px rgba(200,164,77,0.22); }
}
#dialer-config-btn { animation: cfgPuls 3s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { #dialer-config-btn { animation: none; } }

/* ── Markenzeichen des Dialers: goldenes Telefon (nur Rufon) ───────────────
   Bewusst ein eigenes SVG statt ☎️: Emoji sehen auf iPhone, Android und Windows
   verschieden aus — ausgerechnet das Markenzeichen soll ueberall gleich aussehen.
   Groesse haengt an der Schrift (1em), damit es in der Navigation, in der Ueberschrift
   und im Startknopf jeweils von selbst passt. */
.marke-tel {
  width: 1em; height: 1em;
  vertical-align: -0.14em;
  fill: currentColor;
  flex: 0 0 auto;
}
/* Gold — im hellen Modus ist --accent das Navy, deshalb hier ausdruecklich die
   Gold-Marke; auf dunklem Grund ist --accent bereits Gold. */
html.call .marke-tel            { color: #C8A44D; }
html.call body.dark .marke-tel  { color: var(--accent); }
/* In der Seitenleiste sitzt das Zeichen in einem Icon-Feld fester Breite — mittig
   ausrichten, sonst haengt es am Text. */
.nav-icon.dyn-dc-icon, .mtab-i.dyn-dc-icon {
  display: inline-flex; align-items: center; justify-content: center;
}

/* ══════════════════════════════════════════════════════════════════════════
   Marken-Nachzug 22.07.2026 — Stellen, die der html.call-Block oben nicht traf.
   Gefunden bei einer vollstaendigen Durchsicht: die Grundregeln tragen noch das
   alte Schema (Blau #0e3a63 -> Lila #C8A44D). Sichtbar waren vor allem der
   AKTIVE Navigationspunkt und die Benutzer-Pille — beide dauerhaft im Bild.
   Bewusst als html.call-Ueberschreibung und nicht durch Aendern der Grundregeln:
   so bleibt erkennbar, was Marke ist und was Grundgeruest.
   ══════════════════════════════════════════════════════════════════════════ */
html.call .nav-item.active        { background: rgba(200,164,77,.16); color: #C8A44D; }
html.call body.dark .nav-item.active { background: rgba(200,164,77,.22); color: #E4C878; }

html.call .user-avatar,
html.call .cx-avatar,
html.call .task-avatar            { background: linear-gradient(135deg, #0e3a63, #051C2C); color: #fff; }

html.call .clock-widget           { background: linear-gradient(135deg, #0e3a63 0%, #051C2C 100%); }

html.call .accent-bar,
html.call .purple .accent-bar     { background: linear-gradient(90deg, #C8A44D, #E4C878); }

/* Die waehlbaren Oberflaechen "modern"/"glass" (glass.css) faerbten den
   Haupt-Handlungsknopf indigo-violett — ausgerechnet den Knopf, den der
   Vertriebler den ganzen Tag drueckt. */
html.call .glass-cta,
html.call .btn-call-main,
html.call .btn-next-contact       { background: linear-gradient(135deg, #C8A44D, #E4C878); color: #051C2C; }

/* ══════════════════════════════════════════════════════════════════════════════
   FINGERZIELE AUF MOBILGERAETEN  (22.07.2026)

   Gemessen bei 390x844 mit Touch: die Bedienelemente der Seitenleiste sind 32 bis
   41 px hoch — die Empfehlung liegt bei 44. Am Schreibtisch mit Maus faellt das nie
   auf; unterwegs trifft der Daumen daneben, und beim Abtelefonieren passiert das
   hundertmal am Tag.

   Nur die Hoehe wird angehoben: die Breite stimmt ohnehin (368 px). Und nur auf
   Zeigegeraeten ohne genauen Zeiger — am PC waere ein 44-px-Abmeldeknopf klobig.
   ══════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px), (pointer: coarse) {
  .sidebar .nav-item,
  .sidebar .btn-logout,
  .sidebar .theme-toggle,
  .sidebar button {
    min-height: 44px;
  }
  /* Der Knopf im Einrichtungs-Hinweis ("Jetzt eintragen") war mit 32 px der kleinste
     ueberhaupt — ausgerechnet der, der ein halb eingerichtetes Produkt rettet. */
  #einrichtung-hinweis .btn,
  #einrichtung-hinweis button {
    min-height: 44px;
    padding-left: 16px; padding-right: 16px;
  }
  /* Die Rechtliches-Verweise sind Fusszeile, kein Bedienelement — 44 px hoch waeren dort
     absurd. Sie muessen aber mit dem Daumen treffbar bleiben: etwas groessere Schrift und
     Innenabstand geben rund 30 px Trefferflaeche, ohne dass die Zeile laut wird. */
  .sidebar-legal { font-size: 11.5px; gap: 6px 10px; }
  /* Fingerziel 44x44 (04.09.2026, Fund von pruef-mobil). Vorher 60x29 px: der Text ist
     klein und SOLL es bleiben — die Flaeche zum Antippen darf es nicht. Erreicht wird das
     ueber Polsterung, nicht ueber Schriftgroesse; die Links sehen unveraendert aus.
     min-width, weil "AGB" schmaler ist als die Schwelle — der Pruefer misst beide
     Richtungen, und ein 30 px breites Ziel trifft der Daumen genauso wenig. */
  .sidebar-legal a { padding: 14px 8px; min-width: 44px; text-align: center; }

  /* Kleine Aktionsknoepfe und Filter-Chips in Listen: dieselbe Regel, gleiche Begruendung. */
  .action-btn, .filter-chip, .ki-filter {
    min-height: 44px;
    display: inline-flex; align-items: center;
  }
  /* Und die uebrigen Knoepfe im Inhalt. Bewusst BREIT gefasst statt Fall fuer Fall:
     die Messung fand sie in fuenf verschiedenen Klassen, und die naechste neue Schaltflaeche
     waere wieder zu klein. Eine Regel, die auch das erfasst, woran niemand gedacht hat.
     Nur die HOEHE — Breite und Anordnung bleiben unangetastet. */
  .btn, .btn-sm, .btn-ghost, .wb-toggle, .dd-toggle,
  button.btn, .modal button, .card button {
    min-height: 44px;
  }
  /* Reine Symbolknoepfe (Stift, Papierkorb) brauchen auch BREITE — 42 px sind zu schmal,
     und daneben zu tippen heisst hier: den falschen Benutzer erwischen. */
  .btn-sm, .btn.btn-sm { min-width: 44px; }
}

/* ============================================================
   TESTPHASEN-STREIFEN (02.09.2026)
   Dezent, ganz oben im Inhalt. Sichtbar nur, wenn im OPS ein Datum hinterlegt
   ist — die Sichtbarkeit setzt showTrialCountdown() per style.display, nicht CSS.
   Farbe ist Marken-Gold #C8A44D. Das alte Seitenleisten-Badge trug Amber
   #f59e0b, also genau das Orange, auf das pruef-marke.js ansetzt; ein neues
   sichtbares Element in dieser Farbe haette den Pruefer zu Recht ausgeloest.
   Rot (--red) erst, wenn es knapp wird oder abgelaufen ist.
   ============================================================ */
.testphase-streifen {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 14px; padding: 7px 14px;
  /* MUSS positioniert sein, sonst ist der Streifen in den Skins "glass" und "modern"
     UNSICHTBAR — und "glass" ist der Standard.
     Grund: #page-dialer.skin-glass::before ist `position:fixed; inset:0` mit einem
     DECKENDEN Grund (#f5f7fc). #page-dialer ist positioniert und isoliert, dieser
     Streifen war statisch — also malt der gesamte Block von #page-dialer darueber,
     bildschirmfuellend. Am 02.09.2026 gemessen: in klassik gerendert, in glass und
     modern eine leere Flaeche.
     Warum es keiner der Pruefer sah: das Pseudo-Element traegt `pointer-events:none`
     (elementFromPoint uebersieht es) und steht als Pseudo-Element ueberhaupt nicht im
     DOM (eine Abfrage ueber querySelectorAll findet es nie). Layout, gerechnete Farben
     und Trefferpruefung waren alle gruen, waehrend nichts zu sehen war. */
  position: relative; z-index: 1;
  border: 1px solid rgba(200,164,77,0.30);
  border-radius: var(--radius-sm);
  background: rgba(200,164,77,0.09);
  color: var(--text2);
  font-size: 12px; line-height: 1.35;
}
.testphase-streifen .tp-punkt {
  width: 6px; height: 6px; border-radius: 50%;
  background: #C8A44D; flex-shrink: 0;
}
.testphase-streifen .tp-rest { color: var(--text); font-weight: 600; }
.testphase-streifen.tp-knapp {
  border-color: rgba(229,62,94,0.30);
  background: rgba(229,62,94,0.08);
}
.testphase-streifen.tp-knapp .tp-punkt { background: var(--red); }
.testphase-streifen.tp-knapp .tp-rest  { color: var(--red); }
/* Nur der Upgrade-Fall ist anklickbar — sonst zeigt der Zeiger eine Handlung an,
   die es nicht gibt. */
.testphase-streifen.tp-klick { cursor: pointer; }
.testphase-streifen.tp-klick:hover { background: rgba(229,62,94,0.13); }
/* Rechter Block: Upgrade-Ruf (nur wenn die Sperre wirklich greift) + Absenderzeile.
   Das margin-left:auto sitzt am BLOCK, nicht an den einzelnen Elementen — sonst schoeben
   sich im Ablauf-Fall zwei Elemente gegenseitig nach rechts. */
.testphase-streifen .tp-rechts { margin-left: auto; display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
.testphase-streifen .tp-cta  { color: var(--red); font-weight: 700; white-space: nowrap; }
.testphase-streifen .tp-team { color: var(--text3); white-space: nowrap; }
/* Auf schmalen Geraeten faellt die Absenderzeile weg, nicht der Hinweis: die Tage sind
   die Nachricht, der Absender ist die Hoeflichkeit. */
@media (max-width: 640px) {
  .testphase-streifen .tp-team { display: none; }
}

/* ============================================================
   WARTUNGSANKUENDIGUNG (19.09.2026) — oben in der AKTIVEN Seite, gebaut von wartungZeigen()
   in core.js. Drei Phasen, alle in Markenfarben (kein Orange — pruef-marke.js):
     .wb-angekuendigt  gold getoent, als Information, weich
     .wb-bald          kraeftig gold, navy Schrift — auch der Zusatz (in der Vorschau war
                       er grau und zu blass)
     .wb-laeuft        rot getoent, pulsierender Punkt, KEIN ×
   Wie der Testphasen-Streifen positioniert (relative + z-index): die Skins "glass" und
   "modern" legen ein bildschirmfuellendes ::before hinter den Dialer, und ein statischer
   Streifen war dort am 02.09.2026 unsichtbar, waehrend jeder Messwert gruen war.
   Kontrast gerechnet, nicht geschaetzt: der Zusatz traegt --text2 und NICHT --text3 —
   #7c8496 auf dem Goldton erreicht nur 3,5:1. Das Rot der fetten Zeile ist ein eigenes:
   --red (#e53e5e) auf dem Rotton sind 3,6:1 bei 12,5 px, also zu wenig; #b0213f hat 6:1,
   im Dunkeln #ff8a9f.
   ============================================================ */
.wartung-banner {
  --wb-rot: #b0213f;
  display: flex; align-items: center; gap: 10px;
  /* min-height = × (32) + Polster (2 × 6) + Rahmen (2): "laeuft" hat kein × und waere sonst
     4 px niedriger — beim Phasenwechsel rueckte der Inhalt darunter sichtbar nach (im Bild
     gesehen, nicht gemessen). */
  margin-bottom: 14px; padding: 6px 6px 6px 14px; min-height: 46px; box-sizing: border-box;
  position: relative; z-index: 1;
  border: 1px solid rgba(200,164,77,0.38);
  border-radius: var(--radius-sm);
  background: rgba(200,164,77,0.10);
  color: var(--text2);
  font-size: 12.5px; line-height: 1.4;
}
body.dark .wartung-banner { --wb-rot: #ff8a9f; }
.wartung-banner .wb-i { font-size: 15px; line-height: 1; flex-shrink: 0; }
.wartung-banner .wb-text { min-width: 0; padding: 3px 0; }
.wartung-banner b { color: var(--text); font-weight: 700; }
.wartung-banner .wb-zusatz { color: var(--text2); }
/* Der Markenpunkt wie in der App (.login-logo/.logo-text), aber groesser: bei 12,5 px waeren
   .19em nur 2,4 px — von einem Strichende nicht zu unterscheiden (Lehre vom 11.09.2026).
   .26em ergibt 3,25 px. Gold auf dem Goldton und auf dem Rotton; in "bald" steht der Banner
   selbst auf Gold, dort nimmt der Punkt die Schriftfarbe (Gold auf Gold waere unsichtbar). */
.wartung-banner .mp {
  display: inline-block; width: .26em; height: .26em; border-radius: 50%;
  background: #C8A44D; vertical-align: .25em; margin: 0 .06em;
}
/* 32 px Trefferflaeche (WCAG 2.5.8 verlangt 24) — ein × in Schriftgroesse waere am Handy
   neben dem Daumen kaum zu treffen. */
.wartung-banner .wb-x {
  margin-left: auto; flex-shrink: 0; min-width: 32px; min-height: 32px;
  border: 0; border-radius: 7px; background: none; cursor: pointer;
  color: var(--text2); font-size: 18px; line-height: 1; font-family: inherit;
}
.wartung-banner .wb-x:hover { background: rgba(0,0,0,0.06); }
body.dark .wartung-banner .wb-x:hover { background: rgba(255,255,255,0.08); }
.wartung-banner .wb-x:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; }
.wartung-banner.wb-bald { background: #C8A44D; border-color: #C8A44D; color: #051C2C; }
.wartung-banner.wb-bald b,
.wartung-banner.wb-bald .wb-zusatz,
.wartung-banner.wb-bald .wb-x { color: #051C2C; }
.wartung-banner.wb-bald .mp { background: currentColor; }
.wartung-banner.wb-bald .wb-x:hover { background: rgba(5,28,44,0.10); }
.wartung-banner.wb-laeuft { background: rgba(229,62,94,0.09); border-color: rgba(229,62,94,0.38); }
.wartung-banner.wb-laeuft b { color: var(--wb-rot); }
.wartung-banner .wb-puls {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  background: var(--wb-rot); animation: wbPuls 1.6s infinite;
}
@keyframes wbPuls {
  0%   { box-shadow: 0 0 0 0 rgba(229,62,94,0.45); }
  70%  { box-shadow: 0 0 0 7px rgba(229,62,94,0); }
  100% { box-shadow: 0 0 0 0 rgba(229,62,94,0); }
}
/* Die allgemeine Regel weiter oben kuerzt Animationen nur auf 0,01 ms — ein Puls, der einmal
   zuckt, ist trotzdem Bewegung. Bei abgewaehlter Bewegung steht der Punkt still. */
@media (prefers-reduced-motion: reduce) { .wartung-banner .wb-puls { animation: none; } }
/* Handy: der Kurztext statt des Satzes (Spec). Beide stehen im Dokument; display:none nimmt
   den jeweils anderen auch einem Screenreader weg, es wird also nichts doppelt vorgelesen. */
.wartung-banner .wb-kurz { display: none; }
@media (max-width: 640px) {
  .wartung-banner .wb-lang { display: none; }
  .wartung-banner .wb-kurz { display: inline; }
}
/* Der Verbindungsstreifen (core.js, verbindungsBannerZeigen) waehrend einer Wartung: navy
   statt Bernstein. !important, weil der Streifen seine Farbe als Inline-Stil mitbringt. */
#verbindung-weg.vw-wartung { background: #051C2C !important; color: #fff !important; }

/* ============================================================
   DIALER-STARTSEITE: „MEINE LISTEN" — KURZ STATT LANG (01.10.2026)
   ------------------------------------------------------------
   Anlass: Betreiber, Fenster rund 1600×920 — das Datum unten war angeschnitten, und jede
   weitere Liste machte die Seite ~67 px hoeher. Die Zeilen malt dialerListenMalen()
   (dialer.js): am PC die drei zuletzt benutzten, am Handy eine, der Rest hinter
   „Alle Listen (N)". Gemessen von intern/werkzeuge/lokal/pruef-dialer-start.js.

   Bis dahin trug jede Zeile ihre Gestaltung als Inline-Stil. Jetzt Klassen mit dem Vorsatz
   ml- (vorher gesucht: frei) — drei Designs und zwei Fenstergroessen lassen sich am
   Stil-Attribut nicht auseinanderhalten. Farben unveraendert: Markengold fest (nicht
   var(--accent), siehe dialerListeZeile), Navy #051C2C darauf 6,5–8:1.

   Eine Zeile ist am PC 52 px hoch (vorher 67): Name EINZEILIG mit … (voll im title),
   Balken 4 statt 6 px. Die feste Hoehe ist der Punkt — nur so bleibt die Seite, wo sie
   gemessen wurde.
   ============================================================ */
.ml-zeile { display: flex; align-items: center; gap: 12px; padding: 6px 4px; border-bottom: 1px solid var(--border); min-width: 0; }
.ml-zeile:last-child { border-bottom: 0; }
.ml-text { flex: 1 1 auto; min-width: 0; }
.ml-name { font-size: 13px; line-height: 17px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* --text2, nicht --text3 wie bisher: 11 px in #7c8496 auf Weiss sind 3,75:1 (Modern 3,41:1) —
   axe-core meldete jede dieser Zeilen (01.10.2026). --text2 liegt in allen drei Designs ueber 4,5:1. */
.ml-meta { font-size: 11px; line-height: 14px; color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ml-balken { height: 4px; border-radius: 4px; background: var(--bg3); margin-top: 4px; overflow: hidden; max-width: 260px; }
.ml-balken i { display: block; height: 100%; border-radius: 4px; background: linear-gradient(90deg,#C8A44D,#b8913c); transition: width .3s; }
.ml-balken i.fertig { background: #16a34a; }
.ml-knoepfe { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.ml-weiter { padding: 8px 18px; border-radius: 10px; border: none; background: linear-gradient(118deg,#C8A44D,#b8913c); color: #051C2C; font-size: 13px; font-weight: 700; font-family: inherit; line-height: 17px; cursor: pointer; white-space: nowrap; box-shadow: 0 3px 10px rgba(200,164,77,.35); }
.ml-knopf { padding: 8px 12px; border-radius: 10px; border: 1.5px solid var(--border2); background: transparent; color: var(--text3); font-size: 13px; font-family: inherit; line-height: 17px; cursor: pointer; }
.ml-marke { font-size: 12px; padding: 4px 12px; border-radius: 20px; font-weight: 700; white-space: nowrap; }
.ml-marke.fertig  { background: var(--green-bg); color: var(--green-text); }
/* „📭 leer" (15.10.2026): eine Liste ohne jeden Kontakt — dieselbe Flaeche und Schrift wie „Alle Listen" (.ml-alle). */
.ml-marke.leer    { background: var(--bg3); color: var(--text); border: 1px solid var(--border2); }
/* „Alle Listen (N)": EIN Knopf ueber die ganze Breite, sichtbar als Knopf (Flaeche + Rand),
   nicht als Textzeile. Er bleibt beim Aufklappen an seinem Platz — der Rest erscheint
   darunter, und wer zuklappen will, findet ihn dort, wo er geklickt hat. */
.ml-alle { display: flex; align-items: center; justify-content: center; gap: 7px; width: 100%; margin-top: 8px; padding: 7px 14px; min-height: 34px; border-radius: 10px; border: 1px solid var(--border2); background: var(--bg3); color: var(--text); font-size: 12.5px; font-weight: 650; font-family: inherit; line-height: 17px; cursor: pointer; }
.ml-alle:hover { border-color: var(--text3); }
/* Der Pfeil ist gezeichnet (zwei Kanten), kein Zeichen: „▾" war in der Schrift der App bei
   11 px nur ein Punkt (im Bild gesehen). */
.ml-alle-pfeil { width: 7px; height: 7px; margin-top: -4px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); transition: transform .2s, margin-top .2s; }
.ml-alle[aria-expanded="true"] .ml-alle-pfeil { transform: rotate(-135deg); margin-top: 3px; }
/* `hidden` verliert gegen jedes display — deshalb ausdruecklich (Lehre: gerechnet ist nicht gemalt) */
.ml-rest[hidden] { display: none !important; }
.ml-rest { margin-top: 6px; }
/* Platzhalter (02.10.2026): in einem neuen Fenster stehen so viele leere Zeilen, wie gleich Listen kommen
   (dialerListePlatzZeile) — aus denselben Bausteinen wie die echte Zeile, damit die Hoehe in jedem
   Design stimmt. Nur Flaechen, kein Text; der Puls ist ladePuls (Abschnitt „LADEN“ am Ende).
   Die Farbe der Flaechen ist ein Zehntel der Textfarbe: --bg3 ist in „Liquid Glass“ fast weiss auf weiss —
   im Bild stand dort eine leere Karte (02.10.2026). --bg3 bleibt der Wert fuer Browser ohne color-mix. */
.ml-platz { --ml-platz-f: var(--bg3); }
@supports (color: color-mix(in srgb, red 50%, blue)) { .ml-platz { --ml-platz-f: color-mix(in srgb, var(--text) 10%, transparent); } }
.ml-platz .ml-name, .ml-platz .ml-meta { color: transparent; background: linear-gradient(var(--ml-platz-f), var(--ml-platz-f)) no-repeat left center / 100% 10px; border-radius: 6px; }
.ml-platz .ml-name { width: min(220px, 60%); }
.ml-platz .ml-meta { width: min(300px, 80%); }
.ml-platz .ml-weiter, .ml-platz .ml-knopf, .ml-alle.ml-platz { background: var(--ml-platz-f); border-color: transparent; color: transparent; box-shadow: none; cursor: default; pointer-events: none; }
.ml-platz .ml-weiter { min-width: 150px; }
.ml-platz .ml-knopf { min-width: 44px; }
.ml-zeile.ml-platz, .ml-alle.ml-platz { animation: ladePuls 1.2s ease-in-out infinite; }   /* der eine Puls (Abschnitt „LADEN“, 14.10.2026) */
@media (prefers-reduced-motion: reduce) { .ml-alle-pfeil, .ml-balken i { transition: none; } .ml-zeile.ml-platz, .ml-alle.ml-platz { animation: none; } }
/* Handy (die Grenze der App, ≤ 768 px): Text oben, die Knoepfe darunter — „Weitermachen"
   ueber die Breite. Die 44 px Fingerziel kommen aus der allgemeinen Regel (.card button). */
@media (max-width: 768px) {
  .ml-zeile { flex-wrap: wrap; gap: 8px 10px; padding: 6px 2px 8px; }
  .ml-text, .ml-knoepfe { flex: 1 1 100%; }
  .ml-weiter { flex: 1 1 auto; }
  .ml-knopf { min-width: 44px; }
  .ml-marke { margin-right: auto; }
  .ml-alle { margin-top: 6px; }
}
/* „📅 2 Rückrufe dran — zum Kalender" (08.10.2026, Rueckrufe aus dem Kalender): steht an der Stelle von
   „Weitermachen", wenn in der Liste nur noch faellige Rueckrufe offen sind. Das Aussehen kommt von .kal-knopf
   (wie „Zum Kalender" im Streifen darueber) — hier steht nur die Lage: am PC einzeilig, am Handy ueber die
   Breite wie „Weitermachen" und, wenn es eng wird, zweizeilig statt abgeschnitten — umbrochen wird dann nur
   zwischen den beiden Haelften („📅 2 Rückrufe dran" / „— zum Kalender"), nie mitten in einer (im Bild stand
   bei 390 px „… — zum" und darunter allein „Kalender"). */
.ml-zum-kalender { white-space: nowrap; line-height: 17px; }
.ml-zum-kalender span { white-space: nowrap; }
@media (max-width: 768px) { .ml-zum-kalender { flex: 1 1 auto; min-width: 0; white-space: normal; } }
/* Der Kalender-Streifen („Heute: 3 Rückrufe · 1 Termin") steht in der Bahn des ersten
   Schritts, und die haelt ihre Kinder schon 12 px auseinander. Sein eigener Abstand nach
   unten (kalender.css, gedacht fuer eine Seite ohne solche Bahn) kam obendrauf: 24 statt
   12 px bis zur ersten Karte. Mit #page-dialer davor, damit die Reihenfolge der Dateien
   nicht entscheidet. */
#page-dialer .dflow-panel > .kal-streifen { margin-bottom: 0; }

/* KLASSIK: die Schritte liegen untereinander. Zwei davon (Zuordnen, Pruefen) sind auf der
   Startseite LEER — ihre Karten erscheinen erst nach dem Hochladen —, nahmen aber als
   Kasten je 12 px Abstand mit: 37 statt 12 px zwischen „Kontaktliste hochladen" und
   „Gesprächsleitfaden" (gemessen 01.10.2026). `display: contents` nimmt den Kasten weg und
   laesst die Karten stehen; eine versteckte Karte kostet dann nichts mehr.
   Nur Klassik: Modern und Glass brauchen die Kaesten als Bahn (ein Schritt, eine Ansicht).
   :not() statt einer Klasse, weil Klassik keine eigene traegt (siehe glass.css). */
#page-dialer:not(.skin-modern):not(.skin-glass) .dflow-panel { display: contents; }

/* KLASSIK: „Rufon starten" nach dem Hochladen IM BILD (02.10.2026, Vorschlagsliste Bedienung Punkt 6;
   Durchsicht PC, S2). Klassik zeigt alle Schritte untereinander. Nach dem Hochladen schieben sich Zuordnung
   und Vorschau dazwischen, und der Start-Knopf — der naechste Handgriff — lag weit unter dem Fenster (gemessen
   am Stand davor mit neun gespeicherten Leitfaeden: 2.107–2.237 px tief bei 1366×768, 2.184–2.323 px bei
   1280×900, 2.610–2.872 px am Handy). Wer ihn nicht suchte, fand ihn nicht.
   Sobald Kontakte geladen sind (.kontakte-da, gesetzt in dialerCheckStartReady), haelt `sticky` ihn am unteren
   Rand des Bilds. Er behaelt dabei seinen Platz im Fluss: ganz unten angekommen steht er, wo er immer stand,
   und nichts liegt dauerhaft unter ihm. Ohne Kontakte bleibt er, wie er war — ein abgeschalteter Knopf, der
   am Rand mitfaehrt, waere nur im Weg.
   Der Abstand zaehlt in Chromium ab dem INNENrand von .main (dessen Polster unten: 24 px am PC, 96 px am Handy
   fuer die Tab-Leiste) — gemessen steht der Knopf am PC 36 px, am Handy 163 px ueber dem Fensterrand. Die Werte
   sind so gewaehlt, dass er auch dann ueber der Tab-Leiste (.mtab: 59 px und der Bereich, den iOS unten
   freihaelt) bleibt, wenn ein Browser ab der Fensterkante zaehlt: dann 8 px darueber. Firefox und WebKit (Playwright,
   nicht iOS selbst) zaehlen wie Chromium: 36 px bzw. 163 px (Gegenpruefung 04.10.2026).
   Gehalten von intern/werkzeuge/lokal/pruef-erstbesuch.js. */
#page-dialer:not(.skin-modern):not(.skin-glass) #dialer-setup.kontakte-da #dialer-start-btn {
  position: sticky; bottom: 12px; z-index: 5;
}
@media (max-width: 768px) {
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-setup.kontakte-da #dialer-start-btn { bottom: calc(67px + env(safe-area-inset-bottom)); }
}
/* … und wer mit der Tastatur durch die Zuordnung geht, verschwindet nicht unter ihm (Gegenpruefung 04.10.2026,
   WCAG 2.4.11): der Browser rollt ein Feld beim Fokus nur so weit, bis es unten im Bild steht — genau dort klebt der
   Knopf. Gemessen ohne diese Regel: je ein bis zwei Auswahlfelder der Zuordnung GANZ verdeckt (Chromium 1366×768,
   1280×900, 360×740; Firefox 1280×900, 360×740; WebKit 360×740). scroll-padding haelt beim Hinrollen den Streifen
   frei, den der Knopf belegt: am PC 36 px Abstand + 50 px Knopf + 10, am Handy 163 + 59 + 10 — und der Bereich,
   den iOS unten freihaelt, ZWEIMAL: einmal im Polster von .main, einmal im Abstand des Knopfs. Nur in Klassik und
   nur mit Kontakten — wie die Regel darueber. Gehalten von pruef-erstbesuch.js (Zeile „klassik-tab"). */
.main:has(> #page-dialer.active:not(.skin-modern):not(.skin-glass) > #dialer-setup.kontakte-da) { scroll-padding-bottom: 96px; }
@media (max-width: 768px) {
  .main:has(> #page-dialer.active:not(.skin-modern):not(.skin-glass) > #dialer-setup.kontakte-da) { scroll-padding-bottom: calc(232px + 2 * env(safe-area-inset-bottom)); }
}

/* KLASSIK am PC in niedrigen Fenstern (bis 1049 px Hoehe): Klassik zeigt ALLES untereinander
   (Kacheln, Listen, Ablage, Leitfaden, Schnelltest, Start) — mit zwei Listen war ein 920er
   Fenster auf den Pixel voll, die dritte und der Kalender-Streifen passten nicht mehr.
   Deshalb hier: die vier Schritt-Kacheln flach (Symbol links, Text rechts: 49 statt 97 px),
   die Koepfe der Karten mit 32er statt 40er Symbol, Polster knapper; und sobald es Listen
   gibt (.ml-da), die Ablage ohne ihr grosses Symbol (derselbe Ordner steht dann schon im
   Kopf von „Meine Listen"). Gemessen mit drei Listen, „Alle Listen" und dem Kalender-
   Streifen: die Seite braucht 885 px. Ab 1050 px bleibt Klassik, wie es war (1.026 px).
   Unter 900 px zeigt dialerListenMalen() in Klassik EINE Liste statt drei (781 px), unter
   810 px entfallen die Kacheln ganz (wie am Handy: reine Anzeige, die Karten darunter sagen
   dasselbe) — damit passt auch 1366×768 ohne Scrollen (721 px).
   !important, weil Kacheln, Symbole, Ablage und Knopf ihre Masse als Inline-Stil tragen.
   Nur Masse — Farben und Rahmen setzt dialer.js weiter selbst (Kachel „Starten" wird
   rot-golden). */
@media (min-width: 769px) and (max-height: 809px) {
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-step-indicator { display: none !important; }
  /* … und die Zeile unter dem Titel („Kontaktliste laden → Spalten prüfen → Loslegen", 19 px): sie
     sagt, was die Karten darunter zeigen. Mit ihr blieb bei 768 px Hoehe und Testphasen-Streifen 1 px. */
  #page-dialer:not(.skin-modern):not(.skin-glass) .dialer-head-sub { display: none; }
}
@media (min-width: 769px) and (max-height: 1049px) {
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-setup .topbar { margin-bottom: 12px; }
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-step-indicator > div {
    display: grid !important; grid-template-columns: auto minmax(0, 1fr); align-items: center;
    column-gap: 10px; row-gap: 0 !important; padding: 7px 14px !important;
  }
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-step-indicator > div > div:first-child { grid-row: 1 / span 2; }
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-step-indicator > div > div:not(:first-child) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #page-dialer:not(.skin-modern):not(.skin-glass) .dflow-panel[data-panel="liste"] > .card,
  #page-dialer:not(.skin-modern):not(.skin-glass) .dflow-panel[data-panel="leitfaden"] > .card { padding: 12px 18px; }
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-lists-card .dflow-oldhead-row { margin-bottom: 6px !important; }
  #page-dialer:not(.skin-modern):not(.skin-glass) .dflow-panel[data-panel="liste"] .dflow-oldhead { margin-bottom: 8px !important; }
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-lists-card .dflow-oldhead-row > div > div:first-child,
  #page-dialer:not(.skin-modern):not(.skin-glass) .dflow-panel[data-panel="liste"] .dflow-oldhead > div:first-child,
  #page-dialer:not(.skin-modern):not(.skin-glass) .lf-setup-symbol { width: 32px !important; height: 32px !important; font-size: 15px !important; }
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-setup.ml-da #dialer-dropzone { padding: 10px 12px !important; }
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-setup.ml-da #dialer-dropzone > div:first-child { display: none; }
  #page-dialer:not(.skin-modern):not(.skin-glass) #dialer-start-btn { padding-top: 14px !important; padding-bottom: 14px !important; }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   HANDY-FEINSCHLIFF  (08.10.2026, Welle 2, Paket „handy-feinschliff")

   Ein EIGENER Block am Ende, damit er sich mit den anderen Paketen der Welle zusammenfuehren laesst.
   Gemessen von intern/werkzeuge/lokal/pruef-handy-feinschliff.js an 390×844 und 360×740, drei Designs.
   Befunde: durchsicht-2026-10-01 (bedienung-handy.md, apple-abgleich.md V5/V9/V10) und
   durchsicht-2026-10-04 (apple-rest-app.md W7, W9, W10, W11, W14).

   BLOCK 1 · Fingerziele ≥ 44 px und Eingabefelder ≥ 16 px
   Apple nennt 44 pt als uebliches Mass eines Bedienelements; iOS-Safari zoomt beim Antippen in jedes Feld
   unter 16 px hinein und laesst die Seite danach vergroessert stehen. Am 08.10. lagen darunter (390×844):
   „Passwort vergessen?" 26 px hoch, „← Zurück zum Login" und „Abmelden" (Vertragswand) 18, der Kopf von
   „Aufgehobene Sperren" 16, „Neuer Einzelkontakt" 18, das ✕ der Meldung „Neue Version" 12×16, „Neu laden" 30,
   „+1" der Erinnerung 40×28, die Schritte der Startseite 16 (glass) bzw. 32 (modern), „Kontakt suchen" und
   „Anruf-Weg" 36, die Tage und Uhrzeiten beim Buchen 40 bzw. 36, „⋯" 36×36, die Eintraege der Duell-Auswahl
   33, ✕ von Tour und Einrichtung 34×34 und ihre Text-Verweise 18, „Alles klar" 32; Felder: Notiz 13 px,
   Feedback 14, „Passwort setzen" 15.
   Nur bis 768 px (dieselbe Grenze wie die Tab-Leiste): am PC waeren 44-px-Knoepfe klobig, und die Hoehen der
   PC-Ansichten haelt eine Reihe von Proben fest. !important nur, wo das Mass als Inline-Stil am Element steht.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* Die Text-Verweise der Anmeldemasken sind jetzt Knoepfe (W7: vorher <span onclick> — mit der Tastatur nicht
   zu erreichen, fuer VoiceOver kein Bedienelement). Aussehen wie vorher: Schrift der Zeile, Farbe der Marke. */
.login-verweis { background: none; border: 0; padding: 4px 2px; font: inherit; color: var(--accent); cursor: pointer; }
.login-verweis:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

@media (max-width: 768px) {
  /* Die Flaeche waechst nach innen (Innenabstand) — der Abstand der Zeile zur Karte darueber schrumpft um
     dasselbe Mass (16 → 4 px), sonst wuechse die Anmeldekarte um 26 px und schoebe sich bei 360×740 aus dem Bild. */
  .login-verweis { min-height: 44px; min-width: 44px; padding: 0 14px; display: inline-flex; align-items: center; justify-content: center; }
  .login-card > div:has(> .login-verweis) { margin-top: 4px !important; }

  /* Aufklapper: der ganze Kopf ist das Ziel. align-content zentriert die Zeile auch in einem Kasten ohne
     Flexbox (Safari ab 17.4; aeltere setzen die Zeile oben an — die Flaeche stimmt trotzdem). */
  details > summary { min-height: 44px; box-sizing: border-box; align-content: center; }

  /* Sitzung: die drei Knoepfe im Kopf (36 px als Inline-Stil). Die TREFFERFLAECHE waechst auf 44 px (Pseudo-
     Element, je 4 px ueber und unter dem Knopf — zwischen den Reihen sind 8 px Platz), die Knoepfe selbst bleiben
     36 px. Ein erster Versuch mit min-height 44 px machte den Kopf bei 360×740 um 16 px hoeher (zwei Reihen) — und
     schob „🔎 Nummer prüfen" unter die feste Leiste (pruef-sitzung-weiter.js W6, glass 360×740). Die feste Leiste
     unten bleibt, wie sie ist — ihre Knoepfe sind 46 px. */
  #dialer-active #dialer-suche-btn,
  #dialer-active button[onclick="dialerConfigAusSitzung()"],
  #dialer-active button[onclick="dialerStop()"] { position: relative; }
  #dialer-active #dialer-suche-btn::after,
  #dialer-active button[onclick="dialerConfigAusSitzung()"]::after,
  #dialer-active button[onclick="dialerStop()"]::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); }
  /* Notiz zum Gespraech: 13 → 16 px (das Feld, in das am Handy am meisten getippt wird). */
  #page-dialer #dialer-note { font-size: 16px !important; }

  /* Startseite Modern/Glass: die Schritt-Namen (Liste · Zuordnen · Prüfen · Leitfaden) sind Sprungziele, aber
     nur eine Schriftzeile hoch. Die Trefferflaeche waechst ueber ein Pseudo-Element — die Zeile selbst bleibt,
     wie sie ist, und nichts rutscht (die Probe misst die abgetastete Flaeche, nicht den Kasten). */
  #page-dialer .dflow-names span { position: relative; z-index: 2; }   /* ueber der Bahn darunter (glass: z-index 1), sonst nimmt sie den Tipp */
  #page-dialer .dflow-names span::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); }
  /* In Modern ist die Reihe am Handy eine Wisch-Reihe (overflow-x: auto, glass.css) — die schneidet ein
     Pseudo-Element an ihrem INNENRAND ab (32 px hohe Pillen blieben 32). Die Reihe bekommt deshalb oben und
     unten 6 px Innenabstand und gibt sie als negativen Rand zurueck: die Flaeche der Pillen hat Platz (44 px),
     und die Seite bleibt, wie sie ist. Ein erster Versuch liess die Pillen selbst auf 44 px wachsen — die
     Startseite wurde 12 px hoeher, und bei 360×740 lag die Ablage unter der Leiste „Weiter" (pruef-dialer-start). */
  #page-dialer.skin-modern .dflow-names { padding-top: 6px !important; padding-bottom: 6px !important; margin-top: -6px !important; margin-bottom: 0 !important; }
  /* Die Rufnummer in der Sitzung ist ein Verweis (tippen waehlt): 24–32 px hoch → 44 px Flaeche, ebenso ueber ein
     Pseudo-Element — Groesse und Platz der Nummer rechnet dialerNummerEinpassen(), daran aendert sich nichts. */
  #page-dialer #dialer-contact-phone { position: relative; }
  #page-dialer #dialer-contact-phone::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); }
  /* … und diese Flaeche darf dem Knopf „🔎 Nummer prüfen" nichts nehmen (Gegenpruefung 08.10.2026): in Klassik bei
     360×740 steht die Lupe 12 px unter der Oberkante der Nummer, ihre Kaesten ueberschneiden sich — die 44-px-Flaeche
     der Nummer lag ueber dem linken Rand der Lupe (6 von 121 Rasterpunkten, vorher 1 von 25 durch den Kasten selbst),
     und ein Tipp dort haette GEWAEHLT statt geprueft. Die Lupe liegt jetzt obenauf (1 genuegt: die feste Leiste der
     Sitzung traegt 40, die Tab-Leiste 250). Die Trefferhoehe der Nummer an ihrer Mitte bleibt 44 px. */
  #page-dialer #dialer-find-btn { position: relative; z-index: 1; }
  /* Auch die runden Ecken: ausserhalb der Rundung gehoert ein Punkt sonst dem, was dahinter liegt (gemessen: drei
     Punkte am linken Rand blieben bei der Nummer). Der ganze Kasten der Lupe nimmt den Tipp. */
  #page-dialer #dialer-find-btn::before { content: ""; position: absolute; inset: 0; }

  /* Auswahllisten (.dd, z. B. der Duell-Gegner): 33 → 44 px je Eintrag. */
  .dd-option { padding-top: 13px; padding-bottom: 13px; min-height: 44px; box-sizing: border-box; }

  /* Meldung „Neue Version": „Neu laden" 30 → 44, das ✕ 12×16 → 44×44 (die Flaeche, nicht das Zeichen —
     die negativen Raender halten den Abstand zum Nachbarn, sonst bliebe dem Satz bei 360 px zu wenig Breite). */
  #iq-update-reload { min-height: 44px; }
  #iq-update-close { min-width: 44px; min-height: 44px; margin: -6px -10px -6px -8px; }

  /* Wartungsbanner ✕ (32×32), Feedback-Hinweis „Alles klar" (32), Feedback-Text 14 → 16 px. */
  .wartung-banner .wb-x { min-width: 44px; min-height: 44px; }
  .fb-intro-btn { min-height: 44px; padding-left: 18px; padding-right: 18px; }
  #fb-text { font-size: 16px; }
  /* Fenster „Passwort setzen" (Benutzerverwaltung): 15 px als Inline-Stil. */
  #rp-pw { font-size: 16px !important; }

  /* Tour und Einrichtung: ✕ 34×34 → 44×44 (Mass als Inline-Stil), die Text-Verweise („überspringen",
     „← zurück") bekommen 44 px Flaeche; der negative Rand gibt die zusaetzliche Hoehe zurueck — die Karte
     ist bei 360×740 schon knapp. */
  #tour-close, #einr-close { width: 44px !important; height: 44px !important; top: 8px !important; right: 8px !important; }
  #tour-wrap span[onclick], #einr-wrap span[onclick] { display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px; margin: -12px 0 -10px; }
}

/* ── HANDY-FEINSCHLIFF, BLOCK 2 · Tab-Leiste, „Mehr", Hell/Dunkel, die Lampe (08.10.2026) ────────────────────

   (1) HELL / DUNKEL: zwei Haelften statt eines Knopfs, der den Zustand nannte (M4 — auch am PC; core.js
       themaAnzeigen). Die geltende Haelfte ist die helle Platte. Aussen so hoch wie der Knopf vorher (39 px),
       damit die Seitenleiste am PC nicht waechst (pruef-blatt-ausgang.js misst sie mit Erinnerungskarte).
       Schrift der anderen Haelfte: Weiss .66 auf #152735 = 7,4:1. */
.thema-wahl { display: flex; gap: 3px; width: 100%; box-sizing: border-box; margin-bottom: 10px; padding: 3px; border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.06); }
.thema-halb { flex: 1 1 0; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 6px 8px; border: 0; border-radius: 7px;
  background: transparent; color: rgba(255,255,255,0.66); font-size: 13px; font-weight: 600; font-family: inherit; cursor: pointer; transition: background .15s, color .15s; }
.thema-halb[aria-pressed="true"] { background: rgba(255,255,255,0.17); color: #fff; box-shadow: inset 0 0 0 1px rgba(255,255,255,0.20); }
.thema-halb:focus-visible { outline: 2px solid #C8A44D; outline-offset: 1px; }
/* (2) Zeile „Mein Konto" — am PC wie bisher (Name, Rolle, Stift); Titel und Pfeil gibt es nur im „Mehr"-Blatt. */
.user-titel, .user-pfeil { display: none; }

@media (max-width: 768px) {
  /* (3) TAB-LEISTE: Beschriftung 10 → 12 px (Apple nennt 11 pt als Untergrenze; unter 12 px ist am Handy nichts
         mehr). Welcher Tab gilt, setzt core.js (mtabSyncActive: .active + aria-current). */
  /* Feste Zeilenhoehe (10.10.2026): mit 12 px Schrift und line-height „normal" wurde der Tab 52 statt 50 px hoch
         und die Leiste 61 statt 59 px — alles, was „59 px ueber dem Rand" steht (Leiste der Sitzung, „Zurück /
         Weiter", Startknopf), ragte seit dem 08.10. 2 px in die Tabs (gegen live gemessen von pruef-handy-leiste.js:
         unten 785, Tabs ab 783). 6 + 21 (Zeichen) + 3 + 14 (Wort) + 6 = 50: die Leiste ist wieder 59 px hoch, und
         zwar in jeder Schrift — „normal" haengt an der Schriftdatei. Gemessen: lokal/pruef-sitzung-leiste.js L7. */
  .mtab-btn { font-size: 12px; line-height: 14px; }

  /* (4) „MEHR"-BLATT: nur, was unten KEINEN Tab hat. Dialer, Kalender und Wettbewerb standen doppelt da — im
         Blatt hiess der Dialer zudem „Rufon", unten „Dialer". !important, weil core.js die Punkte je nach Rolle
         mit einem Inline-Stil ein- und ausblendet. Mit ein bis drei Punkten brauchen sie keine Ueberschrift
         („Telefonie", „Verwaltung": 10 px Versalien, 2,5:1) und Leitfaeden keinen Einzug als Unterpunkt. */
  .sidebar #nav-dialer, .sidebar #nav-kalender, .sidebar #nav-wettbewerb { display: none !important; }
  .sidebar .nav-section { display: none; }
  .sidebar .nav-sub { padding-left: 14px; margin-left: 0; border-left: 0; font-size: 14px; border-radius: var(--radius-sm); }
  .sidebar .nav-sub .nav-icon { font-size: 17px; width: 22px; }
  .sidebar .nav-verwaltung { margin-top: 0; border-top: 0; padding-top: 0; }
  /* „Mein Konto" als Zeile mit dem Namen darunter (vorher der Name mit einem Stift — dass dahinter das
     Konto liegt, sagte nur der Tooltip, den es am Handy nicht gibt). */
  .sidebar .user-pill { min-height: 52px; box-sizing: border-box; }
  .sidebar .user-titel { display: block; font-size: 14px; font-weight: 700; color: #fff; }
  .sidebar .user-name { font-size: 12px; font-weight: 500; color: rgba(255,255,255,0.72); }
  .sidebar .user-role, .sidebar .user-stift { display: none; }
  .sidebar .user-pfeil { display: block; margin-left: auto; flex-shrink: 0; font-size: 22px; line-height: 1; color: rgba(255,255,255,0.6); }

  /* (5) DIE LAMPE gibt es am Handy NICHT mehr (Nacharbeit 08.10.2026, Entscheidung des Auftraggebers; Begruendung
         und Messwerte in feedback.js bei fbMehrZeile). Sie schwebte ueber rollendem Inhalt und lag je nach Rollstand
         auf „⋯", „Abmelden" oder einem Namen; ein Versuch, sie ausweichen zu lassen, kostete beim Rollen Rechenzeit
         und liess sie blinken. Stattdessen steht im „Mehr"-Blatt die Zeile „💡 Rückmeldung geben" (.mehr-zeile,
         von feedback.js eingesetzt) — gebaut wie die Menuepunkte darueber, 44 px hoch. Am PC (ab 769 px) bleibt die
         Lampe, wie sie war: schwebend, 52 × 52, verschiebbar. Kein !important noetig: core.js (fabSichtbarkeit)
         setzt am Knopf nur display:none oder nimmt den Inline-Stil weg. */
  #feedback-fab { display: none; }
  .sidebar .mehr-zeile { display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box; min-height: 44px; padding: 11px 14px; margin: 0 0 2px;
    border: 0; border-radius: var(--radius-sm); background: none; color: rgba(255,255,255,0.62); font-family: inherit; font-size: 14px; font-weight: 500;
    text-align: left; cursor: pointer; }
  .sidebar .mehr-zeile:focus-visible { outline: 2px solid #C8A44D; outline-offset: -2px; }
  /* Der Einmal-Hinweis („Neu: Feedback & Ideen") zeigte mit seinem Pfeil auf die Lampe. Am Handy sagt er jetzt,
     wo die Rueckmeldung liegt, und steht direkt ueber der Tab-Leiste — sein Pfeil (24 px vom rechten Rand der
     Karte) zeigt auf den Tab „Mehr" ganz rechts. */
  .fb-intro-card { bottom: calc(72px + env(safe-area-inset-bottom)); }
  .fb-intro-text .fb-intro-pc { display: none; }
  .fb-intro-text .fb-intro-handy { display: inline; }
}
/* Am PC gibt es die Zeile nicht (dort schwebt die Lampe) und der Einmal-Hinweis traegt seinen bisherigen Satz. */
.mehr-zeile, .fb-intro-handy { display: none; }

/* ── HANDY-FEINSCHLIFF, BLOCK 3 · Schrift und Darstellung am Handy (08.10.2026) ──────────────────────────────

   (1) LEITFAEDEN: der Name stand neben zwei Knoepfen und war nach 14 Zeichen gekappt („Kaltakquise Hand…").
       Am Handy steht er zweizeilig ueber den Knoepfen; am PC wie bisher eine Zeile (die Regel stand vorher als
       Inline-Stil an der Zeile, leitfaeden.js lfsRender). */
.lfs-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 768px) {
  .lfs-zeile { flex-wrap: wrap; }
  .lfs-zeile > .lfs-text { flex: 1 1 100% !important; }
  .lfs-name { white-space: normal; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
  .lfs-zeile > .btn { flex: 1 1 0; justify-content: center; }

  /* (2) DAS DATUM UNTEN: stand allein unter jeder Seite (11 px, 3,46:1) und sagte nichts, was das Handy nicht in
         der Statusleiste zeigt. Am Handy ist es nicht mehr zu sehen; am PC bleibt es (Entscheidung des Betreibers).
         visibility statt display: der Kasten (37 px) bleibt als Luft am Seitenende stehen. Ein erster Versuch
         mit display:none rueckte die letzten Knoepfe jeder Seite 37 px tiefer — unter die Meldung „Neue Version"
         („Aktivieren" 28 px Trefferflaeche, gemessen) und der letzte Eintrag der Duell-Auswahl war angeschnitten. */
  footer { visibility: hidden; }

  /* (3) KEINE SCHRIFT UNTER 12 PX. Apple nennt 11 pt als Untergrenze; gemessen waren am 08.10. 10–11,5 px an gut
         40 Stellen (Etiketten, Unterzeilen, Abzeichen). Viele tragen ihr Mass als Inline-Stil — die erste Regel
         faengt jede davon ueber den Wortlaut des Stils (auch kuenftige), die Liste darunter die Klassen.
         Nur die GROESSE: Farben bleiben, wie Welle 1 („lesbar") sie gesetzt hat. */
  [style*="font-size:9px"], [style*="font-size: 9px"], [style*="font-size:9.5px"], [style*="font-size: 9.5px"],
  [style*="font-size:10px"], [style*="font-size: 10px"], [style*="font-size:10.5px"], [style*="font-size: 10.5px"],
  [style*="font-size:11px"], [style*="font-size: 11px"], [style*="font-size:11.5px"], [style*="font-size: 11.5px"] { font-size: 12px !important; }
  #profil-extension-hinweis, #dialer-progress-text, #dialer-score-hint, #dialer-contact-note-wrap, #buchung-titel,
  .oc-sub, .oc-val, .metric-label, .kal-art, .kal-label, .ml-meta, .dflow-names span, .sidebar-legal, .sidebar-legal a,
  .login-logo p, .logo-text p, .main th, .topbar .btn, .iqub-sub { font-size: 12px !important; }

  /* (4) ETIKETTEN ALS SATZ statt Versalien (W14, bedienung-handy.md): „TAG", „UHRZEIT", „ERGEBNIS DES ANRUFS",
         „KONTAKTE GESAMT", „TERMIN"/„RÜCKRUF" … — Versalien in 10 px sind am schwersten zu lesen, und VoiceOver
         buchstabiert manche. Normale Schreibweise, ohne gesperrte Buchstaben. */
  [style*="text-transform:uppercase"], [style*="text-transform: uppercase"] { text-transform: none !important; letter-spacing: normal !important; }
  .metric-label, .kal-art, .kal-label, #buchung-titel, .main th { text-transform: none !important; letter-spacing: normal !important; }
  /* … und die Etiketten, die eine Stildatei SETZT (Pseudo-Elemente — in keinem Textknoten zu finden): die
     Benutzer-Karten am Handy („NAME", „E-MAIL", „DURCHWAHL", … 11 px Versalien aus attr(data-label)) und der
     Hinweis „ⓘ Spielregeln" an der Flammen-Platte in Klassik (9,5 px). */
  .user-table td::before { font-size: 12px; text-transform: none; letter-spacing: normal; }
  #page-dialer #dialer-heat-box::after { font-size: 12px; }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════════════════
   FARBEN DER GANZEN APP (08.10.2026, Paket Farben; Durchsicht vom 04.10.2026, W1–W3, W5, W6, W12).
   Gemessen im GEMALTEN Bild — jede Ansicht, hell und dunkel, Chromium und WebKit, Handy 390×844 und PC 1280×900:
   intern/werkzeuge/lokal/pruef-farben-app.js (dort stehen die Messwerte vorher/nachher und die Gegenprobe).
   Hier stehen NUR Farben; nichts aendert, wo etwas steht. Die Variablen dazu (--text3, --red-text, --amber-text,
   --purple-text, --platzhalter) stehen oben in :root und body.dark.
   Als eigener Block und als Ueberschreibung, damit die Regeln der anderen Pakete an ihrer Stelle unberuehrt bleiben.
   ══════════════════════════════════════════════════════════════════════════════════════════════════════════ */

/* (1) PLATZHALTER (W3). Ohne Regel malt jeder Browser sein eigenes Grau: WebKit hell 2,1–2,4:1, Chromium hell
   4,15–4,3:1, Chromium dunkel 2,9–3,6:1. opacity: 1, weil Firefox Platzhalter von sich aus daempft.
   Der Dialer behaelt seine eigenen (glass.css 26 (3), hoehere Spezifitaet). */
input::placeholder, textarea::placeholder { color: var(--platzhalter); opacity: 1; }

/* (2) ROT ALS SCHRIFT (W2): Fehlerkasten der Anmeldung / 2FA / Passwort setzen und die drei Abmelde-Gruende
   3,61:1, „Löschen" und „Zweiten Schritt ausschalten" 4,05:1, „noch 3 Tage" im Testphasen-Streifen 3,37:1.
   Flaechen und Raender bleiben --red. */
.login-error, .btn-danger, .btn-danger-ghost, .btn-danger-ghost:hover, .badge-missed,
.status-bar.err, body.dark .status-bar.err,
.testphase-streifen.tp-knapp .tp-rest, .testphase-streifen .tp-cta { color: var(--red-text); }
/* Rot, das ein Element im style-Attribut traegt („Löschen" in Leitfäden und Auskunft, die Fehlerzeilen der
   Fenster, „Konto löschen"): die Regel greift am Attribut, nicht an der Lage — so ueberlebt sie einen Umbau des
   Markups und braucht keinen Eingriff in die Skripte. Sie greift nur, wo `color` SELBST steht (am Anfang, nach
   „;" oder nach einem Leerzeichen; im Markup ohne, vom Skript gesetzt mit Leerzeichen nach dem Doppelpunkt) —
   nicht bei border-color/background-color (z. B. der rote Knopf „Ausschalten" mit weisser Schrift). */
:is([style^="color:var(--red)"], [style*=";color:var(--red)"], [style*=" color:var(--red)"],
    [style^="color: var(--red)"], [style*="; color: var(--red)"],
    [style^="color:var(--red,"], [style*=";color:var(--red,"], [style*=" color:var(--red,"],   /* mit Ersatzwert: var(--red,#dc2626) */
    [style^="color:#dc2626"], [style*=";color:#dc2626"], [style*=" color:#dc2626"]) { color: var(--red-text) !important; }

/* (3) DIE HUELLE BLEIBT IMMER HELL (W5; Betreiber-Entscheid: die Anmeldung hat keinen Dunkelmodus).
   Anmeldung, Vertragswand, Tour und Einrichtung teilen EINE Huelle (.login-wrap, fester heller Verlauf) mit einer
   Karte (.login-card, var(--bg2)). Im Dunkelmodus wurde die Karte dunkel, der Grund blieb hell — gemessen
   04./08.10.2026: Karte #12293f auf dem hellen Verlauf in allen Tour- und Einrichtungs-Schritten, in der Anmeldung
   nach doLogout()/Rauswurf ohne Neuladen; Platzhalter darin 3,2–3,6:1.
   Weg b der Durchsicht (wie Paket „lesbar" fuer die Glas-Sitzung): die Huelle bekommt den HELLEN Variablensatz fest —
   die Werte von :root und html.call; wer dort einen Wert aendert, aendert ihn hier mit. `color` steht dabei, weil
   die Schriftfarbe von body geerbt wird (als fertige Farbe, nicht als Variable).
   Die Anmeldung selbst traegt body.dark seit dem 08.10.2026 gar nicht mehr (core.js themaHuelle); diese Regel haelt
   Tour, Einrichtung und Vertragswand hell, die UEBER der dunklen App liegen. */
body.dark .login-wrap {
  --bg: #f4f6fb; --bg2: #ffffff; --bg3: #f0f3fa; --bg4: #e8edf8;
  --border: rgba(99,120,200,0.1); --border2: rgba(99,120,200,0.22);
  --text: #141830; --text2: #5a6490; --text3: #5f677a;
  --accent: #051C2C; --accent2: #0a3352; --accent-light: #eef2f6; --accent-ink: #ffffff;
  --green: #0ea579; --green-bg: #e8f8f3; --green-text: #0a7a59;
  --red: #e53e5e; --red-text: #b91c3c; --red-bg: #fdeef2;
  --amber: #d97706; --amber-text: #92400e; --amber-bg: #fef3e2;
  --purple: #C8A44D; --purple-text: #7a5f1c; --purple-bg: #eff8fe;
  --platzhalter: #646c80; --kal-warn: #b45309;
  --shadow: 0 2px 12px rgba(5,28,44,0.07), 0 1px 3px rgba(0,0,0,0.05);
  --shadow-lg: 0 8px 30px rgba(5,28,44,0.12), 0 2px 8px rgba(0,0,0,0.06);
  color: var(--text);
  color-scheme: light;
}
/* „body.dark .login-hinweis" (oben) liest das HELLE Bernstein des Dunkelmodus — in der hellen Huelle 2,9:1. */
body.dark .login-wrap .login-hinweis { color: var(--amber-text); }
body.dark .login-wrap .login-hinweis.bereit { color: var(--green-text); }
/* Der Testphasen-Streifen (z-index 1, damit er ueber dem Grund der Designs liegt) lag am PC UEBER Tour und
   Einrichtung: deren Huelle hatte dort keinen z-index (am Handy seit Paket Handy-Feinschliff 900). 2 legt sie ueber
   den Streifen, den Einrichtungs-Hinweis und die Fusszeile — und laesst sie UNTER der Seitenleiste (100), wie dort
   begruendet (pruef-kalender-tempo.js klickt „Kalender", waehrend die Tour offen ist). */
@media (min-width: 769px) { #tour-wrap, #einr-wrap { z-index: 2; } }

/* (4) color-scheme (W12): damit malt der Browser SEINE Teile passend — Auswahllisten, Datums- und Zeitwaehler,
   Bildlaufleisten, die Schreibmarke. Vorher fehlte die Angabe ganz: im Dunkelmodus blieben sie hell.
   Die Huelle oben und die helle Glas-Sitzung (glass.css Abschnitt 26 (1)) bleiben light. */
:root { color-scheme: light; }
body.dark { color-scheme: dark; }

/* (5) SEITENLEISTE / BLATT „MEHR": die festen Weiss-Toene der Nebentexte. Am PC stehen sie in JEDER Ansicht:
   Abschnittsnamen („TELEFONIE") Weiss .28 = 2,47:1, „Impressum · Datenschutz · AGB" .34 = 3,01:1, „Der Power-Dialer"
   und die Rolle unter dem Namen .42 = 3,85:1 (auf #152735; im Dunklen auf #071b2e praktisch gleich).
   .52 ergibt gerechnet 5,2:1 (hell) / 5,5:1 (dunkel); die Menuezeilen bleiben mit .62 darueber, der Zeiger
   darueber (.72) und „Kontrast erhöhen" (Weiss) auch. */
.logo-text p, .user-role, .nav-section, .sidebar-legal a { color: rgba(255,255,255,.52); }

/* (6) GOLD, BERNSTEIN, GRUEN NUR ALS FLAECHE — als Schrift die dunkle Fassung (W6).
   · Gold: --purple ist seit dem Markenwechsel Gold; als Schrift 2,15–2,20:1 (Rolle „Inhaber", Durchwahl-Marke
     der Benutzerliste). Die Durchwahl-Marke traegt #C8A44D im style-Attribut (cx-users.js).
   · Bernstein: --amber auf --amber-bg 2,90:1 („Nicht konfiguriert", „Dein Plan", Hinweise in Fenstern). Greift am
     style-Attribut, in beiden Schreibweisen (im Markup ohne, vom Skript gesetzt mit Leerzeichen), und nur wo
     `color` selbst steht (Anfang, nach „;" oder Leerzeichen) — nicht bei border-color/background-color.
     Die laufende Sitzung ist ausgenommen: dort hat Paket „lesbar" je Stelle eigene, staerkere Werte gemessen
     (glass.css Abschnitt 26 (4), (8)).
   · Gruener Hinweis der Anmeldung: --green-text hat allein 4,86:1, mit opacity .8 waren es 3,42:1.
   · „Alles klar" am Feedback-Hinweis: Weiss auf --accent — im Dunkelmodus ist --accent Gold (2,37:1).
     --accent-ink ist hell Weiss (auf Navy), dunkel Navy (auf Gold).
   · „Keine Verbindung zum Server": Weiss auf Bernstein 3,19:1. Die Flaeche bleibt (dieselbe Farbe wie der
     Stoerungshinweis der Anmeldung), die Schrift wird Navy — gerechnet 5,45:1. Die Wartungs-Fassung (Navy mit
     Weiss, .vw-wartung) gewinnt weiter ueber ihre hoehere Spezifitaet. */
.badge-voicemail, .cx-role-owner { color: var(--purple-text); }
[style^="color:#C8A44D"], [style*=";color:#C8A44D"] { color: var(--purple-text) !important; }
.count-chip.voll { color: var(--amber-text); }
:is([style^="color:var(--amber)"], [style*=";color:var(--amber)"], [style*=" color:var(--amber)"],
    [style^="color: var(--amber)"], [style*="; color: var(--amber)"]):not(#dialer-active *) { color: var(--amber-text) !important; }
.login-weiter p.klein { opacity: 1; }
.fb-intro-btn { color: var(--accent-ink); }
#verbindung-weg { color: #051C2C !important; }
/* Duell im Wettbewerb, dunkel: die Karte des Fuehrenden ist gruen getoent und damit heller als --bg2 —
   --green-text #0ea579 stand dort mit „führt" (12 px) bei 3,84:1. Eine Stufe heller, nur in dieser Karte. */
body.dark #wb-duel-result { --green-text: #34d399; }

/* ── HANDY-FEINSCHLIFF, BLOCK 4 · Bedienungshilfen des Systems (08.10.2026; Apple-Abgleich V10, Durchsicht vom
   04.10. W10 und W11). Gemessen am 04.10.: „Kontrast erhöhen" aenderte in 0 von 80 Laeufen irgendetwas,
   „Transparenz reduzieren" in 0 von 48; fuer die Aussparung im Querformat gab es keine einzige Regel.

   (1) KONTRAST ERHOEHEN (prefers-contrast: more) — in der GANZEN App, in allen drei Designs, hell und dunkel:
       · Nebentexte tragen die volle Schriftfarbe: --text2 und --text3 werden zu --text (wie in legal.css seit
         dem 04.10. fuer die Rechtstexte). Gesetzt an JEDEM Element (*): die Designs belegen die Variablen an
         #page-dialer, #dialer-active und einzelnen Feldern neu — eine Regel an :root kaeme dort nicht an.
         !important gewinnt gegen jede dieser Belegungen, ohne ihre Selektoren zu kennen.
       · Raender werden sichtbar: --border/--border2 aus der Schriftfarbe des Ortes gemischt (60 % / 80 %) —
         passt so von selbst zu hell, dunkel und zur Glas-Sitzung (deren Rand sonst eine WEISSE Lichtkante ist).
         Kennt ein Browser color-mix nicht, faellt der Rand auf die Schriftfarbe zurueck (currentColor) — auch gut.
       · Die Seitenleiste / das „Mehr"-Blatt traegt feste Weiss-Toene (.28 bis .62): dort Weiss.
       · Der geltende Tab bekommt zusaetzlich einen Strich (Farbe allein reicht bei erhoehtem Kontrast nicht).
       Farben der Marke und der Ergebnis-Knoepfe bleiben (Paket „farben-app"). */
@media (prefers-contrast: more) {
  *, *::before, *::after {
    --text2: var(--text) !important; --text3: var(--text) !important;
    --border: color-mix(in srgb, var(--text) 60%, transparent) !important;
    --border2: color-mix(in srgb, var(--text) 80%, transparent) !important;
  }
  .sidebar .nav-item, .sidebar .mehr-zeile, .sidebar .btn-logout, .sidebar-legal, .sidebar-legal a, .sidebar .logo-text p, .sidebar .nav-section,
  .sidebar .user-role, .sidebar .user-name, .sidebar .user-pfeil, .sidebar .thema-halb { color: #fff !important; }
  .sidebar .btn-logout, .sidebar .thema-wahl, .sidebar .user-pill { border: 1.5px solid rgba(255,255,255,.8) !important; }
  .sidebar .thema-halb[aria-pressed="true"] { box-shadow: inset 0 0 0 2px #fff; }
  /* Der Strich ist 1 px dicker als sonst — das Polster darunter gibt den Pixel zurueck (10.10.2026): die Leiste
     bleibt 59 px hoch, sonst ragten die festen Leisten darueber bei erhoehtem Kontrast 1 px hinein. */
  .mtab { border-top: 2px solid var(--text); padding-top: 3px; }
  .mtab-btn[aria-current] { box-shadow: inset 0 3px 0 currentColor; }
}

/* (2) TRANSPARENZ REDUZIEREN (prefers-reduced-transparency: reduce): keine Unschaerfe mehr, die Flaechen des
       Glas-Designs werden deckend (ihre Variablen stehen am Ende von glass.css), der Schleier hinter Fenstern
       und hinter „Mehr" wird dafuer dunkler (ohne Unschaerfe traegt er sonst zu wenig).
       Safari kennt diese Abfrage NICHT (gemessen 04.10., WebKit) — am iPhone wirkt nur „Kontrast erhöhen".
       Deshalb gilt alles hier AUCH unter prefers-contrast: more; so hat das iPhone einen Weg zum deckenden Bild. */
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  *, *::before, *::after { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
  .modal-overlay { background: rgba(0,0,0,0.55); }
  .app-wrap.nav-open .nav-scrim { background: rgba(10,18,25,.66); }
}

/* (3) QUERFORMAT MIT AUSSPARUNG (env(safe-area-inset-left/right), W11). Ein iPhone quer ist breiter als 768 px
       — es zeigt die PC-Anordnung, und die Aussparung liegt links oder rechts: Markenzeichen und Menue lagen
       darunter, rechts die Knoepfe am Rand. Ohne Aussparung ist env() 0 und nichts aendert sich.
       · Seitenleiste: um die linke Aussparung breiter, ihr Inhalt rueckt ein; der Hauptbereich beginnt dahinter.
       · Hauptbereich: rechts (am Handy auch links) ein durchsichtiger Rand in Breite der Aussparung — so muss
         keine Regel die Polster der einzelnen Breiten kennen, und die Rolleiste rueckt mit ein.
       · Feste Leisten (Tabs, Sitzung, Buchungsblatt) reichen weiter von Rand zu Rand, ihr INHALT rueckt ein.
       · Die Lampe rueckt von der rechten Aussparung weg. */
.sidebar { border-left: env(safe-area-inset-left, 0px) solid transparent; }
#feedback-fab { right: calc(22px + env(safe-area-inset-right, 0px)); }
@media (min-width: 769px) {
  .sidebar { width: calc(240px + env(safe-area-inset-left, 0px)); }
  .main { margin-left: calc(240px + env(safe-area-inset-left, 0px)); border-right: env(safe-area-inset-right, 0px) solid transparent; }
  #status-box { left: calc(276px + env(safe-area-inset-left, 0px)); }
}
@media (max-width: 768px) {
  .sidebar { border-left: 0; padding-left: calc(0.9rem + env(safe-area-inset-left, 0px)); padding-right: calc(0.9rem + env(safe-area-inset-right, 0px)); }
  .main { border-left: env(safe-area-inset-left, 0px) solid transparent; border-right: env(safe-area-inset-right, 0px) solid transparent; }
  .mtab { padding-left: calc(4px + env(safe-area-inset-left, 0px)); padding-right: calc(4px + env(safe-area-inset-right, 0px)); }
  #page-dialer #dialer-active #sitzung-leiste { padding-left: calc(12px + env(safe-area-inset-left, 0px)) !important; padding-right: calc(12px + env(safe-area-inset-right, 0px)) !important; }
  #buchung.blatt { padding-left: calc(14px + env(safe-area-inset-left, 0px)); padding-right: calc(14px + env(safe-area-inset-right, 0px)); }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════════════════
   NEU IN RUFON (12.10.2026) — die Einmal-Ansicht (ohne Menue-Eintrag seit 16.10.2026). Was sie tut und wann sie
   erscheint, steht in js/neu.js; hier steht, wie sie aussieht und sich bewegt.
   Gemessen von intern/werkzeuge/lokal/pruef-neu-in-rufon.js (Lage, Zeiten der Bewegung, Farben im gemalten Bild).
   Als eigener Block am Ende, damit die Regeln der anderen Pakete an ihrer Stelle unberuehrt bleiben.
   ══════════════════════════════════════════════════════════════════════════════════════════════════════════ */

/* (1) DIE ANSICHT — das Fenster der App (.modal, am Handy das Blatt von unten: Regeln weiter oben bei „FENSTER AM
   HANDY") mit eigenem Inhalt. Farben nur ueber die Variablen der App, damit sie hell und dunkel dem Thema der APP
   folgt: Monat = Gold als SCHRIFT (--purple-text), Kachel = Navy (--accent; im Dunkeln die tiefste Flaeche --bg,
   dort ist --accent Gold), Symbol = Gold als Linie (--purple), Saetze --text2, der Knopf ist der
   Hauptknopf der App (btn-primary). */
.modal.neu-fenster { max-width: 480px; padding: 34px 36px 26px; border-radius: 24px; }
.neu-monat { font-size: 13px; line-height: 1.3; font-weight: 700; letter-spacing: .02em; color: var(--purple-text); }
.neu-titel { margin: 4px 0 0; font-size: 28px; line-height: 1.15; font-weight: 800; letter-spacing: -.01em; color: var(--text); }
.neu-linie { display: block; height: 2px; margin: 14px 0 22px; border-radius: 1px; background: linear-gradient(90deg, var(--purple), transparent 88%); transform-origin: left center; }
.neu-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 22px; }
.neu-punkt { display: flex; gap: 16px; align-items: flex-start; }
.neu-kachel { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px; background: var(--accent); color: var(--purple); }
body.dark .neu-kachel { background: var(--bg); box-shadow: inset 0 0 0 1px var(--border2); }
.neu-kachel svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.neu-text { flex: 1 1 auto; min-width: 0; }
.neu-zeile { display: block; margin-bottom: 3px; font-size: 16px; line-height: 1.3; font-weight: 700; color: var(--text); }
.neu-satz { display: block; font-size: 15px; line-height: 1.45; color: var(--text2); }
.btn.neu-weiter { position: relative; overflow: hidden; width: 100%; min-height: 50px; margin-top: 30px; justify-content: center; border-radius: 999px; font-size: 16px; font-weight: 700; }
@media (max-width: 768px) {
  .modal-overlay > .modal.neu-fenster { padding: 8px 22px calc(22px + env(safe-area-inset-bottom)); border-radius: 24px 24px 0 0; }
  .neu-linie { display: none; }            /* die goldene Linie ist eine Zugabe des PCs */
  .neu-liste { margin-top: 24px; }
  .neu-monat { margin-top: 6px; }
}

/* (2) BEWEGUNG AM PC (ab 769 px; Betreiber 12.10.2026: „gern mehr Animation am PC"). Zusammen 1,24 s, nur
   transform / opacity / stroke-dashoffset, alles laeuft genau EINMAL und hinterlaesst nichts (fill „backwards":
   nach dem Ende gilt wieder die Regel von oben — jede Lage ist dieselbe wie ohne Bewegung). Der Knopf ist vom
   ersten Bild an da und bedienbar; er wird nur als Letztes eingeblendet.
     0 ms   Schleier blendet ein (240) · das Fenster kommt mit einer kleinen Feder (440; von 22 px tiefer und 96 %)
   140 ms   Monat gleitet nach (300) · 200 ms Ueberschrift (340)
   380 ms   die goldene Linie zieht sich von links auf (400)
   440 ms   Punkt 1 (360), seine Kachel springt auf (420), ab 520 zeichnet sich das Symbol (440)
   570 ms   Punkt 2 · 700 ms Punkt 3 (je 130 ms versetzt; das dritte Symbol ist bei 1220 ms fertig)
   760 ms   „Weiter" (280) · 900 ms laeuft einmal ein Glanz ueber den Knopf (340)
   Dazu kommt, was der Browser braucht, bis er die Bewegung anwirft (gemessen im Pruefbrowser: rund 50 ms).
   Schliessen: das Fenster zieht sich 160 ms zurueck (neu.js wartet darauf, hoechstens 260 ms). */
@keyframes neuEin { from { opacity: 0; } to { opacity: 1; } }
@keyframes neuAus { from { opacity: 1; } to { opacity: 0; } }
@keyframes neuFeder { 0% { opacity: 0; transform: translateY(22px) scale(.96); } 62% { opacity: 1; transform: translateY(-3px) scale(1.006); } 100% { opacity: 1; transform: none; } }
@keyframes neuGleiten { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes neuLinie { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes neuSprung { 0% { transform: scale(.5); } 60% { transform: scale(1.12); } 100% { transform: none; } }
@keyframes neuZeichnen { from { stroke-dasharray: 1 2; stroke-dashoffset: 1; } to { stroke-dasharray: 1 2; stroke-dashoffset: 0; } }
@keyframes neuGlanz { from { opacity: 1; transform: translateX(-130%) skewX(-18deg); } to { opacity: 1; transform: translateX(330%) skewX(-18deg); } }
@keyframes neuZurueck { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(6px) scale(.97); } }
@media (min-width: 769px) and (prefers-reduced-motion: no-preference) {
  .modal-overlay.neu-schleier { animation: neuEin .24s ease-out backwards; }
  .modal.neu-fenster { animation: neuFeder .44s cubic-bezier(.2,.8,.2,1) backwards; }
  .neu-fenster .neu-monat { animation: neuGleiten .30s var(--ease-out) .14s backwards; }
  .neu-fenster .neu-titel { animation: neuGleiten .34s var(--ease-out) .20s backwards; }
  .neu-fenster .neu-linie { animation: neuLinie .40s var(--ease-out) .38s backwards; }
  .neu-fenster .neu-punkt { animation: neuGleiten .36s var(--ease-out) calc(.44s + var(--neu-i, 0) * .13s) backwards; }
  .neu-fenster .neu-kachel { animation: neuSprung .42s cubic-bezier(.3,1.3,.5,1) calc(.44s + var(--neu-i, 0) * .13s) backwards; transition: transform .18s var(--ease-out); }
  .neu-fenster .neu-kachel svg > * { animation: neuZeichnen .44s ease-in-out calc(.52s + var(--neu-i, 0) * .13s) backwards; }
  .neu-fenster .neu-weiter { animation: neuGleiten .28s var(--ease-out) .76s backwards; }
  /* Der Glanz: ein schmaler heller Streifen, in Ruhe nicht da (opacity 0), laeuft einmal von links nach rechts. */
  .neu-fenster .neu-weiter::after { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 34%; pointer-events: none; opacity: 0;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,.5), transparent); animation: neuGlanz .34s ease-in-out .90s backwards; }
  /* Unter dem Zeiger hebt sich die Kachel der Zeile leicht. */
  @media (hover: hover) { .neu-fenster .neu-punkt:hover .neu-kachel { transform: translateY(-2px) scale(1.05); } }
  .modal-overlay.neu-schleier.neu-geht { animation: neuAus .16s ease-in forwards; }
  .neu-schleier.neu-geht > .modal.neu-fenster { animation: neuZurueck .16s ease-in forwards; }
}
/* AM HANDY: das Blatt kommt von unten wie die anderen Blaetter (blattHoch, oben), die Punkte kurz versetzt
   eingeblendet — mehr nicht (keine Linie, kein Sprung, kein Zeichnen, kein Glanz, kein Zurueckziehen). */
@media (max-width: 768px) and (prefers-reduced-motion: no-preference) {
  .neu-fenster .neu-punkt { animation: neuEin .22s ease-out calc(.10s + var(--neu-i, 0) * .07s) backwards; }
}
/* „BEWEGUNG REDUZIEREN": nur ein kurzes Einblenden der ganzen Ansicht — keine Verschiebung, kein Zeichnen, kein
   Glanz. Die allgemeine Regel oben kuerzt jede Bewegung auf 0,01 ms; das Einblenden bekommt seine Dauer hier
   ausdruecklich zurueck (hoehere Spezifitaet, beide !important). */
@media (prefers-reduced-motion: reduce) {
  .modal-overlay.neu-schleier { animation: neuEin .16s linear backwards !important; animation-duration: .16s !important; }
  .modal-overlay > .modal.neu-fenster, .neu-fenster *, .neu-fenster *::before, .neu-fenster *::after { animation: none !important; transition: none !important; }
}

/* ══ LADEN — EIN SATZ BAUSTEINE FUER DIE GANZE APP (14.10.2026, Paket laden) ══════════════════════════════════
   Betreiber 14.10.2026: „wenn man auf Weitermachen klickt, sollte die Erscheinungsseite mit dem Powerdialer
   gleichmäßig kommen … Und auch wenn was lädt ein einheitliches modernes Redesign fürs Laden." Gemessen vorher
   (lokal, jeder Aufruf 500 ms): nach dem Klick 1,1 s lang KEINE Rueckmeldung, dann kam die Sitzung in drei bis
   vier Schueben (leere Glas-Flaeche, Karte, 450 ms spaeter die Leiste, dann die Flammen — am Handy sprang dabei
   die Karte um 15–22 px). Und es gab drei verschiedene Arten zu warten: Pulsieren (Kalender, Meine Listen),
   ein Schimmer (.skel-*, nirgends benutzt) und das Wort „Lade …".
   Jetzt gibt es EINEN Satz, ueberall gleich:
     · der LEUCHTBALKEN oben (#lade-balken, core.js ladeBalkenHalten): erscheint, wenn ein Aufruf, auf den ein
       Mensch wartet, laenger als 250 ms braucht; laeuft gebremst auf 82 % und vollendet beim Fertigwerden,
     · das LADE-RAD IM KNOPF (.lade-rad, core.js knopfLaedt): der Text bleibt, wo er etwas sagt („Speichert …"),
       der Knopf traegt aria-busy und nimmt keinen zweiten Druck,
     · die PLATZHALTER-FLAECHE (.lade-flaeche + der eine Puls ladePuls): wo frueher „Lade …" stand oder eine Flaeche
       leer blieb — in der Form dessen, was gleich kommt,
     · die EINBLENDUNG (ladeAuf): 8 px aufsteigen und einblenden, Teile um 60 ms versetzt, EINE Kurve.
   Ideen aus einem anderen Projekt des Betreibers uebernommen (Balken, Rad im Knopf, Versatz, Kurve) — Farben und
   Formen sind Rufons (Gold, Navy, die drei Designs).
   BEWEGUNG REDUZIEREN: die allgemeine Regel oben kuerzt jede Animation auf 0,01 ms — es bleibt der Balken als
   Farbe (ohne Lauf), das Rad als stehender Ring, die Platzhalter ohne Puls, die Sitzung erscheint ohne Bewegung. */
:root {
  --lade-kurve: cubic-bezier(.16, .84, .24, 1);
  --lade-dauer: 300ms;
  --lade-versatz: 60ms;
  /* Platzhalter: ein Zehntel der Textfarbe — dieselbe Rechnung wie .ml-platz (02.10.2026): --bg3 ist in
     „Liquid Glass" fast weiss auf weiss. --bg3 bleibt der Wert fuer Browser ohne color-mix. */
  --lade-flaeche: var(--bg3);
}
/* Am Element selbst gerechnet, nicht an :root — sonst galte die Textfarbe der Wurzel auch im Dunkelmodus und in
   jedem Bereich, der --text fuer sich setzt. */
@supports (color: color-mix(in srgb, red 50%, blue)) { .lade-flaeche, .skel-el, .kal-platz span { --lade-flaeche: color-mix(in srgb, var(--text) 10%, transparent); } }
/* Die Einblendung beginnt bei .35, nicht bei 0 — dieselbe Lehre wie pageIn (01.08.2026): ab 0 ist der Schirm zwischen
   dem alten und dem neuen Bild einige Bilder lang LEER (gemessen 14.10.2026: 50–70 ms nichts zwischen Startseite und
   Sitzung). So ist der Inhalt ab dem ersten Bild da und setzt sich nur noch. */
@keyframes ladeAuf  { from { opacity: .35; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes ladeEin  { from { opacity: .35; } to { opacity: 1; } }
@keyframes ladePuls { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes ladeDreh { to { transform: rotate(360deg); } }

/* (1) Der Leuchtbalken. Fest oben ueber die volle Breite, 3 px hoch, nimmt keine Klicks an. Er liegt in den oberen
   3 px des Fensters — dort steht in keinem Design etwas Lesbares oder Bedienbares (die Erinnerung beginnt bei 8 px,
   Testphasen-Streifen und Wartungsankuendigung stehen in der Seite unter dem Polster von .main); nur der
   Verbindungsstreifen liegt ganz oben — ist er da, setzt core.js den Balken unter ihn (--lade-oben).
   Der Lauf: in 6 s gebremst auf 82 % (er sagt „es tut sich etwas", nicht „gleich fertig"), beim Fertigwerden in
   200 ms auf 100 % und weg. */
#lade-balken {
  position: fixed; z-index: 10050; top: var(--lade-oben, 0px); left: 0; right: 0; height: 3px;
  pointer-events: none; transform-origin: 0 50%; transform: scaleX(0); opacity: 0;
  background: linear-gradient(90deg, #8a6d22, #C8A44D 55%, #e3c77d);
  box-shadow: 0 0 10px rgba(200, 164, 77, .65), 0 0 2px rgba(200, 164, 77, .9);
}
#lade-balken.an { opacity: 1; transform: scaleX(.82); transition: transform 6s var(--lade-kurve), opacity .12s linear; }
#lade-balken.fertig { opacity: 0; transform: scaleX(1); transition: transform .2s ease-out, opacity .25s linear .15s; }
@media (prefers-reduced-motion: reduce) {
  /* Nur Farbe: der Balken steht in voller Breite, solange gewartet wird — kein Lauf, kein Ausgleiten. */
  #lade-balken.an { transform: scaleX(1); transition: none; }
  #lade-balken.fertig { transition: none; }
}

/* (2) Das Lade-Rad im Knopf: ein Ring in der Schriftfarbe des Knopfs (damit traegt er in jedem Design und Thema
   den Kontrast des Textes), vor dem Text. Groesse in em — er waechst mit der Schrift des Knopfs. */
.lade-rad {
  display: inline-block; flex: 0 0 auto; box-sizing: border-box; width: 1em; height: 1em; margin-right: .45em;
  vertical-align: -.16em; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent;
  animation: ladeDreh .7s linear infinite;
}
button.laedt, .laedt[role="button"] { cursor: progress !important; }
/* In Knoepfen mit gap (flex) waere der Abstand doppelt. */
.btn > .lade-rad { margin-right: 0; }
/* „Weitermachen" behaelt seine Breite: das Rad (1em + .45em Abstand) kommt aus dem seitlichen Polster. Der Knopf steht
   rechtsbuendig — ohne das wuchs er beim Klick am PC um 18 px nach links (Gegenpruefung 14.10.2026, alle drei Designs). */
.ml-weiter.laedt { padding-left: calc(18px - .725em); padding-right: calc(18px - .725em); }

/* (3) Platzhalter-Flaechen: EIN Aussehen, EIN Puls. Die bestehenden Platzhalter (Meine Listen, Kalender) ziehen
   dieselbe Farbe und denselben Puls (Regeln dort); .skel-* bekommt hier dasselbe Aussehen. */
.lade-flaeche { display: block; border-radius: 8px; background: var(--lade-flaeche); animation: ladePuls 1.2s ease-in-out infinite; }
.lade-flaeche.rund { border-radius: 50%; }
.skel-el { background: var(--lade-flaeche); animation: ladePuls 1.2s ease-in-out infinite; }
/* Zeilen-Platzhalter fuer Listen, die einen Satz „Lade …" ersetzen (Leitfaeden, Bestenliste, Teams, Duell):
   so hoch wie eine Zeile, die gleich kommt; fuer Vorleser steht der Satz im aria-label des Behaelters. */
.lade-zeilen { display: flex; flex-direction: column; gap: 10px; padding: 4px 0; }
.lade-zeilen > .lade-flaeche { height: 14px; }
.lade-zeilen > .lade-flaeche:nth-child(3n+1) { width: 72%; }
.lade-zeilen > .lade-flaeche:nth-child(3n+2) { width: 58%; }
.lade-zeilen > .lade-flaeche:nth-child(3n)   { width: 66%; }
.lade-zeilen.gross > .lade-flaeche { height: 44px; width: 100%; border-radius: 12px; }

/* (4) DIE SITZUNG AUS EINEM GUSS (dialer.js, dialerAufbau…). Waehrend der Aufbau laeuft, steht die Sitzung schon
   im Dokument und wird gemessen (Nummer einpassen, Leiste ausrichten) — aber unsichtbar und ausserhalb des
   Flusses, an genau der Stelle und in genau der Breite, die sie gleich einnimmt (--ds-l/--ds-o/--ds-b). Die
   Startseite bzw. der Platzhalter bleibt so lange stehen. */
/* position: fixed (Lage im Fenster), nicht absolute: ein absolut gesetztes Kind machte die Seite in Klassik 88 px hoeher —
   der Fuss mit dem Datum rutschte waehrend des Wartens unter den Rand (gemessen 14.10.2026). */
/* display von hier, nicht am Element: dort bleibt „display: none" stehen, bis gezeigt wird (dialer.js startDialerSession —
   an „display: flex" im style-Attribut haengen Regeln der Sitzung, die die Startseite veraendern wuerden). */
#page-dialer.ds-baut > #dialer-active {
  display: flex !important; position: fixed !important; left: var(--ds-l, 0px); top: var(--ds-o, 0px); width: var(--ds-b, 100%); box-sizing: border-box;
  visibility: hidden !important; pointer-events: none !important;
}
#page-dialer.ds-baut > #dialer-active * { visibility: hidden !important; }
/* Das Erscheinen: die Flaeche blendet ein, Kopf, Karte und Leiste steigen 8 px auf — um je 60 ms versetzt. NUR
   Deckkraft auf #dialer-active selbst: ein transform dort machte es fuer die Dauer der Animation zum Bezugsrahmen
   der festen Leiste (dieselbe Falle wie pageIn, 09.09.2026). .m-stack steigt als Ganzes (nicht die Karte allein:
   in Modern malt die Karte ihren Stapel mit z-index -1 — ein transform an ihr legte ihn VOR die Karte). Ist am
   Handy das Buchungsblatt offen (fest, in der Karte), steigt nichts (ds-ohne-weg). */
#dialer-active.ds-erscheint { animation: ladeEin calc(var(--lade-dauer) * .8) linear backwards; }
#dialer-active.ds-erscheint > :first-child { animation: ladeAuf var(--lade-dauer) var(--lade-kurve) backwards; }
#dialer-active.ds-erscheint > .m-stack { animation: ladeAuf var(--lade-dauer) var(--lade-kurve) var(--lade-versatz) backwards; }
#dialer-active.ds-erscheint > #sitzung-leiste { animation: ladeAuf var(--lade-dauer) var(--lade-kurve) calc(var(--lade-versatz) * 2) backwards; }
#dialer-active.ds-erscheint.ds-ohne-weg > :first-child,
#dialer-active.ds-erscheint.ds-ohne-weg > .m-stack,
#dialer-active.ds-erscheint.ds-ohne-weg > #sitzung-leiste { animation-name: ladeEin; }
/* Kein Uebergang beim Sichtbarwerden: Knoepfe mit `transition: all` (z. B. „Jetzt anrufen") blendeten sonst ihre
   visibility von hidden nach visible ueber — die ersten Bilder stand die Leiste ohne den Knopf da (gemessen). */
#dialer-active.ds-erscheint, #dialer-active.ds-erscheint * { transition: none !important; }
/* „Bewegung reduzieren" gibt JEDEM Element einen Uebergang von 0,01 ms (Regel oben, transition-property all) — der haelt
   jede Aenderung ein bis zwei Bilder lang auf dem alten Wert. Beim Zeigen wird die Seite in Klassik am PC breiter (die
   :has-Regel in pages/dialer.html, 900 -> 1180 px): die Karte stand zwei Bilder lang 72 px weiter rechts (gemessen
   14.10.2026). In der ersten Sekunde nach dem Zeigen hat die Seite deshalb gar keinen Uebergang (ds-zeigt, dialer.js). */
#page-dialer.ds-zeigt, #page-dialer.ds-zeigt > #dialer-active { transition: none !important; }
/* Bewegung reduzieren: GAR keine Einblendung. Die allgemeine Regel kuerzt nur die Dauer, nicht den Versatz — mit
   `backwards` stuenden Karte und Leiste sonst 60/120 ms lang 8 px tiefer und sprängen dann (gemessen 14.10.2026). */
@media (prefers-reduced-motion: reduce) {
  #dialer-active.ds-erscheint, #dialer-active.ds-erscheint > * { animation: none !important; }
}

/* Der Platzhalter in der FORM der Sitzung (erst nach 1,2 s — oder sofort, wenn kein Knopf gedrueckt wurde: nach
   F5 und aus dem Kalender). Kopf, Karte (Kontakt, Nummer, Leitfaden | Ergebnisse), Leiste. */
.ds-skelett { display: flex; flex-direction: column; gap: 14px; box-sizing: border-box; min-height: calc(100dvh - 80px); padding: 9px 0 12px; animation: ladeEin .2s linear backwards; }
.ds-sk-kopf { display: flex; align-items: center; gap: 12px; min-height: 36px; }
.ds-sk-kopf > .lade-flaeche { height: 22px; }
.ds-sk-stapel { flex: 1 1 auto; display: grid; grid-template-columns: minmax(0, 1fr); gap: 15px; align-items: start; }
.ds-sk-warte { display: none; }
.ds-sk-karte { box-sizing: border-box; width: 100%; max-width: 720px; justify-self: center; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px 20px;
  padding: 18px; border-radius: var(--radius); background: var(--bg2); border: 1px solid var(--border); }
.ds-sk-spalte { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.ds-sk-person { display: flex; align-items: center; gap: 14px; }
.ds-sk-person > .rund { width: 60px; height: 60px; flex: 0 0 auto; }
.ds-sk-person > div { flex: 1 1 auto; display: flex; flex-direction: column; gap: 8px; }
.ds-sk-person > div > .lade-flaeche:first-child { height: 18px; width: 70%; }
.ds-sk-person > div > .lade-flaeche:last-child { height: 12px; width: 45%; }
.ds-sk-nummer { height: 48px; border-radius: 14px; }
.ds-sk-zeile { height: 34px; border-radius: 10px; }
.ds-sk-leiste { box-sizing: border-box; width: 100%; max-width: 720px; align-self: center; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px;
  padding: 10px 16px 12px; border-radius: 18px; background: var(--bg2); border: 1px solid var(--border); }
.ds-sk-leiste > .lade-flaeche { height: 50px; border-radius: 50px; }
/* Dauert es laenger als 8 s (dialer.js dialerAufbauHinweis): EIN ruhiger Satz und „Abbrechen" — UEBER dem Platzhalter
   (absolut), damit er nichts verschiebt. Deckende Flaeche in den Farben der Seite (Text auf --bg2, hell wie dunkel). */
.ds-skelett { position: relative; }
.ds-sk-hinweis { position: absolute; z-index: 2; left: 50%; top: 84px; transform: translateX(-50%); box-sizing: border-box; width: max-content; max-width: min(440px, calc(100% - 24px));
  display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 16px 20px; text-align: center;
  background: var(--bg2); color: var(--text); border: 1px solid var(--border); border-radius: 16px; box-shadow: 0 10px 30px rgba(5, 28, 44, .14);
  animation: ladeEin var(--lade-dauer) linear backwards; }
.ds-sk-hinweis p { margin: 0; font-size: 14px; line-height: 1.45; color: var(--text); }
.ds-sk-hinweis .btn { min-height: 44px; padding-left: 22px; padding-right: 22px; }
/* Klassik am PC: links die Warteschlange, wie in der Sitzung (ab 1100 px). */
@media (min-width: 1100px) {
  #page-dialer:not(.skin-glass):not(.skin-modern) .ds-sk-stapel { grid-template-columns: 260px minmax(0, 1fr); }
  #page-dialer:not(.skin-glass):not(.skin-modern) .ds-sk-warte { display: flex; flex-direction: column; gap: 10px; padding: 14px; border-radius: var(--radius); background: var(--bg2); border: 1px solid var(--border); }
  #page-dialer:not(.skin-glass):not(.skin-modern) .ds-sk-warte > .lade-flaeche { height: 30px; }
}
/* Modern: die schmale Karte (470 px) in einer Spalte. */
#page-dialer.skin-modern .ds-sk-karte { max-width: 470px; grid-template-columns: minmax(0, 1fr); margin-top: 16px; border-radius: 24px; }
#page-dialer.skin-modern .ds-sk-leiste { max-width: 470px; }
/* Liquid Glass: derselbe Grund wie die Sitzung — sonst stuende erst eine weisse Form da und dann die farbige Sitzung,
   ein zweiter Wechsel. Es gilt der LETZTE Grund in glass.css (Abschnitt 24 (1), „Seiden-Grund": Champagner oben ->
   Schiefer unten, dunkle Schrift), nicht die Daemmerung aus Abschnitt 12 — die ist seit Abschnitt 24 ueberdeckt
   (Gegenpruefung 14.10.2026: der Platzhalter stand blau-rosa da, die Sitzung erschien beige; im Bild gesehen). Hier
   der Grundverlauf dieses Abschnitts ohne die weichen Seiden-Baender (die SVG-Grafik dort); die Flaechen darauf ein
   Zehntel der Schriftfarbe der Sitzung (#23252e), Karte und Leiste wie ihre hellen Glasplatten. Wer den Grund in
   glass.css aendert, aendert ihn hier mit. */
#page-dialer.skin-glass .ds-skelett {
  background: linear-gradient(179deg, #f4e7c6 0%, #ecd8ae 18%, #dbc9a3 36%, #bcb4a2 55%, #97969b 74%, #7a7d8a 88%, #6c7280 100%);
  border-radius: 28px; padding: 22px 22px 26px;
}
#page-dialer.skin-glass .ds-skelett .lade-flaeche { background: rgba(35, 37, 46, .10); }
#page-dialer.skin-glass .ds-sk-karte, #page-dialer.skin-glass .ds-sk-leiste { background: rgba(255, 255, 255, .34); border-color: rgba(255, 255, 255, .6); }
@media (max-width: 768px) {
  .ds-skelett { min-height: calc(100dvh - 150px); }
  .ds-sk-karte { grid-template-columns: minmax(0, 1fr); padding: 14px; }
  .ds-sk-spalte + .ds-sk-spalte { display: none; }
  /* Die Leiste steht wie in der Sitzung ueber der Tab-Leiste. */
  .ds-sk-leiste { position: fixed; z-index: 40; left: 0; right: 0; bottom: calc(59px + env(safe-area-inset-bottom)); max-width: none; grid-template-columns: minmax(0, 1fr);
    gap: 8px; padding: 6px 12px 8px; border-width: 1px 0 0; border-radius: 0; }
  .ds-sk-leiste > .lade-flaeche { height: 46px; }
  #page-dialer.skin-glass .ds-skelett { padding: 14px 12px; border-radius: 22px; }
  #page-dialer.skin-glass .ds-sk-leiste { background: rgba(255, 255, 255, .92); }
  #page-dialer.skin-glass .ds-sk-leiste > .lade-flaeche { background: var(--lade-flaeche); }
}

/* ── „Mein Konto" → Darstellung (17.10.2026): die Design-Wahl, vorher oben auf der Startseite des Dialers. ──────────
   Drei gleich gebaute Knoepfe (Wort, darunter ein Satz), der geltende traegt Rahmen und Haken (aria-pressed).
   Am Handy untereinander, jeder >= 48 px hoch. */
.mk-design-satz { font-size: 13px; color: var(--text2); line-height: 1.5; margin: 0 0 10px; max-width: 560px; }
.mk-design-hell { font-size: 12px; margin: 12px 0 0; }
.mk-design-wahl { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; max-width: 560px; }
.mk-design-knopf { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-height: 44px; padding: 10px 12px; border-radius: 10px;
  border: 1.5px solid var(--border2); background: var(--bg2); color: var(--text); font-family: inherit; text-align: left; cursor: pointer; }
.mk-design-knopf[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: var(--accent-light); }
.mk-design-knopf:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mk-dk-wort { font-size: 14px; font-weight: 700; }
.mk-design-knopf[aria-pressed="true"] .mk-dk-wort::after { content: ' ✓'; }
.mk-dk-satz { font-size: 12px; color: var(--text2); line-height: 1.35; }
@media (max-width: 640px) {
  .mk-design-wahl { grid-template-columns: minmax(0, 1fr); }
  .mk-design-knopf { min-height: 48px; justify-content: center; }
}
