/* ═══════════════════════════════════════════════════════════════════════════
   Taktwerk-Engine — Termine. Gestaltung für ZWEI Seiten aus einem System:
   Patient (Handy, oft mit Schmerzen, will schnell einen Termin) und Praxis
   (täglich, will auf einen Blick sehen was zu entscheiden ist).

   Farben: Tiefes Kiefern-Tinte + Jade als Identität, Bernstein AUSSCHLIESSLICH
   als Signal „wartet auf Entscheidung". Alle Paare gegen WCAG AA gerechnet
   (Skript, nicht geschätzt) — Werte siehe Protokoll 05.08.2026.

   Marke ist bewusst in EINEM Block gekapselt: sobald die Praxis eine echte
   Marke hat, wird nur :root ausgetauscht, nichts anderes.

   Hell/Dunkel (06.08.): --tinte/--jade/--signal bleiben über beide Themen
   KONSTANT — sie tragen auch die Rolle „farbige Fläche mit weißer Schrift"
   (Kopfzeile, Seitenleiste, Haupt-Knopf, Plaketten), und ein Umfärben würde
   genau dort die Lesbarkeit brechen. Für die GEGENTEILIGE Rolle — Text/Icon
   AUF einer hellen Fläche — gibt es eigene, je Thema unterschiedliche
   Varianten (--text, --jade-text, --signal-text); --rot/--nebel/--rand/
   --linnen/--karte/--*-fl haben nur diese eine Rolle und werden direkt
   überschrieben. Jedes neue Textpaar erst gegen [[kontrastmessung-drei-eichproben]]-Art
   Skript rechnen (WCAG AA, 4.5:1), nicht schätzen — siehe scratchpad
   `kontrast.js` dieser Sitzung für die Werte unten.
   ═══════════════════════════════════════════════════════════════════════════ */

