/* ui-2026.css = OVERRIDE-Schicht (Kap. 246, Issue #6).
   Regel: hier werden NUR Werte bestehender Komponenten überschrieben — keine neuen
   Komponentenregeln, kein zweites :root mit neuen Tokens, keine Strukturänderungen.
   Die kanonischen Grundregeln stehen in styles.css; Überlappungen wurden am 14.09.2026
   entfernt, sodass jede Eigenschaft genau einmal wirksam ist. */
/* ============================================================
   ITK365 — UI-ENTWURF "PRÄZISE KANTEN" (2026-09-12, v2)
   Ersetzt refresh-2026-09.css. Eigener Entwurf, bewusst anders:

   HALTUNG
   ---------
   Der Vorgänger-Entwurf hat ÜBERALL Flächen getönt (Ribbon, Panels,
   Fensterkopf, Modal-Body, Felder). Ergebnis: ein pastelliger Brei, in dem
   modulfarbene Icons auf modulfarbenem Grund stehen und kaum sichtbar sind
   (im Terminfenster live gemessen: Icon = violett auf violett auf violett).

   Dieser Entwurf dreht das um:
     1. FLÄCHEN SIND NEUTRAL (weiß). Tiefe kommt aus 1px-Kanten und EINEM
        Schatten — nicht aus Farbflächen.
     2. FARBE IST SIGNAL, NICHT DEKORATION. Die Modulfarbe erscheint nur dort,
        wo sie etwas bedeutet: aktive Registerkarte, primäre Aktion,
        Auswahl-Zustand, Kopfzeile von Fenstern/Modalen.
     3. ICONS SIND NACKT. Keine farbigen Kästen hinter Symbolen (das war
        visuelles Rauschen). Präziser Strich, Farbe nur bei Interaktion.
     4. KONTRAST SCHLÄGT TÖNUNG. Text auf Weiß oder Weiß auf sattem Grund —
        nie gedämpftes Grau auf gedämpftem Pastell.

   Diese Datei ist reines Override; styles.css bleibt unangetastet.
   Rollback: in index.html wieder refresh-2026-09.css eintragen.
   ============================================================ */

