/* ============================================================================
 * Chat-App Komponenten — komplett neu geschrieben (2026-07-20).
 * Die Vorgängerdatei war eine 1:1-Kopie des health-pwa-Dashboard-CSS und
 * enthielt keine einzige Regel für die hier gerenderten Klassen. Hier stehen
 * nur noch Komponenten, die die Chat-App wirklich nutzt (Login, Sidebar,
 * Chat, Composer, Dialoge).
 * Farben ausschließlich über --md-sys-color-*-Tokens (Dark/Light läuft
 * automatisch mit). Knopf-Tiefe (2026-08-16): die vormals unter
 * html[data-glass="on"] gekapselten Extra-Regeln für einzelne Knöpfe sind
 * entfernt — die Knopf-Familien im Buttons-Abschnitt gelten jetzt ungated
 * und ersetzen sie vollständig.
 * ========================================================================== */

/* --- Native Formularelemente ---------------------------------------------
 * Eine Basis-Regel statt pro-ID-Styling: deckt Login-Passwort, Modellwahl,
 * Composer-Textarea und alle Settings-Felder gleichzeitig ab.
 * Redesign „Rund“ (2026-09-19): das Feld steht in --panel, also auf derselben
 * Fläche wie Karte und Dialog. Sichtbar macht es deshalb der Rand, und der
 * ist --kante, nicht --rule: --rule erreicht auf --panel nur 1,46:1 (hell)
 * bzw. 1,26:1 (dunkel), ein Eingabefeld braucht als Bedienelement 3:1
 * (WCAG 1.4.11). Der Fokusring ist --text statt einer Akzentfarbe — die
 * Primäraktion hat in „Rund“ keinen Farbton mehr. */
input, textarea, select {
  font-family: inherit;
  font-size: inherit;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--kante);
  border-radius: var(--r-feld);
  padding: 10px 12px;
}
input:focus, textarea:focus, select:focus {
  outline: 2px solid var(--text);
  outline-offset: -1px;
}
select { cursor: pointer; }

/* --- Karten ----------------------------------------------------------------
 * Flach seit dem Redesign „Rund“ (2026-09-19): deckende Fläche --panel,
 * 1-px-Rand in --soft, kein Schatten, kein Verlauf. Einen Schatten tragen
 * nur noch Dinge, die über der Seite schweben (Dialog, Toast, Menü, FAB).
 * Von der Seite hebt sich die Karte über die Tokens ab: --panel ist in
 * beiden Modi heller als --bg. Damit entfallen die Dunkelmodus-Regeln, die
 * den Verlauf umdrehten, die durchscheinende Dashboard-Karte vom 17.08. (sie
 * war nur da, damit das Knopfglas etwas zu brechen hatte) und ihre beiden
 * Notaus-Varianten — der Glas-Notaus fällt in Stufe 1 ganz.
 * Der Rand steht seit Stufe 2 (2026-09-22) direkt in --soft: die Orga-Karten
 * färbten ihn bis dahin über eine eigene Variable in ihrer Kennfarbe, jetzt
 * steht die Kennfarbe nur in Titel und Symbolkreis (die Bausteine der
 * Orga-Karten am Dateiende). Padding setzen die Komponenten selbst (Login
 * braucht 32px). */
.glass-card, .dashboard-card {
  background: var(--panel);
  border: 1px solid var(--soft);
  border-radius: var(--r-karte);
}
/* Die Orga-Karte ist runder als jede andere Karte (Spec „Formen“: 18 statt
   16 px). Die Regel bleibt eigenständig und trägt nur die Form: hier prüft
   karten-tiefe.test.js, dass die Karte kein Stapelkontext wird. Ein
   backdrop-filter, filter, transform, eine opacity unter 1, isolation,
   contain oder will-change an dieser Stelle sperrt die Aufklapp-Menüs
   (z-index 40) in die Karte ein, und die nächste Karte legt sich darüber —
   am 17.08. am Gerät gesehen und mit elementFromPoint nachgemessen. */
.dashboard-card {
  border-radius: var(--r-orga-karte);
}

/* .card ist die Grundfläche der Dialoge (makeDialog(), AppDialog,
 * Kachelmenü): im Markup steht sie nur zusammen mit .modal. Flach wie jede
 * Karte; Schatten und 24-px-Rundung setzt .modal im Abschnitt „Dialoge“. */
.card {
  background: var(--panel);
  border: 1px solid var(--soft);
  border-radius: var(--r-karte);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: var(--text);
}

/* --- Knöpfe: Maße -----------------------------------------------------------
 * Hier stehen nur Maße: Breite, Höhe, Polster, Schrift und die Anordnung des
 * Inhalts. Fläche, Rand, Farbe, Rundung und Zustände kommen aus den
 * Knopf-Familien direkt darunter (Redesign „Rund", 2026-09-19). Bis dahin
 * trugen diese Regeln auch Rand und Farbe, und die Familien mussten sie
 * überstimmen. */
.md-filled-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 24px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
}

.md-icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
}

.md-text-button {
  display: inline-flex;
  align-items: center;
  padding: 8px 12px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
}

/* Der Symbolknopf der Kopf- und Kartenzeilen, Nachfolger von .glass-fab
   (2026-09-19). .glass-fab war eine Pille (min-height 48 px, Polster
   0 15px), mit nur einem Symbol also etwa 54 × 48 px; die Spec gibt dem
   Symbolknopf einen Kreis von 44 px. Die Zentrierung, die vorher .glass-fab
   mitbrachte, steht deshalb hier. */
.knopf-symbol {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  flex: none;
  font: inherit;
}

/* ============================================================================
 * Knopf-Familien — die EINE Stelle für Fläche, Rand, Farbe, Rundung und
 * Zustände eines Knopfes (Redesign „Rund", 2026-09-19).
 *
 * Sechs Familien; jeder Knopf gehört genau EINER an — knopf-familien.test.js
 * prüft das am Markup, nicht an dieser Datei. Die fünf der Spec (Primär,
 * Umriss, Tonal, Symbol, FAB) und dazu ZEILE für Knöpfe, die als Menü- oder
 * Listenzeile, als Kachel oder als Link auftreten. ZEILE ersetzt die
 * Ausnahmeliste „gehört keiner Familie an", die der Wächter sonst bräuchte.
 *
 * Kein backdrop-filter, kein Verlauf, und einen Schatten trägt nur der FAB:
 * er ist das Einzige hier, was über der Seite schwebt. Die Glas-Familie, ihre
 * Kanten-Tokens und der Notaus ?glass=0 sind mit diesem Umbau fort.
 *
 * --knopf-farbe bleibt als Farbanschluss, aber nur Primär und Umriss lesen
 * ihn, jeweils mit Rückfall auf ihre neutrale Farbe. Diktat-Rot, Stopp-Rot
 * und die Bedeutungsfarben der Mail-Aktionen sind Funktion, keine Dekoration;
 * die Module räumen ihre Anschlüsse in ihrer eigenen Stufe auf. Keine Familie
 * SETZT den Anschluss — sonst schlüge sie die Werte der Module.
 *
 * Zustände je Familie, alle bei derselben Spezifität (0,2,0) und in dieser
 * Reihenfolge: :hover, :active, :disabled, :focus-visible. :disabled stellt
 * die Ruhefläche wieder her, weil :hover auch auf gesperrten Knöpfen greift.
 * Die Zustände ändern nur background-color, nie das ganze background: eine
 * Fläche, die ein Modul als Bild malt, bleibt beim Überfahren und Drücken
 * sichtbar. (So überlebten die Aufnahme-Verläufe des Orga-FAB bis Stufe 2;
 * seit dem 2026-09-22 färben ihn zwei Zustandsregeln im FAB-Block flach.)
 * ========================================================================== */

/* KNOPF-FAMILIE PRIMAER — die Hauptaktion eines Bereichs, nie zwei
   nebeneinander: gefüllte Pille in --pri, ohne Rand, ohne Schatten.
   --knopf-schrift gehört zu --knopf-farbe: wer die Fläche umfärbt, setzt die
   Schrift mit, und zwar als feste Farbe — --onpri ist nur gegen --pri und
   --bad gemessen (4,98:1 hell, 5,36:1 dunkel). */