@font-face { font-family: 'Inter'; src: url('/schrift/Inter-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('/schrift/Inter-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('/schrift/Inter-SemiBold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'InterDisplay'; src: url('/schrift/InterDisplay-SemiBold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap; }

:root {
  /* ── RÜCKFALLWERTE der Rollen ────────────────────────────────────────
        🔴 Seit dem 18.08.2026 setzt `lib/marke.js` diese Rollen JE MANDANT aus
        dem gewählten Schema; der eingesetzte Block steht in jeder Auslieferung
        hinter dieser Datei und gewinnt deshalb. Was hier steht, ist der
        Rückfall für den Fall, dass die Datei einmal ohne diesen Block
        betrachtet wird — es sind die Werte des Standardschemas `taktwerk`,
        helle Tönung, wie sie die erste Praxis benutzt hat.
        ⚠️ --marke ist HELL (2,17:1) = Logo-/Zierfarbe, NIE Bedeutungsträger.
        Alles Bedeutsame trägt --jade (5,89:1 gegen --karte). ── */
  --marke:     #58BFC7;
  --tinte:     #22343A;
  --jade:      #0C6F79;
  --jade-fl:   #E3F4F6;
  --signal:    #8A4F08;
  --signal-fl: #FAEEDA;
  --rot:       #A4322A;
  --rot-fl:    #FBE9E7;
  --linnen:    #EFF5F6;
  --karte:     #FFFFFF;
  --nebel:     #4F656B;
  --rand:      #D2E4E7;
  --rand-kraeftig: #6E97A0;

  /* Text-/Icon-Varianten der drei Flächenfarben (s. Kommentar oben) — im
     Hellen identisch zur Flächenfarbe, im Dunklen unten eigens gesetzt. */
  --text:        var(--tinte);
  --jade-text:   var(--jade);
  --signal-text: var(--signal);

  /* ── Schriftfarbe AUF einer Akzentflaeche ────────────────────────────────
     Bis zum 18.08.2026 stand an rund einem Dutzend Stellen schlicht #fff.
     Das trug, solange der Akzent immer dasselbe dunkle Tuerkis war. Seit die
     Engine sieben Erscheinungsbilder kennt (lib/marke.js), traegt es nicht
     mehr: Auf Butter Yellow (#FFF275) ist Weiss mit 1,15:1 unlesbar. Deshalb
     bringt jedes Schema seinen GEMESSENEN Partner mit; der Wert hier ist der
     Rueckfall fuer den Fall, dass diese Datei einmal ohne den eingesetzten
     Block betrachtet wird. */
  --akz-schrift: #FFFFFF;
  /* Vom Layout gesetzt (lib/marke.js): Terminal schreibt Versalien mit
     Sperrung und Monospace, Standard und Milchglas nicht. */
  --vers: none;
  --sp: .02em;
  --mono: 'Inter', system-ui, sans-serif;

  --anzeige: 'InterDisplay', 'Inter', system-ui, sans-serif;
  --text-schrift: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --r-klein: 8px;
  --r: 12px;
  --r-gross: 18px;
  --schatten: 0 1px 2px rgba(34, 52, 58, .06), 0 8px 24px -12px rgba(34, 52, 58, .18);
  color-scheme: light;
}

/* ── Dunkles Thema — per Umschalter (theme.js), NICHT automatisch nach
      Systemfarbe (Praxis/Patient sollen bewusst wählen, kein Flackern beim
      Systemwechsel mitten in der Terminvergabe). Werte gegen WCAG AA
      gerechnet (Skript, s. Kommentar oben), nicht geschätzt:
      --text/--linnen 16,1:1 · --text/--karte 14,3:1 · --nebel/--karte 6,4:1 ·
      --jade-text/--karte 8,8:1 · --signal-text/--karte 7,9:1 · --rot/--karte 6,5:1. ── */
:root[data-theme="dark"] {
  color-scheme: dark;
  --linnen:    #0E1619;
  --karte:     #172226;
  --nebel:     #93A6AB;
  --rand:      #2B383C;
  --rand-kraeftig: #5F7378;
  --text:      #EAF2F3;
  --jade-fl:   #113238;
  --jade-text: #5FD1C6;
  --signal-fl: #3A2712;
  --signal-text: #E7A94C;
  --rot-fl:    #3A1613;
  --rot:       #E98A82;
  --schatten: 0 1px 2px rgba(0,0,0,.5), 0 8px 24px -12px rgba(0,0,0,.7);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--linnen); color: var(--text);
  font-family: var(--text-schrift); font-size: 17px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ── Kopfzeile ─────────────────────────────────────────────────────────── */
.kopf {
  /* 🩸 Hier stand ein Verlauf mit der festen Zweitfarbe #2E4750. Sie war fuer
     EIN Schema gerechnet; bei Butter Yellow oder Emerald Ink waere sie ein
     grauer Fleck im falschen Farbkreis gewesen. Eine achte Farbe zu erfinden
     verbietet sich (die sieben sind gemessen), also traegt die Kopfzeile jetzt
     die Akzentflaeche flach — die Tiefe kommt aus Schatten und Rand. */
  background: var(--tinte);
  color: var(--akz-schrift);
  padding: 14px 20px; display: flex; align-items: center; gap: 12px;
}
/* Praxis-Admin (admin.html): schmalere Kopfzeile, nur noch Marke + wer eingeloggt
   ist — die eigentliche Navigation lebt jetzt in der Seitenleiste darunter. */
.kopf.schmal { padding: 10px 20px; }
.kopf.schmal .marke { font-size: 16px; }
.kopf.schmal .marke img { height: 22px; }
.kopf .marke {
  font-family: var(--anzeige); font-weight: 600; font-size: 19px;
  letter-spacing: -.02em; display: flex; align-items: center; gap: 9px;
}
/* Logo aus der Visitenkarte — Bitmap, deshalb bewusst klein gehalten */
.kopf .marke img { height: 28px; width: auto; display: block; }
/* Emoji-Rückfall, wenn die Praxis kein eigenes Logo hinterlegt hat
   (lib/marke.js:markeHtml). Bewusst gleich hoch wie das Bild — sonst springt
   die Kopfzeile je nachdem, ob eine Datei da ist. */
.kopf .marke .marke-zeichen { font-size: 24px; line-height: 28px; display: block; }
.kopf.schmal .marke .marke-zeichen { font-size: 19px; line-height: 22px; }
/* 🩸 22.08.2026 GEMESSEN, Philip: „bei manchen Farb-Kombinationen ist die
   Schrift oben in weiß schwer lesbar." Ursache war NICHT die Palette — alle 14
   Tönungen tragen `--akz-schrift` auf `--akz` mit mindestens 5:1. Es war das
   `opacity: .72` hier und das `.8` unten: **Deckkraft ist eine Farbänderung.**
   Damit fielen 7 von 14 Kombinationen unter 4,5:1, am schlechtesten
   Dragonfruit hell mit 3,30:1.
   🔑 Nachgerechnet: erst ab Deckkraft 0.92 bestehen alle 14 — und 0.92 ist von
   „voll" nicht zu unterscheiden, die Abstufung wäre also wirkungslos. Deshalb
   trägt die Hierarchie jetzt allein die SCHRIFTGRÖSSE (14px gegen 19px der
   Wortmarke), wie schon vorher. Wer hier wieder eine Deckkraft einsetzt,
   nimmt denselben Fehler zurück ins Haus. */
.kopf .marke .zusatz { font-family: var(--text-schrift); font-weight: 400; font-size: 14px; letter-spacing: 0; }
/* Wrapper statt .rechts selbst: der Umschalter steht VOR #kopfRechts, dessen
   innerHTML app.js/admin.js beim Start komplett ersetzt (auch mit '' im
   abgemeldeten Zustand) — ein Knopf DARIN würde dabei verschwinden. */
.kopf .kopf-aktionen { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.kopf .rechts { display: flex; align-items: center; gap: 10px; font-size: 14px; }
/* Kein `opacity` — siehe die Begründung bei `.kopf .marke .zusatz` oben. */
.kopf .rechts .wer { font-weight: 500; }
/* Die zwei Knöpfe oben rechts: Hell/Dunkel und der Optik-Würfel. Gleiche
   Gestalt, damit sie als Paar lesen.

   🩸 20.08.2026 GEMESSEN: Der Knopf war 34×46 px statt der hier stehenden
   34×34. Ursache ist NICHT der Flex-Kopf (der zieht bei `align-items:center`
   nicht), sondern die allgemeine Knopfregel weiter unten (`button, .knopf`,
   `min-height: 46px`): Eine Mindesthöhe schlägt eine Höhe. Deshalb steht hier
   beides — `height` allein wäre wirkungslos, und zwar lautlos.

   🩸 Farben aus `currentColor` statt aus festem Weiß: Die Kopfleiste des
   Teambereichs trägt die AKZENTFLÄCHE der Praxis. Im Schema „Lime Spark",
   Tönung dunkel, ist das rgb(182,255,46) — ein weißes Zeichen darauf wäre
   praktisch unlesbar. `currentColor` ist die Schriftfarbe der Kopfleiste und
   damit per Bauart die Farbe, die auf ihr trägt (`--akz-schrift`, im Farbwerk
   je Schema gemessen). Das gilt auf heller wie auf dunkler Leiste.

   Welches Zeichen der Hell/Dunkel-Knopf zeigt, steht bewusst NICHT hier,
   sondern in `lib/marke.js` — nur dort ist die Tönung der Praxis bekannt.
   Gezeigt wird die AKTION, nicht der Zustand: im Dunklen die Sonne (→ wechselt
   zu hell), im Hellen der Mond (→ wechselt zu dunkel). */
.theme-toggle, .optik-wuerfel {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; min-height: 34px; flex: none; border-radius: 999px;
  border: 1px solid color-mix(in srgb, currentColor 32%, transparent);
  background: color-mix(in srgb, currentColor 10%, transparent);
  color: inherit; cursor: pointer; padding: 0;
  transition: background .15s ease, border-color .15s ease;
}
.theme-toggle:hover, .optik-wuerfel:hover {
  background: color-mix(in srgb, currentColor 22%, transparent);
  border-color: color-mix(in srgb, currentColor 55%, transparent);
}
.theme-toggle svg, .optik-wuerfel svg { width: 17px; height: 17px; display: block; }
/* 🩸 [hidden] verliert gegen ein CSS `display:` — zweimal passiert, deshalb
   steht die Regel hier und NACH der obigen. */
.optik-wuerfel[hidden], .optik-hinweis[hidden] { display: none; }

/* Der ruhige Hinweis neben dem Würfel: Er sagt, dass der Wurf praxisweit gilt,
   und nennt den Weg zurück beim Namen. Kein Warnkasten — es ist kein Fehler,
   sondern eine Änderung, die andere sehen. */
/* ── 🔴 Der Hinweis steht NEBEN der Kopfleiste, nicht IN ihr (23.08.2026) ────
   🩸 Kais Meldung: „wenn man auf Optik würfeln klickt, geht das auf 2 Zeilen,
   das ist definitiv nicht gewünscht." GEMESSEN mit dem ECHTEN Menü dieser
   Praxis (sechs Reiter, nicht vier): Der rechte Block braucht in Ruhe 288 px —
   und genau so viel ist neben den Reitern frei. Mit dem Hinweis werden daraus
   529 px. Es fehlen also nicht ein paar Pixel, sondern **241**.

   🩸 Mein erster Anlauf hat den Platz für den Hinweis DAUERHAFT reserviert.
   Damit sprang nichts mehr — die Leiste stand dafür IMMER in zwei Zeilen. Kai
   zu Recht: „steht doch immer noch in 2 Zeilen, es hat sich nichts geändert."
   🔑 Eine Meldung, die den Kopf sprengt, wird nicht dadurch besser, dass man
   ihn dauerhaft gesprengt lässt. Aus einem Zustand, der manchmal schlecht ist,
   war ein Zustand geworden, der immer schlecht ist.

   ⇒ Der Hinweis nimmt gar keinen Platz mehr in der Zeile: Er hängt als kleine
   Karte UNTER dem Würfel. Damit ist die Kopfleiste vor und nach dem Wurf
   identisch — nicht, weil der Platz reicht, sondern weil kein Platz gebraucht
   wird. Das gilt bei sechs Reitern genauso wie bei vieren, und bei jedem
   Praxisnamen. */
.optik-hinweis {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 40;
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12.5px; line-height: 1.25;
  /* Eigene Fläche, weil sie über dem Seiteninhalt liegt: Der Kopf-Farbton
     gilt hier nicht mehr, also bringt die Karte ihren eigenen mit. */
  background: var(--karte); color: var(--text);
  border: 1px solid color-mix(in srgb, var(--text) 14%, transparent);
  border-radius: 999px; padding: 6px 8px 6px 14px;
  box-shadow: 0 6px 20px rgba(0,0,0,.18);
  max-width: min(92vw, 420px);
}
/* Der Anker für `position: absolute` oben. Ohne ihn hinge die Karte am
   Ansichtsfenster statt am Würfel. */
.hk-kopf .hk-rechts { position: relative; }
/* 🩸 23.08.2026 — hier stand `overflow: hidden; text-overflow: ellipsis`. Der
   erste Anlauf, das zum Wirken zu bringen (`min-width: 0`), war GEMESSEN grün
   und im BILD falsch: Bei 1100 px stand im Kopf ein zerhacktes „N..".
   🔑 Ein Satz, der zur Hälfte dasteht, ist schlechter als kein Satz — er sieht
   nach Fehler aus, und genau das war Kais Meldung („zerreißt die Schriften").
   Deshalb kein Kürzen mehr: Der Hinweis steht GANZ da oder gar nicht. Wann
   „gar nicht" gilt, regelt die Medienabfrage weiter unten am Kopf. */
.optik-hinweis .optik-wort { opacity: .85; white-space: nowrap; }
/* 🩸 Auf dem Weg hierher hieß eine Hilfsklasse kurz schlicht `leer` — und
   `.leer` gibt es im Haus schon (leere Listen: mittig, 30px/18px Innenabstand).
   Sie war dadurch 36 px zu breit. Weiter unten in DIESER Datei steht seit einem
   früheren Bauteil die Warnung davor (`zw-leer`).
   🔑 Ein Klassenname ist ein globaler Name. Kurze Wörter sind im Haus fast
   immer schon vergeben; der Bauteilname davor kostet nichts. */
.optik-hinweis .optik-zurueck {
  border: 1px solid color-mix(in srgb, currentColor 32%, transparent);
  background: color-mix(in srgb, currentColor 10%, transparent);
  color: inherit; font: inherit; font-weight: 600; font-size: 12.5px;
  min-height: 26px; padding: 3px 10px; border-radius: 999px; cursor: pointer;
  white-space: nowrap;
}
.optik-hinweis .optik-zurueck:hover { background: color-mix(in srgb, currentColor 22%, transparent); }

.huelle { max-width: 680px; margin: 0 auto; padding: 22px 16px 72px; }
.huelle.breit { max-width: 940px; }

h1 { font-family: var(--anzeige); font-weight: 600; font-size: 26px; letter-spacing: -.025em; margin: 0 0 6px; }
h2 { font-family: var(--anzeige); font-weight: 600; font-size: 18px; letter-spacing: -.015em; margin: 30px 0 12px; }
h2:first-child { margin-top: 0; }
h3 { font-family: var(--anzeige); font-weight: 600; font-size: 15px; letter-spacing: -.01em; margin: 22px 0 8px; }
.blass { color: var(--nebel); }
.klein { font-size: 14px; }
.fuehrung { color: var(--nebel); font-size: 15px; margin: 0 0 20px; }

/* Abschnittsmarke: kleine Versalzeile über einem Block */
.marke-zeile {
  font-size: 12px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase;
  color: var(--nebel); margin: 0 0 8px;
}

.karte {
  background: var(--karte); border: 1px solid var(--rand);
  border-radius: var(--r-gross); padding: 20px; margin-bottom: 14px;
}
.karte.eng { padding: 15px; }

/* ── Bedienelemente ────────────────────────────────────────────────────── */
/* 🩸 22.08.2026, Philip nach dem Testlauf: „das Layout sollte generell ein
   wenig weiter voneinander entfernt sein" — vier Formulare gemeldet, eine
   Ursache. Unter einem 46px hohen Eingabefeld waren 14px zu wenig: Die
   Beschriftung klebte optisch am Feld DARÜBER statt an ihrem eigenen darunter,
   die Rahmen schienen sich zu berühren. 22px oben / 6px unten stellt das
   Verhältnis um — die Beschriftung gehört sichtbar zu dem, was unter ihr steht. */
label { display: block; font-size: 14px; font-weight: 600; margin: 22px 0 6px; }
label:first-child { margin-top: 0; }
/* 🩸 13.08.2026: `input:not([type])` ergänzt. Ein <input> OHNE type-Attribut
   ist zwar ein Textfeld, traf aber keinen dieser Selektoren — es blieb bei der
   Browser-Standardbreite (~180px) mitten zwischen 100%-breiten Feldern. Betraf
   auch den älteren Dialog „Kunde anlegen" (Vor-/Nachname) im Kalender, dort
   war es nur nie aufgefallen. Beim Bau des CRM im Screenshot gesehen. */
input:not([type]),
input[type=text], input[type=email], input[type=password], input[type=tel],
/* 🩸 14.08.2026 ergänzt: `search` fehlte in dieser Liste. Die drei Suchfelder
   (Kalender, CRM, Protokolle) trugen deshalb Browser-Standard statt Hausstil —
   in allen dreien war das mit einem eigenen Inline-`style` überklebt worden.
   Dreimal derselbe Behelf ist das Zeichen, dass die Regel fehlt, nicht dass
   der Behelf richtig ist. */
input[type=search],
input[type=datetime-local], input[type=date], input[type=time], input[type=file], textarea, select {
  width: 100%; padding: 12px 13px; border-radius: var(--r);
  border: 1.5px solid var(--rand-kraeftig); background: var(--karte); color: var(--text);
  font: inherit; font-size: 16px; /* 16px: verhindert iOS-Zoom beim Fokus */
}
textarea { resize: vertical; min-height: 84px; }
/* Ankreuzfeld (Anamnesebogen, Einwilligung) — großes Touch-Ziel, Text links bündig */
/* ── Datumsfrage im Anamnesebogen (21.08.2026) ─────────────────────────────
   🔴 Philip: „im patientenbogen sind ort und geburtsdatum zu eng."
   Gemessen im echten Browser: **0 px** Abstand zum Feld darüber, während jedes
   andere Feld 14 px hat (Mittel aus 41 Paaren).
   🔑 Die Ursache ist die Bauart, nicht der Einzelfall: Jede andere Frage bringt
   ihren Abstand über ihr <label> mit (`margin: 14px 0 5px`). Die Datumsfrage
   trägt ihre Beschriftung IM Feld (`.zw-marke`) und ist außen nur eine nackte
   Hülle — für die gab es im ganzen Stilblatt keine einzige Regel. Sie stand
   deshalb überall dort auf Anschlag, wo eine Datumsfrage auf ein Feld folgt;
   Geburtsdatum nach Ort war nur die Stelle, an der es auffiel.
   Der Wähler ist ein KASTEN, kein Text. Wo sonst eine Beschriftung Luft
   schafft, beginnt hier sofort eine Kante — deshalb ein Stück MEHR als der
   Abstand einer gewöhnlichen Beschriftung.
   🔴 22.08.2026: Dieser Wert HÄNGT an `label { margin-top }` weiter oben. Als
   der von 14 auf 22 px stieg, stand die Datumsfrage plötzlich ENGER als jedes
   andere Feld — `pruefung/jahresebene.js` hat es sofort rot gemeldet (eigen 18,
   üblich 22). Wer den einen Wert ändert, ändert den anderen mit: immer 4 px
   darüber. Das ist keine Zierde, sondern Philips Befund von damals. */
.bogen-datum { margin-top: 26px; }
.bogen-datum:first-child { margin-top: 0; }

label.checkbox { display: flex; align-items: flex-start; gap: 10px; font-weight: 500; font-size: 15px; line-height: 1.45; }
label.checkbox input { margin-top: 2px; width: 20px; height: 20px; flex: none; accent-color: var(--jade-text); }
input:focus-visible, textarea:focus-visible, select:focus-visible,
button:focus-visible, a:focus-visible, .kal-tag:focus-visible, .zeit:focus-visible {
  outline: 3px solid var(--jade-text); outline-offset: 2px;
}
::placeholder { color: var(--nebel); opacity: .8; }

button, .knopf {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border: 1.5px solid var(--rand-kraeftig); background: var(--karte); color: var(--text);
  padding: 11px 18px; border-radius: var(--r); font: inherit; font-weight: 600;
  font-size: 15px; cursor: pointer; min-height: 46px; text-decoration: none;
  transition: background .14s ease, border-color .14s ease, transform .14s cubic-bezier(.16,1,.3,1), box-shadow .14s ease;
}
button:hover, .knopf:hover { background: var(--linnen); }
/* 🩸 #095A62 und #0d7d88 waren zwei weitere feste Tuerkistoene im Verlauf, dazu
   ein Schatten in Tuerkis-RGB. Alle drei gehoerten zu EINEM Schema. Der Knopf
   traegt jetzt die Akzentflaeche, der Hover mischt sie mit ihrer eigenen
   Schriftfarbe an — das bleibt in jedem der sieben Bilder in der Familie und
   ist eine Ableitung, keine neue Farbe. Der Schatten ist neutral. */
button.haupt, .knopf.haupt {
  background: var(--jade); color: var(--akz-schrift); border-color: var(--jade);
  box-shadow: 0 1px 2px rgba(0,0,0,.16), 0 8px 16px -10px rgba(0,0,0,.34);
}
button.haupt:hover, .knopf.haupt:hover {
  background: color-mix(in srgb, var(--jade) 88%, var(--akz-schrift));
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0,0,0,.18), 0 12px 22px -10px rgba(0,0,0,.38);
}
button.haupt:active, .knopf.haupt:active { transform: translateY(0); }
button.gefahr { color: var(--rot); border-color: color-mix(in srgb, var(--rot) 45%, var(--karte)); }
button.gefahr:hover { background: var(--rot-fl); }
button.stiller { border-color: transparent; background: transparent; color: var(--nebel); padding: 8px 10px; min-height: 40px; }
button.stiller:hover { background: var(--linnen); color: var(--text); }
/* 🩸 18.08.2026 IM BILDSCHIRMFOTO gefunden, nicht per grep: Die Regel galt nur
   für `button`. Als die Widget-Vorschau vom Knopf zum Link wurde, sah sie
   plötzlich aus wie ein Textlink zwischen zwei Knöpfen — im Markup stand die
   Klasse richtig da. `.knopf` (Z. 225) ist die vorhandene Antwort für Links in
   Knopfgestalt; ihr fehlte nur die kleine Größe. */
button.klein-knopf, .knopf.klein-knopf { min-height: 38px; padding: 7px 13px; font-size: 14px; }
button:disabled { opacity: .45; cursor: default; }
/* Abstände wie bei `label` angehoben (22.08.2026): 10px zwischen zwei
   nebeneinanderliegenden Feldern lasen sich als ein zusammenhängender Block,
   7px zwischen den sieben Wochentag-Schaltflächen ließen ihre Rahmen
   zusammenstoßen. `row-gap` etwas größer als `column-gap`, weil umbrechende
   Zeilen sonst dichter stehen als nebeneinanderliegende. */
.reihe { display: flex; gap: 16px 14px; flex-wrap: wrap; }
.reihe.eng { gap: 10px; }
/* 🩸 22.08.2026, IM ANGEMELDETEN PORTAL GEMESSEN, nachdem die erste Runde nicht
   gereicht hat. Philip: „hier ist immer noch der Rahmen fast auf einer
   gemeinsamen Linie". Gemessen im Formular „Regelmäßig" bei 390 px:
   Wochentage → Von/Bis **0 px** · Von/Bis → Dauer/Pause **0 px** ·
   Dauer/Pause → Ab/Bis **0 px**. Drei Mal auf Anschlag.
   🔑 Die Ursache ist NICHT der Abstand IN einer Zeile (`gap`), sondern der
   fehlende Abstand ZWISCHEN zwei Zeilen: Zwei benachbarte `.reihe` sind
   gewöhnliche Geschwister ohne jeden Rand. Der senkrechte Rhythmus kam bisher
   allein aus den Beschriftungen — und `label:first-child { margin-top: 0 }`
   nimmt ihn genau dort weg, wo eine Beschriftung als erstes Kind einer Spalte
   steht. Eine Zeile ohne eigene Beschriftung (die Zeitwähler tragen ihre IM
   Kasten) hatte damit gar nichts.
   🔑 Deshalb hier und nicht am `label`: Die Zeile bringt ihren Abstand selbst
   mit, unabhängig davon, was in ihr steht. Das ist dieselbe Einsicht wie bei
   `.bogen-datum` weiter oben — ein Kasten braucht außen Luft, weil er innen
   keine schafft. */
/* 🩸 22.08.2026, ZWEITER Anlauf. `.reihe + .reihe` war zu eng gefasst: Philip
   meldete dieselbe Enge im CRM, und dort folgt die Zeile nicht auf eine Zeile,
   sondern auf ein FELD („Schlagworte" → Wiedervorlage/Wiederholung/Wofür:
   gemessen 0 px, genau wie „Straße" → PLZ/Ort).
   🔑 Die Zeile braucht ihren Abstand unabhängig davon, WAS über ihr steht —
   sonst zählt man Nachbarn auf und vergisst den nächsten. Deshalb trägt sie ihn
   jetzt selbst, mit zwei Ausnahmen: ganz oben braucht sie keinen, und direkt
   unter ihrer eigenen Beschriftung gehört sie eng dran (Gruppierung). */
.reihe { margin-top: 18px; }
.reihe:first-child { margin-top: 0; }
label + .reihe { margin-top: 6px; }
/* 🩸 Hier stand `label + .reihe.eng { margin-top: 4px }` — WIRKUNGSLOS und
   deshalb wieder entfernt: Senkrechte Ränder benachbarter Elemente VERSCHMELZEN,
   aus 5 px unten und 4 px oben werden nicht 9, sondern 5. Nachgemessen, nicht
   überlegt.
   Und es soll auch so bleiben: 5 px zwischen einer Beschriftung und dem, was
   sie beschriftet, gegen 18 px zwischen zwei Zeilen — das IST die Gruppierung.
   Was zusammengehört, steht enger. Wer die 5 px vergrößert, löst die
   Beschriftung von ihrem Feld. */

/* ── Meldungen & Plaketten ─────────────────────────────────────────────── */
.meldung { padding: 12px 15px; border-radius: var(--r); margin: 12px 0; font-size: 15px; border: 1px solid; }
.meldung.ok  { background: var(--jade-fl);   color: var(--jade-text);   border-color: color-mix(in srgb, var(--jade-text) 45%, var(--karte)); }
.meldung.err { background: var(--rot-fl);    color: var(--rot);    border-color: color-mix(in srgb, var(--rot) 45%, var(--karte)); }
/* 16.08.2026: Zwischen „alles gut" und „Fehler" fehlte der Ton für einen
   Vorbehalt — der Rechtshinweis über den Belehrungen ist kein Fehler, soll aber
   auch nicht wie eine Bestätigung aussehen. Nutzt die vorhandenen Signalfarben. */
.meldung.warnung { background: var(--signal-fl); color: var(--signal-text); border-color: color-mix(in srgb, var(--signal-text) 45%, var(--karte)); }
.plakette {
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px;
  border-radius: 999px; font-size: 13px; font-weight: 600; white-space: nowrap;
}
.plakette.wartet     { background: var(--signal-fl); color: var(--signal-text); }
.plakette.bestaetigt { background: var(--jade-fl);   color: var(--jade-text); }
.plakette.abgelehnt  { background: var(--rot-fl);    color: var(--rot); }
.plakette.frei       { background: var(--jade-fl);   color: var(--jade-text); }
.plakette.neutral    { background: var(--linnen);    color: var(--nebel); }
.plakette::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.plakette.ohne-punkt::before { display: none; }

/* ── Umschalter Kalender/Liste ─────────────────────────────────────────── */
.umschalter { display: inline-flex; gap: 2px; background: var(--linnen); border-radius: 999px; padding: 3px; }
.umschalter button {
  border: none; background: transparent; color: var(--nebel); min-height: 34px;
  padding: 5px 15px; border-radius: 999px; font-size: 14px; font-weight: 600;
}
.umschalter button:hover { background: color-mix(in srgb, var(--karte) 65%, transparent); }
.umschalter button.aktiv { background: var(--karte); color: var(--text); box-shadow: 0 1px 3px rgba(18,49,44,.14); }

/* Listenansicht: Tage untereinander, jeder mit seinen Zeiten */
.listen-tag { margin-bottom: 22px; }
.listen-tag:last-child { margin-bottom: 0; }
.listen-kopf {
  display: flex; align-items: baseline; gap: 9px; margin-bottom: 9px;
  position: sticky; top: 0; background: var(--karte); padding: 5px 0; z-index: 1;
}
.listen-kopf .tag { font-family: var(--anzeige); font-weight: 600; font-size: 16px; letter-spacing: -.015em; }
/* Bewusst KEIN eigener Scrollbereich: verschachteltes Scrollen ist am Handy
   unangenehm und schnitt Tagesüberschriften mittendurch. Stattdessen werden
   nur die nächsten Tage gezeigt, der Rest auf Knopfdruck. */
/* ── Monatskalender: das Herzstück beider Seiten ───────────────────────── */
.kal { margin-bottom: 6px; }
.kal-kopf { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.kal-monat { font-family: var(--anzeige); font-weight: 600; font-size: 19px; letter-spacing: -.02em; }
/* 🩸 19.08.2026, von Philip am echten Bild gemeldet: „die Rahmen beruehren
   sich". Ursache gemessen: 5 px Abstand bei 1,5 px Rahmen je Zelle — zwischen
   zwei Kaesten blieben effektiv 2 px Luft. Der Abstand ist jetzt groesser als
   die beiden Rahmen zusammen, dann liest sich das Gitter als Raster und nicht
   als Tabelle. */
.kal-wochentage, .kal-gitter { display: grid; grid-template-columns: repeat(7, 1fr); gap: 9px; }
.kal-wochentage {
  margin-bottom: 5px; font-size: 12px; font-weight: 600; color: var(--nebel);
  text-align: center; letter-spacing: .04em;
}
/* Signatur-Bewegung dieser Oberfläche: Dinge „richten sich aus", wenn sie
   erscheinen — passend zum Praxis-Thema. EIN Ort, um Timing/Kurve zu ändern. */
@keyframes einrichten {
  from { opacity: 0; transform: translateY(7px); }
  to { opacity: 1; transform: translateY(0); }
}
.kal-tag {
  /* Quadratisch auf dem Handy, aber gedeckelt: auf breitem Schirm würden 1/1
     sonst ~130px hohe, fast leere Zellen ergeben. */
  position: relative; aspect-ratio: 1 / 1; min-height: 46px; max-height: 72px;
  /* 🔴🩸 20.08.2026 GEMESSEN, von Philip gemeldet („Rahmen berühren und
     überlappen sich"): 30 überlappende Geschwisterpaare im Bereich Termine bei
     1440×900, je 2,16 px breit über die volle Zellenhöhe von 66 px. Ursache
     gemessen, nicht vermutet: Die Spalte war 54,84 px breit (7 Spalten + 6×9 px
     Abstand in 438 px), die Zelle aber 66 px — `aspect-ratio: 1/1` rechnet die
     Mindesthöhe in eine Mindest-BREITE um und sprengt damit die Spalte. 54,84
     + 9 = 63,84; 66 − 63,84 = 2,16. Genau die gemessene Zahl.

     `width: 100%` dreht die Rechnung um: Die Breite ist damit ausdrücklich die
     der Spalte, das Seitenverhältnis leitet daraus die HÖHE ab, und die
     Mindesthöhe hebt nur noch die Höhe an. Die Zelle kann ihre Spalte danach
     nicht mehr verlassen — das ist Bauart, keine Zahl, die beim nächsten
     Umbau wieder passen muss.

     🔑 Dieselbe Falle stand schon einmal im Datumswähler (`.zw-tafel .kal-tag`,
     weiter unten): „eine Mindesthöhe von 46px hätte über die Seitenverhältnis-
     Rechnung auch 46px BREITE verlangt". Dort wurde sie mit `aspect-ratio:auto`
     umgangen — hier wird die Ursache selbst abgestellt, für beide Stellen. */
  width: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: 1.5px solid transparent; border-radius: var(--r); background: transparent;
  font-family: var(--anzeige); font-weight: 600; font-size: 16px; color: var(--nebel);
  cursor: default; padding: 0; min-width: 0;
  transition: background .12s ease, border-color .12s ease;
}
.kal-tag.fuellung { visibility: hidden; }
.kal-tag.zu { color: var(--nebel); opacity: .55; }   /* Vergangenheit / kein Angebot */
.kal-tag.hat {                                        /* Tag mit Angebot — anklickbar */
  background: var(--karte); border-color: var(--rand); color: var(--text); cursor: pointer;
  animation: einrichten .35s cubic-bezier(.16,1,.3,1) backwards;
  animation-delay: calc(var(--zelle, 0) * 10ms);
}
.kal-tag.hat:hover { border-color: var(--jade-text); background: var(--jade-fl); }
/* Praxis-Kalender: die Zelle selbst einfärben, nicht nur einen 7px-Punkt setzen —
   „dass Buchungen existieren" muss auch aus 1m Bildschirmabstand auffallen.
   Reihenfolge = Priorität: eine offene Anfrage übertönt eine reine Buchung. Ruhig
   gehalten (kein Puls/Hover-Lift) — Variante „Agenda-Seitenleiste" war die
   zurückhaltendste der 5 Entwürfe, das zieht sich hier durch.
   var(--text)-in-var(--karte) statt var(--tinte)-in-#fff: dieselbe Formel passt
   sich damit von selbst dem Thema an (hell: dunkle Beimischung in Weiß, dunkel:
   helle Beimischung in die Kartenfarbe) — kein eigener Dunkel-Override nötig. */
.kal-tag.hat.prio-gebucht { background: color-mix(in srgb, var(--text) 9%, var(--karte)); border-color: color-mix(in srgb, var(--text) 30%, var(--karte)); }
.kal-tag.hat.prio-wartet { background: var(--signal-fl); border-color: var(--signal-text); }
.kal-tag.gewaehlt { background: var(--jade); border-color: var(--jade); color: var(--akz-schrift); animation: none; }
.kal-tag.gewaehlt .kal-zahl { color: var(--akz-schrift); }
/* „Heute" als Ring um die Zelle statt als Strich darunter — der Strich sah in
   leeren Zellen wie ein verirrtes Zeichen aus. */
.kal-tag.heute { box-shadow: inset 0 0 0 1.5px var(--rand-kraeftig); }
.kal-tag.heute.hat { box-shadow: inset 0 0 0 1.5px var(--jade-text); }
.kal-tag.heute.gewaehlt { box-shadow: none; }
.kal-zahl { line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
/* Verfügbarkeitsmarke: Anzahl freier Zeiten, klein unter der Tageszahl */
.kal-marke {
  font-family: var(--text-schrift); font-weight: 600; font-size: 11px;
  line-height: 1; padding: 2px 5px; border-radius: 999px;
  background: var(--jade-fl); color: var(--jade-text);
}
/* 22 Prozent von dem, was auf DIESER Flaeche liest: festes Weiss verschwaende
   auf einem hellen Akzent (Butter Yellow, Lime) spurlos. */
.kal-tag.gewaehlt .kal-marke { background: color-mix(in srgb, var(--akz-schrift) 22%, transparent); color: var(--akz-schrift); }
.kal-marke.wartet { background: var(--signal-fl); color: var(--signal-text); }
.kal-marke.gebucht { background: color-mix(in srgb, var(--text) 14%, var(--karte)); color: var(--text); }
.kal-tag.gewaehlt .kal-marke.wartet, .kal-tag.gewaehlt .kal-marke.gebucht { background: color-mix(in srgb, var(--akz-schrift) 22%, transparent); color: var(--akz-schrift); }
/* Praxis: Zahlen statt reiner Punkte (siehe kalender.js) — nur „frei" bleibt ein
   schlichter Punkt, das ist die unwichtigste Information hier. */
.kal-punkte { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; justify-content: center; min-height: 15px; }
.kal-punkt { width: 8px; height: 8px; border-radius: 50%; }
.kal-punkt.frei { background: var(--jade-text); }
.kal-tag.gewaehlt .kal-punkt { background: rgba(255,255,255,.85); }

.kal-legende { display: flex; gap: 14px; flex-wrap: wrap; font-size: 13px; color: var(--nebel); margin-top: 12px; }
.kal-legende span { display: inline-flex; align-items: center; gap: 6px; }
.kal-legende i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }

/* ── Zeitspalte: der Tag als gestapelte Segmente ───────────────────────── */
.tag-kopf {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: 0 0 14px; padding-bottom: 12px; border-bottom: 1px solid var(--rand);
}
.tag-kopf .datum { font-family: var(--anzeige); font-weight: 600; font-size: 21px; letter-spacing: -.025em; }
.saeule { position: relative; }
.zeit {
  position: relative; display: flex; align-items: center; gap: 12px; width: 100%;
  background: var(--karte); border: 1.5px solid var(--rand); border-radius: var(--r);
  padding: 12px 15px; margin-bottom: 7px; cursor: pointer; text-align: left;
  font: inherit; min-height: 54px;
  transition: border-color .12s ease, background .12s ease;
  animation: einrichten .3s cubic-bezier(.16,1,.3,1) backwards;
  animation-delay: calc(var(--reihe, 0) * 30ms);
}
.zeit:hover { border-color: var(--jade-text); background: var(--jade-fl); }
.zeit.gewaehlt { border-color: var(--jade-text); background: var(--jade-fl); border-width: 2px; }
.zeit.nicht-frei { cursor: default; background: var(--linnen); border-style: dashed; }
/* markiert zum Zurückziehen (Praxis-Tagesansicht) */
.zeit.markiert { border-color: var(--rot); border-width: 2px; background: var(--rot-fl); }
.zeit.markiert .uhr { color: var(--rot); }
.zeit.nicht-frei:hover { border-color: var(--rand); background: var(--linnen); }
.zeit .uhr {
  font-family: var(--anzeige); font-weight: 600; font-size: 19px; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; min-width: 62px;
}
.zeit .dauer { color: var(--nebel); font-size: 14px; }
.zeit .rechts { margin-left: auto; display: flex; align-items: center; gap: 10px; }
/* Zeile mit Patient: eigene Zeile für Terminart/Telefon/E-Mail statt alles in
   den Namen zu quetschen (Philip 06.08.: „Liste zeigt zu wenig Informationen"). */
.zeit.hat-patient { padding-top: 10px; padding-bottom: 10px; }
.patient-info { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; text-align: right; }
.kontakt-klein { font-size: 12px; color: var(--nebel); }
/* Termin restlos löschen (06.08., direkt aus Kalender/Liste) — klein und
   zurückhaltend neben der Statusplakette, erst bei Hover/Fokus als Warnung
   eingefärbt. Kein `.klein-knopf`: der ist für Text-Knöpfe gedacht, hier
   reicht ein kompaktes Icon-Quadrat. */
.loesch-knopf { padding: 5px 7px; min-height: 0; font-size: 14px; line-height: 1; color: var(--nebel); }
.loesch-knopf:hover, .loesch-knopf:focus-visible { background: var(--rot-fl); color: var(--rot); }

/* ── Sammelaktion für markierte Zeiten (Praxis) ─────────────────────────────
   „Klebend" im Wortsinn: bleibt am unteren Bildschirmrand sichtbar, solange
   die Liste, in der man markiert hat, noch auf dem Schirm ist — sonst müsste
   man bei einer langen Liste erst ganz ans Ende scrollen, um dort zu löschen,
   wo man markiert hat (Philip 06.08.). `position:sticky` statt `fixed`: bleibt
   dadurch innerhalb ihres eigenen Listen-Containers, überdeckt nicht die
   Seitenleiste oder andere Bereiche der App. */
.aktionsleiste {
  position: sticky; bottom: 14px; z-index: 3;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--karte); border: 1px solid var(--rand-kraeftig); border-radius: var(--r);
  padding: 10px 14px; margin-top: 14px; box-shadow: var(--schatten);
}
.aktionsleiste .anzahl { font-weight: 600; font-size: 14px; }

/* ── Terminkarten (Patient: „Meine Termine", Praxis: Anfragen) ─────────── */
.termin {
  display: flex; gap: 14px; align-items: flex-start;
  border: 1px solid var(--rand); border-radius: var(--r); padding: 15px; margin-bottom: 10px; background: var(--karte);
}
.termin.hervor { border-color: var(--signal-text); border-width: 2px; background: var(--signal-fl); }
.termin .wann { min-width: 92px; }
.termin .wann .tag-zahl {
  font-family: var(--anzeige); font-weight: 600; font-size: 24px; letter-spacing: -.03em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.termin .wann .rest { font-size: 13px; color: var(--nebel); margin-top: 3px; }
.termin .inhalt { flex: 1; min-width: 0; }
.termin .inhalt .titel { font-weight: 600; }
.termin .aktionen { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 11px; }
/* 🩸 22.08.2026, Philip: „Der Text im Portal ist auch nacheinander, das ergibt
   keinen Sinn." Die drei Wunschangaben einer Anfrage werden MIT Zeilenumbruch
   gespeichert (lib/anfragen.js: `zeilen.join('\n')`) — ohne `white-space`
   fallen sie beim Rendern zu einer Zeile zusammen. `pre-line` hält die
   Umbrüche und bricht lange Zeilen trotzdem um. */
.zitat {
  margin: 9px 0 0; padding: 9px 12px; background: var(--linnen); border-radius: var(--r-klein);
  font-size: 15px; color: var(--text); white-space: pre-line;
}
.termin.hervor .zitat { background: color-mix(in srgb, var(--karte) 65%, transparent); }

/* ── Leerzustände ──────────────────────────────────────────────────────── */
.leer { text-align: center; padding: 30px 18px; color: var(--nebel); }
.leer .zeichen { font-size: 26px; display: block; margin-bottom: 8px; opacity: .55; }
.leer .haupt-satz { color: var(--text); font-weight: 600; margin-bottom: 4px; }

/* ── Reiter ────────────────────────────────────────────────────────────── */
.reiter { display: flex; gap: 4px; background: var(--karte); border: 1px solid var(--rand); border-radius: var(--r); padding: 4px; margin-bottom: 20px; }
.reiter button { flex: 1; border: none; background: transparent; min-height: 42px; color: var(--nebel); border-radius: var(--r-klein); }
.reiter button:hover { background: var(--linnen); }
.reiter button.aktiv { background: var(--tinte); color: var(--akz-schrift); }
.reiter button.aktiv:hover { background: var(--tinte); }
.reiter .zaehler {
  margin-left: 6px; background: var(--signal); color: #fff; border-radius: 999px;
  padding: 1px 7px; font-size: 12px; font-variant-numeric: tabular-nums;
}
.reiter button.aktiv .zaehler { background: var(--signal); }

/* ── Praxis-Admin: Agenda-Seitenleiste + Kennzahlen-Leiste (06.08.) ───────
   Aus 5 Entwürfen ausgewählt („Agenda-Seitenleiste"): links Kalender/Liste/
   Anfragen fest erreichbar, oben eine kurze Wochen-Kennzahlen-Leiste. Ersetzt
   den vorigen obenliegenden Reiter „Terminplan/Anfragen" + den verschachtelten
   Kalender/Liste-Umschalter — beide sind jetzt gleichrangige Seitenpunkte. */
.admin-flaeche { display: flex; align-items: flex-start; min-height: calc(100vh - 53px); }
.seitenleiste {
  width: 232px; flex: none; background: var(--tinte); color: var(--akz-schrift);
  padding: 22px 14px; display: flex; flex-direction: column; gap: 20px;
  position: sticky; top: 0; align-self: flex-start; height: 100vh; overflow-y: auto;
}
.sl-gruppe { display: flex; flex-direction: column; gap: 2px; }
.sl-label {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: rgba(255,255,255,.42); padding: 6px 10px 6px;
}
.sl-item {
  display: flex; align-items: center; gap: 9px; justify-content: flex-start;
  border: none; background: transparent; color: rgba(255,255,255,.8);
  padding: 10px 11px; border-radius: 10px; font: inherit; font-weight: 600; font-size: 14px;
  cursor: pointer; min-height: 0; text-align: left;
}
.sl-item:hover { background: rgba(255,255,255,.07); }
.sl-item.aktiv { background: var(--jade); color: var(--akz-schrift); }
.sl-item .sl-badge {
  margin-left: auto; background: var(--signal); color: #fff; font-size: 11px; font-weight: 700;
  border-radius: 999px; padding: 1px 8px; font-variant-numeric: tabular-nums;
}
.admin-inhalt { flex: 1; min-width: 0; padding: 24px 28px 60px; }
.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 20px; }
.kpi { background: var(--karte); border: 1px solid var(--rand); border-radius: 12px; padding: 14px 16px; }
.kpi .n { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.kpi .l { font-size: 12px; color: var(--nebel); margin-top: 2px; }
.kpi.warn .n { color: var(--signal-text); }
@media (max-width: 780px) {
  /* 🩸 19.08.2026 im echten Browser GEMESSEN (pruefung/cockpit.js): Die
     Kopfzeile lief bei 390 px seitlich aus dem Bild — `/crm.html` auf 394 px,
     das Cockpit mit dem längeren Titel „Tageslage" auf 431 px. Sie ist eine
     einzeilige Flex-Reihe ohne Umbruch, und `#kopfRechts` bekommt seit dem
     18.08. zusätzlich den Abmelden-Knopf (public/team-rahmen.js). Damit war
     der Überlauf nicht neu, sondern nur nie gemessen — dieselbe Lehre wie am
     13.08. bei der Seitenleiste. Jetzt bricht die Reihe um, statt zu wachsen. */
  .kopf { flex-wrap: wrap; row-gap: 6px; }
  .kopf .marke { min-width: 0; }
  .admin-flaeche { flex-direction: column; min-height: 0; }
  /* 🩸 13.08.2026: Die Leiste war hier eine EINZEILIGE Reihe ohne Umbruch —
     auf dem Handy liefen die hinteren Punkte rechts aus dem Bild (im Kalender
     „Kunden"/„Sicherheit", im CRM sogar drei). Sichtbar wurde es erst im
     Ganzseiten-Screenshot bei 390px: die Seite war 560 bzw. 768px breit.
     Jetzt umbrechend — jeder Punkt ist erreichbar, ohne seitwärts zu wischen. */
  .seitenleiste {
    width: 100%; position: static; height: auto; overflow: visible;
    flex-direction: row; flex-wrap: wrap; align-items: center;
    padding: 9px 10px; gap: 6px; row-gap: 6px;
  }
  .sl-gruppe { flex-direction: row; flex-wrap: wrap; gap: 4px; }
  .sl-item { padding: 8px 11px; font-size: 13.5px; }
  .sl-label { display: none; }
  .sl-item { padding: 8px 12px; white-space: nowrap; }
  .admin-inhalt { padding: 16px 14px 50px; }
  .kpis { grid-template-columns: repeat(2, 1fr); }
}

/* ── Tabellen (Kundenkartei) ───────────────────────────────────────────── */
.tabelle-huelle { overflow-x: auto; margin: 0 -4px; padding: 0 4px; }
table { width: 100%; border-collapse: collapse; font-size: 15px; }
th, td { text-align: left; padding: 11px 9px; border-bottom: 1px solid var(--rand); vertical-align: middle; }
th { font-size: 13px; font-weight: 600; color: var(--nebel); }
tbody tr.klickbar { cursor: pointer; }
tbody tr.klickbar:hover { background: var(--jade-fl); }
tbody tr:last-child td { border-bottom: none; }

/* ── Dialog ────────────────────────────────────────────────────────────── */
/* ══════════════ Dialoge — gemeinsamer Baustein (15.08.2026 überarbeitet) ═══
   🔴 Philip: „das Protokoll sieht vom Layout wirklich fürchterlich aus … soll
   clean aussehen, aber professionell, damit wir nicht für jeden Kunden ein
   eigenes Layout benötigen." Deshalb steht die Reparatur HIER, im geteilten
   Stylesheet, und nicht in der Protokoll-Ansicht: jeder Dialog dieses Dienstes
   (und jede Kopie für ein anderes Kundensystem) erbt sie.

   🩸 Zwei gemessene Fehler, die das ausgelöst haben:
   1. Der Dialog konnte HÖHER werden als das Fenster (Schreibdialog: 992 px bei
      900 px Fensterhöhe). Gescrollt hat dann der Hintergrund-Container — die
      Knöpfe „Abbrechen"/„Endgültig speichern" standen unterhalb der Kante und
      waren auf dem Handy schlicht NICHT DA. Kein Schönheitsfehler: man konnte
      das Protokoll nicht speichern.
   2. Zwei Dialoge übereinander (Akte + Schreiben) lagen auf derselben Ebene und
      blieben beide sichtbar.

   Die Lösung ist die übliche und langweilige: der Dialog ist eine Spalte mit
   fester Höhengrenze, der MITTELTEIL scrollt, Kopf und Knopfleiste bleiben
   stehen. Damit passt jeder Inhalt, auch ein langer. */
.dialog-grund { position: fixed; inset: 0; background: rgba(18, 49, 44, .45);
  z-index: 20; display: flex; align-items: center; justify-content: center;
  padding: 20px; overflow: hidden; }
/* Ausgeblendet, solange ein Dialog darüber offen ist (siehe dialog() in crm.js
   und admin.js). `display:none` statt Transparenz: ein durchscheinender zweiter
   Dialog ist genau das, was vorher unruhig aussah. */
.dialog-grund.verdeckt { display: none; }

.dialog { background: var(--karte); border-radius: var(--r-gross);
  width: 100%; max-width: 520px; box-shadow: var(--schatten);
  display: flex; flex-direction: column;
  /* dvh statt vh: auf dem Handy schrumpft die sichtbare Höhe, wenn die
     Adressleiste einfährt — mit vh stünden die Knöpfe wieder außerhalb. */
  max-height: calc(100dvh - 40px); overflow: hidden; }

.dialog-kopf { display: flex; align-items: flex-start; gap: 12px;
  padding: 20px 22px 12px; border-bottom: 1px solid var(--rand); flex: 0 0 auto; }
.dialog-kopf h2 { margin: 0; flex: 1; font-size: 1.15rem; }

/* Der einzige Teil, der scrollt. `min-height:0` ist in einer Flex-Spalte
   Pflicht — ohne sie wächst das Kind über den Container hinaus, statt zu
   scrollen (die eigentliche Ursache der fehlenden Knöpfe). */
.dialog-inhalt { flex: 1 1 auto; min-height: 0; overflow-y: auto;
  overscroll-behavior: contain; padding: 16px 22px; }

/* Knopfleiste: bleibt immer sichtbar, am unteren Rand, rechtsbündig. */
.dialog-aktionen { flex: 0 0 auto; display: flex; justify-content: flex-end;
  gap: 10px; flex-wrap: wrap; padding: 14px 22px; border-top: 1px solid var(--rand);
  background: var(--karte); border-radius: 0 0 var(--r-gross) var(--r-gross); }

@media (max-width: 560px) {
  .dialog-grund { padding: 10px; }
  .dialog { max-height: calc(100dvh - 20px); }
  .dialog-kopf { padding: 16px 16px 10px; }
  .dialog-inhalt { padding: 14px 16px; }
  .dialog-aktionen { padding: 12px 16px; }
  /* Auf dem Handy tragen die beiden Knöpfe die volle Breite — nebeneinander
     werden sie zu schmal für einen sicheren Daumentreffer. */
  .dialog-aktionen button { flex: 1 1 100%; min-height: 46px; }
}
.beschreibung { margin: 0 0 4px; }
dl.antworten dt { font-weight: 600; font-size: 14px; color: var(--nebel); margin-top: 14px; }
dl.antworten dd { margin: 3px 0 0; }

a { color: var(--jade-text); }
.fuss { display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 6px 14px; color: var(--nebel); font-size: 13px; padding: 26px 16px 18px; }
.fuss a { color: var(--nebel); }

/* ── Impressum · Datenschutz (20.08.2026) ──────────────────────────────────
   Pflichtangaben nach § 5 DDG und Art. 13 DSGVO, in der Fußzeile jeder
   Patientenseite. Sie stehen VOR der Marken-Pille, weil sie die Angaben der
   PRAXIS sind — der Hinweis auf uns ist der Zusatz, nicht umgekehrt.

   Auf schmalen Geräten bricht die Fußzeile ohnehin um (`flex-wrap` oben); die
   Rechtszeile bleibt dabei zusammen, damit „Impressum · Datenschutz" nicht
   über zwei Zeilen zerfällt und wie zwei unabhängige Fußnoten aussieht.
   Unterstrichen, weil ein Pflichthinweis als Link erkennbar sein muss und
   Farbe allein dafür nicht genügt (WCAG 1.4.1). */
.fuss-recht { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  font-size: 12.5px; }
.fuss-recht a { color: var(--nebel); text-decoration: underline; text-underline-offset: 2px;
  text-decoration-thickness: 1px; }
.fuss-recht a:hover, .fuss-recht a:focus-visible { color: var(--tinte); }
.fuss-trenner { opacity: .5; }
@media (max-width: 520px) {
  .fuss { gap: 4px 10px; }
  .fuss-recht { font-size: 12px; }
}

/* ── „ein Produkt von flowmatik24" — animierte Zugehoerigkeits-Pille ───────
   Vorbild: bolte-portal/bolte-kalender (CSS GELESEN, nicht nachgebaut, siehe
   [[marken-pille-aussage-nicht-name]]). Zwei bewusste Abweichungen:
   1. Farbe haengt an ROLLEN statt an Bolte's fixen Hex-Werten, weil dieses
      Projekt zur Laufzeit zwischen hell/dunkel umschaltet (Bolte hat zwei
      getrennte Seiten) UND seit dem 18.08.2026 sieben Erscheinungsbilder
      kennt. Zwischenstand waren eigene Tokens --pb/--pb-hover mit festen
      Werten; warum auch die nicht reichten, steht direkt darunter.
   2. Das Label nutzt var(--nebel) statt einer neuen Grau-Variable — die ist
      in diesem Projekt schon fuer beide Themen kalibriert (6,4:1 / 7,2:1).
   Das Label faellt nie zuerst weg (es IST die Aussage; der Name allein laese
   sich wie eine zweite, gleichrangige Marke) — die Fusszeile bricht
   stattdessen um (flex-wrap oben). Die GANZE Pille ist der Link, nicht nur
   das Wort. Der Wortlaut steht in lib/marke.js:PILLE_WORTLAUT, an genau einer
   Stelle; hier steht nur die Gestalt. */
/* 🩸 18.08.2026 GEMESSEN, nicht vermutet: Die festen Werte --pb #0e7490 / dunkel
   #22d3ee waren gegen EIN Schema gerechnet. Über alle sieben gerechnet fiel
   „Emerald Ink hell" (Grund #F8E7C9, Champagne) auf **4,40:1** — unter AA, und
   niemand hätte es gesehen, weil die Pille klein ist und niemand sie liest.
   Die Pille wandert deshalb mit dem Schema, wie die im Kalender-Baustein:
   Name in --text, Label in --leise, das Zeichen im Akzent. Damit ist ihr
   Kontrast derselbe wie der von Fließtext zu Seitengrund — über alle 14
   Tönungen schlechtestenfalls 5,02:1, das Zeichen als Grafik 5,28:1. */
/* 🩸 20.08.2026: `flex-wrap: wrap` ist hier KEINE Kosmetik. Mit dem neuen
   Wortlaut („Taktwerk — ein Produkt von" statt „Taktwerk powered by") wuchs
   das Label um acht Zeichen. Ohne Umbruch hätte die Pille auf schmalen Geräten
   die Seite seitlich überlaufen lassen — und die alte Regel ist eindeutig:
   Wird es eng, fällt die GANZE Pille, NIE das Label. Also wird Platz
   geschaffen (die Zeile bricht zwischen Label und Marke um), nicht gekürzt
   und nicht weggeblendet. Beides waren die Fehler vom 17.07.2026.
   `justify-content: center` hält die zweite Zeile unter der ersten mittig,
   statt sie linksbündig unter ein zentriertes Label zu hängen. */
.fuss .pb { display: inline-flex; align-items: center; gap: 9px; font-size: 12px;
  flex-wrap: wrap; justify-content: center; row-gap: 4px;
  color: var(--text); text-decoration: none; transition: color .18s ease; }
.fuss .pb:hover, .fuss .pb:focus-visible { color: var(--jade-text); }
.fuss .pb .pb-label { font-size: 10.5px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--nebel); white-space: nowrap; }
/* Nur das Zeichen trägt den Akzent — wie im Kalender-Baustein (embed.html). */
.fuss .pb .pb-mark { height: 16px; width: 16px; display: block; flex: none; color: var(--jade-text); }
.fuss .pb .pb-name { font-weight: 700; font-size: 12.5px; letter-spacing: -.01em; color: inherit; }
.pb-arc { transform-box: view-box; transform-origin: 70px 70px; animation: pbSpin 9s linear infinite; }
@keyframes pbSpin { to { transform: rotate(360deg); } }
/* Ein ewig drehender Kreis ist genau das, was Bewegungsempfindliche krank
   macht. Er haelt an — die Marke steht trotzdem da. */
@media (prefers-reduced-motion: reduce) { .pb-arc { animation: none; } }

/* ── Die Symbole der Oberfläche (20.08.2026) ────────────────────────────────
   Aus Philips Designsystem „Organic": Lucide, inline SVG, stroke-width 2.75,
   auf `currentColor`. Die Größe steht hier EINMAL; wer ein Symbol woanders
   braucht, erbt sie mit.

   🔑 `currentColor` ist der eigentliche Gewinn gegenüber den Emoji, die hier
   bis heute standen: Das Zeichen trägt automatisch die Farbe seiner Umgebung —
   in allen sieben Erscheinungsbildern und beiden Tönungen, ohne eine einzige
   zusätzliche Regel. Ein Emoji konnte das nie; es blieb bunt.
   `flex: none` verhindert, dass es in einer engen Zeile gestaucht wird —
   ein gestauchtes Symbol sieht aus wie ein Fehler im Zeichensatz. */
.ik { width: 18px; height: 18px; display: block; flex: none; }
/* Das Zeichen eines LEERZUSTANDS ist größer und leiser: Es füllt die Fläche,
   die sonst nichts hat, ohne sich wie ein Knopf anzubieten. `stroke-width`
   wird hier zurückgenommen — 2.75 wirkt bei 44 px plump, während dieselbe
   Stärke bei 18 px genau richtig ist. */
.ik-leer { width: 44px; height: 44px; stroke-width: 1.9; color: var(--nebel); margin: 0 auto 6px; }
.ik-gross { width: 22px; height: 22px; }

/* ── Aufklappbarer Block (Praxis: Termine freigeben) ───────────────────── */
details.block { background: var(--karte); border: 1px solid var(--rand); border-radius: var(--r-gross); margin-bottom: 14px; }
details.block > summary {
  list-style: none; cursor: pointer; padding: 16px 20px; font-weight: 600;
  display: flex; align-items: center; gap: 9px; border-radius: var(--r-gross);
}
details.block > summary::-webkit-details-marker { display: none; }
details.block > summary::after { content: '＋'; margin-left: auto; color: var(--nebel); font-size: 19px; }
details.block[open] > summary::after { content: '−'; }
details.block > summary:hover { background: var(--linnen); }
details.block .block-inhalt { padding: 4px 20px 20px; }

/* ── Praxis-Desktop (nur admin.html — Patientenseite bleibt bei .huelle ohne
      .breit unangetastet): Kalender + Tagesdetail nebeneinander statt
      untereinander, Zellen groß genug für eine Bildschirmarbeitsplatz-Distanz.
      Philip 06.08.: „Kalender in der Desktopvariante zu klein". ── */
@media (min-width: 900px) {
  .huelle.breit { max-width: 1200px; }
  /* 🩸 20.08.2026, zweiter Teil von Philips Meldung: „Kalender Ansicht immer
     noch zu sehr gedrückt". Die feste Spalte von 480px stammt aus der Zeit, als
     der Kalender auf `/admin.html` über die ganze Breite verfügte. In der Hülle
     nimmt die Menüleiste links 224px weg — gemessen blieben der Karte 480px und
     dem Gitter 438px, also 54,8px je Spalte bei 66px Zellenhöhe. Das IST das
     Gedrückte: hoch und schmal.

     `auto-fit` statt zweier fester Spalten: Solange beide Seiten mindestens
     480px bekommen, stehen Kalender und Tagesdetail nebeneinander; darunter
     rücken sie untereinander, statt sich gegenseitig zu erdrücken. Ist kein Tag
     gewählt (`#tagBox:empty`), fällt die zweite Spalte weg und der Kalender
     bekommt die Breite — das ist der Zustand, in dem man ihn am häufigsten
     sieht. `max-width` deckelt ihn dabei, damit aus „Luft" keine Zellen von
     Postkartengröße werden. */
  .termin-flaeche[data-ansicht="kal"] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 480px), 1fr));
    gap: 22px; align-items: start;
  }
  .termin-flaeche[data-ansicht="kal"] > .karte { max-width: 640px; }
  .termin-flaeche[data-ansicht="kal"] #tagBox { position: sticky; top: 20px; }
  .termin-flaeche[data-ansicht="kal"] #tagBox:empty { display: none; }
  /* Der Boden greift nur noch, wenn die Spalte schmaler ist als er — durch
     `width:100%` oben kann er die Zelle nicht mehr in die Breite ziehen. 60
     statt 66, damit eine enge Spalte nicht wieder hoch und schmal wird. */
  .kal-tag { min-height: 60px; max-height: 112px; font-size: 17px; }
  .kal-monat { font-size: 21px; }
  .kal-marke { font-size: 12px; padding: 2px 6px; }
}