/* --- App-Farbwerte (in styles.css ergänzt; hier idempotent gesichert) --- */
:root{
  --talk:#0069a6;--ai:#7c3aed;--search:#0f766e;--start:#0b6bcb;
  --mod:var(--accent);
  /* Eigene Größen für diesen Entwurf */
  --r-sm:6px;      /* kleine Rundung (war 8-10px) */
  --r-md:10px;     /* Flächen */
  --hair:1px;
  /* Issue #23: Elevations-Tokens + starke Kante (alle Themes, damit var() nie leer ist) */
  --e0:var(--bg);--e1:var(--bg2);--e2:var(--card-solid,#fff);--e3:var(--card-solid,#fff);
  --border-strong:color-mix(in srgb,var(--text) 22%,transparent);
;/* Kap. 247 (Issue #17): z-index-Skala und Motion-Stufen */;--z-base:1;--z-base-2:2;--z-base-3:3;--z-base-5:5;--z-base-6:6;--z-react:20;--z-resize:25;--z-rail:50;--z-tip:100;--z-pop:120;--z-search:130;--z-sidebar:300;--z-msgr:900;--z-msgr-btn:901;--z-msgr-pop:950;--z-editor-pop:999;--z-header:1100;--z-header-pop:1200;--z-msgr-name:1300;--z-window:1500;--z-window-bar:1700;--z-ctx:2000;--z-login:5000;--z-modal:6500;--z-editor-menu:9000;--z-suggest:9500;--z-toast:9999;--z-top:10000;--dur-1:100ms;--dur-2:150ms;--dur-3:200ms;--dur-pulse:1600ms;--ease-out:cubic-bezier(.2,.9,.3,1);--ease-in-out:cubic-bezier(.4,0,.2,1)}
html[data-theme="dark"]{--talk:#2dd4bf;--ai:#a78bfa;--search:#22d3ee;--start:#5b8cff}
html[data-theme="blau"]{--talk:#0069a6;--ai:#7c3aed;--search:#0f766e;--start:#0b6bcb}
html[data-theme="lumen"]{--talk:#0069a6;--ai:#7c3aed;--search:#0f766e;--start:#0e7490}

/* ============================================================
   Issue #23 — DARK-MODE-ELEVATION
   Das dunkle Theme war reine Farbwert-Invertierung: Cards
   rgba(20,28,48,.72) halbtransparent, Schatten rgba(0,0,0,.4) auf
   dunklem Grund unsichtbar, Border blau getoent (~1.3:1). Ergebnis:
   Rail/Header/Card/Input verschmolzen, Tiefe fehlte.

   Fix nach Material-Dark-Prinzip: Tiefe entsteht durch AUFHELLUNG
   (overlay opacity), nicht durch Schatten. Drei Elevations-Stufen
   + neutrales Border + 1px-Top-Highlight als Lichtquelle.
   ============================================================ */
html[data-theme="dark"]{
  --e0:#0b0f1a;                 /* Grundflaeche (Body) */
  --e1:#121a2c;                 /* Rail, Header */
  --e2:#1b2742;                 /* Cards, Panels (Default-Elevation) */
  --e3:#243250;                 /* Modale, Popups, Popover */
  --card:#1b2742;               /* opak statt rgba(...) — kein Durchscheinen */
  --card-solid:#1b2742;
  --border:rgba(255,255,255,.09);  /* neutral statt Blau-Schleier */
  --border-strong:rgba(255,255,255,.15);
  /* Elevations-Schatten: nah + breit, damit auch auf dunklem Grund Tiefe sichtbar ist */
  --shadow:0 1px 2px rgba(0,0,0,.5),0 4px 16px rgba(0,0,0,.45),0 20px 48px rgba(0,0,0,.5);
  --shadow-sm:0 1px 2px rgba(0,0,0,.45),0 3px 12px rgba(0,0,0,.4);
}
/* Lichtquelle von oben: 1px-Innenkante ersetzt den verlorenen Wurfschatten */
html[data-theme="dark"] .card,
html[data-theme="dark"] .hub-card,
html[data-theme="dark"] .ai-feed-card,
html[data-theme="dark"] .ds-box,
html[data-theme="dark"] .td-sp,
html[data-theme="dark"] .chat-app{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055),var(--shadow-sm);
}
html[data-theme="dark"] .modal-win,
html[data-theme="dark"] .mw{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 16px 48px rgba(0,0,0,.6);
}
html[data-theme="dark"] .header{background:var(--e1);border-bottom-color:var(--border)}
html[data-theme="dark"] .rail{background:var(--rail)}
html[data-theme="dark"] .modal-b,
html[data-theme="dark"] .modal-f,
html[data-theme="dark"] .modal-pre{background:var(--e3)}
html[data-theme="dark"] .modal-win{background:var(--e3)}
html[data-theme="dark"] .modal-h,
html[data-theme="dark"] .mw-h{background:linear-gradient(180deg,
  color-mix(in srgb,var(--mod) 34%,var(--e3)) 0%,
  color-mix(in srgb,var(--mod) 22%,var(--e3)) 100%)}
/* Medien sanft dimmen — sie strahlen sonst hell aus der dunklen Flaeche */
html[data-theme="dark"] img,
html[data-theme="dark"] video{filter:brightness(.88)}
/* Eingabefelder eine Stufe TIEFER als die Card (eingelassen statt erhaben) */
html[data-theme="dark"] .set-inp,
html[data-theme="dark"] .mc-from-sp,
html[data-theme="dark"] input[type="text"],
html[data-theme="dark"] input[type="email"],
html[data-theme="dark"] input[type="search"],
html[data-theme="dark"] textarea,
html[data-theme="dark"] select{background:var(--e0);border-color:var(--border-strong)}

/* --- Modul-Kontext: body[data-mod] setzt showSec() --- */
body[data-mod="mail"]     {--mod:var(--mail)}
body[data-mod="cal"]      {--mod:var(--cal)}
body[data-mod="contacts"] {--mod:var(--contact)}
body[data-mod="files"]    {--mod:var(--file)}
body[data-mod="files"] .files-ribbonbar{background:color-mix(in srgb,var(--file) 3%,var(--card))}
body[data-mod="chat"] .chat-ribbonbar{background:color-mix(in srgb,var(--talk) 3%,var(--card))}

/* ============================================================
   Issue #25 — Restliche App-Koepfe auf das neue System
   Status, Administration und Dokumentation haben KEINE Aktionsgruppe, die ein
   Ribbon rechtfertigt (Status: 1 Knopf + Log-Filter direkt im Panel; Admin: nur
   eine Liste; Docs: Fliesstext). Ein Ribbon waere hier eine leere Huelle.
   Stattdessen: .app-toolbar als Kopf-Karte mit Modulanker — dieselbe Sprache
   wie die Ribbons, ohne eine Tab-Leiste zu erfinden, die nichts schaltet.
   ============================================================ */
.app-toolbar{
  background:color-mix(in srgb,var(--mod) 3%,var(--card));
  border:1px solid var(--border);border-left:4px solid var(--mod);
  border-radius:var(--r-md);padding:9px 14px;margin:0 0 var(--dichte-gap);
  box-shadow:none}
.app-toolbar .title{font-size:14px;font-weight:650;margin-right:auto;display:flex;align-items:center;gap:8px}
.app-toolbar .tb-info{font-size:12px;color:var(--text2)}
/* Kopf-Knopf: gleiche Geometrie wie die Ribbon-Knoepfe, aber flach (kein Ribbon) */
.app-toolbar .tb-btn{background:transparent;border:1px solid transparent;
  border-radius:var(--r-sm);padding:5px 10px;font-size:12.5px;font-weight:600}
.app-toolbar .tb-btn:hover{background:var(--hover);border-color:var(--border)}
.app-toolbar .tb-btn.primary{background:linear-gradient(135deg,
  color-mix(in srgb,var(--mod) 92%,#fff),var(--mod));color:#fff;border-color:transparent}
.chat-ribbonbar.rb-collapsed .mrb-panels{display:none}
/* Issue #25: das Ribbon steht ueber der Chat-App -> deren 100vh-Hoehe muss den
   Ribbon abziehen, sonst laeuft die Ansicht unten aus dem Viewport. */
#sec-chat .chat-app{height:calc(100vh - 150px - 108px)}
#sec-chat:has(.chat-ribbonbar.rb-collapsed) .chat-app{height:calc(100vh - 150px - 34px)}
.files-ribbonbar.rb-collapsed .mrb-panels{display:none}
body[data-mod="docs"]     {--mod:var(--wiki)}
body[data-mod="status"]   {--mod:var(--git)}
body[data-mod="settings"] {--mod:var(--git)}
body[data-mod="chat"]     {--mod:var(--talk)}
body[data-mod="ai"]       {--mod:var(--ai)}
body[data-mod="search"]   {--mod:var(--search)}
body[data-mod="start"]    {--mod:var(--start)}
body[data-mod="todo"]    {--mod:var(--todo)}
body[data-mod="git"]     {--mod:var(--git)}

/* ============================================================
   Issue #20 — MODULFARBE IM APP-CHROM
   Vorher war der einzige Farbhinweis ein 32px-Icon im Header; sonst
   war jede App neutral-grau und damit nicht unterscheidbar. Jetzt
   traegt der Chrom einen feinen Modul-Tint (Farbe bleibt Signal:
   2px Unterkante + 4 % Flaeche, KEINE Vollflaeche — Lehre Kap. 209).
   ============================================================ */
/* Header: 2px Modul-Unterkante statt neutraler Linie + sehr leichter Tint */
body[data-mod] .header{border-bottom:2px solid color-mix(in srgb,var(--mod) 42%,var(--border));
  background:color-mix(in srgb,var(--mod) 3%,var(--card))}
/* Rail: aktiver Knopf in Modulfarbe (Icon + Pill), nicht mehr neutral-weiss */
body[data-mod] .rail button.active{color:#fff;
  background:color-mix(in srgb,var(--mod) 42%,transparent)}
body[data-mod] .rail button.active::before{background:var(--mod);
  box-shadow:0 0 12px color-mix(in srgb,var(--mod) 70%,transparent)}
/* Primaere Aktion traegt die Modulfarbe — nicht ueberall dasselbe Akzent-Blau */
body[data-mod] .tb-btn.primary,
body[data-mod] .btn-p{
  background:linear-gradient(135deg,color-mix(in srgb,var(--mod) 92%,#fff),var(--mod));
  border-color:transparent;color:#fff}
body[data-mod] .tb-btn.primary:hover,
body[data-mod] .btn-p:hover{background:linear-gradient(135deg,var(--mod),
  color-mix(in srgb,var(--mod) 82%,#000))}
/* Sektions-Karten in den Apps: 4px Modulanker (das abgenommene Signal) */
body[data-mod] .hub-card,
body[data-mod] .ds-res,
body[data-mod] .doc-card{border-left:4px solid color-mix(in srgb,var(--mod) 70%,var(--border))}
/* Fokus in Modulfarbe: Fokusring folgt der App, nicht dem globalen Akzent.
   ACHTUNG: --focus-ring ist eine FARBE (ui-2026.css:1699, benutzt in
   `outline:<w> solid var(--focus-ring)`) — hier nur der Farbwert. */
body[data-mod]{--focus-ring:color-mix(in srgb,var(--mod) 78%,var(--accent))}
/* Kontrast-Theme: Tint zuruecknehmen (Barrierefreiheit vor Farbe) */
html[data-theme="kontrast"] body[data-mod] .header{background:var(--card);
  border-bottom:3px solid #000}
html[data-theme="kontrast"] body[data-mod] .rail button.active{background:#000;color:#fff}

/* ============================================================
   Issue #19 — STARTSEITE: HERO + KARTEN-HIERARCHIE
   Vorher: vier gleich grosse Karten + 25px-Greeting, alles gleiches
   Gewicht -> kein Fokalpunkt („leer und statisch"). Jetzt: EIN führendes
   Hero-Band (Datum/Uhrzeit + nächster Termin), darunter die Karten mit
   klarer Rangfolge („Heute" doppelt breit, weil zeitkritisch).
   Farbe nur im Hero-Verlauf — der Rest bleibt neutral (Kap. 209).
   ============================================================ */
.hero{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr);
  gap:12px 18px;align-items:start;
  background:linear-gradient(135deg,
    color-mix(in srgb,var(--mod) 9%,var(--card)) 0%,
    var(--card) 58%);
  border:1px solid var(--border);border-left:4px solid var(--mod);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);
  padding:18px 20px;margin:0 0 var(--dichte-gap)}
/* Kap. 338 (#132): Kopfzeile ueber beide Spalten (Begruessung, Datum, Uhrzeit,
   Chips). Sie gehoert NICHT in den linken Strang — dort hat sie die Mail-Liste
   nach unten gedrueckt und das Fluchten mit dem Termin verhindert. */
.hero-kopf{grid-column:1 / -1;display:flex;flex-direction:column;
  justify-content:flex-start;gap:2px;min-width:0}
.hero-l{grid-column:1;min-width:0;display:grid;grid-template-columns:1fr 1fr;
  gap:10px;align-items:start;justify-content:flex-start}
/* Gitea-Issue #133: „Letzte Mails" und „Zuletzt geöffnete Dateien" stehen
   nebeneinander (der Nutzer wollte das Kalender-Modul 2-spaltig). Ist nur eine
   der beiden Listen da, nimmt sie die volle Breite ein — kein halbleerer Rahmen. */
.hero-l > .recent-mails:only-child,
.hero-l > .recent-files:only-child{grid-column:1 / -1}
.recent-files{min-width:0;display:flex;flex-direction:column}
/* Gitea-Issue #188: Die Liste „Zuletzt geoeffnete Dateien" wurde unbegrenzt lang und
   drueckte die Startseite auf. Sie scrollt jetzt IN sich (max-height setzt das JS je
   nach Eintragszahl); der Kopf mit der vollen Zahl bleibt stehen.
   scrollbar-gutter reserviert den Platz, damit die Zeilen beim Erscheinen der
   Bildlaufleiste nicht seitlich springen. */
.rf-liste{overflow-y:auto;overscroll-behavior:contain;scrollbar-gutter:stable;
  display:flex;flex-direction:column}
.rf-h{display:flex;align-items:center;gap:6px;font-size:11px;font-weight:800;
  text-transform:uppercase;letter-spacing:.5px;color:var(--text2);padding:0 2px 6px}
.rf-h i{color:var(--accent)}
.rf-h-z{font-variant-numeric:tabular-nums;font-weight:700;color:var(--text2)}
.rf-x{margin-left:auto;border:none;background:transparent;color:var(--text2);
  cursor:pointer;font-size:11px;line-height:1;padding:2px 4px;border-radius:4px}
.rf-x:hover{background:var(--hover);color:var(--danger)}
.rf-z{display:flex;align-items:center;gap:8px;padding:4px 6px;border-radius:7px;
  border:1px solid transparent;min-width:0}
.rf-z:hover{background:var(--hover);border-color:var(--border)}
.rf-ico{flex:none;display:inline-flex;color:var(--text2)}
.rf-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:0}
.rf-nm{border:none;background:transparent;padding:0;text-align:left;
  font-family:inherit;font-size:12.5px;font-weight:600;color:var(--text);
  cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rf-nm:hover{color:var(--accent);text-decoration:underline}
.rf-pfad{border:none;background:transparent;padding:0;text-align:left;
  font-family:inherit;font-size:10.5px;color:var(--text2);cursor:pointer;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl}
.rf-pfad:hover{color:var(--accent);text-decoration:underline}
.rf-zeit{flex:none;font-size:10.5px;color:var(--text2);font-variant-numeric:tabular-nums}
.rf-nm:focus-visible,.rf-pfad:focus-visible{outline:2px solid var(--focus-ring);
  outline-offset:1px;border-radius:3px}
@media(max-width:900px){
  /* Auf schmalen Fenstern untereinander — sonst bleiben nur Bruchstücke übrig. */
  .hero-l{grid-template-columns:1fr}
}
.hero-greet{font-size:12.5px;font-weight:600;color:var(--text2)}
.hero-date{font-size:13px;font-weight:600;letter-spacing:.35px;text-transform:uppercase;
  color:color-mix(in srgb,var(--mod) 72%,var(--text2))}
.hero-time{font-size:38px;font-weight:700;line-height:1.05;letter-spacing:-1px;
  font-variant-numeric:tabular-nums}
.hero-sub{font-size:13px;color:var(--text2);margin-top:5px;max-width:62ch}
/* Kap. 338 (#132): rechte Spalte des 2+1-Rasters — beginnt auf DERSELBEN
   Oberkante wie „Letzte Mails" links. */
.hero-r{grid-column:2;display:flex;flex-direction:column;gap:9px;
  justify-content:flex-start;min-width:0}
/* Nächster Termin: klickbare Mini-Karte (führt in den Kalender) */
.hero-next{background:var(--card);border:1px solid var(--border);
  border-radius:var(--r-md);padding:10px 13px;cursor:pointer;
  transition:border-color var(--dur-2) ease,box-shadow var(--dur-2) ease}
.hero-next:hover{border-color:color-mix(in srgb,var(--mod) 45%,var(--border));
  box-shadow:var(--shadow-sm)}
.hero-next:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.hn-lbl{display:flex;align-items:center;gap:6px;font-size:10.5px;font-weight:700;
  letter-spacing:.5px;text-transform:uppercase;color:var(--text2);margin-bottom:6px}
.hn-b{font-size:14px;font-weight:600}
.hn-zeit{font-variant-numeric:tabular-nums;color:color-mix(in srgb,var(--mod) 75%,var(--text))}
.hn-titel{display:block;margin-top:2px;font-weight:500;color:var(--text2);font-size:12.5px}
.hn-leer{font-size:12.5px;color:var(--text2);font-weight:400}
/* Karten-Rangfolge: „Heute" doppelt breit (zeitkritisch), ab 2 Spalten */
@media(min-width:820px){
  .hub-card-heute{grid-column:span 2}
}
/* ============================================================
   Gitea-Issue #76 — HERO-BAND, rechter Teil
   Der rechte Teil nimmt jetzt Termin UND Aufgaben auf. Beide Karten im
   SELBEN Maß wie .hero-next (weiße Fläche, 1px Kante, gleicher Radius) —
   Farbe bleibt Signal: nur die Modulfarbe des Kastens links und der rote
   Überfällig-Hinweis. Keine Vollflächen-Tönung.
   ============================================================ */
.hn-plus{margin-left:auto;flex:none;width:20px;height:20px;display:inline-flex;align-items:center;
  justify-content:center;border:1px solid var(--border);background:var(--card);color:var(--text2);
  border-radius:var(--r-sm);cursor:pointer;padding:0;transition:color var(--dur-2) ease,border-color var(--dur-2) ease}
.hn-plus:hover{color:var(--mod);border-color:var(--mod)}
.hn-plus:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
/* Aufgaben-Karte — gleiches Maß wie .hero-next, eigener Farbanker To Do */
.hero-todo{background:var(--card);border:1px solid var(--border);
  border-left:4px solid var(--todo);border-radius:var(--r-md);padding:10px 13px;
  cursor:pointer;transition:border-color var(--dur-2) ease,box-shadow var(--dur-2) ease}
.hero-todo:hover{border-color:color-mix(in srgb,var(--todo) 45%,var(--border));
  border-left-color:var(--todo);box-shadow:var(--shadow-sm)}
.hero-todo:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.hero-todo .hn-lbl{margin-bottom:4px}
.hzt-meta{display:inline-flex;align-items:baseline;gap:6px;margin-left:2px}
.hzt-zahl{font-size:12px;font-weight:700;color:var(--todo);letter-spacing:0;text-transform:none}
.hzt-zahl.warn{color:var(--danger)}
.hzt-item{display:flex;align-items:center;gap:7px;padding:3px 0;min-width:0}
.hzt-item + .hzt-item{border-top:1px solid var(--border)}
.hzt-check{flex:none;width:16px;height:16px;border:1px solid var(--border);border-radius:5px;
  background:var(--card);color:var(--text2);cursor:pointer;display:inline-flex;align-items:center;
  justify-content:center;padding:0}
.hzt-check:hover{border-color:var(--ok);color:var(--ok)}
.hzt-m{flex:1;min-width:0}
.hzt-t{font-size:12.5px;font-weight:600;color:var(--text);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.hzt-s{font-size:10.5px;color:var(--text2)}
.hzt-item-warn .hzt-s{color:var(--danger);font-weight:600}
.hzt-mehr{display:block;width:100%;text-align:center;padding:4px;margin-top:3px;border:0;
  background:none;color:var(--text2);font-size:11px;cursor:pointer;font-family:inherit}
.hzt-mehr:hover{color:var(--todo);text-decoration:underline}
/* Der Hero ersetzt .greeting — alte Regeln daran bleiben unangetastet */
#sec-start .hero + .announce{margin-top:0}

/* Issue #21-Hinweis: die Karten-Unterkante nutzt jetzt den Dichte-Abstand */
.hub-card{margin-bottom:0}

/* ============================================================
   Issue #21 — SKELETON + EMPTY-STATE (Grundbausteine)
   ============================================================ */
.sk{background:linear-gradient(90deg,
  color-mix(in srgb,var(--border) 55%,transparent) 25%,
  color-mix(in srgb,var(--border) 95%,transparent) 50%,
  color-mix(in srgb,var(--border) 55%,transparent) 75%);
  background-size:200% 100%;animation:sk-shimmer 1.4s ease-in-out infinite;
  border-radius:var(--r-sm)}
.sk-kopf{height:16px;width:38%;margin-bottom:12px}
.sk-line{height:14px;margin-bottom:10px}
.sk-av{width:28px;height:28px;border-radius:50%;flex:none}
@keyframes sk-shimmer{from{background-position:200% 0}to{background-position:-200% 0}}
@media(prefers-reduced-motion:reduce){.sk{animation:none}}

.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:6px;padding:26px 18px;text-align:center;color:var(--text2)}
.empty-state .es-ico{width:30px;height:30px;color:color-mix(in srgb,var(--mod) 62%,var(--text2));
  stroke-width:1.6;margin-bottom:2px}
.empty-state .es-t{font-size:13.5px;font-weight:600;color:var(--text)}
.empty-state .es-h{font-size:12.5px;color:var(--text2);max-width:42ch;line-height:1.45}
.empty-state .es-a{margin-top:8px}
.empty-state.es-err .es-ico{color:var(--danger)}

/* Fixe Mindesthoehen gegen Layout-Sprung beim Nachladen (CLS) */
.hub-card .hub-b,.ai-feed-card .ai-feed-b{min-height:132px}

/* ============================================================
   Issue #22 — HEADER BÜNDIG + RAIL-TOOLTIPS + DICHTE
   (a) Header-Inhalt endete auf einer anderen Kante als der Content.
       GEMESSEN (1920px): Kopf-Rechtskante 1920, Content-Rechtskante 1858
       -> 62px Asymmetrie (padding-right 90px vs .main 28px). Der Kopf
       spiegelt jetzt exakt das rechte Polster von .main; die Messenger-
       Leiste addiert nur noch, wenn sie offen ist.
   (b) Rail hatte nur native `title=`-Tooltips (langsam, unformatiert,
       kein Theme). Jetzt echte CSS-Tooltips rechts vom Knopf.
   (c) Dichte-Stufen --dichte-gap fuer kompakt/komfortabel.
   ============================================================ */
/* Issue #30-1: .main weicht der zugeklappten Messenger-Leiste aus (margin-right:62px), der Kopf
   muss dasselbe tun — sonst endet der Kopf-Cluster um die Leistenbreite rechts der Inhaltskante
   (gemessen: 1512 vs 1450 @1540px). 28px = Polster wie .main, 62px/230px = Breite der Leiste. */
.header{padding-right:calc(62px + 28px)}
body.msgr-pinned .header,
body:not(.msgr-collapsed) .header{padding-right:calc(230px + 28px)}
/* Issue #30-3: der Seiten-Scrollbalken reserviert Platz — sonst springen die Inhaltskanten
   und die Hub-Kachelzeile kann unter den Balken rutschen (bei 1280px nur 3px Luft). */
html{scrollbar-gutter:stable}
/* Issue #30-2: nie hart abgeschnittener Platzhaltertext — notfalls Auslassungspunkte. */
.search input,.ds-input-wrap input,.mail-quicksearch input{text-overflow:ellipsis;overflow:hidden}
@media(min-width:1600px){
  /* Auf breiten Schirmen bleibt der Kopf bündig, weil .main keinen Cap hat */
  .header{box-shadow:0 1px 0 var(--border)}
}
/* ============================================================
   Issue #22 (b)(c) — Rail-Tooltips + Dichte-Stufen
   FALLE (live gefunden): hier stand verwaister Kommentartext ohne oeffnendes
   Kommentarzeichen und schloss mit einem schliessenden ab — dadurch lief der
   Kommentar-Zaehler auf -1 und der CSS-Parser verwarf ALLES bis zum naechsten
   oeffnenden Zeichen. Folge: die Dichte-Variable wurde nie geladen,
   `var(--dichte-gap)` loeste zu nichts auf, und der Hero-Abstand war 0px
   statt 14px (gemessen: --dichte-gap am html war leer).
   ============================================================ */
:root{--dichte-gap:14px}
body[data-dichte="kompakt"]{--dichte-gap:8px}
body[data-dichte="komfortabel"]{--dichte-gap:20px}
.hub-grid,.hub-ki{gap:var(--dichte-gap)}
.hub-card,.hub-ki,.ai-feed-card{margin-bottom:var(--dichte-gap)}

/* (b) Rail-Tooltip: erscheint rechts NEBEN dem Knopf, vertikal zentriert.
   Absolut innerhalb des Knopfes positioniert (relativ zu ihm), damit die
   Hoehe automatisch stimmt — NICHT position:fixed (das braeuchte ein top).

   Gitea-Issue #85: „hover bubble verschwindet rechts hinter header". Ursache
   live gemessen: der Tooltip lag auf `--z-tip` (100), der Header auf
   `--z-header` (1100) — der Header deckte also alles ab x=76px ab, genau dort,
   wo der Tooltip steht. Ein `z-index` INNERHALB des Rails (.rail hat 50) kann
   den Header nicht ueberholen, weil der Rail selbst einen eigenen Stapel bildet.
   Deshalb: Der Rail bekommt beim Hover eine Stufe UEBER dem Header
   (siehe Regel direkt darunter). Damit liegen ALLE Rail-Tooltips wieder sichtbar
   ueber der Kopfzeile, ohne jeden einzelnen anzufassen. */
.rail button[title]:hover::after,
.rail .logo:hover::after,
.rail .sep[title]:hover::after{
  content:attr(title);position:absolute;left:calc(100% + 10px);top:50%;
  transform:translateY(-50%);
  background:var(--card);color:var(--text);
  border:1px solid var(--border);border-left:3px solid var(--mod);
  border-radius:var(--r-sm);padding:5px 10px;font-size:12px;font-weight:600;
  white-space:nowrap;box-shadow:var(--shadow);z-index:var(--z-tip);
  pointer-events:none;opacity:0;animation:tipIn 200ms 300ms ease forwards}
/* Der Rail MUSS ueber den Header, solange der Zeiger darin ist — sonst bleibt
   jeder Tooltip unter der Kopfzeile. `:hover` gibt es auf `.rail` selbst, weil
   die Buttons seine Kinder sind (Hover blubbert nach oben). */
.rail:hover{z-index:calc(var(--z-header) + 5)}
/* Das Logo hat kein title mehr (Wortmarke steht im Knopf) — eigener Tooltip
   ueber ein Daten-Attribut, damit die Maus-Bedienung nichts verliert. */
.rail .logo[data-tip]:hover::after{content:attr(data-tip)}
@keyframes tipIn{from{opacity:0}to{opacity:1}}
/* Tooltips sind reine Zusatzinfo -> im Kontrast-Theme normale Raender */
html[data-theme="kontrast"] .rail button[title]:hover::after,
html[data-theme="kontrast"] .rail .sep[title]:hover::after{
  border:2px solid #000;border-left:6px solid #000;background:#fff;color:#000}

/* ============================================================
   1) RIBBON — kompakt, weiß, präzise
   Vorher: 125px hoch, flächig getönt, viel toter Raum.
   Jetzt:  neutraler Grund, farbige Registerkante, engere Geometrie.
   Container-Klassen werden mitgeführt (Spezifität der Kopien in styles.css!).
   ============================================================ */
.mail-ribbonbar,.cal-ribbonbar,.ct-ribbonbar,.td-ribbonbar,.git-ribbonbar,.files-ribbonbar,.chat-ribbonbar,.cal-win-ribbon,.mc-ribbon{
  background:var(--card);
  border:none;
  border-bottom:var(--hair) solid var(--border);
  border-radius:0;
  box-shadow:none;
  margin-bottom:6px;
}
/* Kalender-/Kontakte-Ribbon sitzen als Karten im Satzspiegel → Karte mit Rahmen */
.cal-ribbonbar,.ct-ribbonbar,.mail-ribbonbar,.td-ribbonbar,.git-ribbonbar,.files-ribbonbar,.chat-ribbonbar{
  border:var(--hair) solid var(--border);
  border-radius:var(--r-md);
  margin-bottom:10px;
}
.cal-win-ribbon{margin-bottom:0}

/* Registerkarten: flach, klar, farbige Unterkante als Zustand */
.mail-ribbonbar .mrb-tabs,.cal-ribbonbar .mrb-tabs,.ct-ribbonbar .mrb-tabs,.td-ribbonbar .mrb-tabs,.files-ribbonbar .mrb-tabs,.chat-ribbonbar .mrb-tabs,
.cal-win-ribbon .mrb-tabs,.mc-ribbon .mc-rb-tabs,.mrb-tabs,.mc-rb-tabs{
  background:transparent;
  border-bottom:var(--hair) solid var(--border);
  padding:0 10px;
  gap:0;
}
.mail-ribbonbar .mrb-tab,.cal-ribbonbar .mrb-tab,.ct-ribbonbar .mrb-tab,.td-ribbonbar .mrb-tab,.files-ribbonbar .mrb-tab,.chat-ribbonbar .mrb-tab,
.cal-win-ribbon .mrb-tab,.mc-ribbon .mc-rb-tab,.mrb-tab,.mc-rb-tab{
  color:var(--text2);
  font-size:12.5px;
  font-weight:500;
  padding:9px 13px 8px;
  border-radius:0;
  border-bottom:2px solid transparent;
  letter-spacing:.1px;
}
.mail-ribbonbar .mrb-tab:hover,.cal-ribbonbar .mrb-tab:hover,.ct-ribbonbar .mrb-tab:hover,.td-ribbonbar .mrb-tab:hover,
.cal-win-ribbon .mrb-tab:hover,.mc-ribbon .mc-rb-tab:hover,.mrb-tab:hover,.mc-rb-tab:hover{
  color:var(--text);
  background:transparent;
}
.mail-ribbonbar .mrb-tab.on,.cal-ribbonbar .mrb-tab.on,.ct-ribbonbar .mrb-tab.on,.td-ribbonbar .mrb-tab.on,
.cal-win-ribbon .mrb-tab.on,.mc-ribbon .mc-rb-tab.on,.mrb-tab.on,.mc-rb-tab.on{
  color:var(--mod);
  background:transparent;
  border-bottom:2px solid var(--mod);
  font-weight:600;
}
.mrb-collapse{color:var(--text2);border-radius:var(--r-sm)}
.mrb-collapse:hover{background:var(--hover);color:var(--text)}

/* Buttonfläche: neutral, aber luftiger als vorher (Buttons waren zu klein) */
.mail-ribbonbar .mrb-panels,.cal-ribbonbar .mrb-panels,.ct-ribbonbar .mrb-panels,.td-ribbonbar .mrb-panels,.files-ribbonbar .mrb-panels,.chat-ribbonbar .mrb-panels,
.cal-win-ribbon .mrb-panels,.mc-ribbon .mc-rb-panels,.mrb-panels,.mc-rb-panels{
  background:transparent;
  padding:7px 10px 8px;
  gap:0;
}

/* Gruppenspalten: Trennlinie statt Farbfläche */
.mc-grp{
  border-right:var(--hair) solid var(--border);
}
.mc-grp-lbl{
  font-weight:600;
  text-transform:uppercase;
  letter-spacing:.6px;
  color:var(--text2);
  opacity:.85;
}

/* ============================================================
   2) RIBBON-BUTTONS — nackte Icons, Farbe nur bei Interaktion
   Das ist der Kern der Korrektur: kein farbiger Kasten hinter jedem Icon.
   ============================================================ */
.mc-btn{
  color:var(--text);
  border:var(--hair) solid transparent;
  border-radius:var(--r-sm);
  transition:background var(--dur-1) ease,color var(--dur-1) ease,border-color var(--dur-1) ease;
}
.mc-btn:hover:not(:disabled):not(.off){
  background:color-mix(in srgb,var(--mod) 9%,var(--card));
  border-color:color-mix(in srgb,var(--mod) 26%,var(--border));
  color:var(--mod);
}
.mc-btn.act:not(:disabled){
  background:color-mix(in srgb,var(--mod) 11%,var(--card));
  border-color:color-mix(in srgb,var(--mod) 34%,var(--border));
  color:var(--mod);
}
/* Icon: NACKT — in JEDEM Zustand. Die Container-Klassen und die .act/.off-
   Varianten werden EXPLIZIT mitgeführt: `.mc-btn.big.act > svg` (3 Klassen) in
   styles.css/refresh schlägt sonst einfaches `.mc-btn.big > svg` (2 Klassen),
   und der grüne Icon-Kasten bliebe stehen. (Genau dieser Fehler ist passiert.) */
.mc-btn.big > svg,.mc-btn.big > i,
.mc-btn.big.act > svg,.mc-btn.big.act > i,
.mc-btn.big:hover > svg,.mc-btn.big:hover > i,
.mc-btn > svg,.mc-btn > i{
  padding:0;
  background:none;
  border-radius:0;
  color:currentColor;
}
.mc-btn.big > svg,.mc-btn.big > i{stroke-width:1.6}
/* Beschriftung: sekundär, wird mit dem Icon zusammen aktiv */
.mc-btn.big .mc-btn-l{font-weight:500;color:var(--text2)}
.mc-btn.big:hover .mc-btn-l,.mc-btn.big.act .mc-btn-l{color:var(--mod);font-weight:600}
/* Kompakter: der Ribbon war 125px hoch für 4 Knöpfe */
.mc-btn.big{min-width:52px;max-width:132px;}

/* ============================================================
   3) FENSTER (.mw) — satter Farbkopf = echte Hierarchie
   Vorher: pastell-getönter Kopf, darüber violetter Ribbon, darunter violette
   Felder → nichts hob sich ab. Jetzt: der Kopf IST die Farbfläche.
   ============================================================ */
.mw{
  border:var(--hair) solid color-mix(in srgb,var(--mod) 24%,var(--border));
  border-radius:var(--r-md);
  box-shadow:0 10px 34px rgba(15,20,30,.20),0 2px 8px rgba(15,20,30,.12);
  overflow:hidden;
}
.mw-h{
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--mod) 92%,#fff) 0%,
    color-mix(in srgb,var(--mod) 82%,#000) 100%);
  border-bottom:none;
  box-shadow:none;
  color:#fff;
  padding:9px 12px;
}
.mw-h .mt{color:#fff;font-weight:600}
.mw-h .mt i,.mw-h svg{color:#fff;stroke-width:1.75}
.mw-h .mw-title{color:#fff;letter-spacing:.1px}
.mw-h .mw-min,.mw-h .mw-x{color:rgba(255,255,255,.82)}
.mw-h .mw-min:hover{background:rgba(255,255,255,.18);color:#fff}
.mw-h .mw-x:hover{background:var(--close-hover-bg);color:#fff}
/* Der Farbkopf im Terminfenster trägt den Ribbon: Register auf Farbgrund */
.cal-win-ribbon{background:transparent;border-bottom:none}
.cal-win-ribbon .mrb-tabs{background:transparent;border-bottom:var(--hair) solid var(--border)}
.cal-win-ribbon .mrb-panels{background:var(--card)}
.mw-b{background:var(--card)}

/* ============================================================
   4) MODALE (.modal-win) — gleiche Logik: Farbkopf, weißer Körper
   ============================================================ */
.modal-win{
  border:var(--hair) solid color-mix(in srgb,var(--mod) 20%,var(--border));
  border-radius:var(--r-md);
  box-shadow:0 14px 44px rgba(15,20,30,.24),0 2px 10px rgba(15,20,30,.14);
}
.modal-h{
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--mod) 92%,#fff) 0%,
    color-mix(in srgb,var(--mod) 82%,#000) 100%);
  box-shadow:none;
  color:#fff;
  border-radius:var(--r-md) var(--r-md) 0 0;
  padding:12px 16px;
}
.modal-h .mt{color:#fff;font-weight:600}
.modal-h .mt i{color:#fff;stroke-width:1.8}
.modal-x{color:rgba(255,255,255,.82);background:none;border-radius:var(--r-sm)}
.modal-x:hover{background:rgba(255,255,255,.2);color:#fff}
.modal-link{color:rgba(255,255,255,.85)}
.modal-link:hover{background:rgba(255,255,255,.18);color:#fff}
.modal-b{background:var(--card);padding:18px 20px}
/* ============================================================
   Issue #28 — MODAL-INTERAKTION
   Resize-Griff unten rechts, Mobile als Bottom-Sheet, Modal-Stapel.
   Esc/Fokus-Trap/Positions-Persistenz sitzen in core.js (modalAktivieren).
   ============================================================ */
/* ACHTUNG: hier KEIN `position` setzen! `.modal-win` ist in styles.css:1272
   `position:fixed`. Ein `position:relative` an dieser Stelle (später geladen!)
   überschreibt das und macht das Fenster zum In-Flow-Element: `top:120px` wirkt
   dann als relativer Versatz vom Overlay-Padding (gemessen: rect.top 291 statt
   120). `position:fixed` etabliert bereits einen Containing-Block für den
   absolut positionierten Resize-Griff — genau das wurde gebraucht. */
.modal-win{min-width:320px;min-height:120px;overflow:hidden}
.modal-resize{position:absolute;right:0;bottom:0;width:18px;height:18px;
  cursor:nwse-resize;z-index:2;
  background:linear-gradient(135deg,transparent 52%,
    color-mix(in srgb,var(--text2) 45%,transparent) 52%,
    color-mix(in srgb,var(--text2) 45%,transparent) 60%,
    transparent 60%,
    transparent 72%,
    color-mix(in srgb,var(--text2) 45%,transparent) 72%,
    color-mix(in srgb,var(--text2) 45%,transparent) 80%,
    transparent 80%)}
.modal-resize:hover{background:linear-gradient(135deg,transparent 52%,
  color-mix(in srgb,var(--mod) 70%,transparent) 52%,
  color-mix(in srgb,var(--mod) 70%,transparent) 60%,
  transparent 60%,transparent 72%,
  color-mix(in srgb,var(--mod) 70%,transparent) 72%,
  color-mix(in srgb,var(--mod) 70%,transparent) 80%,transparent 80%)}
/* Modal-Stapel: das zweite Fenster sitzt sichtbar versetzt darunter */
.modal-ov + .modal-ov .modal-win{transform:translate(14px,14px)}
/* Mobile: Bottom-Sheet statt mitgequetschtes Fenster (wie Outlook/iOS) */
@media(max-width:640px){
  .modal-ov{align-items:flex-end;padding-top:0}
  .modal-win,.modal-win[style]{position:fixed !important;left:0 !important;right:0 !important;
    top:auto !important;bottom:0 !important;
    width:auto !important;max-width:100vw;max-height:88vh;
    border-radius:14px 14px 0 0;animation:sheetUp var(--dur-3) var(--ease-out)}
  .modal-resize{display:none}
  .modal-h{border-radius:14px 14px 0 0}
  .modal-f{border-radius:0}
}
@keyframes sheetUp{from{transform:translateY(24px);opacity:.6}to{transform:none;opacity:1}}
/* Issue #27: optionaler Footer (Aktionsleiste) + Suchleiste zwischen Kopf und Body. */
.modal-f{padding:10px 20px;border-top:1px solid var(--border);background:var(--card);
  border-radius:0 0 var(--r-md) var(--r-md);display:flex;justify-content:flex-end;
  gap:8px;align-items:center;flex:0 0 auto}
.modal-pre{padding:10px 20px;border-bottom:1px solid var(--border);background:var(--card);
  flex:0 0 auto}
.modal-pre .set-inp{width:100%}

/* Detail-Sektion im Modal: helle Karte mit Kantenmarkierung statt Farbwäsche */
.modal-b .evt-dsection{
  background:var(--card);
  border:var(--hair) solid var(--border);
  border-left:3px solid var(--mod);
  border-radius:var(--r-sm);
  padding:12px 14px;
  margin-bottom:10px;
}
.modal-b .evt-dsection .lbl{color:var(--text2)}



/* ============================================================
   Kap. 300 (Gitea-Issue #104) — App-Sektionen als HOE HENGEBUNDENER Rahmen.
   Befund nach der ersten Runde: `--app-h` wurde gesetzt und die Innenflaechen
   waren korrekt begrenzt (gemessen 840px, kein Innen-Scrollbalken) — die SEKTION
   wuchs trotzdem (Kontakte 1005px, Dateien 1031px), weil Ribbon und Filterleiste
   obendrauf kamen. Deshalb jetzt der Rahmen:
     Sektion = Fensterhoehe minus Oberkante (--app-h, per JS gemessen),
     Inhalt flexibel: feste Leisten oben, Listenbereich darunter scrollt SELBST.
   Nur Apps mit eigenem Listen-/Tabellenbereich. Textseiten (Dokumentation,
   Status) bleiben im natuerlichen Fluss — dort ist Scrollen gewollt.
   ============================================================ */
:is(#sec-contacts, #sec-todo, #sec-git, #sec-files, #sec-mail, #sec-chat, #sec-cal){
  height:var(--app-h, auto);
  min-height:0;
}
/* Feste Leitern (Ribbon, Toolbar, Filter, Suche) behalten ihre Hoehe … */
:is(#sec-contacts, #sec-todo, #sec-git, #sec-files) > :is(.con-ribbonbar, .td-ribbonbar,
  .git-ribbonbar, .files-ribbonbar, .mrb-tabs, .app-toolbar, .con-filter, .git-toolbar,
  .files-toolbar, .td-toolbar, .cal-ribbonbar, .cal-toolbar, .cal-navbar){
  flex:0 0 auto;
}
/* … der App-Rahmen darunter nimmt den Rest und scrollt in sich. */
:is(#sec-contacts, #sec-todo, #sec-git, #sec-files) > :is(.con-app, .td-app, .git-app, .files-app){
  flex:1 1 auto;
  min-height:0;
  height:auto;
}
/* Kalender: die Sektion ist gebunden, der Kalender-Rahmen nimmt den Rest.
   Vorher stand hier eine geratene Rechnung (100vh - 66 - 44 - 60 - 60) —
   sie ergab 720px und liess 22px ueberstehen (live gemessen 972px Seite).
   WICHTIG: 'cal' muss in der Messliste von appHoeheSetzen() stehen, sonst
   bleibt --app-h leer -> height:auto -> der natuerliche Fluss kommt durch
   (live gemessen: Seite wuchs dadurch auf 1425px). Die Kalenderflaeche selbst
   scrollt in sich (Termine/Baum/Agenda), damit die Seite stehen bleibt. */
#sec-cal > .cal-app{
  flex:1 1 auto;
  min-height:0;
  height:auto;
  overflow:hidden;
}
#sec-cal .cal-grid-wrap, #sec-cal .cal-main, #sec-cal .cal-content{
  flex:1 1 auto;
  min-height:0;
  overflow-y:auto;
}
/* Dateien: Tabelle/Kacheln sind selbst die Scrollflaeche -> Hoehe vom Rahmen. */
#sec-files :is(.file-table, .files-tiles){
  max-height:100%;
  min-height:0;
}
/* Dateien: Ribbon/Brotkrumen/Werkzeuge bleiben oben stehen, die Liste nimmt
   den Rest und scrollt in sich (gemessen: main 950px, Seite scrollte dennoch
   -> ein Kind ragte hinaus). */
#sec-files > :is(.files-ribbonbar, .files-crumbs, #fileTools){flex:0 0 auto}
#sec-files > #filesList{flex:1 1 auto;min-height:0;overflow-y:auto}

/* ============================================================
   5) FORMULARFELDER — ruhig, präzise, klarer Fokus
   ============================================================ */
/* Kap. 300 (Gitea-Issue #103 „Meilisearch Suche Eingabefeld falsches CSS"):
   `.ds-input-wrap input` bekam hier dieselbe Feld-Behandlung wie `.set-inp`.
   Das Suchfeld liegt aber IN `.ds-input-wrap` — und die bringt Kante, Radius
   und Polster schon mit. Gemessen: das Feld war 1207px breit und trug eine
   eigene 1px-Kante mit 6px Radius -> ZWEI sichtbare Rahmen ineinander.
   Deshalb: im Wrapper bleibt nur die Schriftfarbe, der Rahmen kommt vom
   Wrapper (der faerbt sich bei Fokus ueber :focus-within). */
.set-inp{
  background:var(--card);
  border:var(--hair) solid var(--border);
  border-radius:var(--r-sm);
  color:var(--text);
  transition:border-color var(--dur-1) ease,box-shadow var(--dur-1) ease;
}
.ds-input-wrap input{
  background:transparent;
  border:0;
  color:var(--text);
}
.set-inp::placeholder{color:var(--text2);opacity:.65}
.set-inp:hover:not(:focus):not(:disabled){border-color:color-mix(in srgb,var(--text2) 45%,var(--border))}
.set-inp:focus{
  border-color:var(--mod);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--mod) 14%,transparent);
}
.set-lbl{
  font-size:11.5px;
  font-weight:600;
  color:var(--text2);
  letter-spacing:.2px;
  text-transform:none;
}

/* ============================================================
   6) BUTTONS — eindeutige Hierarchie
   primär (gefüllt) · sekundär (Kontur) · destruktiv (rot)
   ============================================================ */
.btn-p,.btn-s,.btn-d{
  display:inline-flex;align-items:center;gap:7px;
  border-radius:var(--r-sm);
  padding:9px 17px;
  font-size:13.5px;
  font-weight:600;
  font-family:inherit;
  cursor:pointer;
  transition:background var(--dur-1) ease,border-color var(--dur-1) ease,filter var(--dur-1) ease,box-shadow var(--dur-1) ease;
}
.btn-p{
  background:var(--mod);color:#fff;border:var(--hair) solid transparent;
  box-shadow:0 1px 2px color-mix(in srgb,var(--mod) 40%,transparent);
}
.btn-p:hover{filter:brightness(1.08);box-shadow:0 3px 10px color-mix(in srgb,var(--mod) 34%,transparent)}
.btn-p:active{filter:brightness(.95)}
.btn-p:disabled{opacity:.45;cursor:default;box-shadow:none}
.btn-s{background:var(--card);color:var(--text);border:var(--hair) solid var(--border)}
.btn-s:hover{
  background:color-mix(in srgb,var(--text) 5%,var(--card));
  border-color:color-mix(in srgb,var(--text2) 40%,var(--border));
}
.btn-d{background:var(--danger);color:#fff;border:var(--hair) solid transparent}
.btn-d:hover{filter:brightness(1.08)}
.btn-s svg,.btn-d svg,.btn-p svg{stroke-width:1.8}
.form-actions{display:flex;gap:9px;align-items:center;flex-wrap:wrap}

/* ============================================================
   7) LISTEN — Auswahl als Kante, nicht als Farbwanne
   ============================================================ */
.mail-item{transition:background var(--dur-1) ease}
.mail-item:hover{background:color-mix(in srgb,var(--text) 3.5%,var(--card))}
.mail-item.sel{
  background:color-mix(in srgb,var(--mod) 7%,var(--card));
  box-shadow:inset 3px 0 0 var(--mod);
}
.mail-item.unread{background:var(--card)}
.mail-item.unread .from,.mail-item.unread .subj{font-weight:700;color:var(--text)}
.mail-item.unread .time{color:var(--mod);font-weight:600}
.mail-item.sel .from,.mail-item.sel .subj{font-weight:600}

.con-item{transition:background var(--dur-1) ease}
.con-item:hover{background:color-mix(in srgb,var(--text) 3.5%,var(--card))}
.con-item.sel{
  background:color-mix(in srgb,var(--mod) 7%,var(--card));
  box-shadow:inset 3px 0 0 var(--mod);
}
.cf-btn{
  border:var(--hair) solid var(--border);
  background:var(--card);
  border-radius:var(--r-sm);
  color:var(--text2);
  font-weight:600;
}
.cf-btn:hover{background:var(--hover);color:var(--text)}
.cf-btn.act{
  background:color-mix(in srgb,var(--mod) 10%,var(--card));
  border-color:color-mix(in srgb,var(--mod) 42%,var(--border));
  color:var(--mod);
}
/* Abzeichen: klein, klar, nicht bunt */
.con-badge.own{background:color-mix(in srgb,var(--mod) 11%,var(--card));color:var(--mod)}
.con-badge.shared{background:color-mix(in srgb,var(--todo) 12%,var(--card));color:var(--todo)}
.con-badge.auto{background:var(--hover);color:var(--text2)}

/* ============================================================
   8) IKONOGRAFIE — der "1995"-Punkt
   Lucide-Default ist stroke-width:2, das wirkt bei 14-18px klobig.
   Feiner Strich + dichtere Optik = moderner.
   ============================================================ */
.rail i,.rail svg{stroke-width:1.6}
.mc-btn svg,.mc-btn i,
.mrb-tab svg,.mc-rb-tab svg,
.btn-s svg,.btn-d svg,.btn-p svg,
.tb-btn svg,.mw-h svg,.modal-h svg{stroke-width:1.75}
/* Sehr kleine Glyphen brauchen mehr Gewicht, sonst verschwinden sie */
.con-badge svg,.cf-n svg,.mc-chip svg,.mc-sug-x svg,
.con-mail-btn svg,.mt-f svg,.mc-btn-l + svg{stroke-width:2}

/* ============================================================
   9) FOKUS & BARRIEREFREIHEIT
   ============================================================ */
.mc-btn:focus-visible,.btn-s:focus-visible,.btn-d:focus-visible,.btn-p:focus-visible,
.cf-btn:focus-visible,.mrb-tab:focus-visible,.mc-rb-tab:focus-visible,
.set-inp:focus-visible{outline:2px solid var(--mod);outline-offset:2px}

/* ============================================================
   10) KONTRAST-THEME: strikt schwarz/weiß, keine Farbtöne
   ============================================================ */
html[data-theme="kontrast"] .mw-h,
html[data-theme="kontrast"] .modal-h{background:#000;color:#fff}
html[data-theme="kontrast"] .mail-ribbonbar,
html[data-theme="kontrast"] .cal-ribbonbar,
html[data-theme="kontrast"] .ct-ribbonbar,
html[data-theme="kontrast"] .git-ribbonbar,
html[data-theme="kontrast"] .mrb-panels,
html[data-theme="kontrast"] .modal-b,
html[data-theme="kontrast"] .mw-b{background:#fff}
html[data-theme="kontrast"] .btn-p{background:#000;color:#fff;box-shadow:none}
html[data-theme="kontrast"] .btn-s{border:1px solid #000;background:#fff;color:#000}
html[data-theme="kontrast"] .mail-item.sel,
html[data-theme="kontrast"] .con-item.sel{background:var(--accent-light);box-shadow:inset 3px 0 0 var(--accent)}

/* ============================================================
   11) DUNKLES THEME: Farbköpfe abdunkeln, damit Weiß lesbar bleibt
   ============================================================ */
html[data-theme="dark"] .mw-h,
html[data-theme="dark"] .modal-h{
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--mod) 38%,var(--bg)) 0%,
    color-mix(in srgb,var(--mod) 24%,var(--bg)) 100%);
}

/* ============================================================
   12) FEINSCHLIFF: Ribbon-Höhe straffen
   Die Panels waren 80px hoch (Icon 24 + zweizeiliges Label + Padding).
   Einzeilige Labels + engere Icon-Beschriftung sparen ~22px ohne
   Informationsverlust — der Ribbon wirkt dadurch ruhiger.
   ============================================================ */
.mc-btn.big{min-height:44px;padding:3px 7px 4px;gap:2px}
.mc-btn.big > svg,.mc-btn.big > i{width:19px;height:19px}
.mc-btn.big .mc-btn-l{
  font-size:10px;line-height:1.15;
  max-width:118px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.mail-ribbonbar .mrb-panels,.cal-ribbonbar .mrb-panels,.ct-ribbonbar .mrb-panels,
.cal-win-ribbon .mrb-panels,.mc-ribbon .mc-rb-panels,.mrb-panels,.mc-rb-panels{padding:5px 10px 6px}
.mc-grp-lbl{padding-top:4px;font-size:10px}

/* ============================================================
   13) MAIL-DETAILKOPF — Redesign (Kap. 211)
   Grundsatz wie beim Ribbon: neutrale Fläche, präzise Kanten, Farbe nur als
   Signal. Kein Karten-Look (User-Vorgabe Kap. 79: Header FLACH auf der Seite).

   STRUKTUR (vorher eine einzige Flex-Zeile):
     .mh-top    Avatar · Absender ····· Zeit + Öffnen
     .subj      Betreff + Badges
     .meta-lines  An:/CC:/BCC: über die VOLLE Breite

   Warum: Die Zeit-Spalte (139px, flex:none) saß neben dem Textblock und stahl
   ihm die Breite — bei 1280px blieben den Empfängern nur 223px, der CC brach
   in 3 Zeilen um, obwohl rechts Platz war. Jetzt gehört die Zeit zum Absender
   (sie IST die Nachrichtenzeit) und der Empfängerblock hat volle Breite.
   WICHTIG: `.meta` bleibt die äußere Klasse (JS liest .meta .av-wrap[data-email]
   und .meta .rc-chip[data-email] für Antworten) — nur die Innenstruktur ändert sich.
   ============================================================ */
/* KEINE eigene Trennlinie: die Kopf-Abgrenzung liefert .md-head (styles.css)
   mit Verlauf + 1px Kante. Eine zweite Linie direkt darüber war eine
   Doppel-Trennlinie (User-Kritik Kap. 212). */
.meta{
  display:block;                 /* war: flex — beendet das Nebeneinander */
  margin-bottom:2px;
  padding:2px 0 6px;
  border-bottom:none;
  background:transparent;
}
/* --- Zeile 1: Avatar · Absender · Zeit --- */
.mh-top{display:flex;align-items:center;gap:11px;min-width:0}
.mh-top .av-wrap{flex:none}
.mh-who{flex:1 1 auto;min-width:0}
.mh-who .who{
  font-size:15px;font-weight:600;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.mh-who .who-em{
  font-size:11.5px;color:var(--text2);font-weight:400;margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* Zeit ruhig und rechtsbündig, mit kleinem Uhr-Symbol als Anker */
.meta .meta-time{
  flex:none;margin-left:auto;padding-top:0;
  display:inline-flex;align-items:center;gap:6px;
  font-size:11.5px;color:var(--text2);white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.mh-clock{width:12px;height:12px;flex:none;opacity:.6;stroke-width:1.8}
/* --- Zeile 2: Betreff — die wichtigste Information, klar abgesetzt ---
   Betreff und Badges sind getrennte Kinder: so bricht der ganze Badge-Block
   gemeinsam um und nie ein einzelner Badge allein in eine neue Zeile. */
.meta .subj{
  font-size:16px;font-weight:600;color:var(--text);
  width:100%;padding:10px 0 0;margin:0;
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  letter-spacing:-.1px;row-gap:6px;
}
.meta .subj .subj-txt{
  flex:1 1 auto;min-width:0;
  overflow-wrap:anywhere;
}
.meta .subj .subj-badges{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;
  white-space:nowrap;
}
/* --- Zeile 3+: Empfänger über die VOLLE Breite --- */
.meta .meta-lines{font-size:12px;color:var(--text2);margin-top:7px;line-height:1.5}
.meta .when{display:flex;align-items:flex-start;gap:7px;margin-top:3px;width:100%}
.meta .when .rc-lbl{
  flex:none;padding-top:3px;line-height:1.4;
  font-size:10.5px;font-weight:600;letter-spacing:.4px;text-transform:uppercase;
  color:var(--text2);
}
.meta .when .rc-vals{flex:1 1 auto;min-width:0;display:block;line-height:1.4}
/* Chips: kompakt, ruhig, klar — Farbe nur bei Interaktion */
.rc-chip{
  display:inline-flex;align-items:center;gap:5px;
  padding:2px 9px 2px 3px;margin:1px 3px 1px 0;
  border:1px solid var(--border);border-radius:999px;
  background:var(--card);
  font-size:12px;font-weight:500;color:var(--text);
  cursor:pointer;
  transition:background var(--dur-1) ease,border-color var(--dur-1) ease;
  max-width:100%;
}
.rc-chip .mc-chip-av{width:20px;height:20px;font-size:10.5px;flex:none;border-radius:50%}
.rc-chip:hover{
  border-color:color-mix(in srgb,var(--mod) 45%,var(--border));
  background:color-mix(in srgb,var(--mod) 6%,var(--card));
  color:var(--text);
}
.rc-chip.rc-own{
  background:color-mix(in srgb,var(--ok) 7%,var(--card));
  border-color:color-mix(in srgb,var(--ok) 32%,var(--border));
  cursor:default;
}
.rc-chip .rc-self{color:var(--ok);font-weight:600;font-size:11px}
/* Badges neben dem Betreff: klein, konturiert, nicht bunt */
.meta .hdr-badge,.meta .prio-badge{
  display:inline-flex;align-items:center;gap:4px;
  font-size:10.5px;font-weight:600;line-height:1;
  padding:3px 7px;border-radius:999px;
  border:1px solid var(--border);background:var(--card);color:var(--text2);
}
.meta .prio-badge.prio-high{color:var(--danger);border-color:color-mix(in srgb,var(--danger) 35%,var(--border))}
.meta .prio-badge.prio-low{color:var(--text2)}
.meta .meta-popbtn{opacity:.55}
.meta .meta-popbtn:hover{opacity:1}

/* Dunkles Theme: Zeit/Betreff-Kontrast bleibt, Kante etwas heller */
html[data-theme="dark"] .meta{border-bottom-color:color-mix(in srgb,var(--mod) 22%,var(--border))}
html[data-theme="dark"] .rc-chip{background:color-mix(in srgb,var(--mod) 5%,var(--card))}

/* ============================================================
   14) EMPFÄNGERZEILEN: Umbruch nur, wenn wirklich nötig
   `display:block` (statt inline) nimmt den Zeilenboxen die zusätzliche
   Inline-Lücke; zusammen mit der vollen Breite passen To/Cc/Bcc jetzt in
   EINE Zeile, solange der Platz reicht.
   ============================================================ */
.meta .when .rc-vals .rc-chip:last-child{margin-right:0}

/* ============================================================
   15) AKTIONSLEISTE im Kopf — flach, ruhig, klar getrennt
   Vorher: Reihe nackter Buttons ohne Hierarchie zwischen Antworten (mit Text)
   und Organisieren. Jetzt: Antworten mit Beschriftung, Organisieren als
   Symbolgruppe, dazwischen eine Trennlinie, und die Trennkante zum Text.
   ============================================================ */
/* Aktionsleiste: EINE Kante oben zur Abgrenzung vom Kopf, keine untere
   (der Textkörper wird vom .md-scroll geführt). Zwei Linien eng beieinander
   wirkten unruhig (User-Kritik Kap. 212). */
.reply-sec{
  display:flex;align-items:center;gap:4px;flex-wrap:wrap;
  padding:10px 2px 8px;
  border-top:1px solid var(--border);
  border-bottom:none;
}
.reply-sec.top-actions{border-top:none}
/* WICHTIG (Kap. 212): Die Aktions-Buttons hatten aus styles.css
   `.reply-sec.top-actions .re-act{width:28px;height:28px}` — eine FESTE Box.
   Mein padding:6px 10px ließ darin nur 8px Innenraum übrig, worauf der Flex die
   Icons zusammendrückte (gemessen: 15px-Icon wurde zu 6px breit, das zweite von
   „Allen antworten" auf 2px). Deshalb hier width/height aufheben und die Icons
   mit flex:none gegen Quetschen schützen. */
.reply-sec .re-act,.reply-sec.top-actions .re-act{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  width:auto;height:auto;min-width:0;
  padding:7px 11px;border-radius:var(--r-sm);
  border:1px solid transparent;background:transparent;
  color:var(--text2);cursor:pointer;
  font-size:12.5px;font-weight:500;white-space:nowrap;
  transition:background var(--dur-1) ease,color var(--dur-1) ease,border-color var(--dur-1) ease;
}
/* Icons NIE quetschen (flex-shrink:0) — auch nicht im zusammengesetzten
   „Allen antworten"-Button (Antwort-Pfeil + Personen-Symbol). */
.reply-sec .re-act svg,.reply-sec .re-act i,
.reply-sec.top-actions .re-act svg,.reply-sec.top-actions .re-act i{
  flex:none;width:15px;height:15px;stroke-width:1.75;
}
.reply-sec .re-act svg + svg,.reply-sec.top-actions .re-act svg + svg{
  margin-left:-5px;   /* das zweite Symbol leicht überlappen lassen */
}
.reply-sec .re-act:hover,.reply-sec.top-actions .re-act:hover{
  background:color-mix(in srgb,var(--mod) 8%,var(--card));
  border-color:color-mix(in srgb,var(--mod) 26%,var(--border));
  color:var(--mod);
}
/* Hierarchie (User-Freigabe Kap. 212): die Hauptaktion ist gefüllt, alles
   andere bleibt ruhig. Vorher sahen alle fünf Buttons identisch aus. */
.reply-sec .re-act.primary,
.reply-sec.top-actions .re-act.primary{
  background:var(--mod);border-color:var(--mod);color:#fff;font-weight:600;
  box-shadow:0 1px 2px color-mix(in srgb,var(--mod) 35%,transparent);
}
.reply-sec .re-act.primary:hover,
.reply-sec.top-actions .re-act.primary:hover{
  filter:brightness(1.07);color:#fff;background:var(--mod);
}
.reply-sec .re-act.primary svg,.reply-sec .re-act.primary i{color:#fff}
.reply-sec .re-sep,.reply-sec.top-actions .re-sep{
  width:1px;height:20px;background:var(--border);
  margin:0 6px;flex:none;
}

/* Beschriftung der Aktions-Buttons.
   WICHTIG: .re-lbl erbte eine graue Farbe (rgb(71,85,105)) aus einer anderen
   Label-Regel — im GEFÜLLTEN Primärbutton war die Schrift dadurch grau auf
   Petrol statt weiß (live gemessen). Farbe deshalb explizit setzen. */
.reply-sec .re-lbl{white-space:nowrap;color:inherit;font:inherit}
.reply-sec .re-act.primary .re-lbl,
.reply-sec.top-actions .re-act.primary .re-lbl{color:#fff;font-weight:600}
.reply-sec .re-ic-2{width:11px;height:11px;margin-left:-4px}

/* ============================================================
   16) BETREFF BEGRENZEN (User-Freigabe Kap. 212, Punkt 2)
   Lange Betreffs füllten den Kopf mehrzeilig. Jetzt max. 2 Zeilen mit
   Auslassung; der vollständige Text steht im title-Tooltip.
   ============================================================ */
.meta .subj .subj-txt{
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
}

/* ============================================================
   17) MODAL-VARIANTEN ohne Inline-Styles (Kap. 213)
   Drei Modale umgingen das gemeinsame Modalsystem mit Inline-Styles und
   wichen dadurch vom Design ab (Kopf ohne .mt -> keine weiße Schrift,
   hartkodierte Maße/Paddings). Jetzt eigene Klassen in ui-2026.css:
     .modal-pick      Kontakte auswählen (An/CC/BCC)
     .modal-ai-sugg   KI-Lösungsvorschlag
   ============================================================ */
.modal-pick{
  width:520px;max-width:92vw;max-height:80vh;
  display:flex;flex-direction:column;
}
/* Issue #27: Picker geht jetzt ueber openModal() — der modal-b-Body traegt keine
   eigene Polsterung, damit die Liste die volle Breite nutzt und der Body scrollt. */
.modal-pick-body{padding:0}
.modal-pick-search{padding:10px 14px;border-bottom:1px solid var(--border)}
.modal-pick-search .set-inp{width:100%}
.modal-pick-list{flex:1;overflow-y:auto;padding:8px;min-height:120px}
.modal-pick-foot{
  padding:10px 14px;border-top:1px solid var(--border);
  display:flex;justify-content:space-between;align-items:center;gap:8px;
}
.modal-pick-count{font-size:12px;color:var(--text2)}

.modal-ai-sugg{width:560px;max-width:94vw;overflow:hidden}
/* Issue #27: Inhaltsklassen des KI-Vorschlags (ersetzt die frueheren Inline-Styles).
   Farbe bleibt Signal -> Empfehlung als Karte mit 3px Modulanker, Aktions-Chip
   im Modul-Tint statt harter Akzent-Vollflaeche. */
.modal-ai-sugg .ai-sugg-subj{font-size:13.5px;font-weight:700;margin-bottom:8px}
.modal-ai-sugg .ai-sugg-sum{font-size:13px;color:var(--text2);margin-bottom:12px;line-height:1.5}
.modal-ai-sugg .ai-sugg-reco{font-size:13px;padding:10px 12px;border-radius:var(--r-sm);
  background:var(--hover);border-left:3px solid var(--mod);margin-bottom:10px}
.modal-ai-sugg .ai-sugg-aktion{display:flex;gap:7px;align-items:center;margin-bottom:12px}
.modal-ai-sugg .ai-sugg-aktion .pl-q{
  background:color-mix(in srgb,var(--mod) 14%,transparent);color:var(--mod)}
.modal-ai-sugg .ai-sugg-aktion-l{font-size:13px;font-weight:600}
.modal-ai-sugg .ai-sugg-draft-l{font-size:12px;font-weight:600;color:var(--text2);margin-bottom:5px}
.modal-ai-sugg .ai-sugg-draft{font-size:13px;line-height:1.55;padding:12px;
  border:1px solid var(--border);border-radius:var(--r-sm);background:var(--bg);
  white-space:pre-wrap;max-height:180px;overflow-y:auto}

/* Modaler Fußbereich, wenn kein .form-actions verwendet wird */
.modal-b .form-actions{margin-top:12px;justify-content:flex-end}

/* ============================================================
   18) MODAL-KOPF: Trennlinie entfernen (Verlauf trägt die Abgrenzung)
   Der Kopf hatte Verlauf UND eine 1px-Unterkante — zusammen mit dem
   Verlauf wirkte das doppelt. Farbiger Verlauf + Schattenkante genügt.
   ============================================================ */
.modal-h{border-bottom:none}

/* Textarea im Signatur-Modal: set-inp deckt Höhe/Resize nicht ab */
.sig-ta{width:100%;min-height:170px;resize:vertical;line-height:1.5}
.sig-lbl{margin-top:10px;display:block}
.sig-actions{margin-top:12px}

/* ============================================================
   19) TERMIN-/VIDEOKONF-FENSTER: kompakter ohne Info-Verlust (Kap. 214)
   Der Inhalt war 828px hoch, das Fenster 640px -> der User musste scrollen
   UND größer ziehen. Zwei Hebel: (a) Auto-Höhe in mwNew() (Fenster wächst mit
   dem Inhalt), (b) hier die vertikalen Abstände straffen. Es wird NICHTS
   entfernt oder gekürzt — nur dichter gesetzt.
   ============================================================ */
.cal-win-field{gap:2px}
/* Hinweistexte: gleiche Info, engere Zeilenhöhe, weniger Abstand zum Feld */
.cal-win-body .set-lbl{letter-spacing:.2px}
.cal-win-tip{color:var(--text2);margin-top:2px;
  display:flex;gap:5px;align-items:flex-start;
}
.cal-win-tip svg{width:11px;height:11px;flex:none;margin-top:2px;opacity:.7}
/* Checkbox-Zeile (Ganztägig / Talk-Raum) kompakter */
.cal-win-allday{gap:7px;border-radius:var(--r-sm)}
.cal-win-allday .sub{font-size:11.5px;color:var(--text2);line-height:1.35;display:block;margin-top:1px}
/* Talk-Zeile bekommt das Markenlogo als Eyecatcher (User-Wunsch) */
.cal-win-talk{display:flex;align-items:center;border:1px solid var(--border);border-radius:var(--r-sm);cursor:pointer}
.cal-win-talk.on{border-color:color-mix(in srgb,var(--talk) 45%,var(--border));background:color-mix(in srgb,var(--talk) 7%,var(--card))}
.cal-win-talk .nc-logo{flex:none;
  background:var(--grad-talk);
  display:inline-flex;align-items:center;justify-content:center;
}
.cal-win-talk .nc-logo svg{fill:#fff}
.cal-win-talk .t-txt{min-width:0}
.cal-win-talk .t-title{font-weight:600;color:var(--text);display:block}
/* Terminfenster: Body darf scrollen, aber nur wenn wirklich nötig */
.mw .cal-win-body{overflow-y:auto}

/* ============================================================
   20) VIDEOKONFERENZ-BUTTON im Mail-Ribbon (Kap. 214)
   Nextcloud-Talk-Markenlogo als Eyecatcher (User-Wunsch). Das Logo sitzt in
   einem eigenen Chip, damit es sich wie die übrigen Ribbon-Icons verhält,
   aber als Marke erkennbar bleibt (Markenfarbe statt Modulfarbe).
   ============================================================ */
.mc-btn.big > .mc-vc-ico{
  width:19px;height:19px;flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:5px;
  background:var(--grad-talk);   /* Nextcloud-Blau */
}
.mc-btn.big > .mc-vc-ico svg{width:14px;height:14px;fill:#fff;flex:none}
.mc-btn-vc:hover > .mc-vc-ico{filter:brightness(1.08)}
/* Im Kontrast-Theme bleibt es einfarbig (Barrierefreiheit) */
html[data-theme="kontrast"] .mc-btn.big > .mc-vc-ico{background:#000;border:1px solid #fff}

/* ============================================================
   21) TERMINFENSTER: Ribbon kompakter + Formular dichter (Kap. 214)
   Messung: Fensterhöhe war auf 640px fixiert, Inhalt 745px. Der Ribbon im
   Fenster war allein 104px hoch (Icon-Chips + zweizeilige Labels). Er wird
   hier auf ~64px gestrafft (einzeilige Labels, engere Chips), danach passt der
   Inhalt bei 900/800px Viewport vollständig — ohne Scrollen, ohne Ziehen.
   Es wird NICHTS entfernt: alle Felder und Hinweise bleiben erhalten.
   ============================================================ */
/* Fenster-Ribbon: Icon-Chips kleiner, Labels einzeilig */
.cal-win-ribbon .mc-btn.big{gap:1px}
.cal-win-ribbon .mc-btn.big .mc-btn-l{font-size:10px;line-height:1.1}
/* Formular: vertikale Abstände weiter straffen */
.cal-win-body .set-lbl{font-size:11px}
.cal-win-body .set-inp{font-size:13px}
.cal-win-body textarea.set-inp{height:auto;}
.cal-win-talk{gap:7px}
.cal-win-talk .nc-logo{width:23px;height:23px;border-radius:6px}
.cal-win-talk .nc-logo svg{width:15px;height:15px}
.cal-win-talk .t-title{font-size:12px}
.cal-win-talk .sub{font-size:11px}
.cal-win-tip{font-size:10.5px;line-height:1.3}
.cal-win-grid2{gap:7px}

/* Kap. 214 Feinschliff: Ziel ist, dass das Terminfenster auch bei 800px
   Viewport-Höhe vollständig passt (gemessen fehlten 31px). Gestrafft werden
   nur Abstände/Ribbon-Höhe — KEINE Felder, KEINE Hinweistexte entfallen. */
.cal-win-ribbon .mrb-panels{padding:2px 8px 3px}
.cal-win-ribbon .mc-btn.big{min-height:34px;padding:1px 5px 2px}
.cal-win-ribbon .mc-btn.big > svg,
.cal-win-ribbon .mc-btn.big > i{width:16px;height:16px}
.cal-win-ribbon .mrb-tab{padding:5px 11px 4px;font-size:11.5px}
.cal-win-body{gap:5px;padding:7px 12px 9px}
.cal-win-body .set-inp{height:31px}
.cal-win-body textarea.set-inp{min-height:52px}
.cal-win-talk{padding:4px 8px}
.cal-win-allday{padding:4px 7px}

/* Kap. 214: Bei knappem Viewport werden die Hinweistexte ausgeblendet — die
   Info bleibt über den Tooltip am Info-Icon erreichbar (nichts geht verloren).
   Erst unterhalb 790px Nutzhöhe, wo das Formular sonst scrollen müsste. */
@media (max-height: 800px){
  .cal-win-tip span{display:none}
  .cal-win-tip{cursor:help;margin-top:0}
  .cal-win-tip svg{opacity:.85}
}

/* ============================================================
   22) MODAL-SEGMENTIERUNG: greifbare Abschnitte (Kap. 215)
   User: "das ganze modal wirkt jetzt ziemlich flach, ohne greifbare
   segmente, das auge verliert sich."
   Ursache (gemessen): alle Felder sind randlos (border:0, bg:transparent,
   padding:0) und gleich gewichtet — 8 Zeilen ohne einen einzigen Anker.
   Gegenteil von "EIN Farbanker pro Ansicht" (Kap. 209): dort ging es um
   Flächen-TÖNUNG als Brei. Hier fehlt die STRUKTUR.
   Lösung: drei echte Segmente mit sichtbarer Kante + Titelzeile. Farbe nur
   als schmaler Anker links (4px) — kein Vollflächen-Tint.
   ============================================================ */
.cal-win-sec{
  border:1px solid var(--border);border-radius:var(--r-md);
  background:var(--card);overflow:hidden;
}
.cal-win-sec + .cal-win-sec{margin-top:2px}
.cal-win-sec-h{
  display:flex;align-items:center;gap:7px;
  padding:7px 11px;font-size:11.5px;font-weight:700;letter-spacing:.4px;
  text-transform:uppercase;color:var(--text2);
  background:color-mix(in srgb, var(--mod) 5%, var(--card));
  border-bottom:1px solid var(--border);
  border-left:4px solid var(--mod);
}
.cal-win-sec-h svg{width:13px;height:13px;flex:none;opacity:.75}
.cal-win-sec-b{padding:9px 11px 10px;display:flex;flex-direction:column;gap:7px}
/* Innerhalb eines Segments keine zusätzlichen Trennlinien */
.cal-win-sec-b .cal-win-grid2{gap:8px}
/* ============================================================
   Issue #26 — FORMULAR-SEGMENTE, app-übergreifend
   Das abgenommene Muster (.cal-win-sec*) hiess nach dem Kalender und wurde
   deshalb nur dort benutzt. `.fm-sec*` sind Aliase mit identischen Werten —
   damit können ALLE Apps das Muster nutzen, ohne eine Kalender-Klasse zu
   „borgen". Farbe bleibt Signal: 4px Anker + 5% Tint, keine Vollfläche.
   ============================================================ */
.fm-sec{
  border:1px solid var(--border);border-radius:var(--r-md);
  background:var(--card);overflow:hidden;
}
.fm-sec + .fm-sec{margin-top:2px}
.fm-sec-h{
  display:flex;align-items:center;gap:7px;
  padding:7px 11px;font-size:11.5px;font-weight:700;letter-spacing:.4px;
  text-transform:uppercase;color:var(--text2);
  background:color-mix(in srgb, var(--mod) 5%, var(--card));
  border-bottom:1px solid var(--border);
  border-left:4px solid var(--mod);
}
.fm-sec-h svg{width:13px;height:13px;flex:none;opacity:.75}
.fm-sec-b{padding:9px 11px 10px;display:flex;flex-direction:column;gap:7px}
.fm-sec-b > *{min-height:auto}
.fm-body{display:flex;flex-direction:column;gap:10px}
/* Zwei Felder nebeneinander in einem Segment (z. B. Vorname/Firma) */
.fm-grid2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
@media(max-width:560px){.fm-grid2{grid-template-columns:1fr}}
/* Label im Segment: kleiner als das Standard-Label, damit die Segment-Titel fuehren */
.fm-sec-b .set-lbl{font-size:11.5px;font-weight:600;color:var(--text2);margin-bottom:3px}
.fm-sec-b .set-inp{width:100%}
/* Erklaer-/Hinweistext innerhalb eines Segments (Icon + Text) */
.fm-hint{display:flex;gap:7px;align-items:flex-start;font-size:12px;color:var(--text2);
  line-height:1.45;padding:7px 9px;border-radius:var(--r-sm);
  background:color-mix(in srgb,var(--mod) 4%,var(--bg))}
.fm-hint svg{width:13px;height:13px;flex:none;margin-top:1px;opacity:.8}
/* Aktionsleiste: Speichern deutlicher als Hauptaktion */
.cal-win-body .mc-grp-row{gap:6px}
/* Eingeklapptes Orts-Feld (Ribbon-Schalter "Ort") */
.cal-win-collapsed{display:none}
/* Kurzes Aufleuchten, wenn ein Ribbon-Schalter ein Feld adressiert */
.cal-win-flash{animation:calWinFlash 1.05s ease-out}
@keyframes calWinFlash{
  0%{box-shadow:0 0 0 3px color-mix(in srgb,var(--mod) 42%,transparent)}
  100%{box-shadow:0 0 0 0 transparent}
}
/* Ribbon-Schalter im AKTIVEN Zustand (Ganztägig/Talk/Serie/Erinnerung/Ort) */
.cal-win-ribbon .mc-btn.act{background:color-mix(in srgb,var(--mod) 13%,var(--card))}
.cal-win-ribbon .mc-btn.act > svg,
.cal-win-ribbon .mc-btn.act > i{color:var(--mod)}

/* ============================================================
   23) TERMINMODAL: Verkleinern darf keine Felder verschlucken (Kap. 216)
   USER-BUG: "wenn ich es kleiner ziehe verschwinden felder und ich sehe sie
   nicht mehr".
   GEMESSEN: Beim Verkleinern wurden die Segmente GESTAUCHT statt zu scrollen --
   .cal-win-sec war ein Flex-Kind ohne flex-shrink:0, also schrumpfte es von
   189px auf 65px und der Inhalt wurde an der Segmentkante abgeschnitten
   (overflow:hidden). scrollHeight == clientHeight => nicht scrollbar.
   FIX: Segmente duerfen NICHT schrumpfen (flex:none) und die Kinder duerfen
   nicht unter ihre natuerliche Hoehe gedrueckt werden (min-height:auto); der
   Body scrollt dann als Ganzes.
   ============================================================ */
.cal-win-body > .cal-win-sec{
  flex:0 0 auto;          /* nicht stauchen */
  min-height:auto;
}
.cal-win-sec-b > *{min-height:auto}
/* Der Body ist der Scroll-Container -- er muss ueber den Segmenten liegen */
.cal-win-body{overflow-y:auto;overflow-x:hidden;min-height:0}
/* Sichtbarer Scroll-Hinweis, damit klar ist, dass mehr Inhalt folgt */
.cal-win-body::-webkit-scrollbar{width:9px}
.cal-win-body::-webkit-scrollbar-thumb{
  background:color-mix(in srgb,var(--mod) 32%,var(--border));
  border-radius:6px;border:2px solid transparent;background-clip:content-box;
}
.cal-win-body::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--mod) 55%,var(--border))}
.cal-win-body::-webkit-scrollbar-track{background:transparent}

/* Trennung Ribbon <-> Inhalt (User: "das ribbon verschmilzt mit dem inhalt") */
.cal-win-ribbon{box-shadow:inset 0 -1px 0 var(--border), 0 2px 5px rgba(15,23,42,.05)}
/* Die erste Runde im Body bekommt etwas Luft unter dem Ribbon */
.cal-win-body{padding-top:11px}

/* ============================================================
   24) TRENNUNG Ribbon <-> Inhalt in Fenstern (Kap. 216)
   User: "das ribbon im terminmodal verschmilzt mit dem inhalt darunter, hier
   waere eine trennung gut oder?" + "diese trennung haben wir auch im mailmodal
   bei der view ansicht im neuen tab oeffnen".
   Beide Fenster (.mw) haben oben einen Ribbon direkt ueber dem scrollenden
   Body — ohne Kante wirkt der Ribbon wie ein Teil des Formulars und das Auge
   findet den Anfang des Inhalts nicht.
   Fix: Ribbon bekommt eine klare Unterkante + leichten Abstand;
   gilt fuer Termin- UND Mail-Fenster (jede .mw mit Ribbon).
   ============================================================ */
.mw .cal-win-ribbon,
.mw .mw-ribbon,
.mw .mc-ribbon{
  box-shadow:inset 0 -1px 0 var(--border), 0 3px 7px rgba(15,23,42,.06);
  position:relative;
  z-index:var(--z-base);
}
/* Optionaler Block (Wiederholung/Erinnerung) — nur per Ribbon erreichbar */
.cal-win-sec[hidden]{display:none}
.cal-win-sec.cal-win-optional .cal-win-sec-h{
  background:color-mix(in srgb,var(--mod) 8%,var(--card));
}

/* ============================================================
   25) KALENDER-LEGENDE: Zahnrad, Nur-lesen-Marke, Zeilen-Layout (Kap. 218)
   User: "alle kalender gleiche farbe. mit zahnradsymbol neben kalender sollte
   ein optionsdialog aufgehen um weitere optionen zu sehen".
   Farben kommen jetzt vom Server (individuell) bzw. aus der Palette; hier nur
   die Bedienelemente. Das Zahnrad ist dezent und wird erst bei Hover kräftig —
   die Zeile soll nicht unruhig wirken.
   ============================================================ */
.cal-ovl-it{display:flex;align-items:center;gap:6px}
.cal-ovl-it .ovl-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cal-ovl-it .ovl-ro{
  font-size:10.5px;letter-spacing:.3px;text-transform:uppercase;
  color:var(--text2);border:1px solid var(--border);border-radius:4px;
  padding:0 3px;margin-left:4px;vertical-align:1px;
}
.cal-ovl-it.ro .ovl-dot{opacity:.55}
.cal-ovl-it .ovl-gear{
  display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;padding:0;flex:none;
  background:none;border:none;border-radius:4px;cursor:pointer;
  color:var(--text2);opacity:.45;transition:opacity var(--dur-1),background var(--dur-1);
}
.cal-ovl-it .ovl-gear svg{width:13px;height:13px}
.cal-ovl-it:hover .ovl-gear{opacity:1}
.cal-ovl-it .ovl-gear:hover{background:color-mix(in srgb,var(--mod) 14%,var(--card));color:var(--mod)}
/* Aktionszeile im Optionsdialog (3 Buttons) */
.cal-win-body .form-actions{display:flex;gap:6px;flex-wrap:wrap;padding-top:2px}

/* ============================================================
   26) RECHTE KLAR ANZEIGEN + TERMIN-LEGENDE (Kap. 219)
   User: "im optionsdialog den zugriff als freitextfeld?-schlecht ... jetzt mal
   ordentlich anzeigen, in welchem kalender hab ich welche rechte? - das soll mir
   klar angezeigt werden." Freitextfeld ersetzt durch Rechte-Karte mit Zustand
   und Fähigkeits-Liste. Farbe bleibt Signal (grün=ja, grau/rot=nein).
   ============================================================ */
.cal-acc-card{border:1px solid var(--border);border-radius:8px;padding:10px 12px;background:var(--card)}
.cal-acc-card.ro{border-color:color-mix(in srgb,var(--text2) 28%,var(--border))}
.cal-acc-card.rw{border-left:3px solid var(--mod)}
.cal-acc-state{display:flex;align-items:center;gap:7px;margin-bottom:8px}
.cal-acc-state svg{width:15px;height:15px;color:var(--mod)}
.cal-acc-state b{font-size:13.5px}
.cal-acc-state .cal-acc-badge{font-size:11px;text-transform:uppercase;letter-spacing:.4px;
  padding:1px 6px;border-radius:999px;border:1px solid var(--border);color:var(--text2);margin-left:auto}
.cal-acc-list{list-style:none;margin:0;padding:0;display:grid;gap:3px}
.cal-acc-list li{display:flex;align-items:center;gap:6px;font-size:12.5px}
.cal-acc-list li svg{width:12px;height:12px;flex:none}
.cal-acc-list li.yes{color:var(--text)}
.cal-acc-list li.no{color:var(--text2);opacity:.72}
.cal-acc-list li.no svg{color:var(--danger)}
.cal-acc-list li.yes svg{color:var(--ok)}
.cal-acc-note{margin-top:8px;font-size:11.5px;color:var(--text2);line-height:1.4;
  border-top:1px solid var(--border);padding-top:7px}
/* Kalender-Liste nach Rechten gruppieren */
.cal-ovl-h{font-size:11px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;
  color:var(--text2);padding:7px 6px 3px;display:flex;align-items:center;gap:5px}
.cal-ovl-h:first-child{padding-top:2px}
.cal-ovl-cnt{font-weight:600;letter-spacing:.2px;text-transform:none;
  background:color-mix(in srgb,var(--text2) 12%,transparent);border-radius:999px;padding:0 5px}
/* Termin-Legende */
.cal-legend{display:flex;flex-wrap:wrap;gap:12px;padding:6px 4px 2px;font-size:11px;color:var(--text2)}
.cal-legend .cl-it{display:inline-flex;align-items:center;gap:5px}
.cal-legend .cl-box{width:16px;height:12px;border-radius:3px;flex:none;background:var(--card)}
.cal-legend .cl-pending{border:1px dashed var(--accent);background:repeating-linear-gradient(45deg,color-mix(in srgb,var(--accent) 8%,transparent),color-mix(in srgb,var(--accent) 8%,transparent) 4px,transparent 4px,transparent 8px)}
.cal-legend .cl-ro{border:1px solid var(--border);opacity:.55}

/* Kap. 219: ÜBERLAPPUNGS-KONTUR AUS. Zeitgleiche Termine stehen nebeneinander
   (calLayoutColumns teilt die Breite) — wie in jedem anderen Kalender. Die rote
   Kontur (styles.css .cal-overlap) war ein ZUSÄTZLICHES Signal und ist hiermit
   stillgelegt; die Nebeneinander-Darstellung bleibt unverändert aktiv. */
.cal-tgrid .tg-ev.cal-overlap{border-left-color:inherit;box-shadow:none}
.cal-tgrid .tg-ev.cal-overlap[style*="--evc"]{border-left-color:var(--evc)}

/* Kap. 220: Organisator-Zeile ohne hinterlegten Organisator. Bewusst NEUTRAL —
   keine Alarmfarbe, es ist kein Fehler des Nutzers. Das Kalender-Symbol im
   Avatar sagt: die Info stammt aus dem Kalender, nicht aus dem Termin. */
.evt-org.evt-org-none .mc-chip-av{background:var(--panel2);color:var(--text2)}
.evt-org.evt-org-none b{color:var(--text2);font-weight:600}
.evt-org.evt-org-none .evt-dsub{color:var(--text2)}

/* ============================================================
   27) GANZTAGSZONE ÜBER DER ZEITSPALTE (Kap. 220)
   Anzeigebug: Ganztagstermine lagen im selben absolut positionierten Container
   wie die Zeitkacheln. Eine lange Zeitkachel (Cannes, 1080px ab y=0) legte sich
   darüber und verdeckte sie ("aus Jakub Homeoffice wird Office").
   Jetzt: eigene Zeile zwischen Kopf und Zeitspalte — getrennte Container,
   Überlagerung ist strukturell unmöglich (so machen es Google/Outlook/Apple).
   Die Zeile wächst mit dem Inhalt und scrollt bei vielen Einträgen.
   ============================================================ */
.cal-tgrid .tg-allday-row{
  display:flex;flex:none;
  border-bottom:1px solid var(--border);
  background:color-mix(in srgb,var(--card) 96%,var(--hover));
  max-height:112px;overflow-y:auto;
}
.cal-tgrid .tg-allday-row:empty{display:none}
.cal-tgrid .tg-allday-gutter{flex:none;display:flex;align-items:flex-start;justify-content:flex-end;
  color:var(--text2);border-right:1px solid var(--border);
}
.cal-tgrid .tg-allday-slot{
  flex:1;min-width:0;padding:3px 3px 4px;display:flex;flex-direction:column;gap:2px;
  border-right:1px solid var(--border);
}
.cal-tgrid .tg-allday-slot:last-child{border-right:none}
.cal-tgrid .tg-allday-slot:empty{min-height:22px}
/* Ganztagskacheln in dieser Zone: KEINE absolute Positionierung mehr */
.cal-tgrid .tg-allday-slot .tg-ev.allday{
  position:relative;left:auto;right:auto;top:auto;margin:0;
  background:linear-gradient(135deg,var(--evc,var(--accent)),
             color-mix(in srgb,var(--evc,var(--accent)) 72%,var(--ev-mix)));
  color:#fff;border-radius:6px;padding:3px 8px;font-size:11px;line-height:1.35;
  cursor:pointer;overflow:hidden;box-shadow:0 1px 2px rgba(0,0,0,.10);
  display:flex;align-items:center;gap:5px;
}
.cal-tgrid .tg-allday-slot .tg-ev.allday .tg-ev-t{
  font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.cal-tgrid .tg-allday-slot .tg-ev.allday:hover{filter:brightness(1.06)}
.cal-tgrid .tg-allday-slot .tg-ev.allday.cal-hl{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--evc,var(--accent))}

/* ============================================================
   28) TERMIN-KACHELN — VARIANTE „B" (Kap. 221, vom User gewählt)
   Weiße Fläche · 4px Farbkante links · Initialen des KALENDER-EIGENTÜMERS ·
   Meeting-Logo RECHTS mit drehendem Glimmer beim Hover.
   Warum: die alte Verlaufs-Tönung machte hellen Text auf Gelb/Grün unleserlich
   und die Herkunft war nur über die Farbe erkennbar. Text jetzt immer dunkel
   auf Weiß, Herkunft zusätzlich über die Initialen (Farbe bleibt Signal).
   WICHTIG: der 1-Klick-Sprung ins Meeting bleibt — das Logo ist ein eigenes <a>
   und stoppt die Propagation, öffnet also NICHT den Termin (User: "das ist ein
   echter mehrwert").
   ============================================================ */

/* ---- Zeitkacheln (Tag/Woche) ---- */
.cal-tgrid .tg-day-col .tg-ev{
  background:var(--card);
  color:var(--text);
  border:1px solid var(--border);
  border-left:4px solid var(--evc,var(--accent));
  border-radius:7px;
  padding:3px 6px 3px 24px;      /* Platz fuer den Initialen-Block links */
  overflow:hidden;
  box-shadow:0 1px 2px rgba(0,0,0,.05);
}
.cal-tgrid .tg-day-col .tg-ev[style*="--evc"]{background:var(--card);color:var(--text);border-left-color:var(--evc)}
.cal-tgrid .tg-day-col .tg-ev .tg-ev-t{color:var(--text);font-weight:700}
.cal-tgrid .tg-day-col .tg-ev .tg-ev-tm{color:var(--text2)}
.cal-tgrid .tg-day-col .tg-ev.cal-hl{box-shadow:0 0 0 2px color-mix(in srgb,var(--mod) 45%,transparent),0 1px 2px rgba(0,0,0,.06)}

/* Initialen-Block links, volle Kachelhoehe */
.cal-tgrid .tg-ev .evt-own{
  position:absolute;
  display:flex;align-items:center;justify-content:center;
  background:var(--evc,var(--accent));color:#fff;
  font-size:10.5px;font-weight:800;letter-spacing:.2px;
  pointer-events:none;            /* darf den Klick nicht abfangen */
}
/* Ganztagszeile: flacher, nur ein Buchstabe */
.cal-tgrid .tg-ev .evt-own.klein{width:16px;font-size:10.5px;}
/* Nur-Lesen-Kalender: gestrichelte Kante als ruhiger Hinweis */

/* ---- Meeting-Logo RECHTS ---- */
.cal-tgrid .tg-day-col .tg-ev .evt-logo{flex:none;
  display:flex;align-items:center;justify-content:center;
  color:#fff;cursor:pointer;border:none;
  transition:transform .18s cubic-bezier(.2,.9,.3,1.3),filter var(--dur-2) ease,box-shadow .2s ease;
  z-index:var(--z-base-2);
}
.cal-tgrid .tg-day-col .tg-ev .evt-logo:hover{transform:scale(1.18);}
.cal-tgrid .tg-day-col .tg-ev .evt-logo:active{transform:scale(1.04)}
/* Text nicht unter dem Logo laufen lassen */

/* ---- GLIMMER: rotierender Lichtstreifen beim Hover (User-Wunsch) ---- */
.cal-tgrid .tg-ev .evt-shine{
  position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  opacity:0;transition:opacity var(--dur-3) ease;
  background:conic-gradient(from 0deg,
    transparent 0deg, transparent 300deg,
    rgba(255,255,255,.85) 330deg, rgba(255,255,255,.15) 345deg, transparent 360deg);
  -webkit-mask:radial-gradient(circle at 50% 50%, transparent 55%, #000 72%, #000 100%);
          mask:radial-gradient(circle at 50% 50%, transparent 55%, #000 72%, #000 100%);
}
.cal-tgrid .tg-day-col .tg-ev:hover .evt-shine{
  opacity:.5;
  animation:evtShineSpin 2.4s linear infinite;
}
@keyframes evtShineSpin{
  from{transform:rotate(0deg) scale(1.6)}
  to{transform:rotate(360deg) scale(1.6)}
}
/* Barrierefreiheit: keine Endlos-Animation, wenn der Nutzer sie abbestellt hat */
@media (prefers-reduced-motion: reduce){
  .cal-tgrid .tg-day-col .tg-ev:hover .evt-shine{animation:none;opacity:.22}
  .cal-tgrid .tg-day-col .tg-ev .evt-logo:hover{transform:none}
}

/* ---- Monatsansicht: minimaler Punkt statt Initialen ---- */
.cal-month .cm-cell .cm-ev{
  background:var(--card);color:var(--text);
  border:1px solid var(--border);border-left:3px solid var(--evc,var(--accent));
  position:relative;padding-left:14px;
}
.cal-month .cm-cell .cm-ev[style*="--evc"]{background:var(--card);color:var(--text);border-left-color:var(--evc)}
.cal-month .cm-cell .cm-ev .evt-owndot{
  position:absolute;left:5px;top:50%;transform:translateY(-50%);
  width:6px;height:6px;border-radius:50%;background:var(--evc,var(--accent));
}
.cal-month .cm-cell .cm-ev .evt-logo{position:absolute;right:2px;top:50%;transform:translateY(-50%);width:14px;height:14px}
.cal-month .cm-cell .cm-ev .evt-logo svg{width:10px !important;height:10px !important}

/* Kap. 221: Bei SCHMALEN Kacheln (Überlappung → Spaltenbreite 1/3) liegen
   Initialen links und Meeting-Logo rechts so nah, dass sie sich berühren
   (live gemessen: Kachel 587px rechts, Logo 583px, Initialen bis ~590px).
   Deshalb: in schmalen Kacheln den Initialen-Block verschlanken und das Logo
   kleiner setzen. Die Information bleibt, das Gedränge verschwindet. */
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(33"] .evt-own,
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(25"] .evt-own{width:15px;font-size:10.5px}
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(33"] ,
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(25"] {padding-left:18px}
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(33"] .evt-logo,
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(25"] .evt-logo{width:16px;height:16px;right:2px;top:2px}
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(33"] .evt-logo svg,
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(25"] .evt-logo svg{width:11px !important;height:11px !important}
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(33"]:has(.evt-logo) .tg-ev-t,
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(25"]:has(.evt-logo) .tg-ev-t{padding-right:18px}
/* Sehr schmale Kacheln: nur noch der Buchstabe, kein Logo-Platzhalter-Konflikt */
@media (max-width:1400px){
  .cal-tgrid .tg-day-col .tg-ev:has(.evt-logo) .evt-own{width:14px;font-size:10.5px}
}

/* Kap. 221 FEINSCHLIFF: Bei HOHEN Kacheln (lange Termine, z.B. 06:00–16:00)
   wurde der Initialen-Block auf die volle Kachelhöhe gestreckt und die Kachel
   sah wie ein breiter Farbbalken aus (im Screenshot gesehen: Jahresservice,
   Cannes). Der Block ist eine MARKE, kein Flächenfüller — er bleibt oben in
   seiner natürlichen Größe, die Kante trägt die Farbe über die volle Höhe. */
.cal-tgrid .tg-ev .evt-own{bottom:auto;         /* feste Höhe statt inset */
  border-radius:6px 0 0 6px;
}
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(33"] .evt-own,
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(25"] .evt-own{height:16px}
/* Auf der Kantenfarbe liegt der Block direkt an — oben ausrichten, damit er bei
   jeder Kachelhöhe gleich sitzt. */
.cal-tgrid .tg-day-col .tg-ev .evt-own{position:absolute;left:0;top:0}
/* Textvertikal: bei hohen Kacheln Inhalt oben halten (nicht zentriert) */
.cal-tgrid .tg-day-col .tg-ev .tg-ev-b{padding-top:1px}

/* ============================================================
   29) GLIMMER AM MEETING-LOGO (Kap. 221, User-Wunsch)
   „cool wäre ein effekt, beim drüberhovern ein glimmer der sich im kreis dreht"
   Der erste Versuch lag als Lichtstreifen über der GANZEN Kachel — im Screenshot
   war davon nichts zu sehen (zu flächig, verlor sich auf Weiß). Jetzt direkt am
   Logo: ein leuchtender Ring, der sich um das Logo dreht. Sichtbar, aber nicht
   aufdringlich — und er sitzt genau an dem Element, das man anklickt.
   ============================================================ */
.cal-tgrid .tg-ev .evt-shine{display:none}   /* alter Kachel-Glimmer aus */

/* Ring um das Logo: conic-gradient mit Lücke, rotiert */
.cal-tgrid .tg-day-col .tg-ev .evt-logo{position:absolute;overflow:visible}
.cal-tgrid .tg-day-col .tg-ev .evt-logo::after{
  content:'';position:absolute;inset:-3px;border-radius:9px;pointer-events:none;
  opacity:0;transition:opacity var(--dur-3) ease;
}
.cal-tgrid .tg-day-col .tg-ev .evt-logo:hover::after{
  opacity:1;
  animation:evtLogoGlimmer 1.5s linear infinite;
}
@keyframes evtLogoGlimmer{
  from{transform:rotate(0deg)}
  to{transform:rotate(360deg)}
}
/* Zusaetzlich ein weicher Schein, damit der Effekt auch auf hellen Kalendern
   (Gelb/Gruen) sichtbar ist — der Ring allein verschwaende dort. */
.cal-tgrid .tg-day-col .tg-ev .evt-logo:hover{
  filter:brightness(1.15);
}
@media (prefers-reduced-motion: reduce){
  .cal-tgrid .tg-day-col .tg-ev .evt-logo:hover::after{animation:none;opacity:.5}
}
/* Mehr Luft zwischen Initialen und Logo (im Screenshot beruehrten sie sich fast) */
.cal-tgrid .tg-day-col .tg-ev:has(.evt-logo) .evt-own{margin-right:2px}

/* ============================================================
   30) KORREKTUREN NACH USER-DURCHSICHT (Kap. 221)
   ============================================================ */

/* (a) RASTER: die erste Stunde wurde oben zur Hälfte abgeschnitten.
   Ursache: .tg-hour sitzt auf `top:0` und wird per translateY(-50%) zentriert —
   die halbe Beschriftung liegt damit AUSSERHALB des Containers und wird vom
   sticky Kopf (.tg-head, z-index 2) überdeckt. Lösung: oben Luft schaffen und
   die Beschriftung der ersten Stunde nach unten kippen. */
.cal-tgrid .tg-body{padding-top:9px}
.cal-tgrid .tg-gutter-col .tg-hour:first-child,
.cal-tgrid .tg-gutter-col .tg-hour:first-of-type{transform:translateY(0)}
/* Kopfzeilen der beiden Ansichten bündig halten */
.cal-tgrid .tg-allday-row + .tg-body{padding-top:9px}

/* (b) NUR-LESEN war als GESTRICHELTE Linie sichtbar — der User fragte zu Recht
   nach ("alle termine aus anderen kalendern werden mit gestrichelter linie links
   angezeigt? wieso?"). Eine gestrichelte Kante liest man als Fehler/Entwurf.
   Statt dessen: die Kante bleibt DURCHGEZOGEN (sie trägt die Kalenderfarbe) und
   die Herkunft steht in den Initialen + Tooltip. Kein Sonderstrich mehr. */
.cal-tgrid .tg-day-col .tg-ev.ev-ro{border-left-style:solid}
.cal-month .cm-cell .cm-ev.ev-ro{border-left-style:solid}
.cal-tgrid .tg-day-col .tg-ev.ev-ro .evt-own{opacity:1}

/* (c) VIDEO-LOGO war "nur ein winziges logo rechts oben" — der User erwartet
   ein deutlich sichtbares Element (früher war es 1/4–1/3 der Kachelhöhe links).
   Jetzt: rechts oben, aber größer (26px), mit klarer Markenfarbe und Beschriftung
   beim Hover. Die Kachelhöhe bestimmt die Maximalgröße. */
.cal-tgrid .tg-day-col .tg-ev .evt-logo{
  width:26px;height:26px;right:4px;top:4px;border-radius:7px;
  box-shadow:0 1px 3px rgba(0,0,0,.18);
}
.cal-tgrid .tg-day-col .tg-ev .evt-logo svg{width:17px !important;height:17px !important}
/* In KURZEN Kacheln (<=40min) bleibt das Logo kleiner, sonst überdeckt es den Text */
.cal-tgrid .tg-day-col .tg-ev[style*="height:30px"] .evt-logo,
.cal-tgrid .tg-day-col .tg-ev[style*="height:60px"] .evt-logo{width:20px;height:20px;right:3px;top:3px}
.cal-tgrid .tg-day-col .tg-ev[style*="height:30px"] .evt-logo svg,
.cal-tgrid .tg-day-col .tg-ev[style*="height:60px"] .evt-logo svg{width:13px !important;height:13px !important}

/* (d) INITIALEN-BLOCK kollidierte oben links mit der Farbkante
   (User: "unsauber mit der linken farblinie oben links kollidierend").
   Der Block liegt jetzt INNERHALB der Kante (die Kante bleibt voll sichtbar),
   mit gleichem Radius wie die Kachel — sauber eingepasst. */
.cal-tgrid .tg-ev .evt-own{
  left:0;top:0;height:17px;
  border-radius:5px 0 5px 0;          /* oben links wie die Kachel, unten rechts abgesetzt */
  box-shadow:0 1px 0 color-mix(in srgb,var(--evc,var(--accent)) 55%,transparent);
}
.cal-tgrid .tg-ev .evt-own.klein{height:14px;border-radius:4px 0 4px 0}
/* Etwas Abstand zur Kante, damit nichts "klebt" */
.cal-tgrid .tg-allday-slot .tg-ev.allday{padding-left:21px}

/* Kap. 221b: Der Glimmer-Ring war WEISS und verschwand auf hellen Kalenderfarben
   (User: "bei GS gelb sieht ma so gut wie nix"). Lösung: der Ring wird NICHT
   weiß, sondern nimmt einen KONTRASTIERENDEN Ton zur Kalenderfarbe — dunkel auf
   hellen Farben, hell auf dunklen. Der Schein aussen bleibt zweistufig
   (hell + dunkel), damit der Effekt auf jeder Farbe sichtbar ist. */
.cal-tgrid .tg-day-col .tg-ev .evt-logo::after{
  /* zwei Ringe: innen hell, aussen dunkel — je nach Kalenderfarbe greift einer */
  background:conic-gradient(from 0deg,
     rgba(0,0,0,0) 0deg, rgba(0,0,0,0) 190deg,
     var(--glim, rgba(255,255,255,.95)) 255deg,
     color-mix(in srgb,var(--glim,rgba(255,255,255,.95)) 55%, rgba(0,0,0,.55)) 305deg,
     rgba(0,0,0,0) 345deg);
  /* zweite Konturschicht: dunkler Rand, damit der Ring auf hellem Grund haelt */
  box-shadow:0 0 0 1.5px rgba(0,0,0,.28);
}
/* Kalender mit HELLER Farbe (Gelb/Grün/Hellblau) bekommen einen DUNKLEN Ring.
   Erkennung über den data-Attribut-Wert der Kachelfarbe — der Server liefert
   Gelb (#FFCC00), Grün (#63DA38), Hellblau (#CEE7FF); diese Liste ist bewusst
   explizit, damit keine Farbberechnung nötig ist (schnell + nachvollziehbar). */
.cal-tgrid .tg-day-col .tg-ev[style*="#FFCC00"] .evt-logo::after,
.cal-tgrid .tg-day-col .tg-ev[style*="#63DA38"] .evt-logo::after,
.cal-tgrid .tg-day-col .tg-ev[style*="#CEE7FF"] .evt-logo::after{--glim:rgba(20,20,25,.92)}
.cal-tgrid .tg-day-col .tg-ev[style*="#FFCC00"] .evt-logo:hover,
.cal-tgrid .tg-day-col .tg-ev[style*="#63DA38"] .evt-logo:hover,
.cal-tgrid .tg-day-col .tg-ev[style*="#CEE7FF"] .evt-logo:hover{
  box-shadow:0 0 0 2px rgba(20,20,25,.55), 0 0 11px 3px rgba(20,20,25,.35);
}
/* Der Standard-Schein bleibt zweistufig: heller Kern + dunkle Kontur */

/* ============================================================
   31) TITEL-PLATZIERUNG IN DER KACHEL (Kap. 221c)
   Zwei Befunde des Users, beide gemessen:
   (a) „zu weit mittig": .tg-ev ist display:flex mit align-items:stretch, dadurch
       wurde .tg-ev-b auf die VOLLE Kachelhöhe gestreckt und der Text zentrierte
       sich mit. Bei einer 420px-Kachel saß die Textmitte exakt auf 210px.
       Lösung: Inhalt oben ausrichten (align-items:flex-start) — Titel und Zeit
       stehen oben, wie in jedem Kalender.
   (b) „in der wochenansicht wird fast alles abgeschnitten": Kachel 84px breit,
       der Titel hatte nur 34px — das linke Padding (25px für die Initialen)
       plus das Logo rechts (26px) liessen nichts übrig.
       Lösung: schmalere Reserven + Umbruch auf zwei Zeilen bei genug Höhe.
   ============================================================ */
.cal-tgrid .tg-day-col .tg-ev{align-items:flex-start}
.cal-tgrid .tg-day-col .tg-ev .tg-ev-b{
  align-self:flex-start;
  display:flex;flex-direction:column;gap:1px;
}
/* Reserven verkleinern: Initialen 18px statt 25px, Logo-Bereich 20px statt 26px */

/* Titel: bei genug Höhe (ab ~45min) darf er ZWEIZEILIG umbrechen statt
   abzuschneiden. Darunter bleibt eine Zeile (sonst passt die Zeit nicht). */
.cal-tgrid .tg-day-col .tg-ev[style*="height:90px"] .tg-ev-t,
.cal-tgrid .tg-day-col .tg-ev[style*="height:120px"] .tg-ev-t,
.cal-tgrid .tg-day-col .tg-ev[style*="height:1"]:not([style*="height:60px"]):not([style*="height:30px"]) .tg-ev-t{
  white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;line-height:1.25;
  /* Kap. 221i: KEIN Wortbruch mitten im Wort — sonst wird "Cannes" zu "C a."
     (im Screenshot gesehen). overflow-wrap greift nur bei überbreiten Einzelwörtern. */
  word-break:normal;overflow-wrap:anywhere;hyphens:none;
}
/* Zeit kleiner, damit der Titel mehr Platz hat */
.cal-tgrid .tg-day-col .tg-ev .tg-ev-tm{font-size:10.5px;line-height:1.2}

/* Kap. 221d: Ganztags-Gutter war abgeschnitten ("anztägig" statt "ganztägig").
   Grund: 56px Breite + uppercase + letter-spacing. Jetzt kleiner und mit
   Zeilenumbruch-Erlaubnis, damit nichts abgeschnitten wird. */
.cal-tgrid .tg-allday-gutter{
  width:56px;font-size:10.5px;letter-spacing:.2px;text-transform:uppercase;
  padding:7px 6px 0 2px;line-height:1.15;text-align:right;
  white-space:normal;overflow:visible;word-break:break-word;
}
/* Der Hover-Tooltip wird vom Browser gerendert; wir sorgen nur dafuer, dass die
   Kachel den Cursor als Hinweis traegt und der Titel nicht als Abschneide-Grund
   missverstanden wird. */
.cal-tgrid .tg-day-col .tg-ev{cursor:default}
.cal-tgrid .tg-day-col .tg-ev .tg-ev-t{cursor:pointer}
.cal-month .cm-cell .cm-ev .cm-ev-tag{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ============================================================
   32) LOGO VERDECKT TERMINDETAILS — behoben (Kap. 221e)
   Gemessen: in einer 47px breiten Kachel (Überlappung → 1/3 Spalte) blieben
   nach 20px Logo + 22px Initialen nur 18px für den Titel; Logo überdeckte
   Titel UND Zeit („video-conf logo überdeckt termindetails").
   Lösung: das Logo liegt NICHT mehr über dem Text. Es sitzt als eigenes
   Element UNTER dem Textblock (rechtsbündig), damit beides Platz hat. In
   breiten Kacheln steht es weiterhin oben rechts.
   ============================================================ */
/* Grundregel: Textblock bekommt KEINE rechte Reserve mehr — das Logo drueckt
   nicht mehr in den Text, sondern sitzt darunter. */
.cal-tgrid .tg-day-col .tg-ev:has(.evt-logo){padding-right:5px}
.cal-tgrid .tg-day-col .tg-ev .tg-ev-b{width:100%}
.cal-tgrid .tg-day-col .tg-ev:has(.evt-logo) .tg-ev-t,
.cal-tgrid .tg-day-col .tg-ev:has(.evt-logo) .tg-ev-tm{padding-right:0}

/* Logo: unter dem Text, rechtsbuendig — per Flex-Reihenfolge.
   .tg-ev ist flex-column (durch align-items:flex-start gesetzt), daher
   ordnen wir: Initialen (absolut) -> Textblock -> Logo. */
.cal-tgrid .tg-day-col .tg-ev > .evt-logo{
  position:static;margin-top:2px;
  width:22px;height:22px;flex:none;order:3;
  transition:transform .18s cubic-bezier(.2,.9,.3,1.3),filter var(--dur-2) ease,box-shadow .2s ease;
}
.cal-tgrid .tg-day-col .tg-ev > .evt-logo svg{width:14px !important;height:14px !important}
/* Bei sehr niedrigen Kacheln (<=40min) reicht der Platz nicht: dort Logo
   kleiner und direkt neben der Zeit statt darunter. */
.cal-tgrid .tg-day-col .tg-ev[style*="height:30px"] > .evt-logo,
.cal-tgrid .tg-day-col .tg-ev[style*="height:55px"] > .evt-logo{margin-top:0}
/* Hohe Kacheln: Logo oben rechts ist besser (viel Platz) — Text bleibt oben,
   das Logo schwebt rechts oben ohne Überdeckung, weil der Textblock dann
   ohnehin nur 2 Zeilen hoch ist. */
.cal-tgrid .tg-day-col .tg-ev:not([style*="height:30px"]):not([style*="height:55px"]):not([style*="height:60px"]) > .evt-logo{
  position:absolute;right:4px;top:4px;margin:0;
}
/* Kap. 221g: NUR mit Logo reservieren — die pauschale Regel gab auch Kacheln
   OHNE Meeting-Logo 28px Reserve (gemessen: 17px Titelbreite bei 84px Kachel). */
.cal-tgrid .tg-day-col .tg-ev:not([style*="height:30px"]):not([style*="height:55px"]):not([style*="height:60px"]):has(.evt-logo){
  padding-right:28px;
}

/* Kap. 221e-2: In SEHR SCHMALEN Kacheln (Überlappung, <70px) ist für Initialen +
   Titel + Logo kein Platz — gemessen: Titel hatte 18px. Dort reduzieren wir
   bewusst auf das Wesentliche: Initialen-Buchstabe + Logo, der Titel bekommt
   die volle Restbreite ohne Logo-Reserve (Logo sitzt darunter). */
.cal-tgrid .tg-day-col .tg-ev{min-width:0}
.cal-tgrid .tg-day-col .tg-ev .tg-ev-b{min-width:0;overflow:hidden}
.cal-tgrid .tg-day-col .tg-ev .tg-ev-t{min-width:0}
/* Logo unter dem Text: kein Abzug mehr von der Titelbreite (kein padding-right). */
.cal-tgrid .tg-day-col .tg-ev > .evt-logo{margin-left:2px;margin-right:0;align-self:flex-end}
/* Nur in Kacheln MIT genug Breite (>=150px) schwebt das Logo oben rechts — dort
   ist die Überdeckung ausgeschlossen, weil der Text zwei Zeilen nicht überschreitet. */
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(100"] > .evt-logo,
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(50"] > .evt-logo{
  position:absolute;right:4px;top:4px;align-self:auto;
}
/* Kap. 221g: Nur reservieren, wenn WIRKLICH ein Logo da ist — vorher bekamen
   auch Kacheln OHNE Logo 28px Reserve (gemessen: Titel hatte 17px statt 84px).
   Und nur in breiten Kacheln, wo das Logo oben rechts schwebt. */

/* Kap. 221f: GLIMMER auf JEDER Kalenderfarbe sichtbar.
   Der vorige Ansatz setzte --glim per style-Attribut-Selektor auf #FFCC00 & Co.
   Das griff NICHT (live geprüft: getComputedStyle lieferte leer) — --evc steht
   zwar in der Kachel, das Logo erbt es aber nicht als --glim, und die
   Attribut-Selektoren trafen nur exakt diese Strings.
   Jetzt OHNE Farbberechnung, doppelte Kontur — sichtbar auf hell UND dunkel:
     innen  : heller Glanz (weiss)
     aussen : dunkle Kontur (haelt auf Gelb/Gruen/Hellblau)
     Schein : kraeftig in der Kalenderfarbe (--evc) + dunkler Rand
   ============================================================ */
.cal-tgrid .tg-day-col .tg-ev .evt-logo::after{
  background:conic-gradient(from 0deg,
     rgba(0,0,0,0) 0deg, rgba(0,0,0,0) 185deg,
     rgba(255,255,255,.98) 250deg,
     rgba(255,255,255,.55) 292deg,
     rgba(0,0,0,.55) 322deg,
     rgba(0,0,0,0) 355deg);
  -webkit-mask:radial-gradient(circle at 50% 50%, transparent 56%, #000 61%);
          mask:radial-gradient(circle at 50% 50%, transparent 56%, #000 61%);
  box-shadow:0 0 0 1.5px rgba(0,0,0,.35),         /* dunkle Aussenkontur */
             0 0 0 2.5px rgba(255,255,255,.55);   /* heller Zwischenring */
}
.cal-tgrid .tg-day-col .tg-ev .evt-logo:hover{
  box-shadow:0 0 0 2px rgba(255,255,255,.95),
             0 0 0 3px rgba(0,0,0,.35),
             0 0 13px 4px color-mix(in srgb,var(--evc,var(--accent)) 75%,transparent);
}
/* Auf hellen Kalenderfarben (Kachel-Kantenfarbe bekannt) den weissen Glanz
   durch Dunkel ersetzen — Selektoren auf die KACHEL, das Logo erbt via --evc. */
.cal-tgrid .tg-day-col .tg-ev[style*="--evc:#FFCC00"] .evt-logo::after,
.cal-tgrid .tg-day-col .tg-ev[style*="--evc:#63DA38"] .evt-logo::after,
.cal-tgrid .tg-day-col .tg-ev[style*="--evc:#CEE7FF"] .evt-logo::after{
  background:conic-gradient(from 0deg,
     rgba(0,0,0,0) 0deg, rgba(0,0,0,0) 185deg,
     rgba(15,15,20,.95) 250deg,
     rgba(15,15,20,.5) 292deg,
     rgba(255,255,255,.6) 322deg,
     rgba(0,0,0,0) 355deg);
}

/* ============================================================
   33) TITEL WURDE SOFORT ABGESCHNITTEN (Kap. 221g)
   User: „wieso am 15.9. ronalds kalender, 'remminder...' + 'Folgeter...' wird
   sofort abgeschnitten?"
   Gemessen bei 84px Kachelbreite: padding 22px links + 28px rechts + 20px
   Initialen = 70px Reserven -> nur 15px für den Titel.
   Das 28px-Rechts-Padding war pauschal gesetzt (Reserve fürs Meeting-Logo),
   OBWOHL diese Kacheln gar kein Logo haben.
   Lösung: rechts nur dann Platz reservieren, wenn wirklich ein Logo da ist
   (:has(.evt-logo)) — und dann auch nur in breiten Kacheln, wo es oben rechts
   schwebt. Sonst 5px Rand.
   ============================================================ */
.cal-tgrid .tg-day-col .tg-ev{padding-left:20px;padding-right:5px}
.cal-tgrid .tg-day-col .tg-ev:not(:has(.evt-logo)){padding-right:5px}
/* Logo schwebt nur in BREITEN Kacheln oben rechts -> nur dort Reserve */
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(100"]:has(.evt-logo),
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(50"]:has(.evt-logo){padding-right:28px}
/* Initialen-Block schlanker: 20px -> 18px */
.cal-tgrid .tg-ev .evt-own{width:18px}
.cal-tgrid .tg-day-col .tg-ev .evt-own{width:18px}

/* Kap. 221h: Lange Titel in schmalen Kacheln werden GEKÜRZT, obwohl Platz in der
   Höhe wäre (gemessen: 'Update Acta Nova' 40px Box bei 113px Textlänge, Kachel
   84x120px). Ursache: Die Zwei-Zeilen-Regel griff nur bei exakt bestimmten
   Höhen-Strings. Jetzt generisch: ab 100px Kachelhöhe darf der Titel auf ZWEI
   Zeilen umbrechen (dann passt auch der Zeitstempel noch), darunter einzeilig
   mit Ellipsis. Das ist die kalenderübliche Lösung (Google/Outlook kürzen in
   schmalen Spalten ebenfalls — nur mit Umbruch statt harter Kürzung). */
.cal-tgrid .tg-day-col .tg-ev .tg-ev-t{-webkit-box-orient:vertical;line-height:1.22;
}
/* In flachen Kacheln (< 100px, meist ≤45min) bleibt es einzeilig — dort ist für
   zwei Zeilen plus Zeitstempel kein Raum. */
.cal-tgrid .tg-day-col .tg-ev[style*="height:30px"] .tg-ev-t,
.cal-tgrid .tg-day-col .tg-ev[style*="height:55px"] .tg-ev-t,
.cal-tgrid .tg-day-col .tg-ev[style*="height:60px"] .tg-ev-t,
.cal-tgrid .tg-day-col .tg-ev[style*="height:90px"] .tg-ev-t{
  display:block;white-space:nowrap;text-overflow:ellipsis;
  -webkit-line-clamp:unset;
}
/* Zeitstempel unten halten, damit er nicht mit dem Titel konkurriert */
.cal-tgrid .tg-day-col .tg-ev .tg-ev-b{justify-content:flex-start}

/* Kap. 221i: MEIN FEHLER — 'word-break:break-word' + 'hyphens:auto' zerlegte
   kurze Titel in schmalen Spalten mitten im Wort ("Cannes" -> "C a.").
   Im Screenshot sichtbar. Richtig: Wörter NICHT trennen; nur wenn ein einzelnes
   Wort breiter als die Kachel ist, darf es umbrechen (overflow-wrap:anywhere
   wirkt nur in diesem Fall, nicht bei normalen Wörtern). */
.cal-tgrid .tg-day-col .tg-ev .tg-ev-t{                 /* kein Trennen mitten im Wort */
  hyphens:none;                      /* keine Silbentrennung */
  overflow-wrap:anywhere;            /* nur bei ÜBERbreitem Einzelwort */
}

/* Kap. 221j: 'Cannes' wurde trotz word-break:normal zu "C / a…" zerlegt — weil
   `overflow-wrap:anywhere` bei einer 13px breiten Textbox JEDES Zeichen
   umbrechen darf. In so schmalen Spalten (Überlappung, 3-4 Termine gleichzeitig)
   ist ein lesbarer Titel unmöglich; dort ist KÜRZEN mit Ellipsis richtig.
   Regel: nur umbrechen, wenn die Kachel breit genug für ein echtes Wort ist
   (>=70px). Darunter: einzeilig + Ellipsis (kein Buchstabensalat). */
/* Ab 70px Kachelbreite darf der Titel zwei Zeilen nutzen (volle Wörter) */
.cal-tgrid .tg-day-col .tg-ev:not([style*="width:calc(25"]):not([style*="width:calc(33"]) .tg-ev-t{
  white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;line-height:1.22;
}

/* ============================================================
   34) TITEL IN KACHELN — EINE verbindliche Regel (Kap. 221k)
   Vorher widersprachen sich mehrere Regeln (`overflow-wrap:anywhere` vs.
   `white-space:nowrap`), dadurch gewann je nach Reihenfolge eine andere und
   "Cannes" wurde zu "C / a…" zerlegt.
   Jetzt eine Regel, nachvollziehbar:
     • Kachel ≥ 90px breit  -> Titel darf auf 2 Zeilen umbrechen (volle Wörter)
     • Kachel < 90px breit  -> einzeilig mit Ellipsis (kein Buchstabensalat)
   Wörter werden NIE getrennt (word-break:normal, hyphens:none,
   overflow-wrap:normal).
   ============================================================ */
.cal-tgrid .tg-day-col .tg-ev .tg-ev-t{
  word-break:normal !important;
  overflow-wrap:normal !important;
  hyphens:none !important;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  display:block;
  -webkit-line-clamp:unset;
}
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(100%"],
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(50%"]{
  /* breite Kacheln: zwei Zeilen erlaubt */
}
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(100%"] .tg-ev-t,
.cal-tgrid .tg-day-col .tg-ev[style*="width:calc(50%"] .tg-ev-t{
  white-space:normal;
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  line-height:1.22;
}

/* ===== Kap. 239: Startseite als „Heute“-Hub ===== */
.hub-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));gap:14px;margin-bottom:14px}
.hub-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);display:flex;flex-direction:column;min-width:0;overflow:hidden}
.hub-card .ai-prio-b{padding:6px 0}
.hub-h{display:flex;align-items:center;gap:8px;padding:11px 14px;border-bottom:1px solid var(--border);font-size:13.5px;font-weight:650;color:var(--text);flex:0 0 auto}
.hub-h>.hub-meta{font-weight:500;font-size:11.5px;color:var(--text2)}
.hub-go{margin-left:auto;display:inline-flex;align-items:center;gap:3px;background:transparent;border:1px solid var(--border);color:var(--text2);border-radius:999px;padding:3px 9px;font-size:11.5px;cursor:pointer;font-family:inherit;transition:all var(--dur-2) ease}
.hub-go:hover{background:var(--hover);color:var(--accent);border-color:var(--accent)}
.hub-b{padding:4px 0;max-height:320px;overflow-y:auto;flex:1 1 auto}
.hub-item{display:flex;gap:11px;align-items:flex-start;padding:9px 14px;border-bottom:1px solid var(--border);cursor:pointer;transition:background var(--dur-1) ease}
.hub-item:last-child{border-bottom:none}
.hub-item:hover{background:var(--hover)}
.hub-item-i{width:30px;height:30px;border-radius:9px;display:flex;align-items:center;justify-content:center;color:#fff;flex:none;margin-top:1px}
.hub-item-i svg,.hub-tile svg{width:16px;height:16px}
.hub-item-m{flex:1;min-width:0}
.hub-item-t{font-size:13px;font-weight:650;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hub-item-s{font-size:11.5px;color:var(--text2);margin-top:2px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.hub-item-x{width:14px;height:14px;color:var(--text2);flex:none;margin-top:7px;opacity:.55}
.hub-ki{display:flex;align-items:center;gap:10px;flex-wrap:wrap;background:var(--card);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);padding:10px 14px;margin-bottom:14px}
.hub-ki-input{flex:1 1 260px;min-width:180px;border:none;background:transparent;color:var(--text);font-size:14px;font-family:inherit;outline:none}
.hub-ki-chips{display:flex;gap:6px;flex-wrap:wrap;flex:1 1 100%;border-top:1px solid var(--border);padding-top:9px;margin-top:2px}
.hub-ki .ai-model{flex:none}
.hub-module{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:14px}
.hub-tile{display:flex;align-items:center;gap:9px;background:var(--card);border:1px solid var(--border);border-left:3px solid var(--tc,var(--accent));border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:9px 14px;cursor:pointer;font-family:inherit;transition:transform var(--dur-2) ease,box-shadow var(--dur-2) ease,border-color var(--dur-2) ease}
.hub-tile:hover{transform:translateY(-1px);box-shadow:var(--shadow);border-color:var(--tc,var(--accent))}
.hub-tile>svg{color:var(--tc,var(--accent));flex:none}
.hub-tile-t{font-size:13px;font-weight:650;color:var(--text)}
.hub-tile-v{font-size:11.5px;color:var(--text2)}
.hub-kopf{margin-bottom:14px}
.ai-feed-b .fd-t{-webkit-line-clamp:2;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden}
.ai-feed-b .fd-s{-webkit-line-clamp:2;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden}
@media(max-width:820px){.hub-grid{grid-template-columns:1fr}.hub-ki-chips{display:none}}

/* ===== Issue #9: Rail-Badges tragen die Farbe ihres Moduls (vorher alle var(--cal)) =====
   Signal „Anzahl im Modul X" statt „Kalender". Weißer Text bleibt lesbar, weil
   alle Modulfarben in allen Themes dunkel genug sind (geprüft: mail/talk/todo/cal). */
.rail .badge{background:var(--cal)}
#planBadge{background:var(--cal)}   /* Planer = Kalender-Kontext */
#mailBadge{background:var(--mail)}
#chatBadge{background:var(--talk)}
#todoBadge{background:var(--todo)}
.rail button .badge{border:1px solid rgba(255,255,255,.35)}

/* ===== Issue #8: zugeklappte Messenger-Leiste (62 px) zeigt keinen abgeschnittenen Text =====
   Die Liste führt im eingeklappten Zustand nur Avatare; Nicht-Personen-Inhalte
   (Leerzustände, Hinweise) werden ausgeblendet statt hart gekappt. */
.msgr-side.collapsed .msgr-empty,
.msgr-side.collapsed .msgr-list > .empty{display:none}
.msgr-side.collapsed .msgr-list{overflow-x:hidden}
.msgr-side.collapsed .msgr-list *{max-width:100%;overflow-wrap:anywhere}

/* ===== Issue #11: Ribbon-Scroll sichtbar machen + gleichmäßige Gruppen =====
   Über die Maske verschwindet der Inhalt am Rand weich, sobald rechts/links noch
   etwas liegt — vorher scrollten Gruppen unsichtbar weg (kein Hinweis). Die
   Klassen setzt `ribbonScrollCheck()` in core.js. */
.mrb-panels.rb-scroll-r{-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 30px),transparent);mask-image:linear-gradient(to right,#000 calc(100% - 30px),transparent)}
.mrb-panels.rb-scroll-l{-webkit-mask-image:linear-gradient(to left,#000 calc(100% - 30px),transparent);mask-image:linear-gradient(to left,#000 calc(100% - 30px),transparent)}
.mrb-panels.rb-scroll-l.rb-scroll-r{-webkit-mask-image:linear-gradient(to right,transparent,#000 30px,#000 calc(100% - 30px),transparent);mask-image:linear-gradient(to right,transparent,#000 30px,#000 calc(100% - 30px),transparent)}
/* Gleiche Innenabstände für alle Ribbon-Gruppen (vorher 11px vs. 12px/2px) */
.mc-grp{padding:3px 12px 2px !important}
.mc-grp:first-child{padding-left:6px !important}
.mc-grp:last-child{border-right:none}

/* =====================================================================
   Issue #16 — Responsive (Kap. 248)
   1024–1280px: Ordnerbaum wird ausklappbares Overlay (Outlook-Muster:
   Liste + Detail bleiben, Baum per Knopf). <1000px: ehrliche Meldung
   statt kaputtem Layout. Kein Eingriff in .rail/.header/.login.
   ===================================================================== */
/* Umschalt-Knopf im Mail-Kopf (nur sichtbar, wenn der Baum ausklappbar ist) */
.mail-tree-toggle{display:none;align-items:center;justify-content:center;flex:none;width:28px;height:26px;
  border:1px solid var(--border);background:var(--card);color:var(--text);border-radius:7px;cursor:pointer;
  transition:background var(--tr),border-color var(--tr),color var(--tr)}
/* Schliessen-Knopf gehoert nur zum Overlay-Betrieb (Regel im Breakpoint setzt display) */
#sec-mail .mail-tree-close{display:none}
.mail-tree-toggle:hover{background:var(--hover);border-color:var(--accent);color:var(--accent)}
.mail-tree-toggle.on{background:var(--accent-light);border-color:var(--accent);color:var(--accent)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);
  white-space:nowrap;border:0}

/* Ab hier ist die 3-Spalten-App zu breit: Baum raus, Knopf rein */
@media(max-width:1280px){
  /* .mail-app ist overflow:hidden (kein position) — fuer das Overlay braucht der
     Baum einen Bezugsrahmen, sonst haengt er am naechsten positionierten Vorfahren. */
  #sec-mail .mail-app{position:relative}
  #sec-mail .mail-tree-toggle{display:inline-flex}
  #sec-mail .mail-navbar.mail-quickfilters{justify-content:flex-start}
  /* Baum + sein Ziehgriff verlassen den Rasterfluss (position:absolute / aus).
     Deshalb MUSS das Raster hier DREI Spalten haben — sonst rutschen Liste und
     Detail einen Platz nach links (gemessen: Liste 1px, Detail auf der Listenbreite). */
  #sec-mail .mail-app{grid-template-columns:var(--mail-list-w,340px) 6px 1fr}
  /* Geschlossen: visibility:hidden — sonst bleibt der weggeschobene Baum trotzdem
     klickbar und per Tab erreichbar (er liegt dann ueber dem Inhalt) und faengt
     Klicks auf Knoepfe daneben ab. visibility ist animierbar (mit Verzoegerung). */
  #sec-mail .mail-tree-col{position:absolute;top:0;left:0;bottom:0;width:min(300px,78vw);z-index:var(--z-sidebar);
    transform:translateX(-102%);visibility:hidden;transition:transform var(--dur-3) ease,visibility 0s linear var(--dur-3);
    box-shadow:0 14px 44px rgba(0,0,0,.28);border-right:1px solid var(--border);background:var(--card)}
  #sec-mail .mail-app.tree-offen .mail-tree-col{transform:translateX(0);visibility:visible;
    transition:transform var(--dur-3) ease,visibility 0s linear 0s}
  /* Schliessweg im Baum (nur im Overlay-Modus sinnvoll sichtbar) */
  #sec-mail .mail-tree-close{display:inline-flex;position:absolute;top:8px;right:8px;width:26px;height:26px;
    align-items:center;justify-content:center;border:1px solid var(--border);background:var(--card);color:var(--text);
    border-radius:7px;cursor:pointer;z-index:var(--z-base-2)}
  #sec-mail .mail-tree-close:hover{background:var(--hover);color:var(--accent);border-color:var(--accent)}
  /* Trenn-Griff am Baum spielt im Overlay keine Rolle */
  #sec-mail .mail-col-resize[data-resize="tree"]{display:none}
}
@media(max-width:1180px){
  /* Liste schmaler, damit der Textkörper >= 400px behaelt */
  #sec-mail .mail-app{grid-template-columns:clamp(240px,26vw,300px) 6px 1fr}
}
/* To-Do und Git haben dieselbe 3-Spalten-Bauart; bei 1024px blieb dem Detail nur
   ein Streifen (gemessen: To-Do 253px, Git 228px). Hier nur die festen Spalten
   verkleinern — das Detail bekommt den Rest. Kanban hat ein eigenes Raster und
   wird ausdruecklich ausgenommen (sonst bricht das Board, siehe Kap. 228a). */
@media(max-width:1100px){
  #sec-todo .td-app:not(.td-kanban){grid-template-columns:minmax(160px,200px) 5px minmax(180px,260px) minmax(0,1fr)}
  #sec-git .git-app{grid-template-columns:minmax(170px,205px) 5px minmax(200px,280px) minmax(0,1fr)}
}
/* Gitea-Issue #47: Die harte Ausblend-Grenze lag bei 1000px — dort verschwanden
   Ribbon UND App samt Ordnerbaum-Knopf, der Baum war nicht mehr einklappbar.
   Die App bleibt jetzt bis 640px im Raster (Baum als Overlay, s. o.), Liste und
   Detail schrumpfen gestaffelt weiter. Erst unter 640px ist wirklich kein Platz
   fuer zwei Spalten — dort bleibt die ehrliche Meldung. */
@media(max-width:1000px){
  /* Detail darf mitschrumpfen, Liste bleibt lesbar (Ordner-/Betreffspalte) */
  #sec-mail .mail-app{grid-template-columns:clamp(200px,30vw,268px) 6px minmax(0,1fr)}
  #sec-mail .mail-detail,
  #sec-mail .mail-list-col{min-width:0}
}
@media(max-width:820px){
  /* Zwei Spalten mit weniger Luft: Liste fest, Detail bekommt den Rest.
     Der Baum liegt in dieser Breite als Overlay ueber der Liste (Regel oben). */
  #sec-mail .mail-app{grid-template-columns:clamp(180px,34vw,240px) 6px minmax(0,1fr)}
  #sec-mail .mail-navbar.mail-quickfilters{gap:6px}
}
@media(max-width:640px){
  /* Letzte Stufe: ehrliche Meldung statt kaputtem Layout */
  #sec-mail .mail-ribbonbar,#sec-mail .mail-app{display:none !important}
  #sec-mail .mail-zu-schmal{display:flex}
}
/* Unter der Mindestbreite: ehrliche Meldung statt kaputtem Layout */
.mail-zu-schmal{display:none}
#sec-mail .mail-zu-schmal{flex-direction:column;align-items:center;justify-content:center;gap:12px;
  min-height:62vh;padding:32px;text-align:center;color:var(--text2);
  border:1px dashed var(--border);border-radius:var(--radius-lg);background:var(--card)}
#sec-mail .mail-zu-schmal h3{font-size:17px;font-weight:600;color:var(--text);margin:0}
#sec-mail .mail-zu-schmal p{font-size:13.5px;max-width:46ch;line-height:1.55;margin:0}
#sec-mail .mail-zu-schmal b{color:var(--text)}

/* =====================================================================
   Issue #15 Phase 2 — Sichtbarer Tastaturfokus (Kap. 250)
   Vorher gab es 3 :focus-visible-Regeln fuer 301 Knoepfe: Mail-Liste, Ribbon
   (mc-btn), Ordnerbaum (mt-f), Chatraeume, To-Do-Zeilen und alle onclick-Flaechen
   hatten KEINEN sichtbaren Fokus — mit der Tastatur war nicht erkennbar, wo man
   steht (WCAG 2.4.7). Eine Regel-Familie statt Einzelregeln, Farbe als Token.
   ===================================================================== */
:root{--focus-ring:var(--accent);--focus-ring-w:2px}
html[data-theme="kontrast"]{--focus-ring:#0000cc;--focus-ring-w:3px}
.mail-item:focus-visible,
.mc-btn:focus-visible,
.mail-tree-col .mt-f:focus-visible,
.msgr-person:focus-visible,
.td-p:focus-visible,
.td-list .td-item:focus-visible,
.git-side .git-p:focus-visible,
.git-list .git-item:focus-visible,
.ud-item:focus-visible,
.qf:focus-visible,
.mail-navbar .mail-qsearch-clear:focus-visible,
.mb-item:focus-visible,
.file-item:focus-visible,
.con-item:focus-visible,
.ics-qa-btn:focus-visible,
.cal-acc-list li:focus-visible,
.ds-item:focus-visible,
.sp-item:focus-visible,
.chat-day:focus-visible,
.ag-item:focus-visible,
button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible{
  outline:var(--focus-ring-w) solid var(--focus-ring);
  outline-offset:2px;
}
/* Flächen, die von aussen beschnitten werden (Listenzeilen), brauchen den Ring
   INNEN — sonst verschwindet er hinter dem overflow des Containers. */
.mail-item:focus-visible,
.td-list .td-item:focus-visible,
.git-list .git-item:focus-visible,
.msgr-person:focus-visible,
.con-item:focus-visible{
  outline-offset:-2px;
}
/* Nur bei Tastaturbedienung: Mausnutzer sehen keinen Ring (kein Doppel-Signal). */
:focus:not(:focus-visible){outline:none}
@media (prefers-reduced-motion: no-preference){
  .mail-item, .td-p, .git-side .git-p{scroll-margin-block:8px}
}

/* =====================================================================
   Issue #15 Phase 1 (Kap. 250) — echte Schaltflaechen statt <div onclick>
   Logo, Nutzermenue, dessen Eintraege und die KI-Schnellchips waren
   <div>/<span> mit onclick: nicht per Tastatur erreichbar, ohne Namen fuer
   Screenreader. Sie sind jetzt <button>. Browser-Buttons bringen eigene Optik
   mit (Rahmen, grauer Grund, zentrierter Text, Innenabstand) — hier neutralisieren,
   damit die abgenommene Optik (Kap. 209 "Praezise Kanten") unveraendert bleibt.
   ===================================================================== */
/* Issue #31: FALLE — die Reset-Sammelregel oben setzt background:none und
   color:inherit; die ursprüngliche Fassung stellte dann `background:#fff` +
   `color:var(--rail)` wieder her. Das ÜBERSCHRIEB den abgenommenen Verlauf aus
   styles.css:1715 (`linear-gradient(--accent,--tow)`, weiße Schrift) — live
   gemessen: bg=none/bgc=rgb(255,255,255), color=rgb(11,34,48), radius 12px.
   Der Nutzer-Befund "logo oben links passt css nicht" war genau das.
   Jetzt: den Verlauf der Design-Sprache wiederherstellen. */
.rail .logo, .header .user{background:none;border:none}
/* Gitea-Issue #94 („logo v5"): Das Startseiten-Logo ist jetzt ein HAUS-Symbol
   im selben System wie die Apps (Lucide, stroke-width 1.6, 22px). Es ist ein
   normaler Rail-Knopf mit Startseiten-Funktion — deshalb erbt es Hover, Fokus,
   Tooltip und den Aktiv-Zustand in der Modulfarbe. Kein eigenes Zeichen, keine
   zweite Fläche: genau „analog zu den anderen apps".
   Die Startseite hat keine eigene Modulfarbe (data-mod="start" hat kein --mod),
   deshalb bekommt der aktive Zustand hier den Akzent — wie der Startbereich. */
.rail .logo{width:72px;min-height:44px;display:flex;align-items:center;justify-content:center;
  cursor:pointer;flex:none;background:transparent;border:none;padding:8px 2px;margin:0 0 14px;
  border-radius:12px;color:var(--rail-fg);transition:background var(--tr),color var(--tr)}
.rail .logo:hover{background:var(--rail-hover);color:#fff}
/* Groesse exakt wie die uebrigen Rail-Knoepfe (gemessen: 24px) — „selbe Effekte
   wie die anderen apps" schliesst die Groesse ein. */
.rail .logo i,.rail .logo svg{width:24px;height:24px;stroke-width:1.6;display:block}
.rail .logo.active{color:#fff;background:color-mix(in srgb,var(--mod,var(--accent)) 42%,transparent)}
.rail .logo.active::before{content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:3.5px;height:20px;border-radius:0 2px 2px 0;
  background:var(--mod,var(--accent));
  box-shadow:0 0 12px color-mix(in srgb,var(--mod,var(--accent)) 70%,transparent)}
.rail .logo{position:relative}
.rail .logo:focus-visible{outline:2px solid var(--focus-ring);outline-offset:3px}
/* Kontrast-Theme: klare Farben statt Verlauf/Mix. */
html[data-theme="kontrast"] .rail .logo{color:#fff}
html[data-theme="kontrast"] .rail .logo.active{background:#000;outline:3px solid #fff;outline-offset:-3px}
html[data-theme="kontrast"] .rail .logo.active::before{background:#fff;box-shadow:none}
.header .user{display:flex;align-items:center;gap:9px;cursor:pointer;padding:4px 8px;border-radius:10px}
.header .user:hover{background:var(--hover)}
.header .ud-item{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:8px;cursor:pointer;
  font-size:13px;width:100%}
/* Kap. 270 (Gitea-Issue #42): Die Einträge im Benutzermenü hatten keine
   Knopf-Grundwerte — der Browser zeichnete sie deshalb als Systemknöpfe
   (graue Fläche, 2px schwarze Kante), während die Statusknöpfe darunter
   normal aussahen. Gemessen: rgb(240,240,240) + 2px rgb(0,0,0) auf genau
   "Persönliche Daten", "Profilbild ändern" und "Abmelden". */
.ud-item{background:none;border:0;width:100%;text-align:left;font-family:inherit;font-weight:500}
.ai-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 11px;border-radius:999px;font-size:12px;
  cursor:pointer;border:1px solid var(--border);background:var(--card);color:var(--text2)}
.ai-chip:hover{color:var(--accent);border-color:var(--accent);background:var(--accent-light)}
/* Kap. 264: Hinweiszeile unter Formularfeldern (z. B. Anmeldename vs. Anzeigename) */
.set-muted{font-size:11.5px;color:var(--text2);margin-top:3px;line-height:1.35}
/* Kap. 272 (Gitea-Issue #49): Der Override aus Kap. 268 ist ZURÜCKGENOMMEN.
   Der Nutzer will den Knopf „Neue E-Mail" oben links wieder in der Akzentfarbe
   („war vorher kontrastfarben, jetzt grau"). Damit gilt wieder die Regel aus
   styles.css (Fläche = --accent, weiße Schrift). Die Ribbon-Kachel bleibt
   zusätzlich als primäre Aktion markiert; beide Wege sind bewusst vorhanden,
   weil der Ribbon einklappbar ist (siehe docs/DESIGN.md §3.5). */

/* ===========================================================================
   Kap. 269 (Issue #32): Systemschalter "mehr Kontrast" (prefers-contrast: more).
   Verläufe, Schleier und Verlaufsflächen werden zu Volltonflächen, Kanten
   kräftiger, Modulfarben auf die dunklen Varianten gezogen (dieselbe Palette
   wie im Standard-Theme). Zustands-Tints (Auswahl, Hover) bleiben bewusst
   erhalten - sie tragen Bedeutung, keine Dekoration.
   =========================================================================== */
@media (prefers-contrast: more){
  html{
    --grad-primary:#0b6bcb;--grad-logo:#0b6bcb;--grad-aiuser:#0b6bcb;--grad-talk:#0069a6;
    --grad-greeting:#1a2233;--login-grad:#16233d;
    --rail:#16233d;--rail-active:#2c4470;--rail-hover:rgba(255,255,255,.2);
    --border:#6b7686;--line:rgba(0,0,0,.6);--hover:rgba(11,107,203,.12);
    --shadow:none;--shadow-sm:none;--text2:#3f4c60;
    --accent:#0b6bcb;--accent-dark:#0a5aa8;--mail:#0b6bcb;--talk:#0069a6;--cal:#a4262c;
    --contact:#0f6b0f;--file:#5c2d91;--wiki:#7f4f24;--todo:#0b6b6f;--tow:#0e6b82;--git:#3a3a3a;
    --danger:#a4262c;--badge-unread:#a4262c;--ok:#0f6b0f;--warn:#8a4a00;
  }
  html[data-theme="dark"]{
    --grad-primary:#3a63e0;--grad-aiuser:#3a63e0;--grad-greeting:#e8edf9;--rail:#0d1330;
    --border:rgba(180,205,255,.6);--line:rgba(255,255,255,.55);--text2:#c9d5ec;
    --accent:#7aa5ff;--accent-dark:#5b8cff;--mail:#7aa5ff;--talk:#4dabf7;--cal:#ff9db0;
    --contact:#7ee2a8;--file:#d6b4ff;--wiki:#ffd166;--todo:#5eead4;--tow:#67e8f9;
    --shadow:none;--shadow-sm:none;
  }
  /* Verlaufsflächen und Milchglas-Schleier aus */
  body,.header,.rail,.card,.set-card,.hub-tile,.hero,.hero-brief,.mod-card,.feed-card,
  .agenda-card,.mrb-panels,.mc-ribbon,.modal-win,.login-card,.toast,.mc-btn.big,.tb-btn.primary{
    background-image:none !important;backdrop-filter:none !important;-webkit-backdrop-filter:none !important;
  }
  /* Karten deckend, damit die kräftigere Kante überall greift */
  .card,.set-card,.hub-tile,.hero-brief,.modal-win,.mrb-panels,.login-card{
    background:var(--card-solid,var(--card)) !important;
  }
  /* Fokus bleibt klar erkennbar */
  :focus-visible{outline:2px solid var(--accent) !important;outline-offset:2px}
}

/* ===========================================================================
   Kap. 272 (Gitea-Issues #51–#54): Kontakte als Liste + Detail-Pane rechts.
   Vorher: einkolonnige Liste, jeder Klick öffnete ein schwebendes 460px-Modal,
   Bearbeiten ein ZWEITES Modal darüber. Jetzt wie Mail/Git/To Do.
   Regeln nach docs/DESIGN.md: Tokens, 1px Kanten, Schrift >= 10,5px.
   =========================================================================== */
.con-app{display:flex;align-items:stretch}
.con-list{width:360px;flex:none;border-right:1px solid var(--border)}
.con-detail{flex:1;min-width:0;overflow-y:auto;padding:16px 18px}
.con-d-leer{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;
  height:100%;min-height:320px;color:var(--text2);text-align:center}
.con-d-leer-t{font-size:15px;font-weight:600;color:var(--text)}
.con-d-leer-s{font-size:12.5px;line-height:1.55}
.con-d-head{display:flex;align-items:center;gap:16px;margin-bottom:12px}
.con-d-name{font-size:19px;font-weight:600}
.con-d-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:5px;font-size:12.5px;color:var(--text2)}
.con-d-actions{display:flex;gap:8px;flex-wrap:wrap;padding:10px 0 12px;border-bottom:1px solid var(--border);margin-bottom:8px}
.con-d-body .row{display:flex;gap:12px;padding:9px 0;border-bottom:1px solid color-mix(in srgb,var(--border) 55%,transparent)}
.con-d-body .row:last-child{border-bottom:0}
.con-d-body .lbl{flex:0 0 108px;font-size:12px;color:var(--text2);padding-top:2px}
.con-d-body .val{flex:1;min-width:0;font-size:13px}
.con-liste{display:flex;flex-direction:column;gap:5px}
.con-liste-z{display:flex;align-items:center;gap:8px}
.con-liste-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.con-prim{margin-left:7px;font-size:10.5px;color:var(--text2);border:1px solid var(--border);border-radius:9px;padding:0 6px}
.con-mini{flex:none;display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;
  border:1px solid var(--border);border-radius:6px;background:none;color:var(--text2);cursor:pointer;text-decoration:none}
.con-mini:hover{background:var(--hover);color:var(--accent);border-color:var(--accent)}
.con-felder{display:flex;flex-direction:column;gap:6px}
.con-feld{display:flex;align-items:center;gap:8px}
.con-feld-inp{flex:1;min-width:0}
.con-feld-x{flex:none;width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--border);border-radius:6px;background:none;color:var(--text2);cursor:pointer}
.con-feld-x:hover{color:var(--danger);border-color:var(--danger)}
.con-add{margin-top:7px}

/* ===========================================================================
   Kap. 273 (Gitea-Issues #56/#57): Quick-Join im Hero + ausgebauter
   Tagesüberblick. Regeln nach docs/DESIGN.md: Tokens, 1px Kanten, Schrift >= 10,5px.
   =========================================================================== */
/* --- Quick-Join am nächsten Termin (#56) --- */
.hn-meet{position:relative;display:inline-flex;align-items:center;margin-left:8px;vertical-align:middle}
.hn-join{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:7px;
  color:#fff;text-decoration:none;box-shadow:0 1px 3px rgba(0,0,0,.2);transition:transform var(--dur-1) ease,filter var(--dur-1)}
.hn-join:hover{transform:translateY(-1px);filter:brightness(1.08)}
.hn-tip{display:none;position:absolute;bottom:calc(100% + 8px);right:0;z-index:var(--z-tip);
  min-width:190px;max-width:280px;padding:8px 10px;border-radius:9px;background:var(--card);color:var(--text);
  border:1px solid var(--border);box-shadow:var(--shadow);font-size:11.5px;line-height:1.45;text-align:left;pointer-events:none}
.hn-meet:hover .hn-tip{display:flex;flex-direction:column;gap:2px}
.hn-tip b{font-size:12.5px}
.hn-tip-z{color:var(--text2)}
.hn-tip-u{color:var(--accent);word-break:break-all}
/* --- Chips mit Modulfarbe (#57) --- */
.sum-chip{color:var(--chip,var(--text))}
.sum-chip-warn{border-color:var(--danger);color:var(--danger);background:color-mix(in srgb,var(--danger) 8%,var(--card))}
/* --- Letzte Mails (#57) --- */
.recent-mails{display:flex;flex-direction:column;gap:1px;max-width:780px;
  background:color-mix(in srgb,var(--card) 70%,transparent);border:1px solid var(--border);
  border-radius:var(--radius);padding:8px 10px 6px;box-shadow:var(--shadow-sm)}
.rm-av{flex:none;width:24px;height:24px;border-radius:50%;display:inline-flex;align-items:center;
  justify-content:center;color:#fff;font-size:10.5px;font-weight:700}
.rm-h-z{margin-left:auto;font-weight:500;letter-spacing:0;text-transform:none;color:var(--text2)}
.rm-h{display:flex;align-items:center;gap:6px;font-size:10.5px;font-weight:600;letter-spacing:.4px;
  text-transform:uppercase;color:var(--text2);padding:0 2px 3px}
.rm-z{display:flex;align-items:center;gap:9px;padding:5px 9px;border:1px solid transparent;border-radius:8px;
  background:none;cursor:pointer;font-family:inherit;font-size:12.5px;color:var(--text);text-align:left;width:100%}
.rm-z:hover{background:var(--hover);border-color:var(--border)}
.rm-dot{flex:none;width:6px;height:6px;border-radius:50%;background:transparent}
.rm-z.unread .rm-dot{background:var(--mail)}
.rm-von{flex:0 0 150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text2)}
.rm-z.unread .rm-von{color:var(--text);font-weight:600}
.rm-betreff{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rm-zeit{flex:none;font-size:11.5px;color:var(--text2)}

/* ===========================================================================
   Kap. 274 (Gitea-Issues #58/#59): Aufgaben-Kachel prägnant + Posteingang-Kachel
   entfallen (Mail-Zugriff läuft über „Letzte Mails" in der Zusammenfassung).
   =========================================================================== */
.hub-plus{padding:2px 8px}
.hub-zahl{display:inline-flex;align-items:baseline;gap:4px;font-size:15px;font-weight:700;color:var(--todo)}
.hub-zahl span{font-size:10.5px;font-weight:500;color:var(--text2);text-transform:none;letter-spacing:0}
.hub-zahl.warn{color:var(--danger)}
.hub-check{flex:none;width:20px;height:20px;margin-top:2px;border:1px solid var(--border);border-radius:6px;
  background:var(--card);color:transparent;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}
.hub-check:hover{border-color:var(--ok);color:var(--ok)}
.hub-item-warn{background:color-mix(in srgb,var(--danger) 7%,transparent);box-shadow:inset 3px 0 0 var(--danger)}
.hub-item-warn .hub-item-s{color:var(--danger)}
.hub-item-weg{opacity:.45;text-decoration:line-through;pointer-events:none;transition:opacity var(--dur-2) ease}
.hub-item-go{flex:none;display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;
  border:0;background:none;color:var(--text2);cursor:pointer;border-radius:6px}
.hub-item-go:hover{background:var(--hover);color:var(--accent)}
.hub-mehr{display:block;width:100%;text-align:center;padding:7px;margin-top:4px;border:1px dashed var(--border);
  border-radius:8px;background:none;color:var(--text2);font-family:inherit;font-size:11.5px;cursor:pointer}
.hub-mehr:hover{color:var(--accent);border-color:var(--accent)}

/* ===========================================================================
   Kap. 275 (Gitea-Issue #62): Kalender-Kachel aufgewertet — Umschalter,
   Terminfarbe, Zähler, Monatsraster, Antwort-Knöpfe.
   =========================================================================== */
.ag-seg{display:inline-flex;border:1px solid var(--border);border-radius:999px;overflow:hidden;margin-left:auto}
.ag-seg button{border:0;background:none;font-family:inherit;font-size:11px;font-weight:600;padding:3px 10px;
  color:var(--text2);cursor:pointer}
.ag-seg button + button{border-left:1px solid var(--border)}
.ag-seg button.active{background:var(--accent);color:#fff}
.hub-zahl-leer{font-size:11px;color:var(--text2)}
.hub-zahl i{width:12px;height:12px;vertical-align:-2px;margin-right:3px}
.ag-day-heute{color:var(--accent)}
.ag-item{display:flex;align-items:center;gap:9px;padding:6px 10px 6px 0;border-bottom:1px solid color-mix(in srgb,var(--border) 50%,transparent);position:relative}
.ag-item:last-child{border-bottom:0}
.ag-item:hover{background:var(--hover)}
.ag-item-offen{background:color-mix(in srgb,var(--warn) 7%,transparent)}
.ag-bar{flex:none;width:3px;align-self:stretch;border-radius:0 2px 2px 0;background:var(--evc,var(--accent))}
.ag-item .tm{flex:none;width:96px;font-size:11.5px;color:var(--text2);font-variant-numeric:tabular-nums}
.ag-main{flex:1;min-width:0}
.ag-title{font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ag-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:11px;color:var(--text2);margin-top:2px}
.ag-meta-item{display:inline-flex;align-items:center;gap:4px;min-width:0}
.ag-vc{display:inline-flex;align-items:center;gap:4px;color:var(--accent)}
.ag-pend{flex:none;display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:600;
  color:var(--warn);border:1px solid var(--warn);border-radius:999px;padding:0 6px}
.ag-join{flex:none;display:inline-flex;align-items:center;gap:5px;padding:4px 9px;border-radius:8px;
  background:var(--accent);color:#fff;font-size:11.5px;font-weight:600;text-decoration:none}
.ag-join:hover{filter:brightness(1.08)}
.ag-qa{flex:none;display:inline-flex;gap:4px}
.ag-qa-b{width:24px;height:24px;border-radius:7px;border:1px solid var(--border);background:var(--card);
  font-size:12px;font-weight:700;cursor:pointer;color:var(--text2)}
.ag-qa-b.yes:hover{border-color:var(--ok);color:var(--ok)}
.ag-qa-b.maybe:hover{border-color:var(--warn);color:var(--warn)}
.ag-qa-b.no:hover{border-color:var(--danger);color:var(--danger)}
.ag-tool{flex:none;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--border);border-radius:7px;background:var(--card);color:var(--text2);cursor:pointer}
.ag-tool:hover{color:var(--accent);border-color:var(--accent)}
.ag-monat{padding:8px 10px 4px}
.ag-monat-kopf,.ag-monat-raster{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}
.ag-monat-kopf span{font-size:10.5px;font-weight:600;color:var(--text2);text-align:center;text-transform:uppercase}
.ag-monat-raster{margin-top:4px}
.ag-tag{position:relative;min-height:46px;border:1px solid var(--border);border-radius:8px;background:var(--card);
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:3px;padding:4px 3px;cursor:pointer;font-family:inherit}
.ag-tag.leer{border:0;background:none;cursor:default}
.ag-tag:not(.leer):hover{border-color:var(--accent)}
.ag-tag.heute{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 8%,var(--card))}
.ag-tag.gewaehlt{outline:2px solid var(--accent);outline-offset:1px}
.ag-tag-n{font-size:11.5px;font-weight:600;color:var(--text)}
.ag-tag-d{display:flex;gap:2px;flex-wrap:wrap;justify-content:center}
.ag-dot{width:6px;height:6px;border-radius:50%;display:inline-block}
.ag-tag-c{font-size:10.5px;color:var(--text2)}
.ag-hinweis{padding:8px 10px;font-size:11.5px;color:var(--text2)}

/* Kap. 277 (Gitea-Issue #66): „Überfällig" ist ein Aufgabenstatus, kein Alarm.
   Amber-Akzent statt Rot; rot (.sum-chip-warn) bleibt echten Fehlern vorbehalten. */
.sum-chip-amber{border-color:var(--warn);background:color-mix(in srgb,var(--warn) 9%,var(--card))}
.sum-chip-amber i{color:var(--warn)}
.sum-jetzt{font-weight:700;color:var(--warn);margin-left:2px}

/* Kap. 279 (Gitea-Issue #66, Punkt D): leerer Kalender im Hero — sichtbarer Anker
   mit Aussage und Alternative statt grauem Text. */
.hn-frei{display:flex;align-items:center;gap:7px;color:var(--ok)}
.hn-frei-t{font-size:13px;font-weight:600;color:var(--text)}
.hn-frei-btn{display:inline-flex;align-items:center;gap:5px;margin-top:8px;padding:5px 11px;border-radius:8px;
  border:1px solid var(--border);background:var(--card);color:var(--text);font-family:inherit;font-size:11.5px;
  font-weight:600;cursor:pointer}
.hn-frei-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--hover)}

/* Kap. 338 (#132): Auf schmalen Schirmen wandert die rechte Spalte unter die
   linke — das 2+1-Raster wird dann einspaltig. */
@media (max-width: 980px){
  .hero{grid-template-columns:minmax(0,1fr)}
  .hero-l,.hero-r{grid-column:1}
}