.md-filled-button,
.m3-button-filled,
.app-dialog-ok,
.chat-send-fab,
.chat-stop-fab {
  background: var(--knopf-farbe, var(--pri));
  color: var(--knopf-schrift, var(--onpri));
  border: 0;
  border-radius: var(--r-pille);
  cursor: pointer;
  transition: background-color .15s ease, opacity .15s ease;
}
.md-filled-button:hover, .m3-button-filled:hover, .app-dialog-ok:hover,
.chat-send-fab:hover, .chat-stop-fab:hover {
  background-color: color-mix(in srgb, var(--knopf-farbe, var(--pri)) 88%, var(--knopf-schrift, var(--onpri)));
}
.md-filled-button:active, .m3-button-filled:active, .app-dialog-ok:active,
.chat-send-fab:active, .chat-stop-fab:active {
  background-color: color-mix(in srgb, var(--knopf-farbe, var(--pri)) 76%, var(--knopf-schrift, var(--onpri)));
}
.md-filled-button:disabled, .m3-button-filled:disabled, .app-dialog-ok:disabled,
.chat-send-fab:disabled, .chat-stop-fab:disabled {
  background-color: var(--knopf-farbe, var(--pri));
  opacity: .5;
  cursor: default;
}
.md-filled-button:focus-visible, .m3-button-filled:focus-visible, .app-dialog-ok:focus-visible,
.chat-send-fab:focus-visible, .chat-stop-fab:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

/* KNOPF-FAMILIE UMRISS — Nebenaktionen: „Ändern", „Abbrechen", „Neu messen",
   die Aktionen unter einer Mail. Durchsichtige Pille mit 1-px-Rand in
   --kante: --rule hätte gegen --panel nur 1,46:1, eine Knopfgrenze braucht
   3:1 (WCAG 1.4.11). Mit gesetztem --knopf-farbe färben sich Rand und Schrift
   gemeinsam — so tragen „Erledigt" und „Beobachten" ihre Bedeutung und die
   Gefahr-Variante ihr Rot.
   .knopf-umriss ist am 2026-09-20 aus der Liste gefallen, nicht aus der Welt:
   der generische Name hatte im ganzen Markup genau einen Träger, den Knopf
   „Fertig" des Sortiermodus der Startseite, und der ist mit Stufe 3 entfallen.
   Ein Eintrag ohne Träger ist ein toter Eintrag. Wer den Namen in Stufe 4
   oder 5 braucht, trägt ihn wieder in alle fünf Zeilen ein. */
.mail-act,
.m3-button,
.app-dialog-cancel,
.md-text-button,
.suggest-keep,
.kal-danger,
.betrieb-messen {
  background: transparent;
  color: var(--knopf-farbe, var(--text));
  border: 1px solid var(--knopf-farbe, var(--kante));
  border-radius: var(--r-pille);
  cursor: pointer;
  transition: background-color .15s ease, opacity .15s ease;
}
.mail-act:hover, .m3-button:hover, .app-dialog-cancel:hover, .md-text-button:hover,
.suggest-keep:hover, .kal-danger:hover, .betrieb-messen:hover {
  background-color: color-mix(in srgb, var(--knopf-farbe, var(--text)) 8%, transparent);
}
.mail-act:active, .m3-button:active, .app-dialog-cancel:active, .md-text-button:active,
.suggest-keep:active, .kal-danger:active, .betrieb-messen:active {
  background-color: color-mix(in srgb, var(--knopf-farbe, var(--text)) 14%, transparent);
}
.mail-act:disabled, .m3-button:disabled, .app-dialog-cancel:disabled, .md-text-button:disabled,
.suggest-keep:disabled, .kal-danger:disabled, .betrieb-messen:disabled {
  background-color: transparent;
  opacity: .5;
  cursor: default;
}
.mail-act:focus-visible, .m3-button:focus-visible, .app-dialog-cancel:focus-visible,
.md-text-button:focus-visible, .suggest-keep:focus-visible, .kal-danger:focus-visible,
.betrieb-messen:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

/* KNOPF-FAMILIE TONAL — Chips, Filter und Umschalter-Pillen (Thema,
   Modellfilter, Stimmen). Reiter sind keine Umschalter-Pillen: Post/Hinweise
   der Mail-Karte stehen flach in ZEILE, die Wahl zeigt eine Linie in der
   Kennfarbe. Auch die Wege von einer Karte in ihre volle Liste („ältere
   ungelesene", „Alle N Hinweise", „Ganze Woche") sind seit Stufe 2
   (2026-09-22) Kartenfuß-Zeilen in ZEILE, keine Pillen mehr. Fläche
   --tonal ohne Rand, Schrift immer --text: auf --tonal fielen die Kennfarben
   auf etwa 4:1. Den Farbanschluss liest die Familie nicht — die Themenfarbe
   an „Verschieben" und am gewählten Modell endet damit schon hier und nicht
   erst mit den Paletten in Stufe 3. */
.chat-scroll-fab,
.termin-wahl-knopf,
.drawer-secondary-btn,
.theme-choice,
.model-filter-chip,
.model-option,
.vorlesen-stimme,
.suggest-move,
.schnellfrage,
.message-read-btn,
.message-copy-btn,
.tool-call-chip-button,
.chats-chip {
  background: var(--tonal);
  color: var(--text);
  border: 0;
  border-radius: var(--r-pille);
  cursor: pointer;
  transition: background-color .15s ease, opacity .15s ease;
}
.chat-scroll-fab:hover,
.termin-wahl-knopf:hover,
.drawer-secondary-btn:hover,
.theme-choice:hover,
.model-filter-chip:hover,
.model-option:hover,
.vorlesen-stimme:hover,
.suggest-move:hover,
.schnellfrage:hover,
.message-read-btn:hover,
.message-copy-btn:hover,
.tool-call-chip-button:hover,
.chats-chip:hover {
  background-color: color-mix(in srgb, var(--text) 8%, var(--tonal));
}
.chat-scroll-fab:active,
.termin-wahl-knopf:active,
.drawer-secondary-btn:active,
.theme-choice:active,
.model-filter-chip:active,
.model-option:active,
.vorlesen-stimme:active,
.suggest-move:active,
.schnellfrage:active,
.message-read-btn:active,
.message-copy-btn:active,
.tool-call-chip-button:active,
.chats-chip:active {
  background-color: color-mix(in srgb, var(--text) 16%, var(--tonal));
}
.chat-scroll-fab:disabled,
.termin-wahl-knopf:disabled,
.drawer-secondary-btn:disabled,
.theme-choice:disabled,
.model-filter-chip:disabled,
.model-option:disabled,
.vorlesen-stimme:disabled,
.suggest-move:disabled,
.schnellfrage:disabled,
.message-read-btn:disabled,
.message-copy-btn:disabled,
.tool-call-chip-button:disabled,
.chats-chip:disabled {
  background-color: var(--tonal);
  opacity: .5;
  cursor: default;
}
/* Gewählt. Die Ruhelage ist schon --tonal, die Wahl braucht die nächste
   Stufe. Bis 2026-09-19 stand sie als primary-container in eigenen Regeln
   weiter unten — seit der Alias-Schicht dieselbe Fläche wie die Ruhelage,
   die Wahl wäre unsichtbar geworden. */
.theme-choice[aria-pressed="true"], .model-filter-chip[aria-pressed="true"],
.vorlesen-stimme[aria-pressed="true"], .model-option.active, .chats-chip[aria-pressed="true"] {
  background-color: var(--pri);
  color: var(--onpri);
}
/* Der Nebentext einer gewählten Stimme (ihre Sprache) folgt der Schrift des
   Knopfes: --dim auf --pri hätte etwa 2,6:1. */