/* 🔴 20.08.2026 GEMESSEN auf 390×844: Die Tageslage war ohne die Fußzeile
   842 px hoch — zwei Bildpunkte KÜRZER als das Fenster. Mit ihr wurden daraus
   905, also musste man 61 px scrollen, um die Marke zu sehen. Genau Philips
   ursprünglicher Befund, nur in klein: Die Seite scrollte nicht wegen ihres
   Inhalts, sondern wegen der Fußzeile.
   Gespart wird deshalb dort, wo auf einem Telefon ohnehin nur Luft steht:
   Fußzeilenpolster (63 → 41), unteres Polster der Inhaltsfläche (50 → 16) und
   der Abstand über den Wegen (30 → 22). Zusammen 64 px — gerechnet, nicht
   geschätzt, und unten im Browser nachgemessen. */
@media (max-width: 560px) {
  .fuss { padding: 12px 12px 10px; }
  .hk-inhalt { padding-bottom: 16px; }
  .tl-wege { margin-top: 22px; }
}

@media (max-width: 560px) {
  body { font-size: 16px; }
  .huelle { padding: 18px 13px 60px; }
  .karte { padding: 16px; border-radius: var(--r); }
  h1 { font-size: 23px; }
  .kal-tag { min-height: 42px; font-size: 15px; }
  .kal-marke { font-size: 10px; padding: 1px 4px; }
  .termin { flex-direction: column; gap: 9px; }
  .termin .wann { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
  .termin .wann .rest { margin-top: 0; }
  .kopf { padding: 12px 14px; }
  .kopf .marke { font-size: 17px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ── CRM (13.08.2026) ──────────────────────────────────────────────────────
   Die CRM-Seite nutzt dieselben Bausteine wie die Praxis-Seite (Seitenleiste,
   Kennzahlen, Karten, Dialog). Nur drei Dinge fehlten dort:                 */

/* 1) Die Kontaktakte ist ein Formular MIT Verlauf und Terminliste — im
      520px-Dialog wird das eine Schlucht aus Zeilenumbrüchen. */
.dialog.breit { max-width: 760px; }

/* 2) Seitenleisten-Punkte, die zu einer anderen Seite führen (Kalender,
      Portal), sind Links statt Knöpfe — sie sollen trotzdem gleich aussehen. */
a.sl-item { text-decoration: none; }
/* Ein Menüpunkt, der aus der Praxisoberfläche HERAUS führt (fremde Adresse aus
   `team.menue`), sagt das auch — sonst ist der neue Tab eine Überraschung. */
.sl-extern { margin-left: auto; opacity: .6; font-size: 11px; }
/* Zwei Abzeichen nebeneinander am selben Punkt: offene Anfragen und ungelesene
   Nachrichten. Sie stehen am Bereichs-Eintrag „Termine" und sind damit in
   JEDEM Bereich sichtbar — das war der Auftrag. */
.sl-item .sl-badge + .sl-badge { margin-left: 4px; }
a.sl-item:hover { color: var(--akz-schrift); }

/* 3) Zeilen, die sich wie eine Tabellenzeile anklicken lassen, ohne eine zu
      sein (Übersicht/Wiedervorlagen). */
.klickbar-zeile:hover b { text-decoration: underline; }

/* Der ＋CRM-Knopf in der Terminzeile: bewusst so leise wie der Löschknopf
   daneben — er soll erreichbar sein, aber die Zeile nicht dominieren. */
.crm-knopf {
  font-size: 12px; font-weight: 600; min-height: 32px; padding: 4px 9px;
  border-radius: 999px; white-space: nowrap; color: var(--nebel);
}
.crm-knopf:hover, .crm-knopf:focus-visible { background: var(--jade-fl); color: var(--jade-text); }

/* ══════════════ Einstellungen → E-Mails (15.08.2026) ═══════════════════════
   Liste ausklappbarer Einträge. Bewusst dieselben Bausteine wie überall
   (--karte/--rand/--nebel, .plakette, .klein-knopf) — der Reiter soll nicht
   aussehen wie ein Fremdkörper, nur weil er neu ist. */
.mail-liste { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }

.mail-eintrag {
  border: 1px solid var(--rand); border-radius: var(--r);
  padding: 12px 14px; background: var(--karte);
}
.mail-kopf { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.mail-titel { flex: 1 1 260px; min-width: 0; }
.mail-titel b { font-family: var(--anzeige); }

/* Der Schalter steht neben dem Namen und wirkt sofort — deshalb sieht er auch
   aus wie ein Schalter und nicht wie ein Formularfeld. */
.schalter {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; color: var(--nebel); white-space: nowrap; cursor: pointer;
}
.schalter input { width: 16px; height: 16px; accent-color: var(--jade); cursor: pointer; }

.mail-form { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--rand); }
.mail-form label { display: block; margin: 10px 0 4px; font-size: 13px; font-weight: 600; }
.mail-form input[type="text"], .mail-form textarea {
  width: 100%; box-sizing: border-box; font: inherit;
  border: 1px solid var(--rand); border-radius: 8px; padding: 9px 11px;
  background: var(--linnen); color: var(--text);
}
/* Der Text ist eine Mail, keine Prosa — feste Breite hält Zeilenumbrüche dort,
   wo der Patient sie später auch sieht. */
.mail-form textarea { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; line-height: 1.5; resize: vertical; }

.ph {
  display: inline-block; background: var(--linnen); border: 1px solid var(--rand);
  border-radius: 6px; padding: 1px 6px; font-size: 12px; cursor: help;
}
.mail-knoepfe { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 12px; }

.mail-vorschau { margin-top: 12px; border: 1px dashed var(--rand); border-radius: 8px; padding: 12px; }
.mv-betreff { font-weight: 700; margin: 6px 0 8px; font-family: var(--anzeige); }
/* `pre-wrap` + `overflow-x:auto`: lange Links dürfen die Karte nicht sprengen. */
.mv-text {
  white-space: pre-wrap; word-break: break-word; overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px; line-height: 1.55; margin: 0; color: var(--text);
}

@media (max-width: 640px) {
  .mail-kopf { gap: 8px; }
  .schalter { order: 3; }
}

/* ── Ruhiger Hinweis + Pflichthaken (15.08.2026) ────────────────────────────
   Gemeinsame Bausteine, kein Sonderfall der Protokoll-Ansicht: „damit wir nicht
   für jeden Kunden ein eigenes Layout benötigen" (Philip). Beide Regeln arbeiten
   ausschließlich mit den Marken-Variablen — ein anderes Kundensystem tauscht die
   Farben, nicht das Layout. */
.hinweis-kasten {
  margin: 16px 0 0; padding: 12px 14px;
  background: var(--linnen); border: 1px solid var(--rand);
  border-left: 3px solid var(--nebel); border-radius: 8px;
  font-size: 14px; line-height: 1.55; color: var(--text);
}

/* Der Haken, ohne den nicht gespeichert wird. Große Klickfläche (die ganze
   Zeile), damit er auf dem Handy sicher trifft — und `align-items:flex-start`,
   damit ein zweizeiliger Text nicht am Kästchen klebt. */
.pflichthaken {
  display: flex; align-items: flex-start; gap: 10px; cursor: pointer;
  margin-top: 12px; padding: 12px 14px; min-height: 46px;
  border: 1px solid var(--rand); border-radius: 8px; background: var(--karte);
  font-size: 14px; font-weight: 600; line-height: 1.45;
}
.pflichthaken:hover { border-color: var(--jade); }
.pflichthaken input { width: 18px; height: 18px; margin: 1px 0 0; flex: 0 0 auto; accent-color: var(--jade); cursor: pointer; }
.pflichthaken span { flex: 1; min-width: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   Nachrichten Patient ↔ Praxis (17.08.2026)

   🔑 Es kommt KEINE einzige neue Farbe dazu. Jede Regel hier arbeitet mit den
   Variablen aus :root — damit gelten alle bereits gerechneten Kontrastwerte
   unverändert weiter, und der Bereich zieht automatisch mit, wenn die Praxis
   später eine andere Marke bekommt (MARKENSYSTEM.md). Die vier neu
   entstehenden Paarungen (Text auf --jade-fl, --nebel auf --jade-fl,
   --nebel auf --linnen, --signal-text auf --signal-fl) sind mit
   `pruefung/kontrast-nachrichten.js` in BEIDEN Themen nachgerechnet, nicht
   geschätzt.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Hinweis auf den Kontovorteil am Anmeldeschalter ──────────────────────── */
.vorteil-hinweis {
  display: flex; gap: 12px; align-items: flex-start;
  margin: 16px 0 4px; padding: 13px 15px;
  background: var(--jade-fl); border-radius: var(--r);
  border: 1px solid color-mix(in srgb, var(--jade-text) 30%, var(--jade-fl));
}
.vorteil-hinweis .zeichen { font-size: 20px; line-height: 1.2; flex: none; }
.vorteil-hinweis b { display: block; font-size: 15px; margin-bottom: 3px; }
.vorteil-hinweis .klein { display: block; color: var(--nebel); }

/* ── Bereichswahl Termine / Nachrichten (Patientenseite) ──────────────────── */
.bereichswahl {
  display: flex; gap: 6px; margin: 0 0 18px; padding: 4px;
  background: var(--karte); border: 1px solid var(--rand); border-radius: 999px;
}
.bereichswahl button {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border: none; background: transparent; color: var(--nebel);
  padding: 9px 14px; border-radius: 999px; font-size: 15px; font-weight: 600; min-height: 42px;
}
.bereichswahl button:hover { background: var(--linnen); }
.bereichswahl button.aktiv { background: var(--jade); color: var(--akz-schrift); }
/* Das Abzeichen muss auch auf der EINGEFÄRBTEN Fläche des aktiven Punktes
   lesbar bleiben — deshalb Signalfarbe mit weißer Schrift und nicht die
   sonst übliche helle Signalfläche. */
.bw-badge {
  background: var(--signal); color: #fff; font-size: 12px; font-weight: 700;
  border-radius: 999px; padding: 1px 8px; font-variant-numeric: tabular-nums;
}

/* ── Der Verlauf selbst — beide Seiten, aus chat.js ───────────────────────── */
.chat-verlauf { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.chat-blase {
  max-width: min(88%, 640px); align-self: flex-start;
  background: var(--linnen); border: 1px solid var(--rand);
  border-radius: var(--r-gross); border-bottom-left-radius: var(--r-klein);
  padding: 11px 14px;
}
.chat-blase.eigen {
  align-self: flex-end; background: var(--jade-fl);
  border-color: color-mix(in srgb, var(--jade-text) 26%, var(--jade-fl));
  border-bottom-left-radius: var(--r-gross); border-bottom-right-radius: var(--r-klein);
}
/* Ungelesene Gegennachricht: ein kräftiger Balken an der Kante. Bewusst KEINE
   Flächenfarbe — die trüge Bedeutung („Warnung"), und eine neue Nachricht ist
   keine. */
.chat-blase.neu { border-left: 3px solid var(--signal-text); }
.chat-kopf {
  display: flex; align-items: baseline; gap: 10px; justify-content: space-between;
  font-size: 12.5px; margin-bottom: 5px;
}
.chat-kopf .wer { font-weight: 700; color: var(--text); }
.chat-kopf .wann { color: var(--nebel); white-space: nowrap; }
/* `pre-wrap` hält die Absätze des Schreibers, ohne dass irgendwo HTML gebaut
   werden müsste — der Text bleibt Text, s. lib/nachrichten.js. `overflow-wrap`
   verhindert, dass eine sehr lange Zeichenkette ohne Leerzeichen die Blase
   aus der Karte schiebt. */
.chat-text { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 15.5px; line-height: 1.5; }
.chat-status {
  display: block; margin-top: 6px; font-size: 11.5px; font-weight: 600;
  color: var(--nebel); text-align: right;
}
.chat-status.gelesen, .chat-status.beantwortet { color: var(--jade-text); }
/* In einer EMPFANGENEN Blase steht der Status links — er gehört zur Blase, und
   die sitzt am linken Rand. Rechtsbündig sähe er dort aus, als hinge er in der
   Luft. */
.chat-blase:not(.eigen) .chat-status { text-align: left; }

.chat-karte .chat-karten-kopf {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--rand);
}
/* Abgeschlossene Unterhaltungen stehen als Archiv weiter unten: lesbar, aber
   optisch zurückgenommen. Kein `opacity` — das würde auch den Kontrast des
   Textes senken und wäre damit ein Barrierefreiheitsproblem statt einer
   Gestaltung. Stattdessen nur die Kante. */
.chat-karte.abgeschlossen { border-left: 3px solid var(--rand-kraeftig); }

/* ── Posteingang der Praxis ───────────────────────────────────────────────── */
.pn-flaeche { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 16px; align-items: start; }
.pn-spalte { margin: 0; }
/* Die Liste bekommt eine eigene Höhe mit eigenem Rollbereich, damit der Verlauf
   rechts nicht mitwandert, wenn links dreißig Personen stehen. */
#pnListe { max-height: calc(100vh - 210px); overflow-y: auto; padding: 8px; }
.pn-zeile {
  display: block; width: 100%; text-align: left; border: 1px solid transparent;
  background: transparent; border-radius: var(--r); padding: 11px 12px; margin-bottom: 4px;
  min-height: 0; font: inherit; cursor: pointer;
}
.pn-zeile:hover { background: var(--linnen); }
.pn-zeile.aktiv { background: var(--jade-fl); border-color: color-mix(in srgb, var(--jade-text) 32%, var(--jade-fl)); }
.pn-zeile.ungelesen { border-left: 3px solid var(--signal-text); }
.pn-zeile-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.pn-zeile-kopf .wer { font-weight: 700; font-size: 15px; color: var(--text); }
.pn-betreff { font-size: 13px; font-weight: 600; color: var(--jade-text); margin-top: 2px; }
/* Zwei Zeilen Vorschau, danach abgeschnitten: Die Liste soll orientieren, nicht
   die Nachricht ersetzen. Serverseitig ist die Vorschau ohnehin auf 140 Zeichen
   gekürzt — hier geht es nur um eine ruhige Zeilenhöhe. */
.pn-vorschau {
  font-size: 13.5px; color: var(--nebel); margin-top: 3px; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pn-marken { display: flex; align-items: center; gap: 8px; margin-top: 7px; flex-wrap: wrap; }
.pn-zahl {
  background: var(--signal); color: #fff; font-size: 11.5px; font-weight: 700;
  border-radius: 999px; padding: 2px 8px; font-variant-numeric: tabular-nums;
}
.pn-verlauf-kopf {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
  padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px solid var(--rand);
}
.pn-kopf-aktionen { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; justify-content: flex-end; }
.pn-verlauf-rolle { max-height: calc(100vh - 430px); min-height: 160px; overflow-y: auto; padding-right: 4px; }
.pn-antwort { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--rand); }

@media (max-width: 900px) {
  /* Untereinander statt nebeneinander. Der Verlauf bekommt dann KEINEN eigenen
     Rollbereich mehr — verschachteltes Scrollen ist am Handy unangenehm, genau
     die Lehre aus der Listenansicht weiter oben. */
  .pn-flaeche { grid-template-columns: minmax(0, 1fr); }
  #pnListe { max-height: 46vh; }
  .pn-verlauf-rolle { max-height: none; overflow-y: visible; }
}
@media (max-width: 560px) {
  .bereichswahl button { font-size: 14px; padding: 9px 8px; }
  .chat-blase { max-width: 96%; }
  .pn-verlauf-kopf { flex-direction: column; }
  .pn-kopf-aktionen { justify-content: flex-start; }
}

/* ══ Zeitwahl (18.08.2026) — public/zeitwahl.js ═════════════════════════════
   Ersetzt <input type="date"|"time">. Das native Feld zeichnet das
   BETRIEBSSYSTEM: kein Token dieser Datei erreicht es, eine Praxis auf dunkler
   Tönung bekam beim Klick ein weißes Systemfenster. Deshalb hier ein eigenes
   Bauteil — und deshalb steht unten KEINE feste Farbe: alles über die Tokens,
   damit alle 7 Erscheinungsbilder × 2 Tönungen tragen.
   Der Zeitteil benutzt bewusst DASSELBE Gitter wie der Monatskalender, nur in
   Stunden × Minuten: ein Bedienmuster für beide Größen.                      */
.zw { position: relative; }
.zw-paar { display: grid; gap: 10px; }

/* Das Feld: sieht aus wie unsere Eingabefelder (--rand-kraeftig, var(--r)),
   trägt aber die Beschriftung IN sich — ein Wert braucht immer sein Etikett,
   und ein separates <label> darüber verdoppelte nur die Zeilen. */
.zw-feld {
  width: 100%; display: flex; align-items: center; gap: 12px;
  justify-content: flex-start; text-align: left;
  padding: 9px 13px; min-height: 58px;
  border: 1.5px solid var(--rand-kraeftig); border-radius: var(--r);
  background: var(--karte); color: var(--text); font: inherit; cursor: pointer;
}
.zw-feld:hover { background: var(--karte); border-color: var(--jade-text); }
.zw-feld[aria-expanded="true"] { border-color: var(--jade-text); }
.zw-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.zw-marke {
  font-size: 12px; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--nebel);
}
.zw-wert {
  font-family: var(--anzeige); font-weight: 600; font-size: 17px;
  letter-spacing: -.015em; font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 🩸 `zw-leer`, nicht `leer`: `.leer` gibt es im Haus schon (leere Listen,
   30px Innenabstand, mittig). Ein Wähler mit dieser Klasse war 126px hoch. */
.zw-wert.zw-leer { color: var(--nebel); font-weight: 500; }
.zw-pfeil { flex: none; color: var(--nebel); transition: transform .16s cubic-bezier(.16,1,.3,1); }
.zw-feld[aria-expanded="true"] .zw-pfeil { transform: rotate(180deg); color: var(--jade-text); }

/* Die Tafel klappt IM Fluss auf statt über der Seite zu schweben: ein
   schwebendes Fenster müsste am Handy an Rändern und Rollbereichen entlang
   gerechnet werden und wird genau dort abgeschnitten. */
.zw-tafel {
  display: block; margin-top: 8px; padding: 14px;
  border: 1.5px solid var(--jade-text); border-radius: var(--r);
  background: var(--karte);
  animation: einrichten .22s cubic-bezier(.16,1,.3,1) backwards;
}
/* 🩸 [hidden] verliert gegen ein CSS `display:` — das ist uns schon zweimal
   passiert. Deshalb steht die Regel HIER und nach der obigen. */
.zw-tafel[hidden] { display: none; }
.zw-tafel .kal { margin-bottom: 0; }

.zw-schau { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.zw-gross {
  font-family: var(--anzeige); font-weight: 600; font-size: 28px;
  letter-spacing: -.03em; font-variant-numeric: tabular-nums; color: var(--text);
}
/* Ohne Wert ist „--:--" ein Platzhalter, kein Inhalt — also auch gedämpft. */
.zw-gross.zw-leer { color: var(--nebel); }
.zw-hinweis { font-size: 12.5px; color: var(--nebel); }
.zw-fuss { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; flex-wrap: wrap; }

.zw-rolle { max-height: 258px; overflow-y: auto; overscroll-behavior: contain; }
.zw-zeit-gitter { display: grid; grid-template-columns: auto repeat(4, minmax(0, 1fr)); gap: 5px; align-items: center; }
.zw-stunde {
  font-family: var(--anzeige); font-weight: 600; font-size: 14px;
  color: var(--nebel); font-variant-numeric: tabular-nums;
  text-align: right; padding-right: 7px;
}
.zw-zelle {
  min-height: 46px; padding: 0; width: 100%;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--rand); border-radius: var(--r);
  background: var(--karte); color: var(--text);
  font-family: var(--anzeige); font-weight: 600; font-size: 15px;
  font-variant-numeric: tabular-nums; cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
  animation: einrichten .3s cubic-bezier(.16,1,.3,1) backwards;
  animation-delay: calc(var(--reihe, 0) * 12ms);
}
/* Enge Tafel: ab 7 Spalten je Stunde (Schritt < 10 Min.) muss die Zelle
   schrumpfen, sonst steht die Tafel am Handy breiter als der Bildschirm.
   Die Trefferhöhe bleibt — sie ist die Bedienbarkeit, die Breite ist es nicht. */
/* 🩸 21.08.2026 entfernt: `.zw-eng` machte die Zeitzellen schmaler, sobald eine
   Stunde mehr als sechs Zellen hatte (`schritt: 5`). Philip: „die Zeiten sind so
   dicht zusammengerückt, man kann kaum eine auswählen!" — die Regel war die
   Ursache, nicht die Lösung. Seit `zeitwahl.js` die Stunde auf mehrere Reihen
   umbricht (6 Spalten statt 12), gibt es keinen engen Fall mehr. Eine Klasse,
   die niemand mehr setzt, wird gelöscht und nicht „für alle Fälle" behalten:
   Sonst steht sie in zwei Jahren da und niemand weiß, ob sie noch wirkt. */
/* Gesperrtes Feld (Verwaltung: „eigene Zeit" wird ausgegraut, sobald eine
   freie Zeit gewählt ist). Ein `disabled` am VERSTECKTEN Feld sähe niemand —
   die Sperre gehört auf den Knopf, den man anfassen kann. */
.zw-feld:disabled { cursor: not-allowed; opacity: .55; }
.zw-feld:disabled:hover { background: var(--karte); border-color: var(--rand-kraeftig); }
.zw-zelle:hover { background: var(--jade-fl); border-color: var(--jade-text); }
.zw-zelle.gewaehlt { background: var(--jade); border-color: var(--jade); color: var(--akz-schrift); animation: none; }
.zw-zelle:focus-visible, .zw-feld:focus-visible { outline: 3px solid var(--jade-text); outline-offset: 2px; }

/* ── Grobe Ebenen des Datumswählers: Monat, Jahr, Jahresblock (19.08.2026) ──
   Bewusst DIESELBE Form wie das Zeitgitter (3 Reihen à 4) und dieselben
   Zustandsklassen — wer den Monat bedienen kann, bedient auch das Jahr. */
.zw-grob { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-top: 4px; }
.zw-grobzelle {
  min-height: 46px; padding: 0 4px; width: 100%;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--rand); border-radius: var(--r);
  background: var(--karte); color: var(--text);
  font-family: var(--anzeige); font-weight: 600; font-size: 14px;
  font-variant-numeric: tabular-nums; cursor: pointer; text-align: center;
  transition: background .12s ease, border-color .12s ease;
}
.zw-grobzelle:hover { background: var(--jade-fl); border-color: var(--jade-text); }
.zw-grobzelle.gewaehlt { background: var(--jade); border-color: var(--jade); color: var(--akz-schrift); }
.zw-grobzelle.zu { opacity: .35; cursor: default; border-style: dashed; }
.zw-grobzelle:focus-visible { outline: 3px solid var(--jade-text); outline-offset: 2px; }
/* Die Überschrift IST der Weg nach oben — sie muss deshalb wie ein Knopf
   aussehen und nicht wie eine Beschriftung. */
.zw-hoch {
  border: 1.5px solid transparent; border-radius: var(--r-klein);
  background: transparent; color: inherit; font: inherit; cursor: pointer; padding: 4px 10px;
}
.zw-hoch:hover:not(:disabled) { border-color: var(--jade-text); }
.zw-hoch:disabled { cursor: default; }
.zw-hoch:focus-visible { outline: 3px solid var(--jade-text); outline-offset: 2px; }
/* Tastatur-Eingabe: das native Feld konnte ein getipptes Datum, und für ein
   Geburtsdatum ist Tippen der schnellste Weg überhaupt. */
.zw-tippzeile { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.zw-tippzeile .zw-tippen {
  flex: 1; min-width: 8.5rem; width: auto; margin: 0;
  font-variant-numeric: tabular-nums;
}
.zw-tippfehler { margin: 6px 0 0; font-size: 12.5px; color: var(--signal-text); }

/* Vorlesestelle: für das Auge unsichtbar, für die Vorlesehilfe da. Nicht
   `display:none` — das nähme sie auch der Vorlesehilfe. */
.zw-ansage {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

@media (max-width: 400px) {
  /* Enger, damit die Zellen breit bleiben — Trefferfläche geht vor Randluft. */
  .zw-tafel { padding: 10px; }
  .zw-gross { font-size: 24px; }
}

/* Kalenderzellen IM Wähler: Die geteilte Regel weiter oben stellt sie am Handy
   auf 42px — richtig für den Belegungskalender, wo die Zelle vor allem
   Information ist. Hier IST sie die Eingabe, also bekommt sie eine Trefferhöhe.
   Bewusst nur in der Tafel: die fünf Flächen mit dem Belegungskalender bleiben
   unberührt. (Die Breite bindet die Geometrie — 7 Spalten auf 320px sind 42px.) */
/* `aspect-ratio: auto` MUSS dabei stehen: die geteilte Regel hält die Zelle
   quadratisch, und eine Mindesthöhe von 46px hätte über die Seitenverhältnis-
   Rechnung auch 46px BREITE verlangt — in einer 30px-Spalte überlappen die
   Zellen dann einander. Gemessen: rechte Kante 295px bei 238px Gitter. */
.zw-tafel .kal-tag { aspect-ratio: auto; min-height: 46px; }
/* Die geteilte Zellen-Animation staffelt um 30ms je Tag — im Belegungskalender
   führt das den Blick, in einer AUFKLAPPENDEN Tafel hieße es: der 31. Tag
   erscheint erst nach fast einer Sekunde. Im Bildschirmfoto war die halbe Tafel
   schlicht leer. Hier deshalb dieselbe Bewegung, nur fünfmal schneller. */
.zw-tafel .kal-tag { animation-delay: calc(var(--zelle, 0) * 6ms); }

/* ══ Die gemeinsame Hülle des Teambereichs (19.08.2026, Etappe 1) ══════════
   Philip, nach dem Blick in den Betrieb: „man klickt auf Termine und alles
   öffnet sich, zu viele irreführende Anzeigen … Das Portal verliert an
   Navigationsübersicht" und „zu grelle Farben hindern den Blick".

   🔴 Zwei Ebenen, nicht zwei Navigationen: OBEN eine schmale Leiste mit den
   vier Bereichen, LINKS ausschließlich die Unterpunkte des gewählten. Vorher
   standen auf `/admin.html` zwei Listen übereinander — die Bereichsliste aus
   `team-rahmen.js` und darunter Agenda/Verwaltung/Einstellungen, zusammen 16
   Punkte. Wer 16 Punkte sieht, sieht keinen.

   🔴 EINE Fläche, EIN Dokument: Die Hülle lädt beim Bereichswechsel nichts
   neu. Damit KANN die Kopffarbe zwischen zwei Bereichen nicht mehr
   auseinanderlaufen — das ist keine Absprache, sondern Bauweise.

   Farbe bewusst sparsam: Die Akzentfläche trägt genau EIN Band (die Kopfleiste).
   Die Unterpunkte links stehen auf Kartengrund mit Rand statt auf einer zweiten
   dunklen Fläche — zwei farbige Flächen nebeneinander waren genau das „grell". */
/* 🔴 20.08.2026, ZWEI Zahlen und keine dritte: Die Menüleiste (`--nav-breite`)
   und die Höchstbreite der Inhaltsfläche (`--inhalt-max`) stehen ab hier an
   genau einer Stelle. `--spur` ist ihre Summe — die Breite, in der die ganze
   Oberfläche lebt. Vorher standen 224 und 1200 an drei Stellen; wer eine davon
   ändert, verschiebt sonst die Mitte, ohne es zu merken.

   🩸 Sie stehen am RUMPF und nicht an `.hk`: Die Fußzeile mit der Pille ist
   Geschwister von `.hk`, nicht ihr Kind. An `.hk` definiert, hätte die Pille
   die Spur nie geerbt — `var(--spur)` wäre dort leer geblieben, `max-width`
   ungültig und die Marke stünde wieder in einer anderen Mitte als alles
   darüber. Ungültige Variablen erzeugen keinen Fehler, nur ein schiefes Bild.
   Der Bezug `:has(> .hk)` hält sie zugleich vom Patientenbereich fern, der
   keine Menüleiste hat und für den „nav-breite" nichts bedeutet. */
body:has(> .hk) {
  --nav-breite: 224px;
  --inhalt-max: 1200px;
  --spur: calc(var(--nav-breite) + var(--inhalt-max));
}
.hk { min-height: 100vh; display: flex; flex-direction: column; background: var(--linnen); }
/* 🩸 20.08.2026, von Philip gemeldet: „die ‚Taktwerk powered by Flowmatik24'-
   Pille ist zu weit unten … das Branding musste ich aktiv suchen!"

   GEMESSEN, an drei Gerätegrößen und je einer Fläche mit viel und einer mit
   wenig Inhalt — die Pille war in ALLEN SECHS Fällen ohne Scrollen unsichtbar:
     1440×900  Tageslage (wenig)  Seite 963  · 63 px scrollen nötig
     1440×900  Einstellungen      Seite 3923 · 3023 px
     1920×1080 Tageslage          Seite 1143 · 63 px
     1920×1080 Einstellungen      Seite 3818 · 2738 px
     390×844   Tageslage          Seite 1076 · 232 px
     390×844   Einstellungen      Seite 5938 · 5094 px

   🔴 Die 63 px im günstigsten Fall sind kein Zufall, sondern eine Gewissheit:
   `.hk` ist `min-height: 100vh` und füllt damit IMMER den ganzen Bildausschnitt,
   und `renderShell()` hängt die Pille an `</body>` — also HINTER `.hk`. Das
   Dokument ist deshalb immer mindestens ein Bildausschnitt PLUS Pillenhöhe.
   Es gibt keinen Inhalt, der klein genug wäre, damit sie ins Bild rückt. Genau
   deshalb musste Philip sie suchen: Die Seite sieht fertig aus, und die Marke
   steht knapp darunter.

   Der Rumpf wird deshalb selbst die Spalte, die `.hk` bisher zu sein versuchte:
   Die Hülle nimmt den übrigen Platz, die Pille sitzt bei kurzem Inhalt am
   unteren Bildrand und wandert bei langem Inhalt ganz normal mit.

   🔑 `:has()` statt einer Regel auf `body`: Die Patientenflächen benutzen
   `.huelle` und nicht `.hk`; ein `display:flex` auf JEDEM Rumpf hätte sie
   mitgenommen, ohne dass hier jemand hinsieht. Kann ein Browser `:has()`
   nicht, bleibt es beim heutigen Verhalten — schlechter wird nichts. */
/* 🩸 20.08.2026, ZWEITE Runde: Der erste Zuschnitt galt nur für `.hk`, also
   den Teambereich. An der echten Vorschau gemessen stand die Pille auf der
   ANMELDESEITE bei 390 px wieder unter der Kante — und das ist die allererste
   Fläche, die ein Mensch von Taktwerk sieht. Der Zuschnitt umfasst deshalb
   auch die Vollseiten des Patientenbereichs (`.huelle`) und die Anmeldung
   (`.anmelde-flaeche`).

   🔴 UND AUSDRÜCKLICH NICHT `embed.html` / `widget.html`. Die beiden sitzen in
   einem iframe auf der Website des Kunden und melden ihre gemessene Höhe per
   postMessage nach oben; `embed.js` stellt den Rahmen darauf ein. Ein
   `min-height: 100vh` auf ihrem Rumpf hieße: Der Rahmen auf der Kundenseite
   wächst auf Bildschirmhöhe, mit einem Feld Leere unter dem Kalender. Ein
   Zuschnitt über `body` allein („gilt für jede Seite") hätte genau das
   angerichtet, ohne dass hier jemand hinsieht — die beiden Dateien tragen
   `.einbettung` bzw. `.tw` und wären mitgekommen.

   🔑 `margin-top: auto` an der Fußzeile statt `flex: 1` an einem Kind: Diese
   vier Flächen haben VERSCHIEDENE Wurzelelemente (`.hk`, `.huelle`,
   `.anmelde-flaeche`). Welches davon wachsen soll, müsste man je Fläche
   pflegen — `margin-top: auto` schiebt das letzte Element ans Ende, ganz
   gleich, was darüber steht. Eine Regel statt vier, die auseinanderlaufen. */
body:has(> .hk),
body:has(> .huelle),
body:has(> .anmelde-flaeche) { min-height: 100vh; display: flex; flex-direction: column; }
body:has(> .hk) > .hk { min-height: 0; flex: 1 0 auto; }
body:has(> .hk) > .fuss.werk-herkunft,
body:has(> .huelle) > .fuss.werk-herkunft,
body:has(> .anmelde-flaeche) > .fuss.werk-herkunft { flex: none; margin-top: auto; }
/* Die Fußzeile gehört zur selben Spur wie Kopf und Inhalt — sonst stünde die
   Marke bei 1920 px mittig im FENSTER, während die Oberfläche darüber mittig
   in ihrer Spur steht. Zwei Mitten in einem Bild liest das Auge als schief. */
body:has(> .hk) > .fuss.werk-herkunft { width: 100%; max-width: var(--spur); margin-inline: auto; }
/* 🩸 20.08.2026, zweiter Satz von Philips Meldung: „der Bildschirm sollte sich
   immer am Endgerät zentrieren."

   GEMESSEN bei 1920×1080, VORHER: Die Inhaltsfläche stand zwar mittig — aber
   nur in dem Platz, der neben der Menüleiste übrig blieb. Vom Fensterrand aus
   waren das links 472 px und rechts 248 px. Die ganze Oberfläche klebte also
   an der linken Kante, und rechts stand ein Streifen Leere. Das ist genau der
   Eindruck, den er gemeldet hat: Man sucht die Mitte und findet sie nicht.

   Zentriert wird deshalb die SPUR (Menüleiste + Inhalt) im Fenster, nicht der
   Inhalt neben der Leiste. Das farbige Kopfband bleibt dabei randlos über die
   volle Breite — eine Leiste, die mittendrin aufhört, sähe aus wie ein Fehler;
   nur ihr INHALT rückt in dieselbe Spur wie alles darunter. Deshalb hier
   `padding-inline` statt `max-width`.

   Der Rückfallwert 18px ist der bisherige Wert: Solange das Fenster schmaler
   ist als die Spur, verteilt `max()` nichts und es bleibt beim heutigen Bild. */
.hk-kopf {
  /* Erst die Fläche, dann das Bild: Kann ein Browser `color-mix` nicht, bleibt
     der einfarbige Kopf von vorher — schlechter wird nichts. */
  background-color: var(--tinte);
  background-image: var(--kopf-bild, none);
  color: var(--akz-schrift);
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 8px 18px; row-gap: 6px;
  padding-inline: max(18px, calc((100% - var(--spur)) / 2));
}
.hk-kopf .marke { font-family: var(--anzeige); font-weight: 600; font-size: 16px; display: flex; align-items: center; gap: 9px; letter-spacing: -.02em; }
.hk-kopf .marke img { height: 22px; width: auto; display: block; }
.hk-kopf .marke .marke-zeichen { font-size: 19px; line-height: 22px; display: block; }
.hk-kopf .marke .zusatz { font-family: var(--text-schrift); font-weight: 400; font-size: 13px; opacity: .72; letter-spacing: 0; }
/* Die vier Bereiche. Ein Reiter, kein Knopf: Er zeigt, wo man ist. */
.hk-bereiche { display: flex; align-items: stretch; gap: 4px; margin-left: 8px; flex-wrap: wrap; }
.hk-bereich {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 13px; border-radius: var(--r-klein);
  color: rgba(255,255,255,.82); text-decoration: none;
  font: inherit; font-size: 14px; font-weight: 600; border: 1.5px solid transparent;
  background: transparent; cursor: pointer; white-space: nowrap;
}
.hk-bereich:hover { background: rgba(255,255,255,.10); color: #fff; }
.hk-bereich.aktiv { background: var(--karte); color: var(--text); border-color: var(--karte); }
.hk-bereich .hk-abz {
  background: var(--signal); color: #fff; font-size: 11px; font-weight: 700;
  border-radius: 999px; padding: 1px 7px; font-variant-numeric: tabular-nums;
}
.hk-bereich.aktiv .hk-abz { background: var(--signal-text); color: var(--karte); }
/* 🩸 23.08.2026, von Kai an der echten Oberfläche gemeldet: Nach einem Klick
   auf „Optik würfeln" riss die Kopfleiste in ZWEI Zeilen. Gemessen im Browser:
   ab 1100 px Breite sprang sie von 63 px auf 108 px, sobald der Optik-Hinweis
   erschien.

   🔑 Die Ursache lag NICHT am Hinweis, sondern an dieser Zeile. `margin-left:
   auto` schiebt den rechten Block ans Ende, lässt ihn aber bei seiner vollen
   Wunschbreite. Und ein umbrechender Flex-Container (`.hk-kopf` hat
   `flex-wrap: wrap`) entscheidet über den Zeilenumbruch an genau dieser
   Wunschbreite — GESCHRUMPFT wird erst danach, innerhalb der fertigen Zeile.
   Ein Kind, das nicht schrumpfen darf, bricht deshalb um, statt schmaler zu
   werden. Jedes zusätzliche Element im Kopf hätte denselben Effekt gehabt; der
   Würfel hat ihn nur sichtbar gemacht.

   ⇒ `flex: 1 1 0` statt `margin-left: auto`: Die Wunschbreite ist damit 0, der
   Block passt IMMER in die erste Zeile und füllt den Rest der Breite auf.
   `justify-content: flex-end` hält den Inhalt weiterhin rechts — optisch
   identisch zu vorher, aber ohne den Umbruch zu erzwingen.

   🩸 Und hier stand zuerst zusätzlich `min-width: 0`. GEMESSEN war das grün
   (eine Zeile, kein Überlauf) — im BILD bei 900 px lagen „Protokolle", die
   beiden runden Knöpfe und „Alexander Richter" ÜBEREINANDER. `min-width: 0`
   erlaubt einem Flex-Kind, schmaler zu werden als sein eigener Inhalt; was
   nicht hineinpasst, tritt dann einfach aus und legt sich über den Nachbarn.
   Ohne die Zeile gilt wieder `min-width: auto` = min-content: Der Block wird
   so schmal wie möglich, aber nie schmaler als das, was in ihm steckt.
   🔑 Höhe und Überlauf zu messen reicht bei Überlappung NICHT — sie ändert
   beides nicht. [[reveal-vorfahr-unsichtbar]] */
.hk-kopf .hk-rechts {
  flex: 1 1 0;
  display: flex; align-items: center; justify-content: flex-end;
  gap: 10px; font-size: 14px;
}
/* Der Hinweis ist Text, der nur zeitweise da ist. Ist der Kopf zu eng, um ihn
   GANZ zu zeigen, verschwindet er — der Weg zurück bleibt als Knopf, und was
   der Satz erklärt, steht in dessen `title`/`aria-label` (theme.js). Der Wert
   ist an der gemessenen Stelle gewählt: bis 1220 px reicht der Platz im
   Regelfall nicht mehr für den vollen Satz. */
/* 🔑 Die Ausblendgrenze fuer den Hinweissatz ist entfallen: Die Karte
   konkurriert um keinen Platz in der Zeile mehr, also gibt es nichts mehr zu
   sparen. Der Satz steht wieder auf JEDER Breite ganz da. */
/* Unabhaengig vom Wuerfel: Mit sechs Reitern reicht die Zeile bei 1280 px
   nicht mehr. Das Beiwort der Marke ist Beiwerk (der Praxisname bleibt), und
   seine ~105 px sind genau das, was fehlt. GEMESSEN, nicht geschaetzt. */
@media (max-width: 1360px) {
  .hk-kopf .marke .zusatz { display: none; }
}

/* Auch der Name der angemeldeten Person darf kürzen statt zu drängeln — sonst
   verschiebt eine lange Anrede dasselbe Problem nur an die nächste Stelle.
   🩸 Hier stand zuerst `min-width: 0` an `.hk-wer` selbst. GEMESSEN: Der Block
   schrumpfte damit auf 18 px, während der „Abmelden"-Knopf darin seine 112 px
   behielt — er ragte 84 px über den Fensterrand hinaus und erzeugte eine
   waagerechte Bildlaufleiste. Schrumpfen darf deshalb NUR der Name; `.hk-wer`
   behält seine natürliche Mindestbreite und damit den Knopf im Bild. */
.hk-kopf .hk-wer { opacity: .85; display: inline-flex; align-items: center; }
/* 🩸 Hier stand kurzzeitig `flex: 0 1 0`. Die Zahlen waren makellos — und im
   BILD war der Name bei 1100 px SPURLOS WEG, obwohl reichlich Platz war:
   Basis 0 ohne `flex-grow` heißt „bleib bei 0". Zwei Bildkontrollen, zwei
   verschiedene Fehler, beide von der Messung als grün durchgewinkt.
   🔑 `flex: 1 1 0` ist die Auflösung: Basis 0 meldet der Kopfleiste eine
   Mindestbreite von 0 (ein `white-space: nowrap`-Text meldet sonst seine VOLLE
   Breite, und `min-width: 0` senkt diese Meldung nicht — es erlaubt nur, sie zu
   unterschreiten), und `flex-grow: 1` holt den Namen sofort wieder heraus,
   sobald Platz da ist. Zu breit wird er nie: Er wächst nur in den Raum, den
   `.hk-wer` ohnehin hat.
   🩸 Auch das war falsch: Mit `flex-grow: 1` steht der Name zwar wieder da,
   meldet der Kopfleiste aber erneut seine volle Breite als Mindestmaß — der
   Umbruch kam zurück. Ein Text kann nicht gleichzeitig „ganz da" und „zählt
   nicht" sein. ⇒ Er wird unterhalb einer gemessenen Breite ganz ausgeblendet,
   wie das Beiwort der Marke und der Hinweissatz. Ausblenden ist berechenbar,
   Kürzen ist es nicht. */
.hk-kopf .hk-wer .wer { white-space: nowrap; }
@media (max-width: 1060px) {
  .hk-kopf .hk-wer .wer { display: none; }
}

.hk-flaeche { display: flex; align-items: stretch; flex: 1; min-height: 0;
  width: 100%; max-width: var(--spur); margin-inline: auto; }
/* 🔴 Die Seitenleiste ist eine eigene EBENE, keine Spalte mit Trennstrich —
   die Bauform aus „Organic" (Philips Entscheidung 19.08.2026). Sie liegt sicht-
   bar VOR dem Seitengrund statt daneben. Der Schatten fällt bewusst nur nach
   rechts, in Richtung des Inhalts: ein Schatten nach allen Seiten ließe sie
   schweben, und eine schwebende Navigation liest sich wie ein Dialog.
   `z-index` hält sie über dem Inhalt — ohne ihn läge der Schatten UNTER der
   Inhaltsfläche und wäre unsichtbar. */
/* 🩸 `[hidden]` verliert gegen `display: flex` — deshalb steht die Regel hier
   ausdrücklich und VOR der Leiste selbst. Ohne sie bliebe eine leere Spalte
   sichtbar, obwohl das Skript sie versteckt hat, und niemand fände den Grund
   im JavaScript. */
.hk-unter[hidden] { display: none; }
.hk-unter {
  width: var(--nav-breite); flex: none; background: var(--karte); border-right: 1px solid var(--rand);
  padding: 16px 12px; display: flex; flex-direction: column; gap: 4px;
  box-shadow: 6px 0 18px -14px rgba(0, 0, 0, .38);
  position: relative; z-index: 1;
  /* 🩸 20.08.2026, von Philip gemeldet: „Wenn man links auf der Menü-Leiste mit
     Mausrad scrollt, geht die Seite nicht hoch/runter, nur wenn man rechts
     davon scrollt, das ist mist."

     Ursache: `overscroll-behavior: contain` hält die Scroll-Kette in der Leiste
     an — auch dann, wenn die Leiste selbst gar nichts zu scrollen hat. Gemessen
     im Bereich Termine bei 1440×900: scrollHeight 934 = clientHeight 934 (die
     Leiste hat NICHTS zu scrollen), Seite 1059 > 900 (die Seite hätte sehr wohl
     etwas). Der Normalfall wurde also für einen Ausnahmefall bestraft.

     Die Begründung von damals — „zwölf Unterpunkte in drei Gruppen" — gilt seit
     Etappe 3c nicht mehr: Termine hat zwei. Sie stand hier weiter, und niemand
     sucht nach einer Begründung, die einmal richtig war.

     🔑 Der ZWECK bleibt: `overflow-y: auto` ist das Netz. Ist der Inhalt der
     Leiste wirklich höher als ihr Platz, scrollt sie für sich, und der letzte
     Punkt bleibt erreichbar. Nur die Kette wird nicht mehr angehalten — hat die
     Leiste nichts (mehr) zu scrollen, gibt sie das Rad an die Seite weiter.
     `auto` ist der Vorgabewert und steht hier ausdrücklich, damit die nächste
     Person sieht, dass das eine Entscheidung ist und kein Vergessen. */
  max-height: 100%; overflow-y: auto; overscroll-behavior-y: auto;
}
.hk-unter-titel {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--nebel); padding: 4px 10px 8px;
}
/* Das Symbol eines Unterpunkts ist leiser als seine Beschriftung — es sortiert,
   es ruft nicht. Erst der aktive Punkt bekommt den Akzent. */
.hk-punkt .ik { color: var(--nebel); }
.hk-punkt:hover .ik { color: var(--text); }
.hk-punkt.aktiv .ik { color: currentColor; }
.hk-punkt {
  display: flex; align-items: center; gap: 9px; justify-content: flex-start;
  padding: 9px 11px; border-radius: 10px; border: 1.5px solid transparent;
  background: transparent; color: var(--text); text-decoration: none;
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; text-align: left;
}
.hk-punkt:hover { background: var(--jade-fl); }
.hk-punkt.aktiv { background: var(--jade); color: var(--akz-schrift); }
.hk-leer { color: var(--nebel); font-size: 13px; padding: 6px 11px; line-height: 1.45; }
/* Ab der zweiten Gruppe braucht die Zwischenüberschrift Luft nach oben, sonst
   klebt sie am letzten Punkt der Gruppe davor und trennt nichts mehr.
   (19.08.2026, Etappe 2: „Termine" bringt zwölf Unterpunkte in drei Gruppen.) */
.hk-punkt + .hk-unter-titel { padding-top: 16px; }
/* Die Zahl am Unterpunkt (wartende Anfragen, ungelesene Nachrichten). Sie sitzt
   rechts am Rand, damit die Beschriftungen untereinander bündig bleiben. */
.hk-punkt-abz {
  margin-left: auto; background: var(--signal); color: #fff; font-size: 11px; font-weight: 700;
  border-radius: 999px; padding: 1px 7px; font-variant-numeric: tabular-nums;
}
/* Auf dem gefüllten Punkt kehrt sich das Verhältnis um — sonst stünde ein
   dunkles Abzeichen auf dunklem Grund. 🩸 `--signal-text` ist in beiden
   Tönungen dasselbe wie `--signal`; als Textfarbe auf `--signal` wäre die
   Zahl unsichtbar. Deshalb hier `#fff` bzw. `--karte`, genau wie oben in
   der Bereichsleiste (`.hk-bereich .hk-abz`). */
.hk-punkt.aktiv .hk-punkt-abz { background: var(--karte); color: var(--signal); }
/* 🩸 20.08.2026, zweiter Teil von Philips Meldung: „der Bildschirm sollte sich
   immer am Endgerät zentrieren". GEMESSEN: Die Inhaltsfläche klebte am linken
   Rand und lief bis zum rechten durch — 1201 px bei 1440, **1681 px bei 1920**,
   links 224 px (Menüleiste), rechts 15 px. Auf einem Bildschirm sind das
   Textzeilen über 1600 px; niemand liest so weit, und der Blick findet keinen
   Anfang.

   Die Fläche bekommt deshalb eine Höchstbreite und steht mittig darin. Der
   Wert 1200 px ist nicht erfunden: Es ist dieselbe Höchstbreite, die
   `.huelle.breit` für die Praxisflächen schon trägt (weiter oben) — eine
   zweite Zahl wäre eine zweite Wahrheit.

   🔑 Auf Laptop und Handy ändert sich dadurch NICHTS: Dort ist die verfügbare
   Breite ohnehin kleiner als 1200 px, `margin-inline: auto` verteilt dann
   nichts. Die Menüleiste bleibt am linken Rand — sie ist Navigation und
   gehört an die Kante, nicht in die Mitte. */
/* 🩸 Erster Versuch war `.hk-inhalt > * { max-width; margin-inline:auto }` und
   GEMESSEN untauglich: Welches Element das erste Kind ist, entscheidet jedes
   Bereichsmodul für sich. Bei 1920 stand die Tageslage dann bei links 250 und
   die Einstellungen bei links 465 — dieselbe Absicht, zwei Ergebnisse. Die
   Zentrierung gehört an EINE Box, nicht an das, was ein Modul zufällig zuerst
   ausgibt. */
.hk-inhalt { flex: 1; min-width: 0; padding: 22px 26px 60px; max-width: var(--inhalt-max); margin-inline: auto; }

@media (max-width: 780px) {
  .hk-flaeche { flex-direction: column; }
  .hk-unter {
    width: 100%; border-right: 0; border-bottom: 1px solid var(--rand);
    flex-direction: row; align-items: center; padding: 9px 10px; gap: 6px;
    /* 🔴 19.08.2026, Etappe 2, GEMESSEN bei 390 px: Umbrechend belegten die
       zwölf Unterpunkte von „Termine" 470 der 844 Bildpunkte Höhe — man
       scrollte an der Navigation vorbei, bevor der erste Termin zu sehen war.
       Eine Zeile, die für sich scrollt, ist auf dem Telefon die geläufige
       Form (Reiterleiste) und lässt den Inhalt oben stehen.
       🩸 `overflow-x` sitzt HIER, am Kasten — nicht an der Seite. Die Seite
       darf ausdrücklich nicht seitlich überlaufen; das ist gemessen.
       `max-height`/`overflow-y` der Breitbild-Regel werden zurückgenommen,
       sonst schnitte die liegende Zeile sich selbst ab. */
    flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; max-height: none;
    scrollbar-width: thin;
  }
  .hk-unter-titel { display: none; }
  .hk-punkt { padding: 8px 12px; font-size: 13.5px; white-space: nowrap; flex: none; }
  .hk-inhalt { padding: 16px 14px 50px; }
  /* 🔴 20.08.2026 GEMESSEN auf 390×844: Die Kopfleiste war 175 px hoch — ein
     Fünftel des Bildschirms für Navigation, bevor der erste Inhalt kommt.
     Grund: Marke, fünf Bereichsreiter und die rechten Knöpfe brechen in drei
     Zeilen um, jede mit vollem Polster. Die Reiter bleiben vollständig
     (Wegblenden wäre wieder der Fehler vom 17.07.) — sie werden nur enger. */
  .hk-kopf { padding: 6px 12px; row-gap: 4px; gap: 10px; }
  .hk-bereiche { margin-left: 0; width: 100%; gap: 3px; }
  .hk-bereich { padding: 6px 9px; font-size: 13px; gap: 6px; }
  .hk-bereich .ik { width: 16px; height: 16px; }
  .hk-kopf .marke { font-size: 15px; }
}

/* ── Inhalt des Bereichs „Tageslage" ───────────────────────────────────────
   Stand bis zum 19.08.2026 als `<style>` in `public/cockpit.html`. Mit der
   Hülle gibt es diese Datei nicht mehr; die Regeln gehören dorthin, wo alle
   anderen auch stehen — sonst wäre die Tageslage die eine Fläche, deren
   Aussehen woanders geregelt ist.
   Nur Rollen-Variablen, keine festen Farben: Damit erscheint sie in allen 7
   Schemata und BEIDEN Tönungen richtig, ohne eine eigene Palette zu eröffnen
   (lib/marke.js definiert dieselben Rollen um). Zustandsfarben stehen
   ausdrücklich nicht drin — eine Zahl ist kein Alarm. */
.ck-kopfzeile { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 0 0 4px; }
.ck-kopfzeile h1 { font-family: var(--anzeige); font-size: 26px; margin: 0; letter-spacing: var(--sp); }
.ck-datum { color: var(--nebel); font-size: 14px; }
.ck-hinweis { margin: 18px 0 0; }
.ck-gitter {
  display: grid; gap: 16px; margin: 22px 0 0;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.ck-kachel {
  display: block; text-decoration: none; color: inherit;
  background: var(--karte); border: 1px solid var(--rand); border-radius: var(--r);
  padding: 18px 18px 16px; box-shadow: var(--schatten);
  transition: border-color .15s ease, transform .15s ease;
}
/* Die Kachel hebt beim Überfahren an — die Bauform aus „Organic". Der Weg
   steht in `--kachel-hebt` (lib/marke.js), damit „Terminal" flach bleiben
   kann, ohne diese Regel zu kennen. */
.ck-kachel:hover, .ck-kachel:focus-visible {
  border-color: var(--rand-kraeftig);
  transform: translateY(var(--kachel-hebt, -1px));
  box-shadow: 0 2px 4px rgba(0,0,0,.07), 0 18px 32px -18px rgba(0,0,0,.30);
}
/* Das Symbol trägt den Akzent der Praxis — es ist der einzige farbige Punkt
   der Kachel und führt das Auge zur Zahl darunter. */
.ck-symbol { line-height: 1; color: var(--jade-text); }
.ck-symbol .ik { width: 22px; height: 22px; }
.ck-zahl { font-family: var(--anzeige); font-size: 40px; line-height: 1.1; margin: 10px 0 2px; font-variant-numeric: tabular-nums; }
/* „Nichts zu tun" wird leiser gezeigt, nicht andersfarbig. */
.ck-kachel[data-leer="ja"] .ck-zahl { color: var(--nebel); }
.ck-titel { font-size: 15px; font-weight: 600; }
.ck-erklaerung { color: var(--nebel); font-size: 13px; margin-top: 4px; }
.ck-lade .ck-zahl { color: var(--nebel); }
/* 🔴 20.08.2026: Vier Kacheln UNTEREINANDER belegten auf 390 px rund 520 der
   844 Bildpunkte — man scrollte an der Tageslage vorbei, um die Lage des Tages
   zu sehen. Zwei mal zwei zeigt dieselben vier Zahlen auf einen Blick.
   Die Erklärungszeile entfällt dabei: Sie erklärt den Titel, und auf halber
   Breite kostet sie drei Zeilen für eine Auskunft, die der Titel schon gibt.
   Ab 620 px kommt beides zurück. */
@media (max-width: 620px) {
  .ck-gitter { grid-template-columns: 1fr 1fr; gap: 10px; }
  .ck-kachel { padding: 14px 14px 13px; }
  .ck-zahl { font-size: 30px; margin: 6px 0 2px; }
  .ck-titel { font-size: 14px; }
  .ck-erklaerung { display: none; }
}

/* ── Die Wege auf der Tageslage (20.08.2026) ────────────────────────────────
   Sie füllen die Fläche unter den Kacheln mit WEGEN statt mit Personendaten
   (Begründung in bereich/tageslage.js). Gestaltet als ruhige Zeilen, nicht als
   zweite Kachelreihe: Zwei Kachelraster übereinander würden um dieselbe
   Aufmerksamkeit konkurrieren, und die Zahlen oben sollen gewinnen. */
/* Der Ruhezustand ist ein Satz, kein Kasten: Ein weißer Block mit Rahmen wog
   auf dem Bildschirm schwerer als die vier Zahlen darüber — und damit sagte
   die Seite „hier ist eine Meldung" statt „hier ist nichts zu tun". */
.tl-ruhe { margin: 14px 2px 0; color: var(--nebel); font-size: 14px; }
.tl-wege { margin: 30px 0 0; }
.tl-wege-titel {
  font-family: var(--text-schrift); font-size: 11.5px; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--nebel);
  margin: 0 0 12px;
}
/* Zwei Spalten ab 900 px statt „so viele wie passen": Bei vier Bereichen
   ergab `auto-fit` drei oben und einen allein darunter — eine Reihe, die
   aussieht, als fehlte etwas. Zwei mal zwei steht ruhig, und bei drei oder
   fünf Bereichen bleibt es lesbar. */
.tl-wege-gitter { display: grid; gap: 10px; grid-template-columns: 1fr; }
@media (min-width: 900px) { .tl-wege-gitter { grid-template-columns: 1fr 1fr; } }
.tl-weg {
  display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit;
  background: var(--karte); border: 1px solid var(--rand); border-radius: var(--r);
  padding: 14px 16px;
  transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.tl-weg:hover, .tl-weg:focus-visible {
  border-color: var(--rand-kraeftig);
  transform: translateY(var(--kachel-hebt, -1px));
  box-shadow: 0 2px 4px rgba(0,0,0,.06), 0 16px 28px -18px rgba(0,0,0,.28);
}
/* Das Symbol sitzt auf einer eigenen, getönten Fläche — so trägt die Zeile ein
   Gewicht am Anfang und läuft nicht als Textband aus. Der Ton kommt aus dem
   Akzent der Praxis, nicht aus einer eigenen Farbe. */
.tl-weg-symbol {
  display: grid; place-items: center; flex: none;
  width: 40px; height: 40px; border-radius: var(--r-klein);
  background: color-mix(in oklab, var(--jade-text) 12%, transparent);
  color: var(--jade-text);
}
.tl-weg-symbol .ik { width: 20px; height: 20px; }
.tl-weg-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tl-weg-titel { font-weight: 600; font-size: 15px; }
.tl-weg-unter { font-size: 13px; color: var(--nebel); }
/* Der Pfeil ist der leiseste Teil und rückt beim Überfahren mit — ein Hinweis
   auf die Richtung, kein zweiter Knopf. */
.tl-weg-pfeil { margin-left: auto; color: var(--nebel); transition: transform .15s ease, color .15s ease; }
.tl-weg-pfeil .ik { width: 17px; height: 17px; }
.tl-weg:hover .tl-weg-pfeil { transform: translateX(3px); color: var(--jade-text); }
@media (prefers-reduced-motion: reduce) {
  .tl-weg, .tl-weg-pfeil, .ck-kachel { transition: none; }
  .tl-weg:hover, .tl-weg:focus-visible, .ck-kachel:hover { transform: none; }
}

/* Die Hülle trägt die Überschrift ihres Bereichs im Inhalt, nicht im Kopf —
   der Kopf sagt, WO man ist, der Inhalt WAS dort steht. */
.hk-inhalt > h1 { font-family: var(--anzeige); font-size: 26px; letter-spacing: var(--sp); }
.hk-inhalt > .beschreibung { color: var(--nebel); }


/* ── Der Ansichtsumschalter Kalender/Liste (19.08.2026) ─────────────────────
   Philip: „mir fehlt der Button oben wo man Kalender und Liste aendern kann."
   🔴 Er ist der Ersatz fuer den geloeschten Menuepunkt „Liste" — ohne ihn ist
   die Listenansicht ueberhaupt nicht erreichbar. */
.ansicht-schalter { display: flex; gap: 3px; background: var(--linnen); border: 1px solid var(--rand);
  border-radius: 999px; padding: 3px; }
.ansicht-schalter button { font: inherit; font-size: 13.5px; font-weight: 600; color: var(--nebel);
  background: none; border: 0; padding: 5px 15px; border-radius: 999px; cursor: pointer;
  transition: background .15s ease, color .15s ease; }
.ansicht-schalter button:hover { color: var(--text); }
.ansicht-schalter button[aria-pressed="true"] { background: var(--jade); color: var(--akz-schrift); }
.marke-zeile.mit-schalter { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* ── „Neue Termine freigeben" (19.08.2026, nachgeschärft 22.08.2026) ────────
   Philip 19.08.: „die Verwaltung neuer Termine die man freigibt ist hingegen
   etwas zu gross" ⇒ kompakter.
   Philip 22.08. nach dem Testlauf: „die Rahmen berühren sich" und der Knopf
   „ist optisch zu wenig gehighlighted, man muss kurz suchen".
   🔑 Das ist KEIN Widerspruch, und die Auflösung gehört hierher, damit sie
   niemand zurückdreht: „zu groß" meinte die FLÄCHE des aufgeklappten Blocks,
   „gepresst" meint die ABSTÄNDE zwischen den Feldern darin. Der Block bleibt
   also schlank, die Felder bekommen Luft — 16px statt 10px, weiterhin unter
   den globalen 22px, damit er die Seite nicht wieder übernimmt.
   🩸 Ohne diese Zeilen hätte die globale Anhebung von `label` hier NICHTS
   bewirkt: Der Block, den Philip gemeldet hat, überschreibt sie. */
#freigabeBlock .block-inhalt { padding-top: 4px; }
#freigabeBlock .block-inhalt label { font-size: 13px; margin-top: 16px; margin-bottom: 5px; }
#freigabeBlock .block-inhalt input[type="text"] { padding: 7px 10px; font-size: 14px; }
#freigabeBlock .reiter { margin-bottom: 14px !important; }
#freigabeBlock .reihe { gap: 14px 12px; }
#freigabeBlock .reihe { margin-top: 16px; }
#freigabeBlock .reihe:first-child { margin-top: 0; }
#freigabeBlock label + .reihe { margin-top: 6px; }
#freigabeBlock .reihe.eng { gap: 10px; }
#freigabeBlock .haupt { margin-top: 18px !important; padding: 8px 18px; }

/* Die Aufklapp-Überschrift IST die Haupthandlung dieser Seite — sie sah aber
   aus wie eine Abschnittsüberschrift (Philip: „man muss kurz suchen").
   Sie trägt jetzt die Akzentfläche wie ein Hauptknopf. Farbe und Schrift
   kommen aus dem Erscheinungsbild der Praxis (`--jade` / `--akz-schrift`),
   dieses Paar ist in allen 14 Tönungen auf mindestens 5:1 gemessen. */
#freigabeBlock > summary {
  background: var(--jade); color: var(--akz-schrift); font-size: 15.5px;
}
#freigabeBlock > summary::after { color: var(--akz-schrift); font-weight: 700; }
#freigabeBlock > summary:hover { background: color-mix(in srgb, var(--jade) 88%, var(--text)); }
#freigabeBlock[open] > summary { border-radius: var(--r-gross) var(--r-gross) 0 0; }

/* ── Zufalls-Optik im Kopf (19.08.2026) ─────────────────────────────────────
   Philip: „mir fehlt der Button oben wo man zufall optik auswaehlen kann." */
.hk-wuerfel { font: inherit; font-size: 15px; line-height: 1; background: none; border: 0;
  cursor: pointer; padding: 6px 8px; border-radius: 999px; color: inherit; opacity: .7;
  transition: opacity .15s ease, background .15s ease; }
.hk-wuerfel:hover { opacity: 1; background: color-mix(in srgb, currentColor 14%, transparent); }
.hk-wuerfel:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }
.hk-wuerfel[disabled] { opacity: .4; cursor: progress; }