.vorlesen-stimme[aria-pressed="true"] .vorlesen-stimme-lang {
  color: inherit;
}
.chat-scroll-fab:focus-visible,
.termin-wahl-knopf:focus-visible,
.drawer-secondary-btn:focus-visible,
.theme-choice:focus-visible,
.model-filter-chip:focus-visible,
.model-option:focus-visible,
.vorlesen-stimme:focus-visible,
.suggest-move:focus-visible,
.schnellfrage:focus-visible,
.message-read-btn:focus-visible,
.message-copy-btn:focus-visible,
.tool-call-chip-button:focus-visible,
.chats-chip:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

/* KNOPF-FAMILIE SYMBOL — ein Symbol ohne Wort: Zurück, Schließen, ⋯, das Plus
   im Kartenkopf, Abhaken. Kreis ohne Fläche und Rand, Symbol in --dim; das
   Überfahren legt --tonal darunter. Die Größe gehört dem einzelnen Knopf
   (.knopf-symbol 44 px, oben; die älteren Klassen behalten ihre Maße bis zu
   ihrer Stufe), die Familie legt Form, Farbe und Zustände fest. */
.knopf-symbol,
.md-icon-button,
.m3-button-icon-small,
.todo-check,
.orga-diktat-abbrechen,
.message-edit-btn {
  background: transparent;
  color: var(--dim);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease, opacity .15s ease;
}
.knopf-symbol:hover, .md-icon-button:hover, .m3-button-icon-small:hover,
.todo-check:hover, .orga-diktat-abbrechen:hover,
.message-edit-btn:hover {
  background-color: var(--tonal);
  color: var(--text);
}
.knopf-symbol:active, .md-icon-button:active, .m3-button-icon-small:active,
.todo-check:active, .orga-diktat-abbrechen:active,
.message-edit-btn:active {
  background-color: color-mix(in srgb, var(--text) 12%, var(--tonal));
  color: var(--text);
}
/* Gewählt (2026-09-20, Stufe 3). Bisher malte der Themen-Editor die Fläche
   des gewählten Symbols per style-Attribut — inline schlägt jede Familie, und
   kein Wächter sieht es. Die Ruhelage ist durchsichtig, das Überfahren legt
   --tonal darunter: eine Wahl in --tonal wäre von einem überfahrenen Knopf
   nicht zu unterscheiden. Also dieselbe Sprache wie bei TONAL — die Wahl ist
   --pri/--onpri. Gemessen: --tonal gegen --panel 1,29:1 hell / 1,25:1 dunkel,
   --pri gegen --panel 17,04:1 / 15,34:1. */
.m3-button-icon-small[aria-pressed="true"] {
  background-color: var(--pri);
  color: var(--onpri);
}
.knopf-symbol:disabled, .md-icon-button:disabled,
.m3-button-icon-small:disabled, .todo-check:disabled,
.orga-diktat-abbrechen:disabled, .message-edit-btn:disabled {
  background-color: transparent;
  color: var(--dim);
  opacity: .5;
  cursor: default;
}
.knopf-symbol:focus-visible, .md-icon-button:focus-visible,
.m3-button-icon-small:focus-visible, .todo-check:focus-visible,
.orga-diktat-abbrechen:focus-visible, .message-edit-btn:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

/* KNOPF-FAMILIE FAB — der schwebende Hauptknopf einer Seite: 56 px hoch,
   Rundung 16 px (ein Material-FAB, keine Pille), --pri und der einzige
   Knopfschatten der App. Drei Träger (Stand 2026-09-22): der Orga-FAB
   „Agent“ in der ausgeklappten Variante .knopf-fab-text und die zwei
   Chats-FABs (Chatliste, Themenseite), quadratisch mit Symbol. Die Lage
   setzt jede Ansicht selbst (.orga-fab, .chats-fab), 16 px über der Leiste.
   Die Familie liest den Farbanschluss nicht; die Diktat-Zustände des
   Orga-FAB stehen als eigene Zustandsregeln am Ende dieses Blocks. */
.knopf-fab {
  display: inline-grid;
  place-items: center;
  width: var(--fab-groesse);
  height: var(--fab-groesse);
  padding: 0;
  background: var(--pri);
  color: var(--onpri);
  border: 0;
  border-radius: var(--r-fab);
  box-shadow: var(--schatten-schwebend);
  cursor: pointer;
  transition: background-color .15s ease, opacity .15s ease;
}
/* Die ausgeklappte Variante (Stufe 2, 2026-09-22): Symbol plus Wort, nur am
   Orga-FAB („Agent“, Spec Z. 238). Die Grundregel bleibt quadratisch — mit
   min-width statt width wären die Chats-FABs 60,02 statt 56 px breit
   (Bericht E). Maße aus dem Entwurf F2: 16 px links, 20 px rechts, 10 px
   Lücke, IBM Plex Sans 600 in 15 px; mit dem 24-px-Symbol 110,98 px breit.
   Kein Wort markiert sich beim 400-ms-Halten fürs Diktat, und iOS zeigt
   kein Kontextmenü. */
.knopf-fab.knopf-fab-text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: auto;
  padding: 0 20px 0 16px;
  font: 600 15px/1 var(--schrift-text);
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.knopf-fab:hover {
  background-color: color-mix(in srgb, var(--pri) 88%, var(--onpri));
}
.knopf-fab:active {
  background-color: color-mix(in srgb, var(--pri) 76%, var(--onpri));
}
.knopf-fab:disabled {
  background-color: var(--pri);
  opacity: .5;
  cursor: default;
}
.knopf-fab:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}
/* Die Diktat-Zustände des Orga-FAB (Stufe 2, 2026-09-22) — flach statt der
   Verläufe, die dashboard.js bis dahin malte. Sie stehen HINTER :hover und
   :active: gleiche Spezifität (0,2,0), die spätere gewinnt, also bleibt die
   Aufnahme auch beim Überfahren und beim Tipp zum Abschicken rot. Nur
   background-color, wie jeder Zustand der Familie. Farben wie im Chat
   (chat.js, .chat-diktat-aufnahme/-verarbeitet; dashboard-fab.test.js N3
   hält sie gleich): Aufnahme #c62828 mit #fff (5,62:1), Warten --tonal mit
   --text (13,26:1 hell / 11,68:1 dunkel). Den Puls setzt das Modul. */
.knopf-fab.orga-fab-aufnahme {
  background-color: #c62828;
  color: #fff;
}
.knopf-fab.orga-fab-verarbeitet {
  background-color: var(--tonal);
  color: var(--text);
}

/* KNOPF-FAMILIE ZEILE — Knöpfe, die als Menü- oder Listenzeile, als Kachel
   oder als Link im Text auftreten: Kontextmenü, Listenzeilen der Chats, der
   Zeilenrumpf eines Todos, Modellkarten, Quellenlinks. Durchsichtig und
   randlos; erst das Überfahren zeigt, dass sie antippbar sind. Farbe und
   Rundung bringt jede Zeile selbst mit — ein roter „Löschen"-Eintrag bleibt
   rot. */
.tile-context-action,
.listenzeile,
.todo-main,
.orga-menue-zeile,
.thread-item,
.model-cat-head,
.tool-source,
.mail-older,
.mail-reiter,
.model-card,
.chat-kopf-titel,
.chat-kopf-menu-item,
.kal-more,
.kal-link {
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background-color .15s ease, opacity .15s ease;
}
.tile-context-action:hover,
.listenzeile:hover,
.todo-main:hover,
.orga-menue-zeile:hover,
.thread-item:hover,
.model-cat-head:hover,
.tool-source:hover,
.mail-older:hover,
.mail-reiter:hover,
.model-card:hover,
.chat-kopf-titel:hover,
.chat-kopf-menu-item:hover,
.kal-more:hover,
.kal-link:hover {
  background-color: color-mix(in srgb, var(--text) 6%, transparent);
}
.tile-context-action:active,
.listenzeile:active,
.todo-main:active,
.orga-menue-zeile:active,
.thread-item:active,
.model-cat-head:active,
.tool-source:active,
.mail-older:active,
.mail-reiter:active,
.model-card:active,
.chat-kopf-titel:active,
.chat-kopf-menu-item:active,
.kal-more:active,
.kal-link:active {
  background-color: color-mix(in srgb, var(--text) 12%, transparent);
}
.tile-context-action:disabled,
.listenzeile:disabled,
.todo-main:disabled,
.orga-menue-zeile:disabled,
.thread-item:disabled,
.model-cat-head:disabled,
.tool-source:disabled,
.mail-older:disabled,
.mail-reiter:disabled,
.model-card:disabled,
.chat-kopf-titel:disabled,
.chat-kopf-menu-item:disabled,
.kal-more:disabled,
.kal-link:disabled {
  background-color: transparent;
  opacity: .5;
  cursor: default;
}
.tile-context-action:focus-visible,
.listenzeile:focus-visible,
.todo-main:focus-visible,
.orga-menue-zeile:focus-visible,
.thread-item:focus-visible,
.model-cat-head:focus-visible,
.tool-source:focus-visible,
.mail-older:focus-visible,
.mail-reiter:focus-visible,
.model-card:focus-visible,
.chat-kopf-titel:focus-visible,
.chat-kopf-menu-item:focus-visible,
.kal-more:focus-visible,
.kal-link:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}
/* Der offene Thread im Seitenmenü: --tonal, wie jede aktive Pille. Bis
   2026-09-20 war es ein Verlauf aus zwei Palettentönen mit 82 % Deckkraft
   und fester weißer Schrift — 8 von 10 Paletten lagen damit unter 4,5:1.
   Der Zustand steht im Markup als aria-current und nirgends sonst. */
.thread-item[aria-current="true"] {
  background-color: var(--tonal);
}
/* ENDE KNOPF-FAMILIEN */

/* Gefahr ist ein Modifikator, keine Familie (2026-09-19): er setzt nur den
   Farbanschluss. Am Primärknopf wird die Fläche rot, am Umriss Rand und
   Schrift. Vorher stand .dialog-gefahr in der Glas-Familie und gewann dort
   gegen die gefüllte — der Bestätigen-Knopf eines Löschdialogs war
   primärgetöntes Glas, leiser als ein gewöhnliches OK. */
.dialog-gefahr,
.kal-danger {
  --knopf-farbe: var(--bad);
}

/* Die Kalenderwahl unter einem Termin-Chip (2026-09-11). Hier steht NUR
   Anordnung: Flaeche, Rand und Zustaende der Knoepfe kommen aus der Familie
   UMRISS ueber .m3-button. Die Spec sieht fuer die Kalenderwahl die
   Tonal-Gestalt vor; das zieht Stufe 3 mit dem Chat nach. */
.termin-wahl {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}
.termin-wahl-frage {
  opacity: .8;
}
.termin-wahl-knoepfe {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* 44 px, weil diese Wahl am Handy mitten im Lesefluss getroffen wird und die
   Knoepfe nebeneinander stehen — ein zu kleines Ziel trifft den Nachbarn.
   Rund auf Joerns Ansage (2026-09-11). Der Radius bleibt ausdruecklich stehen,
   weil diese Wahl rund sein MUSS, auch wenn die Familie sich einmal aendert.
   Familie TONAL seit 2026-09-21: die Spec gibt den Chips unter Antworten die
   Tonal-Gestalt (Abschnitt „Chat"), und Stufe 3 hatte nur die halbe Zusage
   eingeloest — der Kopf der Kalenderwahl wurde eine flache Zeile, die
   Wahlknoepfe darunter blieben Umriss. Nebeneinander sah das aus wie zwei
   verschiedene Bedienelemente. Die Klasse m3-button ist dafuer aus dem Markup
   gefallen: sie gehoert zu UMRISS, und ein Knopf gehoert genau EINER Familie
   (tests/knopf-familien.test.js). Der alte Satz „sie stehen unter einem Chip,
   der selbst eine Pille ist" stimmt seit Aufgabe 3 ohnehin nicht mehr — der
   Chip darueber ist eine Zeile. */
.termin-wahl-knopf {
  min-height: 44px;
  padding: 0 18px;
  border-radius: 999px;
}

.spacer { flex: 1; }
.error-text { color: var(--md-sys-color-error); font-size: 13px; }

/* --- Login ----------------------------------------------------------------- */
/* Das Formular trägt im Markup .glass-card (index.html) und bekommt darüber
   die allgemeine Kartenform aus dem Abschnitt „Karten“: --panel, 1 px
   --soft, 16 px (--r-karte). Der Klassenname ist ein Überbleibsel; er
   wechselt mit dem Login in Stufe 5. */
#login-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: min(360px, 100%);
  padding: 32px;
}
#login-form h2 {
  font-size: 28px;
  font-weight: 600;
  text-align: center;
  color: var(--text);
}

/* .chip: Brain-Projekt-Tag auf Themen-Karten (chat.js) — von der alten
   Sidebar übernommen, weiterhin in Gebrauch. */
.chip {
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  font-size: 12px;
  white-space: nowrap;
}

/* --- Dialoge (Speichern-Diff, Einstellungen) --------------------------------- */
/* Gerüst und Fläche der Dialoge stehen seit dem Redesign „Rund“ (2026-09-19)
 * an EINER Stelle, hier. Bis dahin war .overlay doppelt definiert — in
 * layout.css mit 40 % Schwarz, hier mit 42 % (gewann nur, weil
 * components.css später lädt) —, und .modal war auf beide Dateien verteilt.
 * Jetzt gibt es je Selektor eine Regel. Sie steht in components.css, weil
 * .modal NACH .card kommen muss, um dessen Rundung bei gleicher Spezifität
 * zu schlagen.
 * .cs-menu/.cs-trigger (das Custom-Select-Dropdown aus custom-select.js)
 * standen ursprünglich auf derselben Umzugsliste aus glass.css, sind aber
 * tot: das Modul ist in index.html nicht eingebunden und wird von keinem
 * anderen Modul referenziert — die Klassen treffen kein Markup. Die
 * Git-Historie bewahrt sie, falls das Modul je wieder verdrahtet wird. */

/* Task 10, Fix-Runde 1, Befund C: der Scrim trug bis 2026-08-16 selbst
   blur(12px) — "damit das Frosted-Modal davor plastisch traegt statt vor
   flachem Schwarz zu stehen". Gemessen (231-Zeilen-Benachrichtigungs-
   Overlay, Scroll): zwei gestapelte backdrop-filter (Scrim UNTER Modal)
   kosten zusammen ~22 fps statt ~60. Isoliert liegt der Scrim-Blur allein
   bei fast der Hälfte der Kosten, obwohl dahinter — anders als beim Modal —
   kein Text steht, der lesbar bleiben muss. Deshalb faellt er ganz weg; die
   Tönung (42 % Schwarz, seit 2026-09-19 das Token --scrim) bleibt, nur
   ungeblurrt. */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 8000;
  background: var(--scrim);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  animation: overlayIn .16s ease;
}

/* Deckend seit dem Redesign „Rund“ (2026-09-19) — vorher Frosted Glass mit
   blur(14px) und einem Glanzverlauf. Zwei Gründe, und der zweite erzwingt
   den Zeitpunkt: „Rund“ kennt kein Glas und keine Verläufe, und die
   Glasfläche las --glass-grad und --glass-sheen OHNE Rückfallwert. Fallen
   die Tokens (Aufgabe 7), wird die ganze background- bzw.
   box-shadow-Deklaration ungültig — der Dialog stünde durchsichtig und
   schattenlos über dem Scrim. Der Dialog schwebt und trägt deshalb, anders
   als die Karte, den Schwebe-Schatten. */
.modal,
.modal.card {
  background: var(--panel);
  border: 1px solid var(--soft);
  box-shadow: var(--schatten-schwebend);
}
/* Die 24-px-Rundung steht bewusst nur an .modal (0,1,0) und nicht an
   .modal.card (0,2,0): das Einstellungsblatt .model-config-sheet (weiter
   unten) ist auf dem Handy vollflächig mit Rundung 0 und ab 720 px 28 px —
   bei gleicher Spezifität gewinnt es als spätere Regel, gegen .modal.card
   verlöre es. */
.modal {
  width: min(100%, 560px);
  max-height: 86vh;
  overflow: auto;
  border-radius: var(--r-sheet);
  animation: modalIn .18s ease;
}
@keyframes overlayIn { from { opacity: 0; } }
@keyframes modalIn { from { opacity: 0; transform: translateY(10px) scale(.98); } }
@media (prefers-reduced-motion: reduce) {
  .overlay, .modal { animation: none; }
}

.dlg-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
}
.modal h3 { font-size: 18px; font-weight: 500; }
.modal label {
  display: block;
  font-size: 13px;
  color: var(--md-sys-color-on-surface-variant);
}
.modal label input:not([type="checkbox"]),
.modal label textarea,
.modal label select {
  display: block;
  width: 100%;
  margin-top: 4px;
  font-size: 14px;
}
/* Termin: Datum und Uhrzeit sind zwei Felder unter einer Beschriftung. Ein
   <label> darum wäre falsch — es verbindet sich nur mit dem ERSTEN Feld, die
   Uhrzeit bliebe ohne zugänglichen Namen. Deshalb eine Gruppe mit eigenen
   Feldnamen; die Optik von .modal label wird hier nachgezogen, weil deren
   Selektoren ohne <label> nicht mehr greifen. */
.modal .dlg-field { display: block; font-size: 13px; color: var(--md-sys-color-on-surface-variant); }
.modal .dlg-datetime { display: flex; gap: 10px; margin-top: 4px; }
.modal .dlg-datetime input { flex: 1 1 0; width: auto; min-width: 0; margin-top: 0; font-size: 14px; }
/* Der Weg vom Todo zur gemeinten Mail: linksbündig unter den Feldern statt
   neben Abbrechen/Speichern — er ändert nichts, er führt nur woandershin. */
.modal .dlg-mail { display: inline-flex; align-items: center; gap: 6px; margin-top: 12px; }
.modal .dlg-mail .material-symbols-rounded { font-size: 18px; }
.modal details { margin: 4px 0; }
.modal summary { cursor: pointer; font-size: 14px; }
/* Checkbox-Label im Speichern-Dialog (<summary><label><input …) ist Fließtext,
   kein Settings-Formularfeld — inline lassen, Textfarbe erben. */
.modal summary label {
  display: inline;
  font-size: inherit;
  color: inherit;
}
/* .diff-view/-add/-del stehen inline in index.html; nur der Kontext fehlte. */
.diff-ctx { color: var(--md-sys-color-on-surface-variant); }

/* --- Health-PWA-Kompatibilitätsklassen für die 1:1 übernommenen Chat-Templates --- */
/* Die Symbolschrift (Redesign „Rund“, 2026-09-19). Bis Stufe 1 kamen
   font-family, Ligatur, Zeilenhöhe und Umbruchverbot allein aus Googles
   Stylesheet, hier stand nur das Gewicht. Seit Orbit die Schrift selbst
   ausliefert (@font-face in base.css), trägt die Klasse die ganze
   Grundregel — ohne sie stünde an jeder Stelle der Name als Text.
   Kein font-variation-settings: die Teilmenge ist eine statische Instanz
   (wght 300, FILL 0, GRAD 0, opsz 24) ohne Achsen, an denen es drehen
   könnte. font-weight: normal trifft die eine Fläche der Familie und
   verhindert, dass der Browser das Symbol in einem fetten Knopf künstlich
   verbreitert (synthetisches Fett). */
.material-symbols-rounded {
    font-family: 'Material Symbols Rounded';
    font-weight: normal;
    font-style: normal;
    font-size: 24px;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    white-space: nowrap;
    word-wrap: normal;
    direction: ltr;
    font-feature-settings: 'liga';
    -webkit-font-smoothing: antialiased;
    vertical-align: middle;
    user-select: none;
}
/* Nur Maße (2026-09-19) — Form, Farbe und Zustände kommen aus der Familie
   SYMBOL. Die 40 px bleiben, bis die jeweilige Ansicht in ihrer Stufe
   umgebaut wird; die neuen Symbolknöpfe (.knopf-symbol) haben 44. */
.m3-button-icon-small {
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    flex: none;
}
.m3-button-icon-small .material-symbols-rounded { font-size: 20px; }
/* Nur Maße — Fläche, Rand, Farbe und Rundung kommen aus der Familie PRIMAER. */
.m3-button-filled {
    min-height: 44px;
    padding: 0 18px;
    font: inherit;
    font-weight: 500;
}
/* Nur Maße — „OK" ist PRIMAER, „Abbrechen" UMRISS. Abbrechen trug bis
   2026-09-19 --knopf-farbe: primary; als Umriss hieße das ein Rand in --pri
   statt in --kante, lauter als die Nebenaktion sein soll. */
.app-dialog-cancel, .app-dialog-ok {
    min-height: 44px;
    padding: 0 18px;
    font: inherit;
    font-weight: 600;
}
/* Der Toast stand unten am Rand und wurde übersehen. In der Mitte wird er
   gesehen; pointer-events:none hält alles darunter bedienbar, weil er nichts
   ist, worauf man tippt.
   Deckend seit dem Redesign „Rund“ (2026-09-19), vorher Frosted Glass. Er
   schwebt über der Seite und trägt deshalb den Schwebe-Schatten. Die drei
   Töne sind Flächen aus den Tokens — Erfolg --tonal, Fehler und Teilerfolg
   ein Hauch der Wertungsfarbe über --panel —, der Text ist in allen dreien
   --text (mindestens 11:1, dunkel auf dem Teilerfolg). */
.app-toast {
    position: fixed;
    z-index: 9600;
    left: 50%;
    top: 50%;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: min(420px, calc(100vw - 48px));
    padding: 14px 22px;
    border: 1px solid var(--soft);
    /* Keine Pille: zweizeilige Meldungen wie die Anhang-Warnung brechen darin auf. */
    border-radius: var(--r-karte);
    box-shadow: var(--schatten-schwebend);
    transform: translate(-50%, -50%) scale(.96);
    opacity: 0;
    pointer-events: none;
    transition: transform .18s ease, opacity .18s ease;
    font-size: 15px;
    line-height: 1.4;
    color: var(--text);
    background: var(--tonal);
}
.app-toast-error { background: color-mix(in srgb, var(--bad) 14%, var(--panel)); }
/* Der Teilerfolg (z. B. Mail raus, Ablage in "Gesendet" gescheitert): weder
   success (verdeckt den Rest) noch error (verneint, dass etwas gelang). */
.app-toast-warn { background: color-mix(in srgb, var(--watch) 16%, var(--panel)); }
.app-toast.visible { transform: translate(-50%, -50%) scale(1); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .app-toast { transition: none; } }
.md-typescale-label-small { font-size: 11px; font-weight: 500; letter-spacing: .03em; }
.md-typescale-label-medium { font-size: 12px; font-weight: 500; }
.md-typescale-label-large { font-size: 14px; font-weight: 500; }
.md-typescale-body-small { font-size: 12px; line-height: 1.45; }
.md-typescale-body-medium { font-size: 14px; line-height: 1.5; }
.md-typescale-body-large { font-size: 16px; line-height: 1.55; }
.md-typescale-title-small { font-size: 14px; font-weight: 600; }
.md-typescale-title-medium { font-size: 16px; font-weight: 600; }

/* --- Startseite: schwebende Aktionen, Kontextmenü, Sortierung ------------- */
/* Gleiche Größe wie die Kopfknöpfe von Orga und System (Karten sortieren,
   Einstellungen, Aktualisieren): seit 2026-09-19 alle .knopf-symbol, 44 px.
   Bis dahin trug dieser Knopf eigene 48 px, weil die .glass-fab-Pille der
   anderen so hoch war; die Gleichheit bleibt, nur auf dem Maß der Spec. */
.home-settings-fab { position: static; }
.tile-context-menu { width: min(100%, 360px); padding: 10px; }
.tile-context-title { padding: 8px 10px 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 16px; font-weight: 600; }
/* Fläche, Rand und Zustände kommen aus der Familie ZEILE. color bleibt
   eigenständig — ZEILE setzt keine Textfarbe. Der eigene :hover stand hier bis
   2026-09-19 und überstimmte den der Familie (8 % statt 6 %, gleiche
   Spezifität, aber später im Stylesheet) — genau das Gegenbeispiel zu der
   Regel, dass die Familie die eine Stelle ist. Er ist entfallen. */
.tile-context-action { width: 100%; min-height: 48px; display: flex; align-items: center; gap: 12px; border-radius: 14px; padding: 0 12px; color: var(--md-sys-color-on-surface); font: inherit; text-align: left; }
.tile-context-action .material-symbols-rounded { color: var(--md-sys-color-on-surface-variant); }
.tile-context-action.danger, .tile-context-action.danger .material-symbols-rounded { color: var(--md-sys-color-error); }
/* --- Listenzeile ---------------------------------------------------------
   Die Zeile der Chatliste (Spec „Chats": Symbol im Kreis, Name, Titel des
   jüngsten Chats, Datum rechts), auf beiden Ebenen der Chats-Seite. Das
   Seitenmenü des Chats benutzt sie NICHT: dort steht .thread-item mit
   eigenen Regeln in chat.js — dieselbe Gestalt, kleinere Maße (Titel 16
   statt 19 px, Vorschau 12 statt 13, Zeit 10,5 statt 11), weil dem Titel
   angedockt nur 158 px bleiben. Zwei Klassen mit zwei Maßen sind Jörns
   Entscheidung vom 2026-09-21, kein Abschreiben — die Absicht aus Stufe 3,
   eine Klasse für beide Bildschirme, ist damit aufgegeben
   (tests/listenzeile-zwei-klassen.test.js hält es fest).
   Fläche, Rand und Zustände kommen aus der Familie ZEILE; hier stehen nur
   Maße, Anordnung und die Farben der Textstufen. Angelegt 2026-09-20. */
.listenzeile {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 64px;
  padding: 8px 12px;
  border-radius: var(--r-feld);
  color: var(--text);
  font: inherit;
  text-align: left;
  touch-action: manipulation;
}
/* Der Symbolkreis ist EINFARBIG. Die zehn Themenpaletten fielen als
   Symbolfarbe bei sechs von zehn unter 3:1 (WCAG 1.4.11, gemessen am
   2026-09-20: hell wald 2,50, koralle 2,69, bernstein 1,94). --text auf
   --tonal ist die Vorgabe der Spec für diese Fläche. */
.listenzeile-kreis { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--tonal); }
.listenzeile-kreis .material-symbols-rounded { font-size: 22px; color: var(--text); }
.listenzeile-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.listenzeile-kopf { display: flex; align-items: center; gap: 8px; min-width: 0; }
.listenzeile-titel { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--schrift-titel); font-weight: 600; font-size: 19px; line-height: 1.15; }
.listenzeile-unter { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dim); font-size: 13px; }
/* Die Zeit steht in Mono, wie jede Mikro-Beschriftung der Spec. */
.listenzeile-datum { flex: none; align-self: flex-start; padding-top: 3px;
  font-family: var(--schrift-mono); font-size: 11px; color: var(--faint); }
.listenzeile-marke { flex: none; padding: 1px 8px; border-radius: var(--r-pille);
  background: var(--tonal); color: var(--dim); font-size: 10px; font-weight: 600; letter-spacing: .04em; }

/* --- Modell-Konfigurator -------------------------------------------------- */
.model-config-overlay { align-items: stretch; padding: 0; }
.model-config-sheet {
  width: min(100%, 760px);
  max-height: none;
  height: 100dvh;
  border-radius: 0;
  padding: max(16px, env(safe-area-inset-top, 0px)) clamp(16px, 4vw, 28px) calc(18px + env(safe-area-inset-bottom, 0px));
  gap: 16px;
  overflow-y: auto;
}
/* Rechts statt links (2026-08-17): das Einstellungsblatt füllt praktisch den
   ganzen Schirm, ein Tipp daneben trifft fast nie das Overlay — hier IST der
   Knopf der Ausweg. Seit 2026-09-19 ist er ein gewöhnlicher Symbolknopf
   (.knopf-symbol, 44 px wie die Kopfknöpfe von Orga und System): das Glas,
   das ihn von den blanken X der kleinen Aufklapp-Fenster abhob, gibt es
   nicht mehr, und die .glass-fab-Pille, die hier zum Kreis gebogen werden
   musste, auch nicht. */
.model-config-header { display: flex; justify-content: flex-end; }
.model-catalog-section { display: flex; flex-direction: column; gap: 16px; }
.model-catalog-heading { display: grid; grid-template-columns: minmax(0, 1fr) 40px; align-items: start; gap: 10px; }
.model-catalog-heading h3 { margin: 4px 0 2px; font-size: clamp(20px, 4vw, 26px); }
.model-catalog-heading p, .model-config-note { margin: 0; color: var(--md-sys-color-on-surface-variant); line-height: 1.4; }
.theme-preference { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; padding: 12px; border-radius: 16px; background: color-mix(in srgb, var(--md-sys-color-surface-container-high) 58%, transparent); border: 1px solid color-mix(in srgb, var(--md-sys-color-outline-variant) 42%, transparent); }
.theme-preference-label { font-size: 13px; font-weight: 600; color: var(--md-sys-color-on-surface-variant); }
/* overflow-x:auto macht den Kasten in BEIDEN Achsen zum Scroll-Container —
   der Schatten der Knöpfe (0 4px 12px) lief unten dagegen und wurde mit einer
   harten Kante abgeschnitten. Innenabstand schafft ihm Platz, der negative
   Außenabstand nimmt ihn dem Layout wieder ab. (Gemeldet 2026-08-17: „harte
   Kante durch zu großen Dropshadow", und bei den Modell-Filtern sind die
   Chips unten angeschnitten.) */
.theme-choice-row, .model-filter-row { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none;
  padding: 8px 2px 14px; margin: -8px -2px -10px; }
.theme-choice-row::-webkit-scrollbar, .model-filter-row::-webkit-scrollbar { display: none; }
/* Nur Maße — Fläche, Farbe und der Gewählt-Zustand kommen aus der Familie
   TONAL. Die Wahl stand bis 2026-09-19 hier als primary-container; das ist
   seit der Alias-Schicht --tonal, also die Ruhelage selbst. */
.theme-choice, .model-filter-chip { flex: none; min-height: 36px; padding: 0 13px; font: inherit; font-size: 13px; }
.theme-choice[aria-pressed="true"], .model-filter-chip.active { font-weight: 600; }
.model-card-list { display: flex; flex-direction: column; gap: 18px; }
.model-tier-group { display: flex; flex-direction: column; gap: 8px; }
.model-tier-heading { display: flex; justify-content: space-between; align-items: baseline; padding: 0 2px; color: var(--md-sys-color-on-surface-variant); font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.model-tier-heading span { font-weight: 500; letter-spacing: normal; text-transform: none; }
/* Fläche, Rand und Zustände kommen aus der Familie ZEILE — hier bleibt nur
   Anordnung. ZEILE setzt border: 0; die Karte hat also keinen Rand, den eine
   border-color noch einfärben könnte. Die Randfarben für Hover und Gewählt
   standen hier bis 2026-09-19 und sind mit dem Wechsel auf ZEILE wirkungslos
   geworden — deshalb raus, samt border-color aus dem Übergang. Braucht die
   Karte in Stufe 3 wieder einen Rand, gehört er in die Familie. */
.model-card { width: 100%; display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 10px; align-items: start; border-radius: 20px; padding: 16px; text-align: left; transition: transform .16s ease, background .16s ease; }
.model-card:hover { transform: translateY(-1px); }
/* Gewählt heißt flach --tonal, wie .theme-choice[aria-pressed] oben — der
   Verlauf fiel mit dem Glas (Redesign „Rund“, 2026-09-19). */
.model-card.selected { background: var(--tonal); }
.model-card-check { margin-top: 2px; color: var(--md-sys-color-primary); }
.model-card-copy { display: flex; min-width: 0; flex-direction: column; gap: 3px; }
.model-card-name { font-size: 18px; font-weight: 600; }
.model-card-id, .model-card-price { overflow-wrap: anywhere; color: var(--md-sys-color-on-surface-variant); font-size: 13px; line-height: 1.35; }
/* Deckend mit Trennlinie statt Ausblend-Verlauf (2026-09-19): die Liste
   läuft unter einer Kante weg, nicht in einen Schleier. --panel ist die
   Fläche des Blatts, seit .modal deckend ist. */
.model-config-footer { position: sticky; bottom: calc(-18px - env(safe-area-inset-bottom, 0px)); margin: 0 -2px; padding: 12px 2px calc(12px + env(safe-area-inset-bottom, 0px)); background: var(--panel); border-top: 1px solid var(--soft); color: var(--md-sys-color-on-surface-variant); font-size: 12px; line-height: 1.4; }
.model-config-loading { display: grid; place-items: center; min-height: 160px; color: var(--md-sys-color-on-surface-variant); }
@media (min-width: 720px) {
  .model-config-overlay { align-items: center; padding: 24px; }
  .model-config-sheet { height: min(88dvh, 900px); border-radius: 28px; }
}
/* F5: Stimmen-Wähler in den Einstellungen */
.vorlesen-sektion { display: flex; flex-direction: column; gap: 12px; }
.vorlesen-liste { display: flex; flex-direction: column; gap: 8px; }
/* Nur Anordnung — Fläche, Farbe und der Gewählt-Zustand
   (.vorlesen-stimme[aria-pressed="true"]) kommen aus der Familie TONAL. */
.vorlesen-stimme { display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 10px 12px; border-radius: 14px;
    font: inherit; text-align: left; cursor: pointer; }
.vorlesen-stimme-lang { color: var(--md-sys-color-on-surface-variant); font-size: 13px; }

/* Sprechtempo (2026-09-03). Der erste Regler der App — die Bahn wird von
   Hand gezeichnet, weil Browser den Standard sonst grau und dünn malen.
   Kein Knopf, also keine Familie; der Wächter sieht nur <button>. */
.vorlesen-tempo { display: flex; flex-direction: column; gap: 6px; padding: 4px 2px 0; }
.vorlesen-tempo-kopf { display: flex; align-items: baseline; justify-content: space-between;
    font-size: 13px; font-weight: 600; color: var(--md-sys-color-on-surface-variant); }
.vorlesen-tempo-kopf output { font-variant-numeric: tabular-nums; color: var(--md-sys-color-primary); }
/* Rahmen und Fläche der allgemeinen input-Regel (oben) hier abräumen — die
   Bahn wird selbst gezeichnet, ein Kasten drumherum sähe nach Textfeld aus. */
.vorlesen-tempo-regler { -webkit-appearance: none; appearance: none; width: 100%; height: 28px;
    background: transparent; border: 0; padding: 0; border-radius: 0; cursor: pointer; }
.vorlesen-tempo-regler::-webkit-slider-runnable-track { height: 4px; border-radius: 999px;
    background: color-mix(in srgb, var(--md-sys-color-primary) 28%, transparent); }
.vorlesen-tempo-regler::-moz-range-track { height: 4px; border-radius: 999px;
    background: color-mix(in srgb, var(--md-sys-color-primary) 28%, transparent); }
.vorlesen-tempo-regler::-webkit-slider-thumb { -webkit-appearance: none; appearance: none;
    width: 20px; height: 20px; margin-top: -8px; border-radius: 50%; border: 0;
    background: var(--md-sys-color-primary); }
.vorlesen-tempo-regler::-moz-range-thumb { width: 20px; height: 20px; border-radius: 50%; border: 0;
    background: var(--md-sys-color-primary); }
.vorlesen-tempo-regler:focus-visible { outline: 2px solid var(--md-sys-color-primary); outline-offset: 4px; border-radius: 8px; }
/* Kalender-Ausdünnung in den Einstellungen — dieselbe Zeilenform wie beim
   Stimmen-Wähler, damit die beiden Listen nicht auseinanderlaufen. */
.kalender-sektion { display: flex; flex-direction: column; gap: 12px; }
.kalender-liste { display: flex; flex-direction: column; gap: 8px; }
.kalender-pref { display: flex; align-items: center; gap: 10px;
    padding: 10px 12px; border-radius: 14px; border: 1px solid var(--md-sys-color-outline-variant);
    color: var(--md-sys-color-on-surface); font: inherit; cursor: pointer; }
.kalender-punkt { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 999px; }
.kalender-name { flex: 1 1 auto; min-width: 0; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; }
/* Erinnerungen (Stufe 2, 2026-09-22) — der erste Schalter der App: ein
   natives <input type="checkbox" role="switch">, kein <button>, also keine
   Knopffamilie (wie Tempo-Regler und Kalender-Kästchen). Die Zeile ist ein
   <label>; .modal label (0,1,1) setzte sonst display:block und 13 px, darum
   der Vorsatz .model-config-sheet (0,2,0). Rahmen, Fläche und Fokus der
   allgemeinen input-Regeln (oben) räumt .schalter selbst ab. Maße nach
   Material (Bahn 52 × 32 px, Bericht E, Entscheidung 7). Aus: Rand --kante
   gegen --panel 3,29:1 hell / 3,15:1 dunkel, Knopf --dim 6,40:1 / 6,97:1;
   an: Bahn --pri, Knopf --onpri. */
.erinnerungen-sektion { display: flex; flex-direction: column; gap: 12px; }
.model-config-sheet .erinnerungen-zeile { display: flex; align-items: center; justify-content: space-between;
    gap: 12px; min-height: 44px; font-size: 15px; color: var(--text); cursor: pointer; }
.model-config-sheet .erinnerungen-zeile:has(.schalter:disabled) { cursor: default; }
.schalter { -webkit-appearance: none; appearance: none; flex: none; position: relative;
    width: 52px; height: 32px; margin: 0; padding: 0;
    background: var(--panel); border: 1px solid var(--kante); border-radius: var(--r-pille);
    cursor: pointer; transition: background-color .15s ease, border-color .15s ease; }
.schalter::before { content: ''; position: absolute; top: 50%; left: 7px;
    width: 16px; height: 16px; margin-top: -8px; border-radius: 50%; background: var(--dim);
    transition: left .15s ease, width .15s ease, height .15s ease, margin-top .15s ease; }
.schalter:checked { background: var(--pri); border-color: var(--pri); }
.schalter:checked::before { left: 23px; width: 24px; height: 24px; margin-top: -12px; background: var(--onpri); }
.schalter:focus { outline: none; }
.schalter:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
.schalter:disabled { opacity: .5; cursor: default; }
@media (prefers-reduced-motion: reduce) { .schalter, .schalter::before { transition: none; } }

/* ============================================================================
 * ORGA-BAUSTEINE — Redesign „Rund“, Stufe 2 (2026-09-22)
 * Die Teile, aus denen alle vier Orga-Karten gebaut sind: Kennfarbe,
 * Mikro-Beschriftung, Kartenkopf, Unterteilung, Listenzeile, Leersatz,
 * Kartenfuß, Menü, Fokus. EIN Ort, weil dashboard-mails.js und
 * dashboard-calendar.js in ihren Tests einzeln im vm laufen und sonst jede
 * Karte dieselben Regeln abschriebe. Die Module setzen nur Markup und ihre
 * eigenen Zeilenregeln darauf; eine Modulregel nennt nie eine dieser
 * Klassen (tests/orga-bausteine.test.js). Werte: Spec „Gestaltungsregeln“,
 * Maße aus dem Entwurf F2 (Bericht F, Abschnitt S3–S7). Kontraste gerechnet
 * am 2026-09-22 (WCAG 2.x, Tokens aus m3-tokens.css), Zahlen je Regel.
 * ========================================================================== */

/* Kennfarbe. Die Kennklasse hängt cardsHtml() an das äußere .dashboard-card;
   darunter liest jeder Baustein nur --kenn. Kennfarbe steht nur als Titel und
   Symbolkreis (Spec Z. 55), nie auf --tonal (Z. 106). */
.kenn-todo { --kenn: var(--todo); }
.kenn-cal  { --kenn: var(--cal); }
.kenn-mail { --kenn: var(--mail); }
.kenn-call { --kenn: var(--call); }

/* Mikro-Beschriftung (Spec Z. 140–141): Mono, Versalien, Laufweite .09em.
   --faint auf --panel 5,25:1 hell / 5,44:1 dunkel, auf --bg (Datum im
   Seitenkopf) 4,85:1 / 5,88:1 — der knappste Textwert der Seite. */
.mikro, .orga-datum, .orga-zaehler, .orga-unterteilung, .orga-fuss {
  font-family: var(--schrift-mono);
  font-size: 10.5px;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--faint);
}
.orga-datum { margin: 0; }

/* Kartenkopf: Symbolkreis, Titel, Zähler, Knöpfe rechts. Höhe 60 px
   (8 + 44 + 8). Der erste Knopf schiebt sich und alle folgenden an den
   rechten Rand — der Zähler bleibt direkt hinter dem Titel. */
.dashboard-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 60px;
  padding: 8px 6px 8px 14px;
}
.dashboard-card-head > button:first-of-type { margin-left: auto; }
/* Kreis 36 px, Kennfarbe 16 % (Spec Z. 110). Symbol in Kennfarbe auf dem
   Kreis: hell 4,07–5,02:1, dunkel 4,66–5,94:1 (Grafik, Soll 3:1). Der Kreis
   trägt nie Text. aria-hidden am Element, der Titel spricht. */
.orga-kreis {
  flex: none;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--kenn, var(--dim)) 16%, transparent);
  color: var(--kenn, var(--dim));
}
.orga-kreis .material-symbols-rounded { font-size: 20px; }
/* Titel in Kennfarbe auf --panel: hell 5,14–6,34:1, dunkel 5,81–7,93:1. */
.orga-titel {
  margin: 0;
  min-width: 0;
  font-family: var(--schrift-titel);
  font-weight: 600;
  font-size: 21px;
  line-height: 1;
  color: var(--kenn, var(--text));
}
.orga-zaehler { flex: none; white-space: nowrap; }

/* Unterteilung und Gruppenkopf (Todos, Telefonate, Kalendertage). */
.orga-unterteilung {
  margin: 0;
  padding: 8px 14px 4px;
  border-top: 1px solid var(--soft);
}

/* Listenzeile: randlos, Trennlinie oben in --soft (Dekoration, Spec Z. 108).
   position:relative verankert das Menü der Zeile. Keine Fläche, keine
   Deckkraft — eine Zeile ist nie ein Stapelkontext. */
.orga-zeile {
  position: relative;
  padding: 9px 14px;
  border-top: 1px solid var(--soft);
}

/* Der Satz einer leeren Karte (J1 b: nur der Satz, das Plus steht im Kopf).
   --dim auf --panel 6,40:1 / 6,97:1. */
.orga-leer {
  margin: 0;
  padding: 10px 14px 14px;
  border-top: 1px solid var(--soft);
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--dim);
}

/* Kartenfuß: „Erledigt · N“, „N ältere ungelesene“, „Alle N Hinweise“,
   „Ganze Woche“. Mono wie die Mikro-Beschriftung, aber in --dim: --faint
   fiele beim Drücken (ZEILE 12 %) auf 4,11:1 / 3,96:1, --dim hält 5,01:1 /
   5,07:1. Zwei Formen: <summary class="orga-fuss"> in einem <details>, oder
   <div class="orga-fuss"><button class="<Familienklasse> orga-fuss-knopf">
   — die Trennlinie liegt am <div>, nie am Knopf (ZEILE ist randlos). */
.orga-fuss {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border-top: 1px solid var(--soft);
  color: var(--dim);
}
.orga-fuss:has(> .orga-fuss-knopf) { padding: 0; }
.orga-fuss .material-symbols-rounded { font-size: 16px; }
.orga-fuss-knopf {
  flex: 1;
  align-self: stretch;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  text-align: left;
}
summary.orga-fuss { list-style: none; cursor: pointer; }
summary.orga-fuss::-webkit-details-marker { display: none; }
summary.orga-fuss:hover { background-color: color-mix(in srgb, var(--text) 6%, transparent); }
summary.orga-fuss:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }
/* Die Karte schneidet nicht (kein overflow:hidden — Menüs ragen heraus),
   also rundet die letzte Fußzeile ihre Überfahr-Fläche selbst: 18 px Karte
   minus 1 px Rand. */
.dashboard-card > .orga-fuss:last-child,
.dashboard-card > .orga-fuss:last-child > .orga-fuss-knopf,
.dashboard-card > details:last-child:not([open]) > summary.orga-fuss {
  border-radius: 0 0 17px 17px;
}

/* Menü einer Zeile — dieselbe Gestalt wie das ⋯-Menü des Chats
   (chat.js, .chat-kopf-menu). Schwebt, also Schatten (Spec Z. 131).
   Die Zeilen sind Familie ZEILE (Liste oben, Eintrag durch Aufgabe 5);
   hier stehen nur Maße und Textfarbe. Gefahr als Modifikator:
   --bad auf --panel 5,25:1 / 4,96:1. */
.orga-menue {
  position: absolute;
  top: calc(100% - 6px);
  right: 8px;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 212px;
  max-width: min(320px, calc(100vw - 32px));
  padding: 6px;
  background: var(--panel);
  border: 1px solid var(--soft);
  border-radius: var(--r-karte);
  box-shadow: var(--schatten-schwebend);
}
.orga-menue[hidden] { display: none; }
.orga-menue-zeile {
  width: 100%;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  border-radius: var(--r-feld);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  text-align: left;
}
.orga-menue-zeile.orga-menue-gefahr { color: var(--bad); }

/* Fokus (Push/Deep-Link auf ein Telefonat oder Todo), Jörns Wahl J6 (B) vom
   2026-09-22: ein heller Schleier statt des Blurs. Das Abfangen der Tipps
   leistet das Element, nicht der Blur (11 Punkte elementFromPoint, Bericht
   D). Text darunter fällt auf 1,38:1 / 1,45:1 — gewollt unlesbar. Die
   Fokuszeile schwebt darüber: --panel, Kante --kante als 1-px-Ring (gegen
   den Schleier 3,04:1 / 3,41:1, gegen --panel 3,29:1 / 3,15:1) und der
   Schwebe-Schatten. Zwei Rollenerweiterungen, von Jörn gewählt: Schatten
   an einer Zeile (Z. 131 nennt sie nicht) und --kante als Fokusring
   (Z. 91/107). .dashboard-page davor, damit keine Modulregel (0,1,0) sie
   schlägt. z-Kette: Leiste 30 < FAB 31 < Schleier 35 < Menü 40 < Fokuszeile
   41 < ihr Menü 42. */
.dashboard-page [data-call-focus-overlay] {
  position: fixed;
  inset: 0;
  z-index: 35;
  background-color: color-mix(in srgb, var(--bg) 85%, transparent);
}
.dashboard-page [data-call-focus-overlay][hidden] { display: none; }
.dashboard-page .todo-row-focus,
.dashboard-page .call-row-focus {
  position: relative;
  z-index: 41;
  background: var(--panel);
  border-radius: var(--r-feld);
  box-shadow: 0 0 0 1px var(--kante), var(--schatten-schwebend);
}
.dashboard-page .todo-row-focus .orga-menue,
.dashboard-page .call-row-focus .orga-menue { z-index: 42; }
