/* Die Schriften werden NICHT mehr per @import geholt. Der
   Preload-Scanner sieht sie darin nie, weil sie zwei Ebenen tief in
   CSS stehen: HTML, dann site.css laden und parsen, dann fonts.css,
   dann erst die woff2. Jetzt haengen sie als eigenes link plus
   preload im Kopf jeder Seite. Vorgeladen werden nur die beiden
   latin-Dateien; die latin-ext-Fassungen holt der Browser bei
   deutschem Text wegen unicode-range ohnehin nie. */

/* ═══════════════════════════════════════════════════════════════
   PhysioAktiv, Markenebene
   Neubau vom 31.07.2026. Palette und Raster übernommen aus dem
   Vorgänger (physioaktiv/assets/site.css), Farben unverändert:
   jeder Wert stammt aus einem echten Foto der Praxis.

   Zwei Dinge sind neu, beide begründet:
   1. Die Breitenachse von Archivo ist jetzt das tragende
      Gestaltungsmittel und hat eigene Tokens (--w-*). Vorher waren
      es Streuwerte in rund 20 Regeln. Belegt: quellen/
      recherche-typografie-farbe.md, im gescannten Feld benutzt
      diese Achse praktisch niemand.
   2. Die zwei Kontrastdefekte des Vorgängers sind behoben
      (Fokusring, Bedienelement-Rahmen). Siehe --focus und
      --rule-strong. Beide Fixes benutzen vorhandene Projektwerte,
      es kommt keine Farbe dazu.
   ═══════════════════════════════════════════════════════════════ */

:root {
  /* ─── Farbe ───────────────────────────────────────────────────
     UMGESTELLT AM 02.08.2026, auf Anweisung. Der Sandton war zu
     gelb, und zusammen mit dem Goldbraun des Akzents ergab das den
     Wellness-Look, den die Seite nicht haben soll.

     GEAENDERT HABEN SICH FUENF WERTE, nicht das System: der Grund
     wird warm-neutral statt sandig, und der Akzent wechselt von
     Goldbraun auf das tiefe Petrol des neuen Logos. --teal, --ink
     und die Grautoene bleiben, wie sie waren.

       --paper     #F7F2EA -> #FAF8F5
       --paper-2   #EFE8DC -> #F0EDE8
       --bone      #E3D6C3 -> #E2DDD4
       --amber     #B8813F -> #24555F
       --amber-lo  #8C5F28 -> #1A3F47

     NICHT AUF KALTES GRAU, und das war eine Abwaegung: die
     Reportagefotos sind sehr warm (Holz, Lampen, Putz). Auf kaltem
     Grund sehen sie schmutzig-gelb aus. #FAF8F5 behaelt einen
     Hauch Waerme, ohne beige zu sein.

     DIE NAMEN --amber UND --amber-lo STIMMEN NICHT MEHR. Sie
     bleiben trotzdem stehen: umbenennen hiesse 24 Stellen im CSS
     anfassen, ohne dass sich etwas aendert. Wer aufraeumt, macht
     daraus --akzent und --akzent-lo, in einem eigenen Commit.

     DIE ALTEN WERTE STEHEN OBEN, ein Zurueckdrehen ist also fuenf
     Zeilen. Das Vergleichswerkzeug, mit dem entschieden wurde, ist
     nach der Entscheidung geloescht worden: es lag in der
     Auslieferungswurzel und haette sonst mit ausgeliefert werden
     koennen. */
  --ink:      #14181A;   /* Lattenwand im Schatten           */
  --ink-soft: #1E2426;
  --slate:    #2A3136;   /* Trainingsraum-Wand               */
  --paper:    #FAF8F5;   /* Tageslicht am Fenster            */
  --paper-2:  #F0EDE8;
  --bone:     #E2DDD4;   /* warmer Putz                      */
  --amber:    #24555F;   /* Akzent, Petrol aus dem Logo      */
  --amber-lo: #1A3F47;
  --teal:     #14807E;   /* Logo-Relief                      */
  --teal-lo:  #0D5F5E;

  /* BEWERTUNGSSTERNE, eigener Wert seit dem 02.08.2026.
     Sie hingen vorher an --amber und waeren mit auf Petrol
     gekippt. Sterne sind eine Konvention, und petrolfarbene Sterne
     neben dem Google-G lesen sich als Fehler, nicht als
     Gestaltung. Der Wert IST das alte --amber; Akzentfarbe und
     Bewertungsfarbe hatten nur zufaellig denselben.

     ZWEI STUFEN, weil es vorher auch zwei waren: die Sterne im
     Siegel liefen auf --amber, die in den Zitatkarten auf
     --amber-lo. Der Unterschied ist Absicht, die Karten stehen auf
     hellem Grund und brauchen die dunklere Stufe. --stern-lo ist
     das alte --amber-lo. */
  --stern:    #B8813F;
  --stern-lo: #8C5F28;

  --fg:      var(--ink);
  --fg-mute: #5E5A52;
  --rule:    #D8CEBF;
  --rule-ink: #2E3538;

  /* Grenzen von BEDIENELEMENTEN brauchen 3:1 (WCAG SC 1.4.11).
     --rule schafft auf --paper nur 1,40:1 und ist deshalb
     ausschließlich für Trennlinien zulässig, die sind von der
     Anforderung ausgenommen. Für Eingabefelder, Auswahlfelder und
     jede sichtbare Umrandung eines Bedienelements gilt --rule-strong.
     Der Wert ist keine neue Farbe: er stand im Vorgänger bereits im
     prefers-contrast-Block. */
  --rule-strong: #8A8072;

  /* Fokusring. NEU GEMESSEN AM 02.08.2026 nach dem Farbwechsel,
     die alten Zahlen im Kommentar galten fuer das Goldbraun:

       --amber-lo #1A3F47 auf --paper    10,73:1
       --amber    #24555F auf --paper     7,80:1
       --amber    #24555F auf --paper-2   7,08:1
       --amber    #24555F auf --bone      6,11:1

     Der alte Grund fuer die Trennung in zwei Tokens ist damit
     entfallen: Goldbraun schaffte auf getoentem Grund nur 2,35 bis
     3,02:1, das Petrol haelt ueberall mit Abstand. --amber-lo
     bleibt trotzdem als dunklere Stufe fuer Kleinschrift stehen.

     AUF DUNKLEM GRUND KIPPT DAS TOKEN WEITER UM, aber auf einen
     anderen Wert: #24555F traegt auf --ink nur 1,60:1 und waere
     dort so gut wie unsichtbar. Genommen ist das Mint aus dem
     neuen Logo, #74D3B4, mit 9,97:1. Die Umschaltung steht bei
     [data-tone="ink"]. */
  --focus: var(--amber-lo);

  /* Eckenradius fuer Handlungsknoepfe und das Google-Siegel, beides
     auf Kundenwunsch vom 31.07.2026. Siehe Begruendung bei .btn.
     Bewusst klein: 5px runden die Kante ab, ohne dass der Knopf zur
     Pille wird.

     NICHT auf Flaechen, Linien, Bildkanten und Menuefelder anwenden.
     Die Verbotsliste meint mit "border-radius ueberall" genau das,
     und ein Foto mit runden Ecken ist der schnellste Weg zurueck in
     den Baukasten-Look. */
  --radius-btn: 5px;

  /* Der einzige Wert außerhalb der Fotopalette, und der einzige,
     der einen bekommt. Begründung: der Öffnungsstatus ist die eine
     Stelle, an der eine Konventionsfarbe mehr trägt als eine
     Markenfarbe, und die aus den Praxisfotos gesampelte Palette hat
     kein Grün. Der Vorgänger benutzte dafür #5BC08A, das erreicht
     auf --paper nur 1,9:1 und war auf hellem Grund kaum zu sehen.
     Dieser Wert hält 4,77:1. Ausschließlich für den Statuspunkt. */
  --go: #1F7A4D;

  /* ─── Typo ─── */
  /* EINE Schrift fuer die ganze Website, umgestellt am 01.08.2026.
     Vorher trug Archivo die Ueberschriften und Source Serif 4 den
     Fliesstext.

     WARUM DIE SERIF WEG IST: der Fliesstext sollte weniger
     altbacken wirken. Naheliegend waere gewesen, die Serif gegen
     eine zweite Sans zu tauschen, und genau das ist die schlechte
     Loesung: zwei verwandte Grotesk-Schnitte nebeneinander
     erzeugen keinen Kontrast, sondern eine Unsauberkeit, die man
     sieht und nicht benennen kann. Eine Paarung traegt, wenn beide
     Schriften klar verschiedene Rollen haben, und das war die
     Serif. Faellt sie als Rolle weg, ist eine Schrift richtig,
     nicht ein Austausch der zweiten.

     ARCHIVO KANN DIE HIERARCHIE ALLEIN: variabel, Breite 62 bis
     125 Prozent, Gewicht 300 bis 800. Die Breitenachse steht
     darunter schon als Kadenz. Ueberschrift bei 108 Prozent und
     700 gegen Fliesstext bei 100 Prozent und 400 trennt deutlicher
     als die meisten Zwei-Schrift-Loesungen.

     UND DIE TEXTE SIND KURZ: nachgemessen am 01.08.2026, der
     laengste Ratgeberartikel hat 514 Woerter, der Median liegt bei
     235, der laengste Absatz der Website bei 72 Woertern. Der
     Lesevorteil einer Serif entsteht ueber lange Strecken, die es
     hier nicht gibt. Bei Artikeln um 1500 Woerter waere die
     Abwaegung eine andere.

     ZURUECK GEHT UEBER _backup-schrift-2026-08-01/ZURUECK.sh, die
     woff2-Dateien der Serif liegen unangetastet in fonts/. */
  --sans:  'Archivo', system-ui, sans-serif;

  /* Die Breitenachse als Kadenz, nicht als Bauchgefühl.
     Archivo läuft von 62% bis 125%, die Enden sind bewusst nicht
     ganz ausgereizt, damit noch Luft für Betonung bleibt. */
  --w-narrow: 66%;    /* Kontraktion, Schlusszeile der Hero-Achse  */
  --w-label:  72%;    /* Versallabels, Rezeptkürzel                 */
  --w-ui:     92%;    /* Navigation, Buttons                        */
  --w-head:  108%;    /* Überschriften, Zahlen                      */
  --w-wide:  122%;    /* Dehnung, Ortsnamen, Auftaktzeile          */

  /* Der Vorgänger hatte .72rem als Rohwert für Kleinstlabels, im
     Designsystem als „zwei begründete Ausnahmen" vermerkt. Beim
     Neubau wären es vier geworden, also bekommt die Größe eine
     eigene Stufe statt einer wachsenden Ausnahmeliste.
     Untergrenze angehoben: die erste Fassung landete bei 380px auf
     10,9px, und diese Stufe trägt ausschließlich Versalien mit
     0,13em Sperrung. Das ist der Grad, ab dem Sperrung kippt. */
  --t--2: clamp(.72rem, .69rem + .08vw, .76rem);
  --t--1: clamp(.78rem, .76rem + .1vw, .84rem);
  --t-0:  clamp(1rem, .97rem + .16vw, 1.12rem);
  --t-1:  clamp(1.18rem, 1.1rem + .38vw, 1.44rem);
  --t-2:  clamp(1.45rem, 1.28rem + .82vw, 2.1rem);
  --t-3:  clamp(1.9rem, 1.55rem + 1.7vw, 3.2rem);
  --t-4:  clamp(2.5rem, 1.8rem + 3.4vw, 5rem);
  --t-5:  clamp(3.2rem, 1.9rem + 6.2vw, 7.5rem);

  --gap: clamp(1.15rem, 5vw, 3rem);

  /* Bewegung war der einzige Bereich ohne Tokenschicht: die Kurve
     stand achtmal ausgeschrieben, die lange Dauer fuenfmal.

     GEKUERZT AM 31.07.2026 auf Zuruf: .55s und .4s waren zu lang.
     Beide Tokens werden ausschliesslich von der Standortwahl
     benutzt, und dort liefen vier Eigenschaften gleichzeitig ueber
     die volle Dauer. Eine halbe Sekunde ist fuer eine Kachel, die
     sich beim Darueberfahren dehnt, deutlich ueber der Schwelle,
     ab der Bewegung sich aufdraengt statt zu antworten. */
  --ease:     cubic-bezier(.22, 1, .36, 1);
  --dur-lang: .3s;
  --dur-kurz: .18s;

  /* Der Ladeschleier, eigene Dauer. Nicht --dur-lang, weil das eine
     Antwort auf eine Handlung ist und deshalb kurz sein muss,
     waehrend der Schleier ein Auftakt ist und Zeit braucht, um
     ueberhaupt gesehen zu werden. Details bei .laden.
     HIER DREHEN, wenn es zu lang oder zu knapp wirkt.
     Am 01.08.2026 auf Zuruf von 520 auf 760ms verlaengert. */
  --dur-laden: 760ms;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--sans);
  font-size: var(--t-0);
  /* 1.58 statt der 1.62 der Serif. Archivo hat die deutlich
     groessere x-Hoehe, damit fuellt dieselbe Zeile optisch mehr
     Raum und braucht entsprechend weniger Durchschuss. */
  line-height: 1.58;
  color: var(--fg);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  /* Bleibt stehen, obwohl Archivo keine opsz-Achse hat: die
     Eigenschaft ist folgenlos, wenn die Achse fehlt, und richtig,
     sobald eine Schrift sie mitbringt. */
  font-optical-sizing: auto;
}

img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--amber); color: #fff; }

:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 2px; }
:focus:not(:focus-visible) { outline: none; }

/* ─── Ausbruch-Raster: content / breit / randlos aus einer Deklaration ─── */
.grid {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gap), 1fr)
    [wide-start] minmax(0, 6rem)
    [content-start] min(72rem, 100% - var(--gap) * 2) [content-end]
    minmax(0, 6rem) [wide-end]
    minmax(var(--gap), 1fr) [full-end];
}
.grid > *      { grid-column: content; }
.grid > .wide  { grid-column: wide; }
.grid > .full  { grid-column: full; }

/* ─── Rhythmus als Daten: die Kadenz der ganzen Seite an einer Stelle ─── */
[data-density="sparse"] { padding-block: clamp(5.5rem, 12vw, 10rem); }
[data-density="normal"] { padding-block: clamp(3.5rem, 8vw, 6.5rem); }
[data-density="dense"]  { padding-block: clamp(2.5rem, 5vw, 4rem); }

/* Dunkler Kontext: vier Stellen brauchen dieselbe Umschaltung.
   Sie stand dreimal ausgeschrieben, und #mobnav griff als vierte
   ganz daran vorbei und schrieb --rule-ink direkt in eine Regel. */
/* --focus: seit dem 02.08.2026 NICHT mehr var(--amber). Der Akzent
   ist jetzt ein tiefes Petrol und traegt auf --ink nur 1,60:1.
   #74D3B4, das Mint aus dem Logo, kommt auf 9,97:1. Gemessen, nicht
   geschaetzt. */
[data-tone="ink"], .ort, .foot, #mobnav {
  --rule: var(--rule-ink); --fg-mute: #9AA3A5; --focus: #74D3B4;
}
[data-tone="ink"]  { background: var(--ink); color: var(--paper); }
[data-tone="tint"] { background: var(--paper-2); }

/* ═══ Typografie ═══════════════════════════════════════════════ */

h1, h2, h3 {
  font-family: var(--sans);
  font-weight: 600;
  font-stretch: var(--w-head);
  line-height: 1.02;
  letter-spacing: -.022em;
  text-wrap: balance;
}
h1 { font-size: var(--t-5); }
h2 { font-size: var(--t-4); }
h3 { font-size: var(--t-2); }

p { text-wrap: pretty; }

/* Strukturlabel: schmale Versalien mit vorangestelltem Strich */
.label {
  font-family: var(--sans);
  font-size: var(--t--1);
  font-weight: 600;
  font-stretch: var(--w-label);
  text-transform: uppercase;
  letter-spacing: .18em;
  color: var(--amber-lo);
  display: flex;
  align-items: center;
  gap: .7rem;
}
.label::before {
  content: "";
  inline-size: 1.6rem;
  block-size: 1px;
  background: currentColor;
  flex: none;
}
[data-tone="ink"] .label { color: var(--bone); }

/* ─── Kleinstlabel ─────────────────────────────────────────────
   Sieben Regeln bauten dieselben sechs Deklarationen: Sans, --t--2,
   Gewicht 600, --w-label, Versalien, 0.13em Sperrung. Unterschieden
   haben sie sich nur in Farbe und Abstand. Das steht jetzt einmal
   hier, die Regeln darunter tragen nur noch ihr Eigenes.
   .label bleibt eigenstaendig: es hat den vorangestellten Strich und
   eine andere Sperrung, ist also ein anderer Baustein.            */
.micro dt, .artikel-meta, .prose dt, .fact dt,
.crew-role, .field label, .foot h2, .bewertung-txt, .verlauf-titel {
  font-family: var(--sans);
  font-size: var(--t--2);
  font-weight: 600;
  font-stretch: var(--w-label);
  text-transform: uppercase;
  letter-spacing: .13em;
}

.lede { font-size: var(--t-1); line-height: 1.5; color: var(--fg-mute); max-inline-size: 46ch; }

/* Hero und Abschnittskopf sind derselbe Bauteil: Label, große Zeile,
   Lede, Inhalt. Sie hatten zwei verschiedene Kadenzen, und ausgerechnet
   der größere von beiden (--t-4 bis 5rem) bekam weniger Luft: 1rem
   unter einer 5rem-Zeile mit line-height 1.02 heißt, die Lede klebt an
   den Unterlängen. Jetzt dieselben Abstände wie im Hero.
   16ch waren außerdem auf keinen realen Text eingestellt, die längste
   Überschrift im Bestand lief damit dreizeilig. 20ch bringt jede auf
   höchstens zwei. */
/* Die Schriftgroesse steht seit dem 01.08.2026 an der KLASSE, nicht
   mehr am Element. Der Abschnittskopf des Ratgebers ist seit dem
   Wegfall seines Auftakts eine h1, und die ist eine Stufe groesser
   als h2: fuenf Zeilen Riesensatz fuellten den ersten Bildschirm,
   bevor der erste Beitrag kam. Ein Abschnittskopf ist ein
   Abschnittskopf, unabhaengig davon, welche Rangstufe die
   Gliederung der Seite an dieser Stelle verlangt.               */
.sec-h    { font-size: var(--t-4); margin-block: 1.6rem 1.8rem; max-inline-size: 20ch; }
.sec-lede { margin-block-end: 2.6rem; }

/* Abschnittskopf zweispaltig ab 60rem.
   Vorher standen Label, Überschrift und Vorspann alle links
   untereinander, und rechts blieben rund 60 Prozent der Zeile leer.
   Drei unabhängige Bildkritiken haben das übereinstimmend nicht als
   Ruhe gelesen, sondern als Umbruchfehler: der Hero darüber läuft
   über die volle Breite, darunter fällt alles auf eine schmale
   Spalte zusammen.

   Die erste Fassung hing an .wide:has(> .sec-h). Das sparte die
   Markupänderung, war aber die richtige Wirkung am falschen Träger:
   ausgezählt trafen 55 von 55 Abschnittscontainern zu, die Bedingung
   filterte also nichts, sie unterschied nur Abschnitt von Fußzeile.
   .wide trug damit zwei Aufgaben, Rasterspalte und Abschnittslayout,
   und die zweite war als Inhaltsabfrage getarnt. Jetzt sagt das
   Markup, was es ist. Kostete 55 Stellen in 35 Dateien. */
/* Ab 48rem statt ab 60rem. Bei 800 Pixeln standen Label, eine
   20ch-Ueberschrift und eine 46ch-Lede untereinander, waehrend
   rechts rund 48 Prozent der Zeile leer blieben. Genau der
   Umbruchfehler, den der Kommentar oben beschreibt, nur eine Stufe
   tiefer. Die Spaltenverhaeltnisse bleiben unveraendert. */
@media (min-width: 48rem) {
  .sec {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    column-gap: clamp(2rem, 5vw, 4.5rem);
    align-items: start;
  }
  .sec > *         { grid-column: 1 / -1; }
  .sec > .label    { grid-column: 1; }
  .sec > .sec-h    { grid-column: 1; margin-block-end: 0; max-inline-size: 22ch; }
  .sec > .sec-lede { grid-column: 2; grid-row: 2; align-self: end; margin-block: 0 .4rem; max-inline-size: none; }
  /* Alles, was nicht zum Kopf gehört, ist Inhalt und bekommt den
     Abstand darunter. Vorher waren die sechs Inhaltsbausteine
     namentlich aufgezählt, jeder siebte hätte nachgetragen werden
     müssen. */
  .sec > :not(.label, .sec-h, .sec-lede) { margin-block-start: 2.6rem; }
}

/* ─── Standortseiten mittig, NUR SCHMAL, 02.08.2026 ────────────
   Auf Anweisung. Erste Fassung war ein Modifier .sec-mitte an
   einzelnen Abschnitten; das ist am selben Tag durch diesen
   Seitenschalter ersetzt worden, weil sonst jeder kuenftige
   Abschnitt einzeln nachzuziehen waere und der Stimmen-Kopf
   ausserdem eine andere Verschachtelung hat als .sec.

   DIE KLASSE STEHT AM <body> DER DREI STANDORTSEITEN, sonst
   nirgends. Leistungen, Ratgeber und die uebrigen 36 Seiten
   bleiben linksbuendig.

   DIE GRENZE IST 48rem UND NICHT FREI GEWAEHLT: genau darueber
   wird .sec zum Zweispalter, Ueberschrift links, Lede rechts.
   Zwei Spalten haben keine gemeinsame Mitte, ein zentrierter Kopf
   waere dort kein Kopf mehr. 47.999rem statt 48rem, damit sich
   die beiden Bereiche nicht auf dem Grenzwert ueberlappen.

   ES GREIFT AUF KOEPFE UND HERO, NICHT AUF INHALT. Zentriert
   werden Label, Ueberschrift, Vorspann, die Hero-Achse und was im
   Hero daran haengt. Nicht zentriert: Namen unter den Portraits,
   Leistungskacheln, FAQ, Formularbeschriftungen und die Karte.
   Ein zentriertes Formularfeld waere kein Stilbruch, sondern ein
   Bedienfehler.

   DREI BAUSTEINE BRAUCHEN MEHR ALS text-align, weil sie Flex
   sind und text-align darin nichts ausrichtet: .label (Strich
   plus Wort), .hero-act (Knopf plus Rufnummer) und .g-bewertung
   (Siegel). Die bekommen justify-content.

   .status ist inline-flex in einem Absatz und muesste sich ueber
   das text-align des Elternteils zentrieren lassen — der Hero-
   Container ist aber nicht mit zentriert, deshalb schaltet die
   Regel es selbst auf flex um.

   DER ZWEITE STRICH AM LABEL ist keine Zierde: mit nur dem einen
   davor saesse das Wort sichtbar aus dem Lot, obwohl es
   rechnerisch mittig steht.                                    */
@media (max-width: 47.999rem) {
  .standort-mittig .label,
  .standort-mittig .sec-h,
  .standort-mittig .sec-lede,
  .standort-mittig .axis,
  .standort-mittig .hero-sub,
  .standort-mittig .stimmen-meta { text-align: center; }

  .standort-mittig .label { justify-content: center; }
  .standort-mittig .label::after {
    content: "";
    inline-size: 1.6rem;
    block-size: 1px;
    background: currentColor;
    flex: none;
  }

  .standort-mittig .sec-h,
  .standort-mittig .sec-lede,
  .standort-mittig .hero-sub { margin-inline: auto; }

  .standort-mittig .hero-act,
  .standort-mittig .g-bewertung,
  .standort-mittig .stimmen-kopf { justify-content: center; }

  /* justify-content allein reicht dem Siegel nicht: es ordnet die
     Flexkinder an, aber „43 Bewertungen bei Google" ist Fliesstext
     INNERHALB eines Kindes und blieb dadurch linksbuendig. */
  .standort-mittig .g-bewertung { text-align: center; }

  .standort-mittig .status { display: flex; justify-content: center; }
}

/* ═══ Buttons ══════════════════════════════════════════════════ */

/* --radius-btn gilt AUSSCHLIESSLICH fuer Handlungsknoepfe, auf
   Kundenwunsch vom 31.07.2026. Die Verbotsliste des Designsystems
   meint mit "border-radius ueberall" etwas anderes: Karten, die als
   schwebende Kaesten aus der Flaeche treten. Ein Knopf ist ohnehin
   ein Objekt und darf wie eins aussehen.

   Der Wert steht hier als Token, damit er an EINER Stelle liegt.
   Wer ihn spaeter erhoeht, sollte wissen, dass ab etwa 10px die
   Grenze zum Pillen-Look laeuft, und der steht auf der Liste.
   Flaechen, Linien und Bildkanten bleiben scharf.                 */
.btn {
  font-family: var(--sans);
  font-size: var(--t--1);
  font-weight: 600;
  font-stretch: var(--w-ui);
  letter-spacing: .04em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .95rem 1.6rem;
  border: 1px solid transparent;
  border-radius: var(--radius-btn);
  background: var(--teal);
  color: #fff;
  cursor: pointer;
  transition: background .18s ease, color .18s ease;
}
.btn:hover      { background: color-mix(in oklch, var(--teal), black 14%); }
.btn-block      { justify-content: center; }

/* Telefon als typografisches Element, nicht als Fußnote */
.phone {
  font-family: var(--sans);
  font-stretch: var(--w-head);
  font-weight: 600;
  font-size: var(--t-1);
  letter-spacing: -.01em;
  white-space: nowrap;
  border-bottom: 2px solid var(--amber);
  padding-bottom: .1rem;
}
.phone:hover { border-color: currentColor; }

.skip {
  position: absolute; inset-inline-start: -9999px; z-index: 99;
  font-family: var(--sans); font-size: var(--t--1);
  background: var(--ink); color: var(--paper);
  padding: .8rem 1.2rem;
}
.skip:focus { inset-inline-start: 1rem; inset-block-start: 1rem; }

/* ═══ LADESCHLEIER ═══════════════════════════════════════════════
   Auf Anweisung vom 01.08.2026. Beim Aufruf einer Seite liegt kurz
   ein Schleier ueber der Seite, darin das Logo, danach ist die
   Seite da.

   ES IST EIN GESTALTUNGSMITTEL, KEIN LADEVORGANG. Diese Website
   ist statisches HTML, sie ist fertig, bevor der Schleier
   abgelaufen ist. Er zeigt also nichts an, er setzt einen Auftakt.
   Das ist eine legitime Absicht, aber es heisst auch: er darf
   NIEMALS im Weg stehen. Die drei Vorkehrungen dafuer:

     1. pointer-events: none, durchgehend. Wer sofort klicken will,
        klickt durch den Schleier hindurch.
     2. Die Animation laeuft in reinem CSS und endet in
        visibility: hidden mit forwards. Ohne JavaScript,
        bei einem Skriptfehler und bei blockiertem JS verschwindet
        er trotzdem. Es gibt keinen Zustand, in dem er haengen
        bleibt.
     3. Der Inhalt wird NICHT versteckt. Der Schleier ist
        durchscheinend und unschaerft das, was darunter schon
        fertig steht. Kein Aufbauruckeln, kein leerer Bildschirm,
        und fuer Suchmaschinen aendert sich gar nichts.

   DIE IDEE, in einem Satz: zwei Unschaerfen laufen gegeneinander.
   Das Logo kommt aus der Unschaerfe in die Scharfe, die Seite
   dahinter macht in derselben Zeit das Gegenteil. Fuer eine
   Physiotherapiepraxis ist das das passende Bild, etwas Steifes
   wird klar und loest sich. Deshalb kein Kreisel, kein
   Fortschrittsbalken, keine Prozentzahl: die alle behaupten eine
   Wartezeit, die es nicht gibt.

   z-index 80: ueber der Kopfzeile (50), dem Untermenue (40) und
   der festen Leiste (60), aber UNTER dem Sprunglink (99). Der
   Sprunglink muss auch im ersten Moment erreichbar sein.

   DAUER an einer Stelle, --dur-laden, siehe dort. Der Korridor:
   unter etwa 300ms nimmt niemand ein Logo wahr, ueber etwa einer
   Sekunde faengt es an, sich in den Weg zu stellen. Steht derzeit
   auf 760ms, am 01.08.2026 von 520ms heraufgesetzt.

   DIE PROZENTWERTE DER KEYFRAMES SIND ANTEILE, keine
   Millisekunden. Sie gelten deshalb bei jeder Dauer weiter, und
   --dur-laden ist wirklich der einzige Wert, der zu aendern
   ist.                                                       ═══ */
.laden {
  position: fixed; inset: 0; z-index: 80;
  display: grid; place-items: center;
  pointer-events: none;
  /* --paper durchscheinend. AM 02.08.2026 MITGEZOGEN: stand als
     rgba(247, 242, 234) da, dem alten Sandton, und waere beim
     Farbwechsel als einziges Gelb stehen geblieben. Die
     Hex-Suche findet so etwas nicht — wer die Palette wieder
     anfasst, sucht auch nach rgb-Literalen. */
  background: rgb(250 248 245 / .55);
  -webkit-backdrop-filter: blur(20px) saturate(1.08);
  backdrop-filter: blur(20px) saturate(1.08);
  animation: laden-schleier var(--dur-laden) var(--ease) forwards;
}

/* Die Marke laeuft ueber DIESELBE Dauer wie der Schleier, nur mit
   anderen Zwischenschritten. Zwei getrennte Dauern waeren zwei
   Dinge, die auseinanderlaufen koennen. */
.laden img {
  inline-size: clamp(8.5rem, 32vw, 15rem);
  block-size: auto;
  animation: laden-marke var(--dur-laden) var(--ease) forwards;
}

@keyframes laden-schleier {
  0%, 52%  { opacity: 1; }
  100%     { opacity: 0; visibility: hidden; }
}

/* 0 bis 36 Prozent scharfstellen, halten, dann mit einer Spur
   Aufwaertsbewegung weich raus. Das Anheben ist minimal, .3rem:
   es soll gehen wirken, nicht wegfliegen. */
@keyframes laden-marke {
  0%   { opacity: 0; filter: blur(14px); transform: scale(.965); }
  36%  { opacity: 1; filter: blur(0);    transform: scale(1); }
  62%  { opacity: 1; filter: blur(0);    transform: scale(1); }
  100% { opacity: 0; filter: blur(7px);  transform: scale(1) translateY(-.3rem); }
}

/* ─── Der Weg hinaus, beim Klick auf einen internen Link ───
   Setzt uebergang.js. Kuerzer als der Auftakt: hier wartet jemand
   tatsaechlich, naemlich auf die naechste Seite. */
.laden.laden-ab {
  visibility: visible;
  animation: laden-ab 170ms var(--ease) forwards;
}
.laden.laden-ab img {
  animation: laden-marke-ab 170ms var(--ease) forwards;
}
@keyframes laden-ab       { from { opacity: 0; } to { opacity: 1; } }
@keyframes laden-marke-ab {
  from { opacity: 0; filter: blur(7px); transform: scale(1) translateY(-.3rem); }
  to   { opacity: 1; filter: blur(0);   transform: scale(1) translateY(0); }
}

/* Wer Bewegung abbestellt hat, bekommt keinen Schleier. Nicht eine
   ruhigere Fassung, sondern gar keinen: der Schleier hat keine
   Funktion, die ohne Bewegung uebrig bleiben wuerde.
   uebergang.js prueft dieselbe Abfrage und fasst dann keine Links
   an. */
@media (prefers-reduced-motion: reduce) {
  .laden { display: none; }
}

/* Hier stand vom 31.07. bis 01.08.2026 `.nur-vorlesen`, eine Klasse
   fuer Text, der vorgelesen, aber nicht angezeigt wird. Sie trug
   einen Tag lang die h1 der Startseite, weil die Seite nach dem
   Wegfall des Auftakts gar keine Ueberschrift mehr hatte.

   Der Willkommensabschnitt traegt sie seit dem 01.08.2026 wieder
   sichtbar, die Klasse ist damit ohne Verwendung und entfernt.
   Totes CSS bleibt hier nicht liegen.

   Falls wieder gebraucht: NICHT display:none und NICHT
   visibility:hidden, beides nimmt den Text auch aus der
   Vorlesereihenfolge. Der Weg geht ueber clip-path: inset(50%) in
   einem 1px-Kasten, dazu white-space: nowrap, sonst brechen
   Woerter zu einem Buchstabenturm um und manche Screenreader
   buchstabieren ihn. Die Fassung steht in der Historie.        */

/* ═══ Kopfzeile ════════════════════════════════════════════════ */

/* ═══ SPRUNGMARKEN UNTER DER KLEBENDEN KOPFZEILE, 06.09.2026 ════
   Die Kopfzeile klebt oben und ist 67 Pixel hoch. Ein Anker scrollt
   sein Ziel an die Oberkante des Fensters, also unter die Kopfzeile:
   die ersten 67 Pixel des Ziels sind verdeckt.

   Auf /kontakt/ hiess das konkret, dass „Nummern der drei Praxen"
   an der Tuerenreihe landete und die Ueberschrift „Oder direkt in
   die Praxis" darueber verschluckt wurde. Der Anker ist deshalb auf
   den Abschnitt gewandert, und hier kommt der Abstand dazu, damit
   die Ueberschrift auch wirklich im Bild steht.

   80 statt 67: die Kopfzeile plus etwas Luft, sonst klebt die
   Ueberschrift an ihrer Unterkante. Auf [id] statt auf einzelne
   Marken, damit jeder Anker der Seite gleich behandelt wird. Ohne
   Sprung kostet die Eigenschaft nichts.                          */
main [id] { scroll-margin-block-start: 5rem; }

/* ═══ BOT-FALLE, 06.09.2026 ════════════════════════════════════
   Ein Feld, das formular.php auswertet: ist es gefuellt, war ein
   Skript am Werk. Es muss fuer Menschen unerreichbar sein, aber im
   Dokument stehen, sonst faellt kein Bot darauf herein.

   NICHT display:none und nicht hidden. Beides erkennen gute Bots,
   und schlechte Bildschirmleser lesen es dann trotzdem vor. Aus dem
   Sichtfeld schieben plus aria-hidden und tabindex -1 im Markup ist
   der Weg, der beides erfuellt.                                  */
.honigtopf {
  position: absolute; inset-inline-start: -9999px;
  inline-size: 1px; block-size: 1px; overflow: hidden;
}

.masthead {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--rule);
}
.masthead-in {
  display: flex; align-items: center; gap: clamp(1rem, 4vw, 2.5rem);
  padding-block: .8rem;
}
.masthead-logo img { block-size: 40px; inline-size: auto; }
.nav { margin-inline-start: auto; display: flex; align-items: center; gap: 1.6rem; }
.nav a {
  font-family: var(--sans); font-size: var(--t--1); font-weight: 500;
  font-stretch: var(--w-ui); letter-spacing: .01em;
  padding-block: .4rem;
  border-bottom: 2px solid transparent;
}
.nav a:hover, .nav a[aria-current="page"] { border-color: var(--amber); }

/* ═══ Untermenü Leistungen ════════════════════════════════════
   Der Kunde führt seine Leistungen in drei Kategorien und wollte
   das hier genauso. Drei zusätzliche Punkte auf oberster Ebene
   hätten die Kopfzeile auf sechs Einträge plus Rufnummer gebracht;
   ein Untermenü hält sie bei vier.

   Kein JavaScript: :hover und :focus-within, dieselbe Technik wie
   bei der Standortwahl. Der Elternpunkt bleibt ein echter Link auf
   /leistungen/, damit ein Fingertipp auf dem Telefon irgendwo
   ankommt statt ins Leere zu greifen. Auf schmalen Breiten ist das
   Menü ohnehin die Mobilnavigation, dort stehen die drei flach
   untereinander.

   Eine Fläche statt einer Linie ist hier die Ausnahme, die die
   Regel braucht: ein Menü, das über Inhalt schwebt, muss deckend
   sein. Deshalb Haarlinie statt Schatten und kein Radius.       */
.nav-gruppe { position: relative; display: flex; align-items: center; }

/* Der Pfeil sagt, dass es weitergeht. Inline-SVG mit currentColor,
   wie jedes Icon der Seite: ein Zeichensatzpfeil saesse je nach
   Schrift anders auf der Grundlinie. Er dreht sich beim Oeffnen,
   damit die Bewegung den Zustand zeigt und nicht nur schmueckt. */
.nav-pfeil {
  inline-size: .7em; block-size: .7em; flex: none;
  margin-inline-start: .35em; margin-block-start: .1em;
  transition: transform .18s ease;
}
.nav-gruppe:hover .nav-pfeil,
.nav-gruppe:focus-within .nav-pfeil { transform: rotate(180deg); }

/* Auch der hervorgehobene Kontaktknopf traegt ein Untermenue. Es
   haengt rechtsbuendig, sonst liefe es bei 1280 aus dem Fenster. */
.nav-cta .nav-unter { inset-inline-start: auto; inset-inline-end: 0; }
.nav-unter {
  position: absolute; inset-block-start: calc(100% + .55rem); inset-inline-start: -1rem;
  min-inline-size: 17rem; z-index: 40;
  background: var(--paper); border: 1px solid var(--rule);
  display: grid;
  opacity: 0; visibility: hidden; transform: translateY(-.25rem);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
}
.nav-gruppe:hover .nav-unter,
.nav-gruppe:focus-within .nav-unter { opacity: 1; visibility: visible; transform: none; }
.nav-unter a {
  display: block; padding: .75rem 1rem; border: 0;
  border-block-end: 1px solid var(--rule);
  font-family: var(--sans); font-size: var(--t--1); font-stretch: var(--w-ui);
}
.nav-unter a:last-child { border-block-end: 0; }
.nav-unter a:hover { background: var(--paper-2); border-block-end-color: var(--rule); }
.nav-unter a:last-child:hover { border-block-end-color: transparent; }
.nav-unter span {
  display: block; font-size: var(--t--2); color: var(--fg-mute);
  margin-block-start: .15rem; letter-spacing: 0;
}

/* HIER STAND .mob-unter, der Einzug der Unterpunkte im
   Mobilmenue. Entfallen am 01.08.2026: die Zuordnung kommt jetzt
   ueber benannte Gruppen statt ueber Einzug und eine senkrechte
   Linie. Siehe .mobnav-label. */
/* In der Kopfzeile stand bis zum 31.07.2026 die Rufnummer. Sie ist
   dort entfallen: sie steht im Hero jeder Seite, in der Fusszeile,
   in der Anrufleiste des Telefons und auf der Kontaktseite. Vier
   Wiederholungen sind genug, und der frei gewordene Platz traegt
   jetzt den einen Punkt, auf den es ankommt.

   Kontakt ist deshalb ein Knopf und kein Link mehr. Er behaelt die
   Groesse der Navigation, damit die Kopfzeile nicht kippt.        */
.nav-cta { display: flex; align-items: center; gap: 1rem; margin-inline-start: .4rem; }
.nav-cta .btn {
  padding: .5rem 1rem; font-size: var(--t--1);
  border-block-end: 0;
}
.nav-cta .btn:hover { border-block-end: 0; }

.burger { display: none; background: none; border: 0; padding: .5rem; cursor: pointer; color: inherit; transition: color .18s ease; }
.burger:hover { color: var(--amber-lo); }
.burger svg { inline-size: 24px; block-size: 24px; }

/* Die aktuelle Seite war nur in .nav sichtbar markiert. In der
   Mobilnavigation und in der Fußzeile stand aria-current rein
   programmatisch, ohne optische Entsprechung. */
#mobnav a[aria-current], .foot a[aria-current] { color: var(--bone); }

/* Ohne Popover-Unterstützung (Safari vor 17) gibt es keine UA-Regel
   [popover] { display: none }. #mobnav wäre dann ein statischer div in
   Praxisschwarz über volle Bildschirmhöhe zwischen Kopf und Inhalt,
   und unter 48rem gäbe es zugleich gar keine Navigation, weil .nav
   ausgeblendet ist und der Burger nichts tut. */
/* ═══ REPARIERT AM 04.09.2026 ═══════════════════════════════════
   DIESE RUECKFALLEBENE WAR WIRKUNGSLOS, und zwar aus zwei Gruenden
   gleichzeitig:

   1. SIE VERLOR NACH REIHENFOLGE. Sie stand hier bei Zeile 753 und
      setzte .nav auf display:flex. Rund 3200 Zeilen weiter unten
      setzt @media (max-width: 60rem), (hover: none) dasselbe .nav
      auf display:none. Gleiche Spezifitaet, spaeter im Stylesheet,
      also gewann die zweite Regel.
   2. SIE HING AN DER FALSCHEN SCHWELLE. 48rem war der Stand vor dem
      31.07.2026; seitdem schaltet die Navigation bei 60rem um, und
      zusaetzlich bei jedem Geraet ohne Zeigegeraet.

   WAS DAS IN DER PRAXIS HIESS: in jedem Browser ohne Popover, also
   Safari vor 17 und damit iOS 16, hatte die Seite auf JEDEM
   Touchgeraet gar keine Kopfnavigation. .nav aus, #mobnav aus, der
   Burger ohne Funktion. Erreichbar blieb nur die Fusszeile. Das
   trifft aeltere Geraete, und damit einen Teil der Patienten.

   DER FIX ARBEITET UEBER SPEZIFITAET, nicht ueber die Position.
   .masthead .nav ist (0,2,0) und schlaegt das spaetere .nav (0,1,0)
   unabhaengig davon, wo der Block steht. Ein Verschieben ueber 3200
   Zeilen waere die zerbrechlichere Loesung gewesen: die naechste
   Regel, die weiter unten dazukommt, haette dasselbe Problem
   wieder erzeugt.                                                */
@supports not selector(:popover-open) {
  #mobnav { display: none; }
  @media (max-width: 60rem), (hover: none) {
    .masthead .burger { display: none; }
    .masthead .nav { display: flex; flex-wrap: wrap; margin-inline-start: 0; gap: .8rem 1.2rem; }
    .masthead .nav-cta { margin-inline-start: 0; }
  }
}

/* ═══ MOBILNAVIGATION ════════════════════════════════════════════
   Natives Popover: Esc, Klick nach aussen und die Fokusfalle
   kommen vom Browser, kein JavaScript.

   NEU GEBAUT AM 01.08.2026, weil die erste Fassung optisch nicht
   getragen hat. Was an ihr falsch war, der Reihe nach, damit es
   nicht zurueckkommt:

     · ZWOELF GLEICHE ZEILEN. Alles stand in --t-1 mit Gewicht 500
       und einer Haarlinie darunter. Die drei Standorte waren nur
       durch Einzug von den Leistungen zu unterscheiden. Der
       Kopfnavigation gab es Gruppen mit Beschreibungen, das Menue
       hat sie fallen gelassen.
     · ELF HAARLINIEN als Leiter, und die der eingerueckten
       Eintraege begannen weiter rechts als die der Oberpunkte. Das
       sah nach Fehler aus, nicht nach Absicht.
     · DIE RUFNUMMER WAR LINK NUMMER ZWOELF, gesetzt wie
       „Ratgeber". Fuer eine Praxis ist Anrufen die Handlung,
       nicht ein Listenpunkt.
     · KEINE ADRESSEN. Genau die unterscheiden die drei Standorte
       voneinander, in der Kopfzeile stehen sie, im Menue nicht.
     · „STANDORTE" UND „BERGKAMEN" ZEIGTEN BEIDE AUF /. Zwei
       Zeilen, ein Ziel.

   WAS JETZT TRAEGT: drei benannte Gruppen statt einer Liste, die
   Standorte mit ihrer Adresse als zweite Zeile, keine Linien
   zwischen den Eintraegen mehr (Abstand und Gruppentitel ordnen),
   und die Rufnummer als gefuellter Knopf am unteren Rand.

   ABSICHTLICH OHNE OEFFNUNGSZEITEN. Der naechste Griff waere, unter
   den Knopf „Mo–Do 8–19 Uhr" zu schreiben. Das waere FALSCH: dieses
   Menue steht auf allen 39 Seiten gleich, und die Zeiten
   unterscheiden sich je Standort (Bergkamen bis 19 Uhr, Dortmund
   bis 18 Uhr, Freitag 15 gegen 12 Uhr). Eine Zeitangabe hier waere
   auf zwei von drei Standortseiten unwahr.

   DASSELBE GILT FUER DIE RUFNUMMER. Hier stand zuerst, sie sei
   projektweit dieselbe. Das war falsch: es gibt DREI Nummern, je
   Standort eine (Bergkamen 02389 4030410, Dortmund-Mitte
   0231 577225, Klinikviertel 0231 53068625). Der Knopf im Fuss
   traegt deshalb auf den drei Standortseiten die jeweils eigene
   Nummer und auf allen uebrigen Seiten den Verweis
   /kontakt/#praxen, weil dort nicht entscheidbar ist, welche
   gemeint waere. Wer hier eine feste Nummer eintraegt, macht sie
   auf zwei Dritteln der Website zur falschen Auskunft.

   AUCH ABSICHTLICH: die Leistungen tragen KEINE zweite Zeile,
   obwohl die Kopfzeile dort Beschreibungen hat. Adressen
   unterscheiden drei Standorte voneinander und sind deshalb
   Funktion; „Unsere Therapieangebote" unter „Physiotherapie" ist
   Werbung und haette die Hoehe des Menues verdoppelt.        ═══ */
#mobnav {
  border: 0; padding: 0; margin: 0;
  inline-size: min(23rem, 90vw); max-inline-size: none;
  block-size: 100dvh; max-block-size: none;
  inset: 0 0 0 auto;
  overflow-y: auto;
  background: var(--ink); color: var(--paper);
  /* Wie oben bei [data-tone="ink"]: das Petrol traegt auf --ink
     nicht, der Ring nimmt das Mint aus dem Logo. */
  --focus: #74D3B4;

  /* Hereinfahren von rechts, ohne JavaScript. allow-discrete ist
     der Teil, der zaehlt: ohne ihn springt display von none auf
     block, bevor die Bewegung laufen kann, und das Zuklappen waere
     gar nicht zu sehen. Fehlt einem Browser @starting-style, dann
     erscheint das Menue schlicht ohne Bewegung. */
  translate: 100% 0;
  transition:
    translate var(--dur-lang) var(--ease),
    overlay   var(--dur-lang) allow-discrete,
    display   var(--dur-lang) allow-discrete;
}
#mobnav:popover-open { translate: 0 0; }
@starting-style { #mobnav:popover-open { translate: 100% 0; } }

#mobnav::backdrop {
  background: rgb(10 12 13 / .55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity var(--dur-lang) var(--ease), overlay var(--dur-lang) allow-discrete, display var(--dur-lang) allow-discrete;
}
#mobnav:popover-open::backdrop { opacity: 1; }
@starting-style { #mobnav:popover-open::backdrop { opacity: 0; } }

/* Spalte statt Raster: der Fuss braucht margin-block-start: auto,
   damit der Knopf am unteren Rand sitzt und nicht direkt unter dem
   letzten Link, wenn das Menue hoeher als sein Inhalt ist. */
.mobnav-in {
  display: flex; flex-direction: column;
  min-block-size: 100%;
  padding: 1rem var(--gap) var(--gap);
}

.mobnav-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding-block-end: 1.1rem;
  border-block-end: 1px solid var(--rule);
  margin-block-end: 1.6rem;
}
/* Dasselbe Logo auf demselben Dunkel wie in der Fusszeile, nur
   kleiner. Kein eigenes Negativlogo, es gibt keins. */
.mobnav-kopf img { block-size: 30px; inline-size: auto; }

.mobnav-close {
  flex: none; background: none; border: 0; padding: .5rem; margin-inline-end: -.5rem;
  color: var(--fg-mute); cursor: pointer;
  transition: color .18s ease;
}
.mobnav-close:hover { color: var(--paper); }

.mobnav-nav { display: flex; flex-direction: column; }

/* Der Gruppentitel, dieselbe Behandlung wie .label im Inhalt:
   Versalien, 72 Prozent Breite, gesperrt. Er ist KEIN Link, das
   war der doppelte Verweis auf / in der alten Fassung. */
.mobnav-label {
  font-family: var(--sans); font-size: var(--t--2);
  font-weight: 700; font-stretch: var(--w-label);
  text-transform: uppercase; letter-spacing: .13em;
  color: var(--fg-mute);
  margin-block: 1.5rem .55rem;
}
.mobnav-label:first-child { margin-block-start: 0; }

#mobnav .mobnav-nav a {
  font-family: var(--sans); font-size: var(--t-1); font-weight: 600;
  font-stretch: var(--w-ui); letter-spacing: -.01em;
  /* 44px Mindesthoehe fuer den Daumen, ueber die Innenabstaende
     erreicht statt ueber eine feste Hoehe. Negativer Aussenabstand
     links, damit die Schrift trotz Klickflaeche an der Fluchtlinie
     der Gruppentitel bleibt. */
  padding: .55rem .6rem;
  margin-inline: -.6rem;
  border-radius: var(--radius-btn);
  transition: background .18s ease, color .18s ease;
}
#mobnav .mobnav-nav a:hover { background: var(--ink-soft); color: #fff; }

/* Die Adresse. Macht aus drei Ortsnamen drei unterscheidbare
   Standorte, und genau das ist die Frage, die im Menue ansteht. */
#mobnav .mobnav-nav a span {
  display: block;
  font-size: var(--t--2); font-weight: 400; font-stretch: normal;
  letter-spacing: 0; color: var(--fg-mute);
  margin-block-start: .1rem;
}

/* Die aktuelle Seite bekommt eine sichtbare Marke, nicht nur eine
   andere Textfarbe wie vorher.

   AMBER UND NICHT TEAL, obwohl Teal die Markenfarbe ist: --teal
   haelt auf --ink 3,76:1, --amber 5,32:1. Fuer eine reine Grafik
   genuegen zwar 3:1, aber diese Marke ist die einzige Anzeige, wo
   man gerade ist, und sie steht auf der dunkelsten Flaeche der
   Website. Nachgerechnet am 01.08.2026. */
#mobnav .mobnav-nav a[aria-current] {
  color: var(--bone);
  box-shadow: inset 2px 0 0 var(--amber);
  background: var(--ink-soft);
}

.mobnav-fuss {
  margin-block-start: auto;
  padding-block-start: 1.8rem;
}
.mobnav-fuss .btn { inline-size: 100%; justify-content: center; font-size: var(--t-0); }

@media (prefers-reduced-motion: reduce) {
  #mobnav, #mobnav::backdrop { transition: none; }
}

/* ═══ Hero, die Breitenachse IST die Aussage ══════════════════
   Drei Zeilen, die von der Dehnung in die Kontraktion laufen:
   122% → 92% → 66%. Statisch gesetzt, nicht animiert, damit es
   ohne JS, ohne Buildstep und bei reduzierter Bewegung gleich
   aussieht. Vorbild: diepraxis.io (hellofarm), wo die variable
   Achse das einzige Gestaltungsmittel der Marke ist.             */

.hero { padding-block: clamp(3.5rem, 9vw, 7rem); position: relative; isolation: isolate; }

/* ═══ VERKÜRZT AM 31.07.2026 ═══
   Auf der Startseite lagen Handlungsknopf und Google-Siegel genau
   auf der Faltlinie: bei 1280 x 860 wurde das Siegel unten
   angeschnitten, auf einem Laptop mit 768 Pixeln Höhe fiel es ganz
   heraus. Beides ist der Grund, warum die Seite überhaupt da ist,
   und beides stand unter der Kante.

   Nur der BILDHERO wird kürzer, nicht `.hero` allgemein. Die 34
   typografischen Auftakte über `.auftakt` tragen kein Siegel, und
   dort ist die Höhe die Aussage: die Achse braucht Luft, sonst
   wird aus dem Auftakt eine Überschrift.

   Es ist bewusst nur Polsterung und Abstand, nicht die
   Schriftgröße der Achse. Die Achse ist die Marke; sie kleiner zu
   setzen, um ein Siegel über die Kante zu ziehen, wäre der falsche
   Tausch.                                                        */
.hero:not(.auftakt) { padding-block: clamp(2rem, 5vw, 3.6rem); }
.hero:not(.auftakt) .hero-sub { margin-block-start: 1.2rem; }
.hero:not(.auftakt) .hero-act { margin-block-start: 1.8rem; }

/* ═══ AUFTAKT MIT STANDORTWAHL, Startseite, 31.07.2026 ══════════
   Der Auftakt der Startseite trägt seit der Zusammenlegung die
   Kachelreihe in derselben Sektion. Zwei Dinge folgen daraus.

   ERSTENS steht das Google-Siegel jetzt IN der Handlungszeile,
   nicht mehr absolut in der Ecke eines Fotos. Es gibt keine Ecke
   mehr, und ein absolut gesetztes Element über hellem Grund
   schwebte ohne Bezug. `margin-inline-start: auto` schiebt es in
   der Flex-Zeile nach rechts, neben Knopf und Rufnummer; wird es
   eng, bricht es von selbst um.

   ZWEITENS braucht die Kachelreihe Luft nach oben. Sie ist ein
   zweites Kind derselben Sektion, nicht ein eigener Abschnitt mit
   eigenem data-density.                                          */
.hero.auftakt .g-bewertung {
  position: static; margin: 0 0 0 auto; max-inline-size: 27rem;
}
/* Unter 60rem gilt weiter, was die Regel für den Bildhero schon
   sagte: das Siegel geht in den Fluss und nimmt die ganze
   Spaltenbreite. Die Zeile ist nötig, weil `.hero.auftakt
   .g-bewertung` spezifischer ist als das `.hero .g-bewertung` in
   jener Media-Query und sie sonst aushebelt. Ohne sie hing das
   Siegel bei 900 Pixeln als schmaler Block rechts in der Luft. */
@media (max-width: 60rem) {
  .hero.auftakt .g-bewertung { margin-inline-start: 0; max-inline-size: none; }
}
.hero.auftakt .orte { margin-block-start: clamp(2rem, 5vw, 3.2rem); }

/* Foto hinter dem Hero.

   KORRIGIERT AM 31.07.2026. Vorher lag eine 78-Prozent-Tönung über
   das GANZE Bild, dazu 45 Prozent Entsättigung. Die Rechnung ging
   für die Schrift auf, aber sie ging am Zweck vorbei: seit der
   Bildhero nur noch dort steht, wo der Raum die Aussage ist, darf
   er den Raum nicht unsichtbar machen. Vom blauen Trainingsraum mit
   Gegenlicht blieb ein grauer Schleier, bei 380 Pixeln gar nichts.

   Der Schleier bleibt flächig über dem ganzen Bild, nur schwächer:
   68 statt 78 Prozent, Entsättigung 20 statt 45 Prozent. Eine
   deckende Fläche NUR hinter der Textspalte war der erste Versuch
   und ist verworfen: sie las sich als schwebender Kasten mit
   sichtbaren Kanten, und Kästen sind in diesem System genau das,
   was durch Linien ersetzt wurde.

   Der eigentliche Fehler saß ohnehin woanders. Gerechnet war nur
   --paper auf dem Schleier. Die Statuszeile nimmt aber --fg-mute,
   auf dunklem Grund #9AA3A5, und kam damit über einer hellen
   Bildstelle auf rund 3,8:1. Für 13-Pixel-Versalien sind 4,5:1
   nötig. Sie steht deshalb unten auf --bone.

   Rechnung für 68 Prozent über der hellsten denkbaren Bildstelle:
   Untergrund etwa #4E5052, darauf --paper 7,1:1 und --bone 5,6:1.

   Das Bild trägt class="full", damit sein umgebender Block die volle
   Rasterbreite ist und nicht die Inhaltsspalte. */
.hero-bild { position: absolute; inset: 0; z-index: -1; overflow: hidden; }
.hero-bild img {
  inline-size: 100%; block-size: 100%; object-fit: cover;
  object-position: 50% 50%;
  filter: grayscale(.2) contrast(1.04);
}
/* MITTIG GESCHNITTEN STIMMT FUER RAEUME, nicht fuer Menschen. Der
   Hero ist deutlich breiter als hoch, das Foto nicht: object-fit
   cover wirft oben und unten je rund ein Sechstel weg. Bei einem
   Behandlungsraum faellt das auf Decke und Boden, bei einem
   Gruppenbild auf die oberste Kopfreihe.

   Gesteuert ueber ein Attribut, wie data-tone und data-size auch,
   und nicht ueber eine Seitenklasse: der Wert gehoert zum Bild,
   nicht zur Seite. 22 Prozent statt 50 sind an diesem Motiv
   ausgemessen, es bleibt Luft ueber dem hoechsten Kopf.        */
.hero-bild[data-schnitt="oben"] img { object-position: 50% 22%; }
.hero-bild::after {
  content: ""; position: absolute; inset: 0;
  background: color-mix(in srgb, var(--ink) 68%, transparent);
}

/* Über einem Foto reicht --fg-mute nicht, siehe Rechnung oben.
   Gilt nur im Bildhero, nicht im typografischen Auftakt. */
.hero:has(.hero-bild) .status { color: var(--bone); }
/* ─── Seitenauftakt ohne Bild ──────────────────────────────────
   Der Bildhero bleibt der Startseite und den drei Standortseiten
   vorbehalten. Dort IST der Raum die Aussage.

   Auf den uebrigen 34 Seiten war er Gewohnheit statt Entscheidung:
   34 mal dieselbe dunkle Flaeche, 34 mal ein grosses Bild geladen,
   und der eigentliche Inhalt begann erst unter der Falz. Ein
   Ratgeberartikel und eine Leistungsseite oeffnen jetzt so, wie
   Text oeffnet, naemlich mit Text.

   .auftakt sitzt AUF .hero, statt es zu ersetzen. Damit gelten die
   Regeln fuer .hero .status und .hero .micro unveraendert weiter,
   und hier steht nur, was der helle Grund wirklich aendert. Das
   sind drei Farben, die fuer dunklen Grund gesetzt waren und auf
   --paper zwischen unlesbar und blass lägen.

   Abgeschlossen wird mit einer Haarlinie, nicht mit einer
   Farbkante: getrennt wird in diesem System mit Linien.         */
.auftakt {
  padding-block: clamp(2.4rem, 5.5vw, 4rem) clamp(1.6rem, 3.5vw, 2.6rem);
  border-block-end: 1px solid var(--rule);
}

/* Der Auftakt steht auf derselben Achse wie die Abschnittsköpfe
   darunter. Ohne diese Regel landet sein Inhalt in der Spur
   `content`, während fast jeder folgende Abschnitt `.wide` trägt:
   16 Pixel Versatz zwischen dem Seitentitel und allem darunter.
   Das liest sich als Schluderei, nicht als Absicht.

   Der Fließtext in .prose bleibt bewusst schmaler. Das ist eine
   Lesebreite, kein Raster, und als solche erkennbar. */
.auftakt > * { grid-column: wide; }
.auftakt .hero-sub,
.auftakt .artikel-meta,
.auftakt .axis-3 { color: var(--fg-mute); }
.auftakt .hero-act { margin-block-start: clamp(1.6rem, 3.5vw, 2.2rem); }

/* Der erste Abschnitt nach dem Auftakt zieht seinen oberen Abstand
   zurueck. Sonst stehen dort die bis zu 2,6rem des Auftakts UND die
   bis zu 6,5rem der Sektion untereinander, also fast neun Zentimeter
   Leere direkt unter einer Haarlinie. Das liest sich als Versehen.
   Beim dunklen Hero fiel es nicht auf, weil die Farbkante den Bruch
   schon gesetzt hat.                                              */
.auftakt + [data-density] { padding-block-start: clamp(2.2rem, 5vw, 3.5rem); }

/* ─── Auftakt MIT Bildgrund ────────────────────────────────────
   Seit dem 02.08.2026 gibt es beides zusammen: der Auftakt der
   Kontaktseite steht auf der Lattenwand. .auftakt war fuer hellen
   Grund geschrieben, drei Dinge muessen deshalb zurueckgenommen
   werden. Alles haengt an :has(.hero-bild), damit der Auftakt ohne
   Bild unveraendert bleibt.

   1. DIE SPUR DES BILDES. Das ist die Regel, ohne die es still
      falsch aussieht: `.auftakt > *` setzt jedes Kind auf die Spur
      `wide` und ist dabei spezifischer als das `full` am Bild. Fuer
      ein absolut gesetztes Element ist die Rasterspur aber nicht
      Dekoration, sondern sein umgebender Block — das Bild wuerde
      also brav in der Inhaltsspalte kleben statt randlos zu laufen,
      und zwar ohne Fehlermeldung. */
.auftakt > .hero-bild { grid-column: full; }

/* 2. DIE ABSCHLIESSENDE HAARLINIE faellt weg. Sie trennt hellen
      Grund von hellem Grund; zwischen dunklem Hero und hellem
      Abschnitt trennt bereits die Farbkante. Zwei Trennungen
      uebereinander liest man als Rahmen. */
.auftakt:has(.hero-bild) { border-block-end: 0; }

/* 3. DIE DREI GEDAEMPFTEN FARBEN. --fg-mute ist auf dunklem Grund
      #9AA3A5 und kommt ueber dem 68-Prozent-Schleier des Bildes auf
      rund 3.2:1 — genug fuer Grosstext, zu wenig fuer den Vorspann
      (SC 1.4.3 verlangt 4.5:1). --bone haelt dort 5.6:1, gerechnet
      im Kommentar bei .hero-bild. Dieselbe Entscheidung wie bei
      .hero:has(.hero-bild) .status, nur fuer den Auftakt. */
.auftakt:has(.hero-bild) .hero-sub,
.auftakt:has(.hero-bild) .artikel-meta,
.auftakt:has(.hero-bild) .axis-3 { color: var(--bone); }

/* ═══ FREIGESTELLTE FIGUR NEBEN DEM AUFTAKT, 01.08.2026 ═════════
   Bisher genau eine Verwendung: Chiara auf der Kontaktseite.

   Das Bild hat einen Alphakanal und steht ohne Rahmen, ohne Kasten
   und ohne Schatten auf dem Papier. Genau deshalb braucht es hier
   auch keine Bildunterschrift: es ist kein Motiv, das benannt
   werden muss, sondern die Person, die antwortet.

   align-items: end setzt die Figur auf dieselbe Grundlinie wie den
   Textblock, damit sie auf der Haarlinie des Auftakts steht statt
   darueber zu schweben.

   Einspaltig unter 60rem, und dort deutlich kleiner: auf dem
   Telefon soll das Portrait den Handlungsknopf nicht unter die
   Faltlinie schieben.                                            */
/* DIE FIGUR SITZT IN DER ECKE, und das ist kein Geschmack: der
   Freisteller hat zwei SCHNITTKANTEN, die die Vorlage schon hatte.
   Rechts endet der Arm an der Bildkante, unten hoert die Figur in
   Huefthoehe auf. Mitten auf der Flaeche liest sich beides als
   Fehler. Buendig in der unteren rechten Ecke liest sich dasselbe
   als angeschnitten: unten steht sie auf der Haarlinie des
   Auftakts, rechts laeuft sie aus dem Bildschirm.

   Deshalb unten KEIN Abstand und rechts KEIN Abstand. Wer hier
   Polsterung ergaenzt, holt beide Kanten zurueck.               */
/* ═══ FLACHER ALS DIE UEBRIGEN AUFTAKTE, 01.08.2026 ════════════
   Der Kontakt-Auftakt war der hoechste der Website: dreizeilige
   Achse auf --t-5, darunter vier Zeilen Fliesstext, und darum
   die volle Polsterung. Auf 1440 Pixern standen so rund 750
   Pixel, bevor der erste Satz Inhalt kam, und das Formular, um
   das es auf dieser Seite geht, begann unter der Falz.

   Gekuerzt wird an vier Stellen zugleich, weil eine allein zu
   wenig traegt: Polsterung, Abstand ueber der Achse, ueber dem
   Fliesstext und ueber den Knoepfen. Die Achse selbst geht im
   Markup eine Stufe zurueck (data-size="m"), also ueber das
   vorgesehene Attribut und nicht ueber eine Sonderregel hier.

   ANGEHAENGT AN :has(.auftakt-figur), nicht an eine neue Klasse:
   die Figur gibt es genau einmal, auf der Kontaktseite. Die
   uebrigen 33 Auftakte bleiben unberuehrt. Kommt die Figur
   irgendwann auf eine zweite Seite, gilt dort dasselbe, und das
   ist beabsichtigt: der Auftakt mit Portrait ist die kompakte
   Variante.                                                    */
.auftakt:has(.auftakt-figur) {
  padding-block: clamp(1.8rem, 3.5vw, 2.6rem) clamp(1.2rem, 2.5vw, 1.8rem);
}
.auftakt:has(.auftakt-figur) .axis     { margin-block-start: 1rem; }
.auftakt:has(.auftakt-figur) .hero-sub { margin-block-start: 1.2rem; }
.auftakt:has(.auftakt-figur) .hero-act { margin-block-start: clamp(1.2rem, 2.5vw, 1.6rem); }

.auftakt-figur {
  display: grid; align-items: end;
  gap: clamp(1.2rem, 4vw, 2.4rem);
}
.auftakt-figur .figur {
  display: block; block-size: auto;
  inline-size: min(60%, 13rem);
  justify-self: end;
  /* Bis an die Bildschirmkante: die Spur `wide` beginnt --gap vom
     Rand, so viel wird zurueckgenommen. Genau so viel, nicht mehr,
     sonst entsteht waagerechter Ueberlauf. */
  margin-inline-end: calc(var(--gap) * -1);
  /* Auf die Haarlinie: die untere Polsterung des Auftakts wird
     aufgehoben, damit die Figur darauf steht. DER WERT MUSS DER
     UNTEREN POLSTERUNG OBEN ENTSPRECHEN, sonst steht die Figur
     daneben statt darauf. Seit dem 01.08.2026 ist das die
     gekuerzte Polsterung des Auftakts mit Figur. */
  margin-block-end: calc(clamp(1.2rem, 2.5vw, 1.8rem) * -1);
  filter: saturate(.92) contrast(1.04);
}
/* ═══ AUF SCHMALEN SCHIRMEN GAR NICHT, 01.08.2026 ══════════════
   Auf Anweisung. Unter 60rem liegt die Figur IM Raster, nicht
   absolut: sie bekommt dort eine eigene Rasterzeile unter den
   Knoepfen und schiebt damit alles nach unten, was danach kommt.
   Auf einem Telefon war das ein rund 350 Pixel hoher Block, und
   die Seite handelt vom Formular darunter.

   60rem UND NICHT 48rem, obwohl „mobil" naeher bei 48 liegt: die
   Grenze trennt nicht Telefon von Tablet, sondern die
   Rasterfassung von der absoluten. Ab 60rem haengt die Figur in
   der unteren rechten Ecke und kostet keine Hoehe, darunter kostet
   sie immer eine ganze Zeile. Genau das soll weg, also gilt genau
   diese Grenze. Wer die Figur auf Tablets zurueckhaben will, setzt
   hier 48rem ein und nimmt die zusaetzliche Zeile in Kauf.

   display: none, nicht visibility oder Groesse 0: nur so faellt
   auch die Rasterzeile weg. Die 43 KB der Datei werden dadurch auf
   dem Telefon aller Wahrscheinlichkeit nach nicht mehr geladen,
   siehe dazu loading="lazy" im Markup der Kontaktseite.       ═══ */
@media (max-width: 59.999rem) {
  .auftakt-figur .figur { display: none; }
}

@media (min-width: 60rem) {
  /* Feste zweite Spur statt minmax: die Figur liegt gleich absolut
     und traegt dann nichts mehr zur Spaltenbreite bei. Ohne festen
     Wert fiele die Spur auf 0 zusammen und der Text liefe unter
     die Figur. */
  .auftakt-figur { grid-template-columns: minmax(0, 1fr) 15rem; }
  /* MIT DER HOEHE DES AUFTAKTS ZURUECKGENOMMEN, 01.08.2026. Die
     Figur haengt an der Unterkante und ist 1,72 mal so hoch wie
     breit. Bei 23rem waren das rund 630 Pixel, und der gekuerzte
     Auftakt ist nur noch etwa 560 hoch: sie waere oben aus dem
     Abschnitt heraus in die Kopfzeile gewachsen. Bei 18rem sind
     es rund 500, sie bleibt damit im Abschnitt.
     Wer den Auftakt weiter kuerzt, muss hier mitgehen. */
  .auftakt-figur .figur {
    position: absolute;
    inset-block-end: 0; inset-inline-end: 0;
    inline-size: clamp(15rem, 20vw, 18rem);
    margin: 0;
  }
}

/* Ohne Foto bleibt der Hero wie bisher eine ruhige dunkle Fläche. */

.axis {
  display: grid;
  margin-block: 1.6rem 0;
  line-height: .96;
}
/* Leistungsnamen sind lang („Krankengymnastik am Gerät"). Bei
   --t-5 und 122% reißt das die Inhaltsspalte auf, deshalb eine
   Stufe kleiner, gesteuert wie der Rest des Systems über ein
   data-Attribut, nicht über eine zweite Klasse. */
.axis[data-size="m"] { font-size: var(--t-4); }
.axis[data-size="s"] { font-size: var(--t-3); }

.axis span { display: block; transform-origin: left center; }
.axis-1 { font-stretch: var(--w-wide); }
.axis-2 { font-stretch: var(--w-ui); }
.axis-3 { font-stretch: var(--w-narrow); color: var(--bone); }

/* Zweizeilige Achse: ohne die Mittelstufe springt die Überschrift von
   122% auf 66%, also fast den ganzen Achsenbereich in einem Schritt,
   und wechselt dabei auch noch die Farbe. Zwei Zeilen sehen dann nach
   zwei Schriften aus statt nach einer Verjüngung. Die Breite darf den
   Sprung machen, die Farbe nicht.
   Einzeilig ist die Achse ohnehin sinnlos, dort steht ein blankes h1. */
.axis:not(:has(.axis-2)) .axis-3 { color: inherit; }

.hero-sub {
  font-size: var(--t-1); line-height: 1.5; color: var(--bone);
  max-inline-size: 44ch; margin-block-start: 1.8rem;
}
.hero-act {
  display: flex; flex-wrap: wrap; align-items: center; gap: 1.4rem clamp(2rem, 5vw, 3rem);
  margin-block-start: 2.6rem;
}

/* ─── Bewertung im Hero ────────────────────────────────────────
   Dezent, aber sichtbar: die Sterne laufen in --amber auf dunklem
   Grund (5,32:1), der Wert traegt die Ueberschriftenbreite, der
   Zusatz das Kleinstlabel. Kein Kasten, kein Schatten, keine
   Auszeichnung ausser Typografie und Farbe.

   Die Sterne sind Inline-SVG: fuenf Umrisse in currentColor, darueber
   dieselben fuenf gefuellt und auf ein Rechteck beschnitten. So zeigt
   4,9 vier volle Sterne plus 90 Prozent des fuenften statt einer
   gerundeten Luege.

   Hier steht nur die Gestaltung. Der Wert selbst und die Breite des
   Schnittrechtecks stehen zusammen im Markup, samt Rechenweg, damit
   das Aendern eine Datei betrifft und nicht zwei.                   */
/* DECKEND, NICHT TRANSPARENT. Ausdrueckliche Vorgabe vom 31.07.2026.
   Ueber dem Hero-Foto stand die Bewertung vorher blank auf dunklem
   Grund und ging im Motiv unter, seit der Schleier von 78 auf 68
   Prozent zurueckgenommen ist erst recht. Eine helle Flaeche ist
   hier die begruendete Ausnahme von "getrennt wird mit Linien":
   ein Guetesiegel, das mit dem Untergrund verschwimmt, ist keins.

   Haarlinie statt Schatten, kein Radius. Die Sterne bleiben auf
   --amber, obwohl das auf --paper nur rund 2,6:1 schafft: sie
   tragen keine Information mehr, seit der Wert als "4,9 / 5" im
   Text steht. Wer sie nicht erkennt, liest die Zahl.            */
.bewertung {
  display: inline-flex; align-items: center; gap: .7rem;
  margin-block-start: clamp(1.6rem, 4vw, 2.4rem);
  padding: .55rem .9rem;
  background: var(--paper); color: var(--fg);
  border: 1px solid var(--rule);
  transition: background .2s ease;
}
.bewertung:hover { background: var(--paper-2); }
.sterne { display: inline-flex; flex: none; color: var(--stern); }
.sterne svg { inline-size: 6.2rem; block-size: 1.2rem; }
.bewertung-wert {
  font-family: var(--sans); font-weight: 700; font-stretch: var(--w-head);
  font-size: var(--t-1); letter-spacing: -.015em; color: var(--fg);
}
.bewertung-txt { color: var(--fg-mute); }
/* ═══ Standortwahl, Ziehharmonika aus hohen Panels ════════════

   ÜBERSETZT AUS EINER v0-VORLAGE
   (interactive-portfolio-gallery-with-hover-video-cards).
   Übernommen wurde, was v0 entscheiden darf, Struktur, Anordnung,
   Interaktion: die Reihe hoher Panels, die Dehnung des aktiven auf
   Kosten der übrigen, die Entsättigung bis zur Aktivierung, der
   Textblock, der von unten einfährt, und die lange, ruhige Kurve.

   Verworfen wurde, was das Designsystem entscheidet: die
   Glasmorphismus-Karte, der 2,5rem-Radius, die Schlagschatten, der
   Custom-Cursor samt cursor:none, die Monospace-Typo und die fünf
   eingebundenen Fremdvideos.

   Der eigentliche Grund für diese Vorlage: das Dehnen und
   Zusammenziehen der Panels IST die Breitenachse. Der Ortsname
   fährt deshalb mit, von --w-narrow zusammengezogen auf --w-wide
   gedehnt. Interaktion und Typografie sagen dasselbe.

   Ohne JS gebaut: :hover und :focus-within reichen. v0 brauchte
   dafür React-State.                                              */

/* ═══ KACHELBEHANDLUNG DER v0-VORLAGE, 31.07.2026 ═══════════════
   Auf Anweisung uebernommen. Vorlage ist
   werkzeuge/v0-galerie/index.html, der Nachbau des v0-Pakets
   "interactive-portfolio-gallery-with-hover-video-cards".

   DREI PUNKTE DER VERBOTSLISTE SIND HIER AUSGESETZT, und zwar nur
   hier, auf ausdruecklichen Wunsch:

     · runde Ecken jenseits von --radius-btn (2.5rem statt 5px)
     · Glassmorphism (backdrop-filter auf der Texttafel)
     · Trennung durch Abstand statt durch Haarlinien

   Der Rest des Stylesheets bleibt davon unberuehrt. Wer die
   Ausnahme ausweitet, hebt die Regel auf; dann lieber die Regel
   aendern statt sie zu unterlaufen.

   WAS AUS UNSERER FASSUNG BLEIBT, und warum:

   Name und Oeffnungsstatus stehen WEITER IMMER da. Die Vorlage
   versteckt saemtliche Beschriftung bis zum Hover. Bei einer
   Portfoliogalerie geht das, bei einer Standortwahl nicht: wer
   wissen will, wo die Praxis ist, darf das nicht erst auf Zuruf
   erfahren, und ohne Zeigegeraet gar nicht. Es faehrt deshalb nur
   das Detail ein, nicht der Name.                                */
/* ═══ DIE RANDLOSE KACHELREIHE ══════════════════════════════════
   Sie war am 31.07.2026 das Erste auf der Startseite; seit dem
   01.08.2026 steht der Willkommensabschnitt darüber.

   Wenig Polsterung oben, mehr unten. Der Abschnitt darüber bringt
   seine eigene untere Polsterung mit, zusammen ergibt das den
   normalen Abstand; eine zweite volle Polsterung oben wäre die
   doppelte Lücke. Unten dagegen braucht es den vollen Abstand zum
   nächsten Abschnitt, sonst klebt die Leistungsüberschrift an den
   Kacheln.

   `.orte` trägt im Markup zusätzlich `full` und liegt damit in der
   Spur `full` des Rasters, also von Bildschirmkante zu
   Bildschirmkante. Es ist der einzige randlose Baustein neben
   `.band` und `.hochband`.                                        */
/* ╔══════════════════════════════════════════════════════════════╗
   ║  DIESER GANZE BLOCK IST SEIT DEM 01.08.2026 OHNE VERWENDUNG. ║
   ╚══════════════════════════════════════════════════════════════╝
   Die Standortwahl stand nur auf der Startseite, und die ist an
   diesem Tag durch die Praxisseite Bergkamen ersetzt worden. Kein
   Markup traegt mehr .orte, .ort oder eines der .ort-*.

   ER BLEIBT TROTZDEM STEHEN, bewusst, aus zwei Gruenden:

   1. Zwei Regeln sind GETEILT und wuerden beim Herausschneiden
      etwas mitnehmen, das weiterlebt:
        .ort-go, .door-go { … }
        .ort:hover .ort-go span, .door:hover .door-go span { … }
      .door-go traegt die Regalbretter (.doors) auf sechs Seiten.
      Dazu nennt der Token-Umschalter oben `.ort` in einer Liste
      mit [data-tone="ink"], .foot und #mobnav.
   2. Die Komponente ist an einem Tag mehrfach umgebaut worden und
      kann jederzeit zurueckgeholt werden. Das Markup dafuer steht
      in der Historie, Commit 16a01f9 und frueher.

   Wer sie endgueltig entfernt: die beiden geteilten Regeln vorher
   auf .door-go allein umschreiben und `.ort` aus dem
   Token-Umschalter nehmen. Etwa 250 Zeilen, dazu die zwei Bloecke
   in den Media-Queries fuer 60rem und prefers-reduced-motion.   */
.orte-buehne { padding-block: clamp(.9rem, 2vw, 1.6rem) clamp(2.5rem, 6vw, 4.5rem); }
/* Derselbe Rueckzug wie bei `.auftakt + [data-density]`: sonst
   stehen die bis zu 4,5rem der Buehne UND die bis zu 4rem des
   folgenden Abschnitts untereinander, also ueber acht Zentimeter
   Leere zwischen den Kacheln und der Leistungsueberschrift. */
.orte-buehne + [data-density] { padding-block-start: clamp(1.4rem, 3vw, 2.2rem); }

.orte {
  display: flex; align-items: stretch;
  gap: clamp(.7rem, 1.6vw, 1rem);
}

.ort {
  position: relative;
  overflow: hidden;
  border-radius: 2.5rem;
  /* ═══ DREI KACHELN, GLEICH BREIT UND UNBEWEGT ═══════════════
     Am 31.07.2026 zurueckgenommen: die Dehnung beim Darueberfahren
     ist raus, ebenso die gedaempfte Deckkraft im Ruhezustand und
     der weisse Schein. Damit ist von der Kachelbehandlung der
     Vorlage die FORM geblieben (runde Ecken, Glastafel, randlos)
     und die BEWEGUNG entfallen.

     `flex: 1 1 0%` statt `.85` gegen `1.8`: drei gleich breite
     Kacheln, die stehen bleiben. Es gibt keinen Uebergang mehr,
     der laufen koennte, deshalb auch keine transition.

     Was beim Darueberfahren bleibt, ist das Aufklappen des
     Details, also Anschrift, Zeiten, Rufnummer und der Link. Das
     ist keine Verzierung, sondern der Zweck der Kachel. */
  flex: 1 1 0%; min-inline-size: 11rem;
  /* min-block-size, NICHT block-size: die Kachel muss wachsen
     duerfen, wenn der Text laenger ist als das Bild hoch.

     Die Vorlage setzt hier feste 600px. Fest geht hier nicht: sie
     ist der Anfang der Startseite, und auf einem flachen Fenster
     waeren 600px die ganze Sicht ohne einen Hinweis, dass es
     weitergeht. Der obere Wert liegt deshalb bei 46rem, also 736px,
     deutlich ueber den 600 der Vorlage; darunter regelt 82vh, und
     der Anschnitt des naechsten Abschnitts bleibt sichtbar. */
  min-block-size: clamp(30rem, 82vh, 46rem);
  display: flex; flex-direction: column; justify-content: flex-end;
  background: var(--slate);
  color: var(--paper);
}

/* Ohne Foto faellt die Mindesthoehe ganz weg. Das Muster gibt es im
   Projekt schon einmal (.axis:not(:has(.axis-2))): die Regel liest
   den Inhalt, statt eine zweite Klasse zu verlangen, die jemand zu
   setzen vergisst. Genau das war hier passiert. */
.ort:not(:has(.ort-media)) { min-block-size: 0; }

/* ═══ DIE DEHNUNG IST RAUS, 31.07.2026 ═══════════════════════════
   Hier standen zwei Regeln, die beim Darueberfahren die aktive
   Kachel dehnten und die beiden anderen zusammenzogen. Sie sind
   an einem Tag dreimal nachjustiert worden, .9/1.5, dann
   .95/1.22, dann .85/1.8, und dann ersatzlos entfallen.

   Die Kacheln sind jetzt gleich breit und bleiben stehen. Was
   beim Darueberfahren passiert, ist das Aufklappen des Details
   weiter unten: Anschrift, Zeiten, Rufnummer, Link. Das ist der
   Zweck der Kachel, keine Verzierung.

   Wer die Dehnung zurueckholen will, braucht drei Zeilen:
   .orte:hover .ort, .orte:focus-within .ort { flex-grow: .85 }
   .orte .ort:hover, .orte .ort:focus-within { flex-grow: 1.8 }
   und eine transition auf flex in .ort.                        */

/* ═══ FARBE, UND ZWAR SOFORT, 01.08.2026 ═══════════════════════
   Hier stand grayscale(1) brightness(.75) im Ruhezustand, das beim
   Darueberfahren auf volle Farbe ging. Beides ist raus.

   Die Fotos tragen jetzt dieselbe Gradation wie JEDES andere Bild
   der Website, saturate(.92) contrast(1.04): .band, .galerie und
   .hochband halten es genauso. Die Standortwahl war die einzige
   Stelle mit eigener Behandlung, und das war eine Anleihe aus der
   Vorlage, nicht aus diesem System.

   Der Kontrast der Glastafel haengt jetzt allein an ihren 55
   Prozent Schwarz, nicht mehr zusaetzlich an brightness(.75), das
   das Foto vorher abdunkelte. Die 55 Prozent sind genau dafuer
   gerechnet, siehe die Begruendung bei .ort-in: sie tragen auch
   ueber einem hellen Foto in voller Farbe.

   WAS DAMIT ZURUECKKOMMT, bewusst in Kauf genommen: die drei
   Raeume haben verschiedenen Weissabgleich. Bergkamen ist warm
   beleuchtet, der Empfang neutral, der Geraeteraum blau
   gestrichen. Genau das war am 31.07.2026 als „nicht identisch"
   beanstandet und mit Entsaettigung beantwortet worden. Farbe war
   danach ausdruecklich gewuenscht, also ist der Farbstich jetzt
   sichtbar. Verlaeufe gibt es hier weiterhin keine, im ganzen
   Stylesheet steht kein einziger `gradient`.

   Wer die Reihe wieder vereinheitlichen will, ohne auf Farbe zu
   verzichten, dreht an der Saettigung dieser einen Zeile, etwa
   saturate(.55). Das haelt die Farbe und nimmt den Stich.       */
.ort-media { position: absolute; inset: 0; }
.ort-media img {
  inline-size: 100%; block-size: 100%; object-fit: cover;
  object-position: 50% 50%;
  filter: saturate(.92) contrast(1.04);
}

/* Deckender Textblock wie die Bildunterschrift im Band. Name und
   Öffnungsstatus stehen IMMER, anders als in der Vorlage, die
   sämtliche Beschriftung bis zum Hover versteckt. Bei einer
   Portfoliogalerie geht das; bei einer Standortwahl darf die
   Adresse nicht erst auf Zuruf erscheinen. */
/* ═══ GLASTAFEL AUS DER VORLAGE ═════════════════════════════════
   backdrop-blur-xl bg-black/20 rounded-2xl p-6 border-white/10.

   EINE ZAHL IST GEÄNDERT, und das ist keine Geschmacksfrage.
   Die Vorlage nimmt `bg-black/20`. Weiße Schrift auf 20 Prozent
   Schwarz über einem hellen Foto ergibt rechnerisch etwa 1,6:1.
   Gefordert sind 4,5:1. Die Vorlage kommt damit durch, weil ihre
   fünf Bilder durchweg dunkel sind; unsere Empfangsaufnahme ist
   es nicht, und beim Darüberfahren geht sie auf volle Farbe.

   55 Prozent Schwarz ergibt im ungünstigsten Fall, also über
   reinem Weiß, rund 4,8:1. Damit trägt die Tafel über jedem Foto,
   auch über einem, das erst später dazukommt. Der Blur bleibt,
   er verdunkelt nichts, er ist der Glaseffekt.

   Aus demselben Grund wird --fg-mute innerhalb der Tafel auf
   --bone gehoben: das gedämpfte Grau war für den vorher
   deckenden --ink-Block gerechnet.                              */
.ort-in {
  position: relative; z-index: 1;
  margin: clamp(.9rem, 2.2vw, 1.6rem);
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  background: rgb(0 0 0 / .55);
  border: 1px solid rgb(255 255 255 / .12);
  border-radius: 1rem;
  padding: clamp(1.1rem, 2.5vw, 1.5rem);
  display: grid; gap: .7rem;
  --fg-mute: var(--bone);
}
/* ═══ GEÄNDERT AM 31.07.2026 ═══
   Der Ortsname fuhr beim Darüberfahren von 66 auf 108 Prozent
   Schriftbreite. Das war der auffälligste Teil der Bewegung: nicht
   eine Fläche, die sich ändert, sondern Buchstaben, die vor den
   Augen die Form wechseln, und zwar genau die, die man gerade
   liest. Auf einer Reihe von drei Kacheln passiert das beim
   Überqueren dreimal hintereinander.

   Die Breitenachse bleibt das Konzept dieser Seite, sie ist hier
   nur nicht mehr animiert: der Name steht fest auf --w-narrow,
   der Zusatz darunter auf --w-label. Statisch gesetzt ist die
   Achse ohnehin überall sonst, siehe .axis im Hero.            */
.ort-name {
  font-family: var(--sans); font-weight: 600;
  font-stretch: var(--w-narrow);
  font-size: var(--t-3); line-height: 1;
  letter-spacing: -.025em;
}

/* Zwei der drei Praxen liegen in Dortmund. Der Stadtteil steht
   deshalb als eigene Zeile unter dem Ortsnamen, nicht als
   Klammerzusatz dahinter, der die Achse bräche. */
.ort-zusatz {
  display: block;
  font-size: var(--t--1); font-weight: 600;
  font-stretch: var(--w-label);
  text-transform: uppercase; letter-spacing: .16em;
  color: var(--bone);
  margin-block-start: .5rem;
}

/* ═══ ZURÜCKGEBAUT AM 31.07.2026 ═══
   Hier stand ein bernsteinfarbener Statuspunkt mit einem
   box-shadow-Ring als Halo. Das war die Sonderbehandlung aus der
   Zeit, als das Klinikviertel weder Adresse noch Zeiten noch ein
   Foto hatte und „Demnächst" trug.

   Zwei Gründe für den Rückbau. Erstens hat die Kachel inzwischen
   Foto, Anschrift und einen echten Öffnungsstatus wie die anderen
   beiden, der Punkt meinte also nichts mehr, stach aber als
   einziger gelb heraus. Genau das ist beanstandet worden. Zweitens
   ist ein leuchtender Ring um ein Element Neon-Glow, und der steht
   auf der Verbotsliste des Designsystems.

   Dass die Öffnungszeiten dieses Standorts unbestätigt sind, bleibt
   richtig und wichtig. Es ist als offene Kundenfrage in README und
   CLAUDE.md festgehalten, wo es hingehört. Ein farbiger Punkt auf
   der Startseite hätte es ohnehin niemandem erklärt.

   Der Hintergrund bleibt, er liegt hinter dem Foto und fällt nur
   ins Gewicht, solange kein Bild geladen ist.                   */
.ort-neu { background: var(--ink-soft); }

/* Der Detailblock darf im Ruhezustand KEINEN Platz belegen. Mit
   opacity allein tat er das: der deckende Textblock war dreimal so
   hoch wie sein sichtbarer Inhalt und drückte das Foto auf einen
   Streifen zusammen. 0fr auf 1fr ist der einzige Weg, eine Höhe von
   0 auf auto zu animieren, und braucht dafür das innere div. */
.ort-detail {
  display: grid; grid-template-rows: 0fr;
  opacity: 0; translate: 0 .3rem;
  transition: grid-template-rows var(--dur-lang) var(--ease),
              opacity var(--dur-kurz) ease var(--dur-kurz),
              translate var(--dur-kurz) var(--ease) var(--dur-kurz);
}
.ort-detail > div { overflow: hidden; min-block-size: 0; display: grid; gap: .7rem; }
.ort:hover .ort-detail,
.ort:focus-within .ort-detail { grid-template-rows: 1fr; opacity: 1; translate: none; }

/* Hier stand am 01.08.2026 kurzzeitig `.ort-offen`, mit dem die
   mittlere Kachel dauerhaft aufgeklappt war. Auf Zuruf wieder
   entfernt, alle drei verhalten sich jetzt gleich.

   Falls wieder gebraucht, es ist eine Zeile:
   .ort-offen .ort-detail { grid-template-rows: 1fr; opacity: 1;
                            translate: none; }
   Kein !important noetig, sie steht nach der Grundregel und setzt
   dieselben drei Eigenschaften.

   BLEIBT ALS EINWAND STEHEN: das Detail der Kacheln zeigt sich nur
   bei :hover oder :focus-within. Wer die Seite zum ersten Mal
   sieht, kann nicht wissen, dass dort etwas aufklappt. Auf
   Geraeten ohne Zeigegeraet loest das die gestapelte Darstellung,
   dort steht alles offen. Auf dem Desktop bleibt es ein
   Entdeckungsproblem.                                            */

.ort-adr { font-size: var(--t-0); color: var(--fg-mute); line-height: 1.5; }
/* .ort-go und .door-go sind derselbe Baustein, nur in zwei Farben. */
.ort-go, .door-go {
  font-family: var(--sans); font-size: var(--t--1); font-weight: 600;
  font-stretch: var(--w-ui); letter-spacing: .06em; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: .45rem;
}
.ort-go span, .door-go span { transition: transform .2s ease; }
.ort:hover .ort-go span, .door:hover .door-go span { transform: translateX(4px); }
.ort-go { color: var(--bone); }

/* ─── Gestapelte Darstellung ───────────────────────────────────
   Gilt in ZWEI Fällen: unter 60rem, weil drei Panels nebeneinander
   dort zu schmal werden, und auf jedem Gerät ohne Zeigegerät,
   unabhängig von der Breite, weil es dort kein Hover gibt und die
   Adresse sonst unerreichbar wäre.

   Beide Fälle standen vorher getrennt im Stylesheet und sind
   auseinandergelaufen: der Hover-Fall trug noch die erste Fassung
   mit absolut liegendem Bild. Auf einem Tablet im Querformat, also
   ohne Zeigegerät und breiter als 60rem, deckte der Textblock das
   Foto deshalb wieder vollständig zu. Ein Fall, zwei Bedingungen,
   eine Regel.                                                     */
@media (max-width: 60rem), (hover: none) {
  .orte { flex-direction: column; gap: clamp(1rem, 3vw, 1.6rem); background: none; border-block: 0; }
  /* flex-basis 0 aus der Grundregel bedeutet in Spaltenrichtung
     Höhe null. Gestapelt richtet sich die Kachel nach ihrem Inhalt.
     Deckkraft zurück auf 1: die .9 der Grundregel gehört zum
     Ruhezustand einer Reihe, in der eine Kachel hervorgehoben
     werden kann. Gestapelt gibt es kein Hervorheben. */
  .ort  { flex: 0 0 auto; block-size: auto; min-block-size: 0; opacity: 1; box-shadow: none; }
  /* Die Ecken bleiben rund, das Glas nicht: gestapelt liegt das
     Foto ÜBER dem Text, nicht dahinter. Eine Tafel, die etwas
     durchscheinen lässt, hätte hier nichts zum Durchscheinen und
     wäre nur ein grauer Kasten mit Rand. */
  /* Seitlich --gap, nicht ein eigener Wert: die Kachel laeuft seit
     dem 31.07.2026 randlos, ihre Kante IST die Bildschirmkante.
     Mit --gap steht der Kacheltext auf derselben senkrechten Linie
     wie jeder andere Text der Seite. Mit einem eigenen Wert stand
     er bei 900 Pixeln rund 18 Pixel weiter links als die
     Ueberschrift des naechsten Abschnitts, und das liest sich als
     Schluderei. */
  .ort-in {
    margin: 0; backdrop-filter: none; -webkit-backdrop-filter: none;
    background: var(--ink); border: 0; border-radius: 0;
    padding: clamp(1.2rem, 3vw, 1.9rem) var(--gap);
    --fg-mute: #9AA3A5;
  }
  /* Das Bild wird zum Band über dem Text, statt dahinterzuliegen,
     wo der deckende Textblock es vollständig verdecken würde. */
  /* Seitenverhaeltnis statt fester Hoehe. Bei 800 Pixeln zeigte die
     feste Hoehe von einer 640 x 961 hohen Quelle noch rund 21
     Prozent, auf einem Touch-Tablet bei 1000 Pixeln sogar nur 15:
     der Trainingsraum wurde zur blauen Flaeche. 16:7 bleibt ein
     Band und kippt nicht in den Streifen. */
  /* Das Seitenverhältnis gehört ans BILD, nicht an den Behälter.
     Am Behälter war es wirkungslos: dessen Höhe steht auf auto und
     richtet sich nach dem Inhalt, das Bild darin stand auf
     block-size 100 Prozent und richtete sich nach dem Behälter.
     Zwei Angaben, die aufeinander zeigen, und der Browser löst das
     über die Eigenhöhe der Quelle auf. Ergebnis: ein 640 x 961
     hohes Foto lief bei 900 Pixeln über 1200 Pixel hoch, und die
     Kachel war eine Bildschirmseite, bevor der Ortsname kam.
     Am Bild ist die Angabe eindeutig. */
  .ort-media { position: static; block-size: auto; }
  /* Die Farbe steht seit dem 01.08.2026 schon in der Grundregel,
     hier war sie vorher nachgetragen, weil die Entsättigung sich
     nur bei :hover löste und den gibt es gestapelt nicht. */
  .ort-media img { block-size: auto; aspect-ratio: 16 / 7; }
  .ort-name   { font-stretch: var(--w-wide); }
  .ort-detail { grid-template-rows: 1fr; opacity: 1; translate: none; }
}

/* Öffnungsstatus. Ohne JS bleibt der Fallback im Markup stehen. */
.status {
  font-family: var(--sans); font-size: var(--t--1); font-weight: 600;
  font-stretch: var(--w-label); letter-spacing: .05em; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: .6rem;
  color: var(--fg-mute);
}
.status-dot {
  inline-size: 7px; block-size: 7px; border-radius: 50%;
  background: var(--fg-mute); flex: none;
}
.status[data-open="true"] { color: var(--fg); }
.status[data-open="true"] .status-dot {
  background: var(--go);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--go) 16%, transparent);
}

/* Positionen im Hero, vorher als style-Attribut im Markup. */
.hero .status { margin-block-start: 1.8rem; }
.hero .micro  { max-inline-size: 22rem; margin-block-start: 2rem; }

/* ═══ Micrographics, technische Information als Gestaltungsebene
   Behandlungsdaten klein, präzise, auf Haarlinien. Kostet nur
   Typo-Hierarchie und Linien, beides ist ohnehin da.              */

.micro { display: grid; gap: 0; margin-block-start: .4rem; max-inline-size: 30rem; }
.micro > div {
  display: flex; justify-content: space-between; gap: 1rem;
  padding-block: .5rem;
  border-block-start: 1px solid var(--rule);
}
.micro dt { color: var(--fg-mute); flex: none; }
.micro dd {
  font-family: var(--sans); font-size: var(--t--1);
  font-stretch: var(--w-ui); letter-spacing: .01em;
  font-variant-numeric: tabular-nums;
  text-align: end;
}

/* ═══ Leistungen als Index, kein zweites Karten-Raster ════════
   Die Kürzel links sind die aus dem Heilmittelkatalog. Wer ein
   Rezept in der Hand hält, sucht genau danach. Die Spalte rechts
   beantwortet die Frage, die eine Mehrstandort-Seite aufwirft:
   „gibt es das auch bei mir?"                                    */

.index { border-block-start: 1px solid var(--rule); }
.row {
  display: grid;
  grid-template-columns: var(--row-cols, 5.5rem minmax(0, 1fr) minmax(0, 1.15fr) 10rem 1.5rem);
  gap: clamp(.7rem, 2.5vw, 1.8rem);
  align-items: baseline;
  padding-block: clamp(1.3rem, 3vw, 1.9rem);
  border-block-end: 1px solid var(--rule);
  transition: background .2s ease;
}
.row:hover { background: var(--paper-2); }
.row-code {
  font-family: var(--sans); font-weight: 700; font-stretch: var(--w-label);
  font-size: var(--t-0); letter-spacing: .08em; color: var(--amber-lo);
  font-variant-numeric: tabular-nums;
}
.row-name { font-family: var(--sans); font-weight: 600; font-stretch: var(--w-head); font-size: var(--t-1); letter-spacing: -.015em; }
.row-desc { font-size: var(--t--1); color: var(--fg-mute); line-height: 1.55; }
.row-at {
  font-family: var(--sans); font-size: var(--t--2); font-weight: 600;
  text-align: end;
  font-stretch: var(--w-label);
  text-transform: uppercase; letter-spacing: .1em;
  color: var(--fg-mute); line-height: 1.5;
}
.row-go { font-family: var(--sans); color: var(--teal-lo); justify-self: end; transition: transform .2s ease; }
.row:hover .row-go { transform: translateX(4px); }

/* Auf einer Standortseite entfällt die Spalte „verfügbar an" —
   dort ist der Standort ja bereits die Antwort. */
.index-local { --row-cols: 5.5rem minmax(0, 1fr) minmax(0, 1.3fr) 1.5rem; }

/* Im Ratgeber steht in der ersten Spalte kein Rezeptkürzel, sondern ein
   Themenwort („Rehabilitation", „Lymphdrainage"). Im 5,5rem-Track brach
   das zweizeilig um, und weil die Zeile auf baseline sitzt, kippte
   dadurch die ganze Zeile aus der Linie. */
.index-tags { --row-cols: 8rem minmax(0, 2.6fr) max-content max-content 1.5rem; }
.index-tags .row-code {
  font-size: var(--t--2); font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; line-height: 1.35;
}

/* ═══ Gruppenkopf im Ratgeberindex, 01.08.2026 ════════════════
   Die Übersicht war eine einzige Liste von zwanzig Zeilen, nach
   Erscheinungsdatum sortiert. Das ist eine Redaktionsordnung, und
   niemand kommt mit der Frage „was war zuletzt?" auf eine
   Physiotherapieseite. Jetzt stehen fünf Gruppen von drei bis
   fünf Zeilen, jede mit eigener Überschrift, sortiert nach der
   Frage, mit der jemand herkommt.

   Der Kopf ist ABSICHTLICH kein sec-h: er gliedert eine Liste
   INNERHALB eines Abschnitts und darf dessen h2 nicht überbieten.
   Also dieselbe Versalienzeile wie .label, aber ohne den Strich
   davor, sonst stünden zwei Striche in einem Abschnitt und keiner
   hieße mehr etwas.                                             */
.gruppe-h {
  font-family: var(--sans); font-size: var(--t--2); font-weight: 700;
  font-stretch: var(--w-label); letter-spacing: .14em;
  text-transform: uppercase; color: var(--fg-mute);
  margin-block-end: .9rem;
}
/* Der Abstand nach oben muss ueber `.sec >` laufen: die Sammelregel
   `.sec > :not(.label, .sec-h, .sec-lede)` setzt jedem Inhaltsbaustein
   2,6rem und ist spezifischer als eine einzelne Klasse. Ohne diese
   Schreibweise bliebe der Gruppenkopf auf den 2,6rem haengen, und
   fuenf Gruppen saehen aus wie fuenf Absaetze.

   Die erste Gruppe folgt direkt auf .sec-lede, deren Abstand
   reicht bereits. */
.sec > .gruppe-h { margin-block-start: clamp(3.2rem, 6.5vw, 4.4rem); }
/* Die erste Gruppe folgt seit dem 01.08.2026 nicht mehr direkt auf
   .sec-lede, sondern auf das Suchfeld. Die vollen 3,2rem waeren
   dort zu viel, gar keine zu wenig. */
.sec > .gruppe-h:first-of-type { margin-block-start: clamp(1.8rem, 4vw, 2.6rem); }
/* Trefferzahl gehoert ans Suchfeld, nicht in die Reihe der
   Inhaltsbausteine, deren 2,6rem die Sammelregel oben verteilt. */
.sec > .suche-stand { margin-block-start: .2rem; }
/* Der Index bringt eigene 2,6rem Vorlauf mit. Zusammen mit den
   .9rem des Kopfes stand der Kopf naeher an der Gruppe DARUEBER
   als an seiner eigenen, und ein Kopf, der nach oben gehoert,
   ordnet nichts. */
.gruppe-h + .index { margin-block-start: 0; }

/* ═══ Seitenkopf ohne Auftakt, 01.08.2026 ════════════════════
   Der Ratgeber beginnt auf Anweisung direkt mit seinem ersten
   Abschnitt, ohne die typografische Auftaktfläche davor. Ohne
   Ausgleich stieße dessen Label fast an die Kopfzeile: die
   Sektionspolsterung ist für einen Abschnitt MITTEN auf der Seite
   bemessen, nicht für den ersten unter dem Logo.

   Der Wert ist der obere Anteil von .auftakt. Damit steht der
   Seitenanfang dort, wo er auf allen anderen Seiten auch steht,
   nur ohne die Haarlinie darunter, denn getrennt wird hier
   nichts mehr, es ist ja der Anfang.                           */
.seitenkopf { padding-block-start: clamp(2.4rem, 5.5vw, 4rem); }

/* ═══ Suche im Ratgeberindex, 01.08.2026 ═════════════════════
   Ein Feld, kein Knopf zum Absenden: gefiltert wird beim Tippen,
   ein „Suchen"-Knopf hätte nichts zu tun. Das Feld trägt im
   Markup `hidden` und wird erst von ratgeber-suche.js
   freigegeben, siehe die Begründung dort.

   Die Beschriftung steht ÜBER dem Feld und bleibt stehen. Ein
   Platzhalter allein ist keine Beschriftung: er verschwindet
   beim ersten Zeichen, und genau dann braucht man ihn.        */
.suche {
  display: grid; gap: .5rem;
  max-inline-size: 34rem;
  margin-block-end: 1.4rem;
}
.suche label {
  font-family: var(--sans); font-size: var(--t--2); font-weight: 700;
  font-stretch: var(--w-label); letter-spacing: .14em;
  text-transform: uppercase; color: var(--fg-mute);
}
.suche input {
  font: inherit; font-size: var(--t-0); color: var(--fg);
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  padding: .75rem .9rem;
  inline-size: 100%;
}
.suche input::placeholder { color: var(--fg-mute); opacity: .85; }
.suche input:focus-visible {
  outline: 2px solid var(--teal); outline-offset: 2px;
  border-color: var(--teal);
}
/* Der Zurücksetzen-Knopf erscheint erst, wenn etwas dasteht. Er
   ist für Touch-Geräte da, auf denen es keine Escape-Taste gibt. */
.suche-weg {
  justify-self: start;
  font-family: var(--sans); font-size: var(--t--1); font-weight: 600;
  font-stretch: var(--w-ui);
  color: var(--teal-lo); background: none; border: 0;
  padding: 0; cursor: pointer;
  border-block-end: 1px solid var(--rule-strong);
}
.suche-weg:hover { color: var(--fg); }
/* Die Trefferzahl ist eine Statusmeldung (role=status): sie wird
   vorgelesen, sobald sie sich ändert. Deshalb steht sie im
   Dokument auch dann, wenn sie leer ist, statt ein- und
   ausgehängt zu werden. */
.suche-stand {
  font-size: var(--t--1); color: var(--fg-mute); line-height: 1.55;
  margin-block-end: 1.4rem; max-inline-size: 52ch;
}

/* Das `hidden`-Attribut steht im Browser-Stylesheet und wird von
   JEDER eigenen display-Regel geschlagen. `.row` steht auf
   display: grid, ausgefilterte Zeilen blieben deshalb sichtbar,
   waehrend die Trefferzahl daneben etwas anderes behauptete. Die
   Gruppen verschwanden nur zufaellig richtig: `.index` hat keine
   eigene display-Regel.

   Deshalb hier ausdruecklich, und nur fuer die drei Bausteine, die
   die Suche wirklich versteckt.                                 */
.row[hidden], .index[hidden], .gruppe-h[hidden], .suche[hidden] { display: none; }

/* Weiterlesen am Fuß eines Artikels: dieselbe Zeile, aber ohne
   Anriss und ohne Datum. Wer unten angekommen ist, sucht keinen
   Anriss mehr, sondern die nächste Tür. */
.index-weiter { --row-cols: 8rem minmax(0, 1fr) max-content 1.5rem; }
.index-weiter .row-code {
  font-size: var(--t--2); font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; line-height: 1.35;
}

/* Der Anrisstext steht UNTER dem Titel in derselben Spur, nicht in
   einer eigenen. Eine sechste Spur haette bei 1280 jede Spalte auf
   unter 30 Zeichen gedrueckt, und der Index waere eine Tabelle
   geworden statt einer Liste.

   .row sitzt auf align-items: baseline. Das bezieht sich auf die
   ERSTE Zeile der Zelle, Titel, Lesezeit und Datum bleiben also in
   einer Linie, auch wenn der Anriss darunter drei Zeilen braucht.

   Die Zuruecksetzung ist noetig, weil der Anriss in .row-name sitzt
   und dessen 600 und Breitenstufe sonst erbt. Seit dem 01.08.2026
   traegt die ganze Website Archivo, die Schriftfamilie muss also
   nicht mehr gewechselt werden, Gewicht und Breite dagegen schon. */
.row-teaser {
  display: block;
  font-family: var(--sans); font-size: var(--t--1); font-weight: 400;
  font-stretch: normal; letter-spacing: 0; line-height: 1.5;
  color: var(--fg-mute);
  margin-block-start: .45rem; max-inline-size: 62ch;
}

/* Artikelüberschriften tragen keine Breitenstaffelung: ein Titel mit
   bis zu 93 Zeichen in einer einzelnen Zeile auf --w-wide ergab bei
   380px elf Zeilen Überschrift. Die Achse braucht mindestens zwei
   Zeilen, sonst ist sie keine Achse, sondern nur breit. */
.artikel-titel {
  font-size: var(--t-3); font-stretch: var(--w-head);
  max-inline-size: 24ch; margin-block: 1.2rem 0;
}

/* Metazeile des Artikelkopfs. Vorher eine Definitionsliste mit
   Trennlinien für zwei Werte, also viel Apparat für wenig Inhalt,
   und „Umfang" als umständliche Bezeichnung für Lesezeit. */
.artikel-meta { color: var(--bone); margin-block-start: 1.6rem; }

/* ═══ Brotkrume im Artikelkopf, 01.08.2026 ════════════════════
   Über dem Titel stand das Themenwort als .label, also ein Etikett
   ohne Ziel: zwanzig Artikel, und von keinem führte ein Weg zurück
   zur Übersicht. Aus dem Etikett wird ein Weg, der Kategoriename
   bleibt daneben stehen.

   Kein <ol> mit Listenpunkten: die Krume hat zwei Stufen, und für
   zwei Stufen ist eine Liste mehr Apparat als Inhalt. Das <nav>
   mit aria-label sagt einem Vorleseprogramm, was es ist.
   Der Schrägstrich ist Dekoration und deshalb aria-hidden.      */
.krume {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: .55rem;
  font-family: var(--sans); font-size: var(--t--1); font-weight: 600;
  font-stretch: var(--w-label); letter-spacing: .18em;
  text-transform: uppercase; color: var(--fg-mute);
}
.krume a { color: var(--amber-lo); }
.krume a:hover { color: var(--fg); }
.krume span[aria-hidden] { color: var(--rule-strong, var(--fg-mute)); opacity: .7; }

/* Prüfvermerk am Textende. Steht ÜBER dem Haftungshinweis, nicht
   darunter: erst wer den Text geprüft hat, dann was er nicht
   ersetzt. Bewusst leiser gesetzt als der Hinweis, es ist eine
   Angabe zur Herkunft, keine Warnung.                          */
.pruef {
  font-family: var(--sans); font-size: var(--t--1); line-height: 1.6;
  color: var(--fg-mute); margin-block: 1.6rem 0; max-inline-size: 62ch;
}

/* Rechtstexte tragen denselben Kopf wie alle Seiten, aber eine Stufe
   leiser: sie werden nachgeschlagen, nicht beworben, und der große
   Block schob den ersten Sachinhalt aus dem ersten Bildschirm. */
.hero-recht    { padding-block: clamp(2.4rem, 6vw, 4rem); }
.hero-recht h1 { font-size: var(--t-3); }

/* ═══ Fließtext für Rechtstexte und Ratgeber ═══════════════════
   Der einzige Ort im Projekt, an dem längere Prosa vorkommt.
   68 Zeichen Zeilenlänge, Überschriften über Abstand getrennt
   statt über Linien, hier trägt der Rhythmus, nicht die Struktur.

   Hier stand bis zum 01.08.2026 eine Serif. Wenn Ratgeberartikel
   später deutlich länger werden, ist DAS die Stelle, an der die
   Abwägung neu aufzumachen ist: gemessen wurde bei 514 Wörtern im
   längsten Artikel, und bis dahin trägt die Sans mühelos.        */

/* ═══ EINE LINKE KANTE FÜR DIE GANZE SEITE, 02.08.2026 ══════════
   .prose lag als gewoehnliches Rasterkind in der Spur `content`,
   der Artikelkopf darueber (Brotkrume, h1, Zeile mit Datum und
   Lesezeit) liegt ueber `.auftakt > *` in der Spur `wide`. Zwischen
   beiden Spuren liegen bis zu 6rem, und genau um diesen Betrag
   ruecke der Fliesstext gegenueber seiner eigenen Ueberschrift nach
   rechts ein. Auf einem Ratgeberartikel sah das aus wie zwei
   Layouts untereinander, nicht wie eins.

   ES WAR EINMAL ABSICHT: der Kommentar bei `.auftakt > *` haelt
   fest, der Fliesstext bleibe „bewusst schmaler … eine Lesebreite,
   kein Raster". Das Argument stimmt fuer die BREITE und bleibt —
   64ch sind weiterhin schmaler als die Spur. Es traegt aber nicht
   fuer die KANTE: eine Lesebreite muss nicht eingerueckt sein, um
   als Lesebreite erkennbar zu sein, sie muss nur schmal sein. Die
   Einrueckung hat nichts erklaert, sie hat nur die Flucht gebrochen.

   Jetzt beginnt der Text dort, wo die Ueberschrift beginnt, und
   endet 64 Zeichen spaeter. Dieselbe Kante wie `.sec`, wie die
   Fusszeile und wie jeder Abschnittskopf darunter.               */
.grid > .prose { grid-column: wide; }
.prose { max-inline-size: 64ch; }
.prose > :first-child { margin-block-start: 0; }
/* .9rem unter der h2 gegen 1rem zwischen zwei Absätzen: das ist keine
   Gruppierung, die Überschrift stand optisch gleich weit von ihrem
   Absatz wie zwei Absätze voneinander. Die h3 daneben machte es mit
   .5rem richtig. */
.prose h2 { font-size: var(--t-2); font-stretch: var(--w-head); margin-block: clamp(2.2rem, 5vw, 3.2rem) .5rem; max-inline-size: 28ch; }
.prose h3 { font-size: var(--t-1); font-stretch: var(--w-head); margin-block: 1.9rem .5rem; }
.prose p, .prose ul, .prose ol { margin-block-end: 1rem; }
.prose ul, .prose ol { padding-inline-start: 1.35rem; }
.prose li { margin-block-end: .4rem; }
/* Der Amber-Unterstrich stand viermal identisch, zweimal davon mit
   dem physischen border-bottom statt der logischen Eigenschaft. */
:is(.prose, .fact, .roster-fuss, .check) a { border-block-end: 1px solid var(--amber); }
:is(.prose, .fact, .roster-fuss, .check) a:hover { border-color: currentColor; }
.prose strong { font-weight: 600; }
.prose dl { display: grid; gap: .9rem; margin-block-end: 1.4rem; }
.prose dt { color: var(--fg-mute); }
.prose dd { margin-block-start: .15rem; }

/* Redaktionelle Anmerkung, kein Warnkasten mit Schatten und
   Radius, sondern ein eingerückter Block an einer Amber-Kante. */
.note {
  border-inline-start: 3px solid var(--amber);
  padding: .2rem 0 .2rem 1.2rem;
  margin-block: 1.6rem;
  font-size: var(--t-0); line-height: 1.6; color: var(--fg);
  max-inline-size: 62ch;
}

/* .article-cta ist eine ANZEIGE IN EIGENER SACHE und sah bis zum
   31.07.2026 aus wie der Haftungshinweis direkt darunter: dieselbe
   Amber-Kante, dieselbe Einrückung, dieselbe Schriftgröße. Ein
   Werbeblock und ein Disclaimer dürfen nicht dasselbe Zeichen
   tragen; wer den einen überliest, überliest den anderen mit.

   Der Aufruf steht jetzt auf getönter Fläche zwischen zwei
   Haarlinien, also mit demselben Vokabular wie der Rest der Seite,
   aber unverwechselbar anders als .note. Kein Kasten, kein Radius,
   kein Schatten. */
.prose .article-cta {
  margin-block: clamp(2.2rem, 5vw, 3.2rem) 1.6rem;
  padding: clamp(1rem, 2.5vw, 1.4rem) 0;
  border-block: 1px solid var(--rule);
  background: var(--paper-2);
  padding-inline: clamp(1rem, 3vw, 1.6rem);
  font-size: var(--t-0); line-height: 1.6;
  max-inline-size: 62ch;
}
.prose .article-cta p:last-child { margin-block-end: 0; }
.prose .article-cta a { border-block-end: 1px solid var(--amber); }

/* ═══ Fakten- und Öffnungszeitenblock ══════════════════════════ */

.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 6vw, 5rem); align-items: start; }

/* ═══ FORMULAR, ZUSAMMENFALTBAR ══════════════════════════════════
   Auf Anweisung vom 01.08.2026, Begruendung im Markup bei
   .formular-klapp.

   AB 48rem GIBT ES DAS AUFKLAPPEN NICHT: das summary ist weg und
   das details steht offen im Markup, das Formular sieht also
   genauso aus wie vorher. Es ist ausschliesslich eine Massnahme
   fuer schmale Schirme.

   marker und ::-webkit-details-marker muessen auch hier weg, sonst
   steht das Standarddreieck des Browsers vor dem eigenen Zeichen. */
.formular-klapp > summary { display: none; }

@media (max-width: 48rem) {
  /* DIESELBE BEHANDLUNG WIE .btn, auf Anweisung vom 01.08.2026:
     --teal gefuellt, weisse Schrift, Versalien. Vorher war es ein
     heller Kasten mit Rahmen.

     WARUM DAS RICHTIG IST: die Zeile steht unmittelbar ueber der
     Anrufkarte, und der Nummernknopf darin ist ein .btn. Zwei
     gleichrangige Wege zur Praxis, schreiben oder anrufen, duerfen
     nicht wie Haupt- und Nebenweg aussehen.

     WERTE AUS .btn UEBERNOMMEN, nicht die Klasse: ein <summary>
     kann kein .btn tragen, ohne dessen inline-flex und dessen
     Innenabstaende gegen das eigene Flexlayout zu stellen. Die
     Groesse folgt .anruf-btn (--t-0, .7rem 1rem), damit die beiden
     wirklich gleich gross sind und nicht nur gleich gefaerbt.
     BEI EINER AENDERUNG AN .btn hier mitziehen. */
  .formular-klapp > summary {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem;
    padding: .7rem 1rem;
    border: 1px solid transparent;
    border-radius: var(--radius-btn);
    background: var(--teal);
    color: #fff;
    cursor: pointer; list-style: none;
    font-family: var(--sans);
    font-size: var(--t-0); font-weight: 600; font-stretch: var(--w-ui);
    letter-spacing: .02em; text-transform: uppercase;
    transition: background .18s ease;
  }
  .formular-klapp > summary:hover { background: color-mix(in oklch, var(--teal), black 14%); }
  .formular-klapp > summary::-webkit-details-marker { display: none; }
  .formular-klapp > summary::marker { content: ''; }
  /* KEINE EIGENE FOKUSREGEL. Die globale oben (3px --focus mit 3px
     Abstand) trifft das summary schon und ist breiter als eine
     eigene waere. Wichtig ist dabei der Abstand: --focus haelt auf
     gefuelltem --teal nur 1,17:1 und waere direkt auf der Flaeche
     unsichtbar. Durch outline-offset liegt der Rahmen ausserhalb
     des Knopfes auf --paper, dort sind es 4,98:1. Wer den Abstand
     entfernt, macht den Fokus auf diesem Knopf unbrauchbar. */
  .formular-klapp[open] > summary { margin-block-end: 1.4rem; }
  .formular-klapp[open] > summary .faq-zeichen { transform: rotate(180deg); }
  /* currentColor, also Weiss: das Zeichen gehoert zur Schrift des
     Knopfes, nicht zur Flaeche. */
  .formular-klapp > summary .faq-zeichen { color: currentColor; }
}

/* Lesebreite fuer Fakten und Zeiten. Zwischen 768 und 960 Pixeln
   ist .split bereits einspaltig, .facts hatte aber keine Begrenzung:
   dann standen "Montag–Donnerstag" links und "08:00–19:00" rechts
   mit rund 440 Pixeln Leere dazwischen. Ohne Fuehrungspunkte ist
   die Zuordnung Tag zu Uhrzeit auf einen Blick nicht mehr sicher.
   34rem entspricht der Breite, bei der die Paare noch zusammen
   gelesen werden. */
.facts { display: grid; gap: 1.4rem; max-inline-size: 34rem; }
.fact  { display: grid; gap: .2rem; padding-block-end: 1.1rem; border-block-end: 1px solid var(--rule); }
.fact dt { color: var(--fg-mute); }

/* ═══ VERLAUF, die Firmengeschichte als Abfolge ═══════════════════
   Neu am 01.08.2026, weil die Ueber-uns-Seite unstrukturiert wirkte.
   DAS WAR DIE URSACHE: zwei voellig verschiedene Inhalte trugen
   dieselbe Kleidung. „Wie alles begann" ist eine ABFOLGE in vier
   Schritten, „Wonach wir arbeiten" ein SATZ von vier Grundsaetzen
   ohne Reihenfolge. Beide standen als .facts in einem
   zweispaltigen .split, also als 2x2-Feld gleich aussehender
   dt/dd-Paare. Wer die Seite ansieht, kann dann nicht erkennen,
   dass das eine eine Geschichte ist und das andere eine Liste.

   DER ALTE KOMMENTAR IM MARKUP war der Beleg dafuer: dort stand,
   dass die Schritte 1 und 3 links und 2 und 4 rechts liegen
   muessen, damit sie quer gelesen in der richtigen Reihenfolge
   erscheinen. Eine Reihenfolge, die man ueber die Spaltenverteilung
   von Hand retten muss, gehoert nicht in ein 2x2-Feld. Sie gehoert
   in eine Spalte.

   <ol> UND NICHT <dl>: es ist eine geordnete Liste, und
   Vorleseprogramme sagen jetzt „Liste mit 4 Eintraegen" an, samt
   Position. Die Reihenfolge steht damit im Markup, nicht in der
   Anordnung.

   KEINE ZIFFERN 01 bis 04. Die Schritte heissen Gruendung,
   Wachstum, Nach Dortmund und Heute, das tragen Namen besser als
   Zahlen. Linie und Knoten zeigen die Abfolge schon.

   DIE RUNDEN KNOTEN sind eine bewusste Ausnahme von der
   Radius-Verbotsliste bei --radius-btn. Die verbietet gerundete
   ECKEN auf Flaechen, Linien und Bildkanten, weil das in den
   Baukasten-Look fuehrt. Hier sind es keine abgerundeten Rechtecke,
   sondern Kreise, und sie haben einen Grund im Zeichen der Praxis
   selbst: das Logo ist eine absteigende Reihe von Punkten neben
   einem Blatt, eine Wirbelsaeule. Eine senkrechte Linie mit Knoten
   ist dasselbe Bild.                                          ═══ */
.verlauf {
  list-style: none;
  max-inline-size: 62ch;
}
.verlauf li {
  position: relative;
  padding-inline-start: 1.9rem;
  padding-block-end: 1.7rem;
}
.verlauf li:last-child { padding-block-end: 0; }

/* Die Linie beginnt auf Hoehe des Knotens und laeuft bis zum
   naechsten. Beim letzten entfaellt sie, sonst haengt sie in der
   Luft, dieselbe Regel wie bei den Menuelinien. */
.verlauf li::before {
  content: '';
  position: absolute;
  inset-block: .75rem 0;
  inset-inline-start: .3rem;
  border-inline-start: 1px solid var(--rule);
}
.verlauf li:last-child::before { content: none; }

.verlauf li::after {
  content: '';
  position: absolute;
  inset-block-start: .3rem;
  inset-inline-start: 0;
  inline-size: .7rem; block-size: .7rem;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--teal);
}
/* Der letzte Knoten ist gefuellt: „Heute" ist der Stand, nicht
   eine weitere Station. Ein einziger Unterschied am Ende der Reihe
   sagt das, ohne ein Wort dafuer zu brauchen. */
.verlauf li:last-child::after { background: var(--teal); }

.verlauf-titel { color: var(--fg-mute); margin-block-end: .25rem; }
.verlauf p:not(.verlauf-titel) { line-height: 1.55; }

/* ─── Verlauf und Gruenderbilder nebeneinander ─────────────────
   Auf Anweisung vom 01.08.2026: rechts neben die Abfolge die beiden
   Gruender. Die Abfolge hat max-inline-size 62ch, rechts davon
   blieb auf breiten Schirmen die halbe Zeile leer, und derselbe
   Einwand steht weiter oben schon bei .sec.

   EIGENER KASTEN, NICHT DIE SPALTEN VON .sec: dort haengen die
   Zeilennummern daran, ob ein .sec-lede vorhanden ist, und auf
   dieser Seite ist er entfallen. Mit grid-column auf die Spalten
   von .sec zu greifen waere damit von einem Absatz abhaengig, den
   es hier nicht gibt. Dieser Kasten spannt ueber beide Spalten und
   teilt sich intern selbst, also unabhaengig davon.

   ERST AB 60rem ZWEISPALTIG, nicht ab 48rem wie .sec: bei 800px
   waeren die Portraits rund 150px breit, und zwei Gesichter in
   dieser Groesse neben einem Text sind Dekoration statt Aussage.
   Darunter stehen sie unter der Abfolge, in voller Breite. */
.verlauf-block { display: grid; gap: clamp(2.4rem, 6vw, 3.4rem); }
@media (min-width: 60rem) {
  .verlauf-block {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    column-gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
  }
  /* Die Portraits setzen unten an der letzten Station an, nicht an
     der ersten: oben stehen sie sonst neben „Gruendung" und deuten
     eine Zuordnung an, die es nicht gibt, denn die beiden gehoeren
     zur ganzen Abfolge. */
  .gruender { margin-block-start: .35rem; }
}

/* ═══ FACT-RASTER, ein Satz gleichrangiger Angaben ════════════════
   Fuer die vier Grundsaetze auf der Ueber-uns-Seite. Vorher standen
   sie als ZWEI .facts-Listen in einem .split, und damit lief die
   Lesefolge spaltenweise: „Ehrlich und nachvollziehbar" stand oben
   rechts, „Was daraus folgt" darunter. Quer gelesen kam „Was daraus
   folgt" also hinter „Evidenz trifft Erfahrung" zu stehen, waehrend
   es sich auf „Ehrlich" bezieht. Ein Satz, der „was daraus folgt"
   heisst, muss unmittelbar auf seinen Bezug folgen.

   EIN Raster mit EINER Liste loest das: das Raster fuellt
   zeilenweise, die Reihenfolge im Markup ist damit auch die
   Lesefolge. Kein Verteilen von Hand mehr.                     ═══ */
.fact-raster {
  display: grid; gap: 1.5rem 3rem;
  max-inline-size: none;
}
@media (min-width: 48rem) {
  .fact-raster { grid-template-columns: 1fr 1fr; }
}

/* ═══ TELEFONLISTE, drei Praxen, drei Nummern ═════════════════════
   Auf der Kontaktseite. Die Klasse stand am 01.08.2026 im Markup,
   hatte aber KEINE einzige CSS-Regel. Die sechs Elemente, drei
   Nummern und drei Ortsnamen, liefen deshalb als Fliesstext
   hintereinander und brachen dort um, wo die Zeile zu Ende war:

     02389 4030410 Bergkamen-Rünthe 0231 577225
     Dortmund-Mitte 0231 53068625 Klinikviertel

   Welcher Ort zu welcher Nummer gehoert, war damit Ratesache, und
   bei Rufnummern ist Raten die schlechteste Eigenschaft, die eine
   Liste haben kann.

   ZWEI SPALTEN, EINE ZEILE JE PRAXIS. Das Raster nimmt die flache
   Folge a, span, a, span, a, span und legt sie zeilenweise ab, das
   Markup braucht dafuer keine Verschachtelung. Die Nummern stehen
   damit linksbuendig untereinander, die Orte rechts daneben.

   DER PUNKT trennt Nummer und Ort, dieselbe Rolle wie in
   „Mo–Do 8–19 Uhr · Fr 8–15 Uhr" an anderen Stellen der Website.
   aria-hidden geht hier nicht, weil es ein ::before ist; das ist
   unkritisch, generierte Inhalte werden von Vorleseprogrammen
   unterschiedlich behandelt und ein Mittelpunkt wird entweder
   uebersprungen oder als kurze Pause gelesen.

   baseline und nicht center: die Nummern tragen den Amber-Strich
   von .phone, an einer Mittelachse saessen die Ortsnamen dadurch
   sichtbar zu hoch.                                           ═══ */
.telefonliste {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: .55rem;
  row-gap: .65rem;
  align-items: baseline;
}
.telefonliste span { color: var(--fg-mute); }
.telefonliste span::before {
  content: '·';
  margin-inline-end: .45rem;
}

/* Unter 26rem, also auf den schmalsten Telefonen, reicht die Zeile
   fuer „0231 53068625 · Dortmund-Mitte" nicht. Dann untereinander,
   und der Punkt entfaellt: er trennt zwei Dinge in EINER Zeile, in
   zwei Zeilen trennt der Umbruch schon. Der Einzug haelt die
   Zuordnung. */
@media (max-width: 26rem) {
  .telefonliste { grid-template-columns: 1fr; row-gap: .25rem; }
  .telefonliste span { padding-inline-start: .1rem; margin-block-end: .5rem; }
  .telefonliste span::before { content: none; }
  .telefonliste span:last-child { margin-block-end: 0; }
}
.fact dd { font-family: var(--sans); font-size: var(--t-1); font-stretch: var(--w-head); font-weight: 500; letter-spacing: -.01em; }
/* dd.plain ist Fliesstext und braucht eine Lesebreite. Ohne sie lief
   er im einspaltigen Bereich ueber rund 88 Zeichen je Zeile. */
.fact dd.plain { font-family: var(--sans); font-size: var(--t-0); font-weight: 400; letter-spacing: 0; line-height: 1.55; max-inline-size: 62ch; }
/* Ohne diese Regel greift nur die globale Zurücksetzung a { color:
   inherit; text-decoration: none }. Die Maps-Route, die E-Mail-Adresse
   und die Querverweise im Klinikviertel waren dadurch als Links
   überhaupt nicht erkennbar, was gegen SC 1.4.1 verstößt. Dasselbe
   Muster wie .prose a und .phone. */

/* ═══ FAQ ════════════════════════════════════════════════════════
   Auf Anweisung vom 01.08.2026. Loest die Faktenliste ab, die
   vorher in der rechten Spalte neben dem Terminformular stand.

   NATIVES <details>, deshalb steht hier fast nur Aussehen und kaum
   Verhalten. Das Aufklappen, die Tastaturbedienung und die Ansage
   als aufklappbarer Bereich kommen vom Browser.

   DIE FRAGE IST DIE FLAECHE, nicht ein Symbol daneben: das ganze
   summary ist die Schaltflaeche, inklusive Leerraum bis zum
   Zeichen rechts. Ein Klickziel, das nur so gross ist wie ein
   Pfeil, ist auf einem Telefon eine Zumutung.

   DIE ANTWORT BLEIBT SCHMAL, 62 Zeichen, obwohl der Bereich jetzt
   die volle Breite hat. Breit heisst breite FLAECHE, nicht breite
   ZEILE. Ueber etwa 75 Zeichen findet das Auge den Zeilenanfang
   nicht mehr zuverlaessig.

   KEIN border-radius, siehe Verbotsliste bei --radius-btn.      ═══ */
.faq { border-block-start: 1px solid var(--rule); }

.faq-item { border-block-end: 1px solid var(--rule); }

.faq-item summary {
  display: flex; align-items: baseline; gap: 1.2rem;
  justify-content: space-between;
  padding-block: 1.15rem;
  cursor: pointer;
  font-size: var(--t-1);
  font-weight: 600; font-stretch: var(--w-head);
  letter-spacing: -.015em;
  /* Der Standardmarker faellt weg, das Zeichen rechts ersetzt ihn.
     ::-webkit-details-marker fuer aeltere Safari-Fassungen. */
  list-style: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::marker { content: ''; }

/* Kein eigenes :focus-visible. Die globale Regel weiter oben legt
   3px --focus mit 3px Abstand um das summary, und das umschliesst
   ohnehin die ganze Zeile, weil die ganze Zeile das Element ist. */
.faq-item summary:hover { color: var(--teal-lo); }

/* Das Zeichen dreht sich, es wird nicht ausgetauscht: ein Wechsel
   von Plus zu Minus behauptet zwei Zustaende, die Drehung zeigt
   denselben Zustand in Bewegung. flex: none, sonst quetscht der
   Flexkasten es bei langen Fragen zusammen. */
.faq-zeichen {
  flex: none; inline-size: .85rem; block-size: .85rem;
  color: var(--teal-lo);
  transition: transform var(--dur-kurz) var(--ease);
  transform: translateY(.1rem);
}
.faq-item[open] .faq-zeichen { transform: translateY(.1rem) rotate(180deg); }

.faq-antwort {
  padding-block-end: 1.35rem;
  max-inline-size: 62ch;
  font-size: var(--t-0); font-weight: 400;
  font-stretch: normal; letter-spacing: 0; line-height: 1.55;
}
/* Die Antwort kommt herein, statt zu erscheinen. Nur die Antwort,
   nicht die Hoehe des Kastens: eine Hoehenanimation auf <details>
   braucht interpolate-size oder ::details-content und faellt in
   aelteren Browsern hart aus. Das hier laeuft ueberall. */
.faq-item[open] .faq-antwort {
  animation: faq-auf var(--dur-lang) var(--ease);
}
@keyframes faq-auf {
  from { opacity: 0; transform: translateY(-.4rem); }
  to   { opacity: 1; transform: none; }
}

.faq-fuss {
  margin-block-start: 2rem;
  font-size: var(--t--1); color: var(--fg-mute);
  max-inline-size: 62ch;
}
.faq-fuss a { border-bottom: 1px solid var(--rule-strong); }
.faq-fuss a:hover { border-color: currentColor; }
/* ═══ RUFNUMMER IM FLIESSTEXT, 04.09.2026 ═══════════════════════
   .phone ist fuer den eigenen Stand gebaut, mit --t-1 und einer
   2 Pixel starken Kante. In diesem Absatz stand sie damit auf 23
   Pixeln in einem 13,4-Pixel-Absatz, also 1,7 mal so gross, bei
   einer Zeilenhoehe von 21. Die Zeile beulte aus und die
   Unterstreichung schnitt in die Folgezeile.

   Hier erbt sie die Absatzgroesse und wird nur noch durch Farbe
   und Kante ausgezeichnet. Die Kante duenner, sonst waere sie bei
   dieser Schriftgroesse der lauteste Strich der Seite. Ueberall
   sonst bleibt .phone unveraendert.                             */
.faq-fuss .phone {
  font-size: inherit;
  font-stretch: var(--w-ui);
  color: var(--teal-lo);
  border-bottom-width: 1px;
  padding-bottom: 0;
}

@media (prefers-reduced-motion: reduce) {
  .faq-zeichen { transition: none; }
  .faq-item[open] .faq-antwort { animation: none; }
}

/* Drei Nummern in einem .fact, seit jede Praxis ihre eigene hat.
   Ohne diese Regel laufen Nummer und Ortsname als Fliesstext in
   eine Zeile („02389 4030410 Bergkamen-Ruenthe 0231 577225
   Dortmund-Mitte …"), und keine Zuordnung ist mehr erkennbar.
   Zwei Spalten: die Nummer traegt die Zeile, der Ort steht als
   Beschriftung daneben. */
.telefonliste {
  display: grid; grid-template-columns: auto 1fr;
  gap: .35rem .9rem; align-items: baseline;
}
.telefonliste span {
  font-family: var(--sans); font-size: var(--t--2); font-stretch: var(--w-ui);
  color: var(--fg-mute); letter-spacing: .03em;
}

.hours { display: grid; gap: .35rem; max-inline-size: 34rem; font-family: var(--sans); font-size: var(--t-0); font-stretch: var(--w-ui); }
.hours div { display: flex; justify-content: space-between; gap: 1rem; }
.hours .off { color: var(--fg-mute); }

/* ═══ Anrufkarte in der rechten Spalte von .split ══════════════
   Gesicht, Rolle, Nummer als Knopf. Begruendung fuer das Portrait
   steht im Markup bei .anruf, hier nur die Form.

   ALS VISITENKARTE, auf Anweisung vom 02.08.2026. Vorher stand das
   Portrait auf 8.5rem neben dem Knopf und war damit das lauteste
   Element der Spalte; es zog den Blick vom Formular weg, obwohl es
   nur den Anruf begleiten soll. Jetzt Daumennagel plus Name in
   einer Zeile, Knopf darunter: die Reihenfolge, in der man eine
   Visitenkarte liest.

   Deshalb hier AUSNAHMSWEISE ein Kasten statt einer Haarlinie.
   Sonst trennt dieses Projekt mit Linien (.fact, .roster, .doors),
   und die Regel bleibt auch richtig. Eine Visitenkarte ist aber
   genau das, was ein Kasten meint: ein Stueck mit eigener Kante,
   das man aus der Spalte herausnehmen koennte. Radius und Fuellung
   sind Projektwerte (--radius-btn, --paper-2), keine neuen. */
.anruf {
  max-inline-size: 24rem;
  padding: clamp(1rem, 2.5vw, 1.3rem);
  margin-block-end: clamp(1.8rem, 4vw, 2.4rem);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius-btn);
}
/* Der Abschnitt kann getoent sein (Standortseiten). Dann faellt die
   Fuellung mit dem Grund zusammen und die Karte verschwindet bis
   auf ihre Kante. Auf getoentem Grund deshalb Papierweiss. */
[data-tone="tint"] .anruf { background: var(--paper); }

.anruf-kopf {
  display: flex; align-items: start; gap: .95rem;
}
/* DAS GANZE BILD, nur klein, auf Anweisung vom 02.08.2026. Damit
   ist der ganze Zuschnitt-Apparat entfallen, der hier zwei Anlaeufe
   lang stand: erst aspect-ratio plus object-fit: cover, dann ein
   Rahmen mit overflow und ein Bild im Ueberhang. Beides ist
   Rechnerei, die an EIN Portrait gebunden war.

   Falls jemand den Ausschnitt zurueckholen will, hier die Falle,
   ueber die beide Anlaeufe gestolpert sind, damit sie nicht ein
   drittes Mal Zeit kostet: die Quelle ist mit 640 x 961 hochkant,
   Verhaeltnis 0.67. Jedes quadratische oder 5:7-Ziel ist BREITER
   als das, also beschneidet cover ausschliesslich oben und unten
   und object-position 50% laeuft auf der Waagerechten ins Leere.
   Chiara steht in der Vorlage aber bei 64 Prozent der Breite,
   mittig sitzt die Stehlampe. Seitlich beschneiden geht nur ueber
   einen Rahmen mit overflow — und dann verlangt die globale Regel
   img { max-inline-size: 100% } zusaetzlich ein max-inline-size:
   none, sonst klemmt sie das Bild wieder auf die Rahmenbreite.

   Hochkant heisst hier: 3.6rem Breite ergeben 5.4rem Hoehe. Das
   ist die Hoehe, an der sich die Spalte rechts orientiert.
   Gradation wie .roster img, damit dasselbe Gesicht auf dieser
   Seite nicht in zwei Bearbeitungen erscheint.                   */
.anruf-bild {
  display: block; flex: none;
  inline-size: 3.6rem; block-size: auto;
  filter: grayscale(.28) contrast(1.03);
}
/* min-inline-size: 0 ist noetig, sonst weigert sich das
   Flex-Element, unter die Breite der E-Mail-Adresse zu schrumpfen,
   und die Karte laeuft in schmalen Spalten ueber ihre Kante. */
.anruf-daten { min-inline-size: 0; }
.anruf-name {
  font-family: var(--sans); font-size: var(--t--1); font-weight: 600;
  font-stretch: var(--w-label); text-transform: uppercase; letter-spacing: .1em;
}
.anruf-rolle {
  font-family: var(--sans); font-size: var(--t--2); font-stretch: var(--w-ui);
  letter-spacing: .04em; color: var(--fg-mute); line-height: 1.35;
}
/* EINZIGER Knopf im Projekt, der aus der Knopfgroesse ausbricht,
   und zwar begruendet: seine Beschriftung IST die Auskunft. Alle
   anderen tragen ein Verb („Anfrage senden"), das man antippt und
   nicht liest. Eine Rufnummer wird gelesen, vorgelesen und in ein
   anderes Geraet abgetippt. Auf --t--1 mit .04em Versalienspur war
   sie dafuer zu klein und zu weit gesperrt.

   Schmaler gepolstert als ein normaler Knopf: er steht in einer
   Spalte von rund 14rem, nicht auf der Flaeche. Die 44 Pixel
   Antippflaeche bleiben ueber die Zeilenhoehe erhalten.          */
.anruf-btn {
  display: flex; justify-content: center;
  margin-block-start: .7rem;
  padding: .7rem 1rem;
  font-size: var(--t-0);
  letter-spacing: .02em;
}
/* Die Adresse ist mit 30 Zeichen laenger als ihre Spalte. Ohne
   break-word steht sie sonst ueber der Kartenkante: overflow-wrap
   allein greift bei einer Zeichenkette ohne Leerzeichen nicht
   zuverlaessig, wenn sie als Flex-Element in einer festen Breite
   sitzt. Unterstrichen in --amber wie .phone und .prose a, sonst
   waere sie durch die globale Zuruecksetzung nicht als Link
   erkennbar (SC 1.4.1).                                          */
.anruf-mail {
  display: inline-block;
  margin-block-start: .55rem;
  font-family: var(--sans); font-size: var(--t--2); font-stretch: var(--w-ui);
  line-height: 1.4;
  overflow-wrap: anywhere; word-break: break-word;
  border-block-end: 1px solid var(--amber);
}
.anruf-mail:hover { border-color: currentColor; }
.anruf-zeit {
  font-family: var(--sans); font-size: var(--t--2); font-stretch: var(--w-ui);
  color: var(--fg-mute); line-height: 1.45;
  margin-block-start: .9rem;
  padding-block-start: .8rem;
  border-block-start: 1px solid var(--rule);
}

/* ═══ Laufband mit Google-Bewertungen ══════════════════════════
   Acht Karten, die langsam nach links wandern, und dahinter
   dieselben acht noch einmal. Warum es zwei Saetze sind, steht im
   Markup; hier steht, wie die Bewegung zustande kommt.

   Der Kopf steht in der Spur `wide`, das Band selbst in `full`:
   ein Laufband, das an der Textkante endet, sieht aus wie ein
   abgeschnittener Kasten. Randlos liest es sich als Fortsetzung
   ueber den Bildschirm hinaus, und genau das soll es sein.       */
.stimmen-kopf {
  display: flex; flex-wrap: wrap; gap: 1.4rem 3rem;
  align-items: end; justify-content: space-between;
  margin-block-end: clamp(2rem, 5vw, 3rem);
}
.stimmen-kopf .sec-h { margin-block-end: 0; }
/* OHNE DIESE BEIDEN ZEILEN steht die Meta-Spalte unter der
   Ueberschrift statt neben ihr, und zwar auch auf breiten Schirmen.
   Gerechnet: die Ueberschrift beansprucht als Flex-Element ihre
   Inhaltsbreite (974 Pixel), die Meta-Spalte 480, dazu 48 Abstand —
   1502 in einer Spur, die nur 1344 breit ist. Also Umbruch. Mit
   `flex: 1 1` darf die Ueberschrift schrumpfen und bricht statt
   dessen auf zwei Zeilen, was hier ohnehin besser aussieht. */
.stimmen-kopf > :first-child { flex: 1 1 20rem; min-inline-size: 0; }
.stimmen-meta { flex: 0 1 24rem; max-inline-size: 24rem; }
.stimmen-schnitt {
  font-family: var(--sans); font-size: var(--t-0); font-stretch: var(--w-ui);
  line-height: 1.5;
}
/* Der Hinweis auf die Auswahl steht bewusst nicht im Kleingedruckten
   der Fusszeile, sondern hier oben neben dem Schnitt: er gehoert zur
   Aussage, nicht zu ihrer Fussnote. */
.stimmen-hinweis {
  font-family: var(--sans); font-size: var(--t--1); font-stretch: var(--w-ui);
  color: var(--fg-mute); line-height: 1.5; margin-block-start: .3rem;
}
.stimmen-hinweis a { border-block-end: 1px solid var(--amber); }
.stimmen-hinweis a:hover { border-color: currentColor; }

.lauf { position: relative; display: flex; overflow: hidden; }
/* Die Vorlage traegt nur <defs> und darf keinen Platz einnehmen.
   Ohne diese Regel steht ein leeres SVG mit der Standardgroesse von
   300 x 150 Pixeln im Flex-Fluss und schiebt das Band nach rechts. */
.lauf-vorlage { position: absolute; inline-size: 0; block-size: 0; }

.lauf-spur {
  display: flex; flex: none; gap: clamp(1rem, 2.5vw, 1.6rem);
  padding-inline-end: clamp(1rem, 2.5vw, 1.6rem);
  animation: lauf 90s linear infinite;
}
/* 90 Sekunden fuer einen Durchlauf klingt viel und ist es nicht:
   die Strecke ist die Breite von acht Karten, also rund 3000 Pixel.
   Das sind etwa 33 Pixel je Sekunde — langsam genug, um im
   Vorbeigehen einen Satz zu Ende zu lesen. Schneller wird es zur
   Laufschrift, und Laufschrift liest niemand. */
@keyframes lauf { to { transform: translateX(-100%); } }

/* ANHALTEN, drei Wege. Der Schalter ist der verbindliche (WCAG
   2.2.2), Zeigen und Tastaturfokus sind die bequemen. :has() traegt
   den Schalter ueber die Baumgrenze hinweg — er steht im Kopf, das
   Band ist sein Onkel, mit Geschwisterselektoren waere das nicht zu
   erreichen. */
.stimmen:has(.lauf-schalter:checked) .lauf-spur,
.lauf:hover .lauf-spur,
.lauf:focus-within .lauf-spur { animation-play-state: paused; }

/* Das Kaestchen selbst ist unsichtbar, aber NICHT display:none: es
   muss mit der Tastatur erreichbar bleiben. Sichtbar ist sein Label,
   und der Fokusring liegt ueber :has() auf ebendiesem Label. */
.lauf-schalter {
  position: absolute; inline-size: 1px; block-size: 1px;
  margin: -1px; padding: 0; border: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.lauf-knopf {
  display: inline-block; margin-block-start: .9rem; cursor: pointer;
  padding: .5rem .9rem;
  border: 1px solid var(--rule-strong); border-radius: var(--radius-btn);
  font-family: var(--sans); font-size: var(--t--2); font-weight: 600;
  font-stretch: var(--w-label); text-transform: uppercase; letter-spacing: .08em;
}
.lauf-knopf:hover { border-color: currentColor; }
.stimmen:has(.lauf-schalter:focus-visible) .lauf-knopf {
  outline: 2px solid var(--focus); outline-offset: 2px;
}
/* Die Beschriftung sagt, was der naechste Druck bewirkt, nicht was
   gerade laeuft. */
.stimmen .lauf-aus { display: none; }
.stimmen:has(.lauf-schalter:checked) .lauf-an  { display: none; }
.stimmen:has(.lauf-schalter:checked) .lauf-aus { display: inline; }

.stimme {
  flex: none; inline-size: min(22rem, 78vw);
  display: flex; flex-direction: column; gap: .8rem;
  padding: clamp(1.1rem, 2.5vw, 1.5rem);
  background: var(--paper);
  border: 1px solid var(--rule); border-radius: var(--radius-btn);
}
.stimme-sterne { color: var(--stern-lo); }
.stimme-sterne svg { inline-size: 5.4rem; block-size: auto; fill: currentColor; }
.stimme blockquote {
  font-family: var(--serif); font-size: var(--t--1); line-height: 1.55;
  flex: 1;
}
/* Sicherheitsnetz, kein Gestaltungsmittel: die acht Zitate sind so
   gewaehlt, dass sie hineinpassen. Wer eines gegen ein laengeres
   tauscht, bekommt hier drei Punkte statt einer Karte, die aus der
   Reihe ragt. Gekuerzt wird dann sichtbar, nicht heimlich. */
.stimme blockquote {
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 9; overflow: hidden;
}
.stimme figcaption {
  font-family: var(--sans); font-size: var(--t--2); font-stretch: var(--w-ui);
  color: var(--fg-mute); letter-spacing: .03em;
  padding-block-start: .7rem; border-block-start: 1px solid var(--rule);
}

/* ZURUECKGENOMMENE BEWEGUNG: die Animation muss AUSGESCHALTET
   werden, nicht nur verkuerzt. Die globale Regel weiter unten setzt
   animation-duration auf 0.01ms !important — bei einer endlos
   laufenden Bewegung waere das kein Stillstand, sondern ein Flackern
   mit hundert Durchlaeufen je Sekunde. Stattdessen steht das Band
   still und laesst sich von Hand schieben; der zweite Satz entfaellt,
   weil er ohne Bewegung nur eine Wiederholung waere. */
@media (prefers-reduced-motion: reduce) {
  .lauf { overflow-x: auto; }
  .lauf-spur { animation: none !important; }
  .lauf-spur[aria-hidden="true"] { display: none; }
  .lauf-knopf, .lauf-schalter { display: none; }
}

/* ═══ Karte, eingebettetes Google Maps ═════════════════════════
   Auf Anweisung vom 02.08.2026. Bis dahin standen hier zwei
   stehende OpenStreetMap-Bilder, die beim Hineinscrollen
   ineinander zoomten.

   MIT DEM WECHSEL IST RUND EIN DRITTEL DIESES BLOCKS ENTFALLEN,
   und zwar ersatzlos: die view-timeline am Rahmen, .karte-weit
   und .karte-nah, der @supports-Block und die beiden Keyframes
   karte-weg/karte-her. Sie hingen alle daran, dass zwei Bilder
   uebereinander lagen. Eine Google-Karte zoomt selbst, und zwar
   auf Zuruf statt beim Scrollen. Die Fassung mit der Ueberblendung
   steht vollstaendig in der Git-Historie, Stand 750c4a0.

   Was geblieben ist: die Lesebreite, der Rahmen und die
   Bildunterschrift.                                             */
.karte { max-inline-size: 34rem; margin-block-end: clamp(1.8rem, 4vw, 2.4rem); }

/* Der Rahmen traegt das Seitenverhaeltnis, nicht der iframe.
   Ein iframe ohne Hoehenangabe faellt auf 150px zurueck, und
   aspect-ratio direkt am iframe wird von aelteren Fassungen
   ignoriert. Der Kasten drumherum ist die verlaessliche Angabe.
   overflow: hidden schneidet die Ecken der Karte am Radius ab,
   der iframe selbst kennt den Radius seines Rahmens nicht. */
.karte-fenster {
  position: relative;
  aspect-ratio: 10 / 7;
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: var(--radius-btn);
  background: var(--paper-2);
}

/* ═══ KARTE ERST AUF KLICK, 06.09.2026 ═════════════════════════
   Das Fenster traegt jetzt entweder ein statisches Bild mit einem
   Knopf darauf oder, nach dem Klick, das iframe. Beide fuellen
   denselben Rahmen, damit die Seite beim Laden nicht springt.

   DER KNOPF SITZT MITTIG AUF DEM BILD und ist deckend, nicht
   durchscheinend: er steht auf einem Kartenausschnitt mit Strassen,
   Schrift und Farbflaechen, und auf so einem Grund ist kein
   Transparenzwert zuverlaessig. --ink auf --paper sind 15,8:1.

   Kein Radius ueber --radius-btn, kein Schatten. Der Knopf folgt
   .btn, damit er als Knopf erkannt wird und nicht als Hinweis. */
.karte-fenster { position: relative; }
.karte-fenster img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }

.karte-knopf {
  position: absolute; inset-block-start: 50%; inset-inline-start: 50%;
  transform: translate(-50%, -50%);
  display: grid; gap: .3rem; justify-items: center;
  padding: .8rem 1.2rem;
  background: var(--ink); color: var(--paper);
  border: 1px solid var(--ink); border-radius: var(--radius-btn);
  font-family: var(--sans); font-size: var(--t--1); font-weight: 600;
  font-stretch: var(--w-ui); letter-spacing: .04em;
  cursor: pointer; max-inline-size: min(22rem, 80%);
}
.karte-knopf:hover { background: var(--slate); border-color: var(--slate); }
/* Der Zusatz erklaert, was der Klick ausloest. Er gehoert in den
   Knopf, nicht daneben: wer ihn drueckt, soll es vorher gelesen
   haben, und ein Hinweis neben dem Knopf wird ueberlesen. */
.karte-hinweis {
  font-size: var(--t--2); font-weight: 400; letter-spacing: .02em;
  color: var(--bone); text-align: center; line-height: 1.35;
}
/* border: 0 ist noetig, nicht kosmetisch: Browser zeichnen um
   iframes von Haus aus einen 2px-Rahmen, und der saesse hier
   INNERHALB des eigenen. */
.karte-fenster iframe {
  position: absolute; inset: 0;
  inline-size: 100%; block-size: 100%;
  border: 0;
  display: block;
}

.karte-fuss {
  margin-block-start: .7rem;
  font-family: var(--sans); font-size: var(--t--2); font-stretch: var(--w-ui);
  color: var(--fg-mute); line-height: 1.5;
}
/* Der Routenlink stand vorher als .karte-hinweis IM Bild, weil das
   Bild selbst der Link war. Die eingebettete Karte faengt Klicks
   selbst ab, eine Schaltflaeche darueber waere entweder im Weg
   oder unerreichbar. Er steht deshalb jetzt in der Zeile unter der
   Karte, wo er auch ohne Maus zu erreichen ist.
   Unterstrichen, sonst waere er durch die globale Zuruecksetzung
   nicht als Link erkennbar. */
.karte-route {
  display: block;
  color: var(--teal-lo);
  font-weight: 600;
  border-block-end: 1px solid transparent;
  inline-size: fit-content;
}
.karte-route:hover { border-block-end-color: currentColor; }

/* ═══ Team ═════════════════════════════════════════════════════
   Zwei Varianten, weil der Bildbestand zwei Zustände hat:
   .roster mit Portraits.crew nur mit Namen. Portraits einer
   anderen Praxis einzusetzen wäre etwas anderes als ein
   Platzhalter-Raum, das sind echte Personen. Wo es keine
   Portraits gibt, stehen deshalb Namen.                          */

/* ─── Portraitreihe ────────────────────────────────────────────
   Vorher stand jedes Portrait auf einer anderen Höhe, treppenförmig
   versetzt. Das war unruhig und verstärkte zusätzlich, dass die sechs
   Aufnahmen sechs verschiedene Augenhöhen haben: bei versetzten
   Rahmen fällt jede Abweichung doppelt auf.

   Jetzt eine geschlossene Reihe auf einer Linie, getrennt durch
   Haarlinien. Das ist dasselbe Idiom wie bei der Standortwahl und
   beim Leistungsindex: getrennt wird mit Linien, nicht mit
   schwebenden Kästen. Die Trennung läuft über Ränder statt über
   gap plus Hintergrund, damit die Reihe auf jeder Fläche
   funktioniert und nicht nur auf der getönten.                     */
/* auto-fit statt drei fester Stufen. Die alten Media-Queries liefen
   verkehrt herum: bei 744 Pixeln standen zwei Portraits zu je 335
   Pixeln, bei 800 waren es drei zu je 240. Die Reihe wurde beim
   Breiterwerden KLEINER, weil die Zweispaltigkeit an "unter 48rem"
   hing statt an einer echten Untergrenze je Portrait.

   Jetzt bestimmt die Mindestbreite eines Gesichts die Spaltenzahl,
   und die Zahl der Spalten ergibt sich von selbst. Kein Breakpoint,
   keine nth-child-Arithmetik, die bei jeder Spaltenzahl anders
   aussieht.

   Die Trennung laeuft deshalb ueber einen Haarspalt mit
   Rasterhintergrund, wie bei .doors und .galerie: Raender ueber
   nth-child setzen ein festes Raster voraus, das es hier nicht
   mehr gibt. Das ist derselbe Baukasten, nur die andere Haelfte. */
.roster {
  list-style: none;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
  gap: 1px; background: var(--rule);
  border-block: 1px solid var(--rule);
}
/* Die Kacheln muessen deckend sein, sonst schlaegt der
   Rasterhintergrund durch. Sie nehmen den Grund ihres Abschnitts,
   deshalb die zweite Regel: der Teamabschnitt steht auf tint. */
.roster-item { background: var(--paper); }
[data-tone="tint"] .roster-item { background: var(--paper-2); }

.roster-item { min-inline-size: 0; padding-block-end: clamp(.9rem, 2vw, 1.3rem); }
.roster img {
  inline-size: 100%; aspect-ratio: 5 / 7; object-fit: cover; object-position: 50% 22%;
  filter: grayscale(.28) contrast(1.03);
  transition: filter .35s ease;
}
.roster-item:hover img { filter: none; }
.roster-name {
  font-family: var(--sans); font-size: var(--t--1); font-weight: 600;
  font-stretch: var(--w-label); text-transform: uppercase; letter-spacing: .1em;
  margin-block-start: .8rem; padding-inline: clamp(.5rem, 1.4vw, .9rem);
}
.roster-role {
  font-family: var(--sans); font-size: var(--t--2); font-stretch: var(--w-ui);
  letter-spacing: .04em; color: var(--fg-mute); line-height: 1.35;
  padding-inline: clamp(.5rem, 1.4vw, .9rem);
}

/* Fußnote unter der Portraitreihe. Sie benennt, welches Team zu sehen
   ist, damit sechs Gesichter nicht als Gesamtheit gelesen werden. */
.roster-fuss {
  font-size: var(--t--1); color: var(--fg-mute); line-height: 1.6;
  max-inline-size: 52ch; margin-block-start: clamp(3.2rem, 7vw, 4.5rem);
}

.crew { list-style: none; border-block-start: 1px solid var(--rule); }
.crew li {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: .2rem 1.5rem;
  padding-block: clamp(.9rem, 2vw, 1.3rem);
  border-block-end: 1px solid var(--rule);
}
.crew-name { font-family: var(--sans); font-size: var(--t-1); font-weight: 600; font-stretch: var(--w-head); letter-spacing: -.015em; }
.crew-role { color: var(--fg-mute); align-self: center; }

/* ═══ Terminanfrage ════════════════════════════════════════════
   KEIN Live-Kalender. Bei Physiotherapie ist das die falsche
   Abstraktion: die Verordnung muss binnen 28 Tagen begonnen
   werden, zwischen Terminen dürfen höchstens 14 Tage liegen, und
   Erst- gegen Folgetermin brauchen verschiedene Slotlängen. Ein
   blinder Kalender produziert dadurch falsche Buchungen, ATHERA
   mit 31 Praxen verzichtet aus genau diesem Grund darauf.
   Stattdessen die strukturierte Anfrage mit zugesagter Antwortzeit. */

.form { display: grid; gap: 1rem; }
.field { display: grid; gap: .35rem; min-inline-size: 0; }
.field label { color: var(--fg-mute); }
/* --rule-strong statt --rule: Rahmen von Bedienelementen brauchen
   3:1 nach SC 1.4.11, --rule schafft nur 1,40:1. Das war Defekt 2
   der Vorgängerseite. */
.field input, .field select, .field textarea {
  font-family: var(--sans); font-size: var(--t-0); color: var(--fg);
  background: var(--paper); border: 1px solid var(--rule-strong);
  padding: .75rem .85rem; inline-size: 100%;
}
.field textarea { min-block-size: 7rem; resize: vertical; }
.field input:hover, .field select:hover, .field textarea:hover,
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { border-color: var(--amber-lo); }

/* ─── Dateifelder der Bewerbung ───────────────────────────────
   Nur auf /karriere/. Der native Auswahlknopf sieht in jedem
   Browser anders aus; ::file-selector-button holt ihn in die
   Typografie der Seite, ohne JavaScript.

   Der Dateiname daneben bleibt die native Anzeige des Browsers.
   Eine nachgebaute Anzeige bräuchte ein Skript, und ohne dieses
   Skript sähe der Benutzer nicht mehr, was er hochlädt. Die
   Marken-Regel „Linien statt Kästen" gilt weiter, --radius-btn
   trägt hier ein echter Knopf, nichts anderes.               */
.field input[type="file"] {
  font-family: var(--sans); font-size: var(--t--1);
  font-stretch: var(--w-ui); color: var(--fg-mute);
  padding: .5rem .55rem; cursor: pointer;
}
.field input[type="file"]::file-selector-button {
  font-family: var(--sans); font-size: var(--t--1); font-weight: 600;
  font-stretch: var(--w-ui); letter-spacing: .04em; text-transform: uppercase;
  color: var(--fg); background: var(--paper-2);
  border: 1px solid var(--rule-strong); border-radius: var(--radius-btn);
  padding: .5rem 1rem; margin-inline-end: .85rem;
  cursor: pointer; transition: background .18s ease, border-color .18s ease;
}
.field input[type="file"]:hover::file-selector-button { border-color: var(--amber-lo); background: var(--bone); }

/* Erklärt Format und Grenze am Feld, nicht in einer Fußnote:
   wer erst beim Absenden erfährt, dass 30 MB zu viel sind, hat
   die Bewerbung schon geschrieben. */
.field-hint { font-size: var(--t--2); color: var(--fg-mute); line-height: 1.5; }

/* „(Optional)" steht im Label statt in einer Legende, damit ein
   Screenreader es zusammen mit dem Feldnamen vorliest. Unterschieden
   wird über das Gewicht, nicht über Deckkraft: --fg-mute liegt bei
   var(--t--2) schon nah an der 4,5:1-Grenze, ein Alphawert darunter
   würde sie reißen. */
.field label .opt { font-weight: 400; }

/* Zwei feste Spuren waren nicht auflösbar: die Min-Content-Breite eines
   <select> ist seine längste Option, und „KG-ZNS, Krankengymnastik ZNS"
   braucht rund 220px. Bei 380px Viewport bleiben je Feld etwa 165px,
   die Zeile konnte nicht schrumpfen und schob die Seite horizontal auf.
   auto-fit löst das ohne neuen Breakpoint. */
.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr)); gap: 1rem; align-items: start; }

.check { display: flex; gap: .7rem; align-items: flex-start; }
.check input { inline-size: 1.1rem; block-size: 1.1rem; flex: none; margin-block-start: .2rem; accent-color: var(--teal); }
.check label { font-family: var(--sans); font-size: var(--t--1); text-transform: none; letter-spacing: 0; color: var(--fg); line-height: 1.5; }

.form-note { font-size: var(--t--1); color: var(--fg-mute); line-height: 1.55; }
.form-note a { border-bottom: 1px solid var(--rule-strong); }
.form-note a:hover { border-color: var(--amber-lo); }

/* ═══ Glaszone ═════════════════════════════════════════════════
   Uebernommen aus dem v0-Export "liquid-glass-login-page", auf
   ausdrueckliche Entscheidung vom 31.07.2026. Gewollt ist das
   FORMULAR in dieser Optik, nicht die Buehne darum: der
   violett-rosa Farbverlauf und die schwebenden Glaskugeln des
   Exports bleiben draussen, auf Ansage. Die Zone sitzt deshalb
   auf data-tone="tint", also auf --paper-2 aus der eigenen
   Palette, und die Karte hebt sich davon ab.

   Was bleibt, widerspricht der Verbotsliste weiterhin an drei
   Punkten: Glassmorphism, Schlagschatten als Gestaltung statt
   als Ausnahme, Radius auf Flaechen. Das ist bekannt und
   gewollt.

   Der Block ist GEKAPSELT: alles haengt an .glaszone, die
   Rohwerte stehen als --glas-* Tokens am Zonenwurzelelement, und
   ohne diese Klasse aendert sich auf den uebrigen Seiten nichts.
   Wer die Zone entfernt, entfernt zwei Klassen je Seite.

   Drei Abweichungen vom Export, jede erzwungen:

   1. INTER liegt nicht vor und darf nicht von Google geladen
      werden (DSGVO, genau der Fehler der Altseiten). Es steht
      Archivo auf Normalbreite, dieselbe Gattung. Eine dritte
      Schriftfamilie fuer zwei Seiten waere ein zweiter Download.
   2. FELDRAHMEN. Der Export zeichnet sie in rgba(255,255,255,.4),
      also hell auf hell, gemessen rund 1,2:1. SC 1.4.11 verlangt
      3:1 fuer Bedienelemente, und bei drei Praxen greift das
      BFSG. Der Rahmen ist deshalb --glas-kante-stark und bleibt
      weich.
   3. HILFSTEXTE. rgba(55,65,81,.5) des Exports liegt auf hellem
      Grund bei rund 3:1. Sie stehen jetzt auf --glas-fg-mute.

   4. SAETTIGUNG, 01.08.2026 nachgetragen. Der Export legte das
      Glas ueber einen violett-rosa Verlauf; dort war das
      saturate(250%) im backdrop-filter der Effekt. Hier liegt
      --paper-2 darunter, ein warmes Beige, und 250 Prozent
      verstaerken genau dessen Gelbanteil: die Karte stand
      sichtbar gelbstichig auf einer Seite, die sonst neutral
      ist. Es bleibt der Weichzeichner, die Saettigung faellt
      weg. Was die Karte traegt, sind Kante, Innenglanz und
      Schatten, nicht die Farbverstaerkung.

      Weil ohne den Sprung in der Saettigung der Unterschied zur
      Zone kleiner wird, steigt die Deckkraft: Karte .55 auf .68,
      Platte .3 auf .42, Feldfuellung .6 auf .78. Die Karte liegt
      damit bei #FAF8F4, also fast neutral, statt den Beigeton
      der Zone zu uebertreiben.

   Kontraste, Stand 31.07.2026 am Bild nachgemessen, am
   01.08.2026 fuer die neuen Flaechen nachgerechnet:
   Text auf der Karte 11,8:1 (vorher 12,2), Hilfstexte 7,1:1
   (7,3), Feldrahmen 3,6:1 gegen die Fuellung (3,4) und 3,5:1
   gegen die Karte (3,6), Knopfschrift und Fokusring unveraendert.
   Die hellere Fuellung nimmt dunklem Text ein Zehntel und gibt
   es dem Rahmen zurueck; beide Grenzen, 4,5:1 fuer Text und 3:1
   fuer Bedienelemente, bleiben deutlich gehalten.

   Ohne den Verlauf ist die Flaeche hinter der Karte konstant,
   die Rechnung gilt deshalb fuer die ganze Karte und nicht nur
   stellenweise.

   Wer --glas-kante-stark aufhellt, reisst als Erstes die 3:1 am
   Feldrahmen. Bei .45 waren es 2,6:1, gemessen.               */

.glaszone {
  --glas-fg:           #2C3440;
  --glas-fg-mute:      #4A5568;
  --glas-flaeche:      rgba(255, 255, 255, .68);
  --glas-flaeche-lo:   rgba(255, 255, 255, .42);
  --glas-feld:         rgba(255, 255, 255, .78);
  --glas-kante:        rgba(255, 255, 255, .7);
  --glas-kante-stark:  rgba(38, 45, 56, .58);
  --glas-tief:         #0C115B;
  --glas-radius:       1rem;
  --glas-radius-feld:  .75rem;

  /* Dieselbe Umschaltung wie [data-tone="ink"], nur in die andere
     Richtung: die Zone schreibt die Tokens um, statt dass jede
     Regel darin ihre Farbe von Hand setzt. */
  --fg: var(--glas-fg);
  --fg-mute: var(--glas-fg-mute);
  --rule: rgba(38, 45, 56, .18);
  --rule-strong: var(--glas-kante-stark);
  --focus: var(--glas-tief);

  color: var(--glas-fg);
  font-family: var(--sans);
  font-stretch: 100%;
}

/* Archivo ist eine Breitenschrift, Inter nicht. Was im Export
   normalbreit steht, steht hier sonst auf --w-label oder --w-ui
   und wirkt daneben gequetscht. */
.glaszone :is(.field label, .fact dt, .form-note, .field-hint, .lede) { font-stretch: 100%; }
/* Der Export beschriftet Felder in Satzschreibung, nicht als
   Versal-Kleinstlabel. Das ist der sichtbarste Unterschied
   zwischen den beiden Formularen, deshalb steht er hier. */
.glaszone .field label {
  font-size: var(--t--1); font-weight: 500;
  text-transform: none; letter-spacing: 0;
  color: var(--glas-fg);
}
.glaszone .field label .opt { font-weight: 400; color: var(--glas-fg-mute); }
/* HIER STAND EIN RUECKHOLER fuer .field input, .field select,
   .field textarea, .check label und .fact dd.plain. Die fuenf
   setzten die Serif ausdruecklich und mussten in der Zone einzeln
   auf die Sans zurueckgeholt werden. Seit der Umstellung vom
   01.08.2026 tragen sie ohnehin Archivo, die Regel war eine
   Wiederholung ohne Wirkung. */

/* ─── Die Karte ───────────────────────────────────────────────
   Der einzige Ort der Website mit Schlagschatten als Gestaltung
   statt als Ausnahme.

   Die Deckkraft liegt hoeher als im Export (.68 statt .25). Dort
   lag ein Foto darunter, das durchscheinen sollte; hier liegt
   eine ruhige Flaeche, und bei .25 waere die Karte von ihr kaum
   zu unterscheiden gewesen. Die Kante, der Innenglanz und der
   Schatten tragen die Optik, nicht die Transparenz.           */
.glaskarte {
  padding: clamp(1.4rem, 4vw, 2.4rem);
  border-radius: var(--glas-radius);
  background: var(--glas-flaeche);
  /* Ohne saturate(): siehe Punkt 4 im Kopf der Zone. */
  backdrop-filter: blur(40px);
  -webkit-backdrop-filter: blur(40px);
  border: 1px solid var(--glas-kante);
  box-shadow:
    0 32px 80px rgba(0, 0, 0, .3),
    0 16px 64px rgba(255, 255, 255, .2),
    inset 0 3px 0 rgba(255, 255, 255, .6),
    inset 0 -1px 0 rgba(255, 255, 255, .3);
}
/* Die zweite Spalte traegt die leichtere Stufe des Exports
   (dort die Knoepfe "Continue with"), damit sie zur Karte
   gehoert, ohne ihr den Rang abzulaufen. */
.glasplatte {
  padding: clamp(1.2rem, 3.5vw, 1.9rem);
  border-radius: var(--glas-radius);
  background: var(--glas-flaeche-lo);
  backdrop-filter: blur(25px);
  -webkit-backdrop-filter: blur(25px);
  border: 1px solid rgba(255, 255, 255, .3);
  box-shadow: 0 8px 32px rgba(0, 0, 0, .1), inset 0 1px 0 rgba(255, 255, 255, .4);
}

.glaszone :is(.field input, .field select, .field textarea) {
  background: var(--glas-feld);
  border: 1px solid var(--glas-kante-stark);
  border-radius: var(--glas-radius-feld);
  color: var(--glas-fg);
  transition: background .2s ease, border-color .2s ease;
}
/* Heller als der Ruhezustand, nicht dunkler. Solange --glas-feld
   bei .6 stand, war .55 im Hover praktisch derselbe Wert; seit
   der Fuellung .78 waere es ein Rueckschritt, und das Feld haette
   bei Beruehrung abgedunkelt. */
.glaszone :is(.field input, .field select, .field textarea):hover,
.glaszone :is(.field input, .field select, .field textarea):focus-visible {
  background: rgba(255, 255, 255, .95);
  border-color: var(--glas-tief);
}
.glaszone .field input[type="file"]::file-selector-button {
  background: var(--glas-flaeche);
  border-color: var(--glas-kante-stark);
  border-radius: var(--glas-radius-feld);
  color: var(--glas-fg);
  letter-spacing: .02em;
}
.glaszone .field input[type="file"]:hover::file-selector-button {
  background: rgba(255, 255, 255, .9); border-color: var(--glas-tief);
}
.glaszone .check input { accent-color: var(--glas-tief); }

.glaszone .btn {
  background: var(--glas-tief);
  border-radius: var(--glas-radius-feld);
  padding-block: 1.15rem;
  font-weight: 700;
  letter-spacing: .03em;
  transition: transform .3s cubic-bezier(.4, 0, .2, 1), box-shadow .3s cubic-bezier(.4, 0, .2, 1);
}
.glaszone .btn:hover { background: var(--glas-tief); transform: translateY(-2px); box-shadow: 0 10px 25px rgba(0, 0, 0, .25); }
.glaszone :is(.form-note a, .fact a) { border-bottom-color: var(--glas-kante-stark); }
.glaszone :is(.form-note a:hover, .fact a:hover) { border-bottom-color: var(--glas-tief); }
.glaszone .phone { border-bottom-color: var(--glas-tief); }

/* Nicht verhandelbar, steht so im Designsystem: wer Bewegung
   abschaltet, bekommt keine. Das Glas bleibt, nur das Anheben
   des Knopfes hoert auf. */
@media (prefers-reduced-motion: reduce) {
  .glaszone .btn:hover { transform: none; }
}

/* ═══ Bildband ════════════════════════════════════════════════
   BILDREGEL, verbindlich für alle Seiten: es wird der RAUM
   gezeigt, nicht die Pose. Räume, Hände, Geräte, Tageslicht —
   keine gestellten Personen, keine Stockfotos, keine Vorher-
   Nachher-Gegenüberstellungen. Jedes Bild läuft randlos über die
   volle Breite, hat dieselbe Gradation und trägt eine Bildunter-
   schrift, die benennt, was zu sehen ist UND wo es steht.
   Portraits gehören ausschließlich in den Team-Zusammenhang der
   jeweiligen Standortseite, nie in die redaktionelle Fläche.     */

.band { position: relative; }
/* Die Hoehe ist zusaetzlich an die BREITE gekoppelt. Ohne das min()
   stand auf einem 380er Telefon ein Feld von 380 x 416 Pixeln vor
   einer Quelle im Verhaeltnis 3:2: rund 39 Prozent der Bildbreite
   fielen dem Beschnitt zum Opfer. Beim Zeichen auf der Lattenwand
   fehlte das "v" von "Aktiv", waehrend die Bildunterschrift "Das
   Zeichen" darunterstand. 66vw haelt den Ausschnitt auf jeder
   Breite nahe am Seitenverhaeltnis der Quelle. */
.band img {
  inline-size: 100%;
  block-size: min(clamp(22rem, 52vh, 34rem), 66vw);
  object-fit: cover;
  filter: saturate(.92) contrast(1.04);
}
/* Gruppenaufnahmen sitzen im Bild anders als ein Raum: ueber den
   Koepfen ist wenig Luft, unter den Fuessen viel Boden. Der
   mittige Beschnitt von .band nimmt deshalb ausgerechnet die
   Koepfe weg und laesst den Boden stehen. Auf /karriere/ und
   /ratgeber/ war den Personen in der hinteren Reihe der Scheitel
   abgeschnitten, am Bild gesehen, nicht am Code.

   .hoch verschiebt den Ausschnitt nach oben, statt die Bandhoehe
   fuer alle Baender zu aendern. Nur fuer Aufnahmen mit Personen
   noetig, bei Raeumen ist mittig richtig.                        */
.band img.hoch { object-position: 50% 18%; }

/* ═══ GRUPPENAUFNAHMEN BRAUCHEN HOEHE, NICHT NUR EINEN ANDEREN
   BESCHNITT, 04.09.2026 ═══════════════════════════════════════
   Auf /karriere/ schnitt das Band zwei Personen der vorderen Reihe
   den Kopf ab. Die Quelle hat 3:2, angezeigt wurde sie bei 1440
   Pixeln mit 3,08:1, es fielen also 51 Prozent der Bildhoehe weg.

   MIT object-position IST DAS NICHT ZU LOESEN, und das ist der
   Punkt: bei 48 Prozent sichtbarer Hoehe passen die stehende Reihe
   (oben) und die sitzende Reihe (unten) nicht gleichzeitig hinein.
   .hoch mit 18 Prozent rettet die Koepfe oben und opfert dafuer die
   vordere Reihe. Jeder andere Wert dreht das nur um.

   Deshalb hier eine echte Ausnahme von der gedeckelten Bandhoehe:
   2:1 statt bis zu 3:1. Bei 1440 sind das 720 statt 468 Pixel, und
   damit bleiben 75 Prozent der Quelle stehen. Der Beschnitt sitzt
   bei 38 Prozent, also knapp unter der Mitte: oben faellt die leere
   Deckenflaeche weg, unten bleibt die vordere Reihe drin.

   NUR FUER GRUPPENAUFNAHMEN. Ein Raum braucht das nicht, bei ihm
   ist der flache Streifen richtig. Wer die Klasse auf ein Raumbild
   setzt, macht das Band ohne Grund hoch.                        */
.band img.gruppe {
  /* UEBER DAS SEITENVERHAELTNIS, nicht ueber vh. Der erste Versuch
     hing an 62vh und blieb damit auf einem 760 Pixel hohen Fenster
     bei 471 Pixeln stehen, also genau beim alten Beschnitt. Wie viel
     vom Bild uebrig bleibt, haengt vom Verhaeltnis ab und von sonst
     nichts, also gehoert die Regel auch dorthin. */
  block-size: auto;
  aspect-ratio: 2 / 1;
  object-position: 50% 38%;
}
/* Auf dem Telefon gar kein Beschnitt: bei 390 Pixeln Breite waeren
   2:1 nur 195 Pixel hoch, und darin ist ein Gruppenbild nicht mehr
   zu erkennen. Die volle Quelle ist dort 260 Pixel hoch, das traegt. */
@media (max-width: 48rem) {
  .band img.gruppe { aspect-ratio: 3 / 2; object-position: 50% 50%; }
}
.band figcaption {
  position: absolute; inset-block-end: clamp(1rem, 3vw, 2rem); inset-inline-start: clamp(1rem, 3vw, 2rem);
  background: var(--ink); color: var(--paper);
  padding: 1rem 1.3rem; max-inline-size: 26rem;
  font-size: var(--t--1); line-height: 1.5;
}
.band figcaption strong {
  font-family: var(--sans); font-weight: 600; font-stretch: var(--w-label);
  text-transform: uppercase; letter-spacing: .12em; font-size: var(--t--2);
  color: var(--bone); display: block; margin-block-end: .4rem;
}

/* ═══ ZWEI BILDBLOECKE HINTEREINANDER, 03.09.2026 ══════════════
   Seit die drei Standortseiten neben der Reportagestrecke ein
   eigenes Band ihrer Raeume tragen, stossen dort zwei randlose
   Bildbloecke unmittelbar aneinander.

   OHNE ABSTAND VERSCHMELZEN SIE. Die Unterschrift der Strecke
   klebt an der Oberkante des naechsten Fotos, und wo das eine
   aufhoert und das andere anfaengt, ist nicht mehr zu sehen. Am
   Bild aufgefallen, im Quelltext war nichts Auffaelliges: beide
   Bloecke sind fuer sich richtig gebaut, falsch ist nur, dass sie
   sich beruehren.

   DER ABSTAND IST KEIN NEUER WERT, sondern der Zwischenraum eines
   Abschnitts. Getrennt wird hier durch Papier statt durch eine
   Haarlinie, weil eine Linie zwischen zwei randlosen Fotos wie
   eine Bildkante aussaehe und nicht wie eine Trennung.

   Der Selektor greift ueber Kommentare hinweg, die zaehlen als
   Geschwister nicht mit. Er gilt in beide Richtungen, damit auch
   ein Block NACH einem Band Luft bekommt.                       */
figure + .band,
.band + figure,
.band + .hochband { margin-block-start: clamp(3rem, 7vw, 5rem); }

/* ═══ Drei Wege, der deutsche Rezept/Privat-Split ═════════════
   Kein „Feature-Raster": Patienten kommen auf genau drei Wegen in
   die Praxis, und das sind sie. Sitzt als Regalbrett ohne eigenes
   padding-block direkt am Nachbarabschnitt.                       */

/* auto-fit statt drei fester Spalten plus Media-Query. Uebernommen
   von .field-row, der besten intrinsischen Loesung im Stylesheet:
   die Spaltenzahl folgt aus der Mindestbreite einer Kachel, nicht
   aus einer Bildschirmbreite. Der Umbruch findet damit dort statt,
   wo der Inhalt ihn braucht.

   Bei .doors sind alle Kacheln gleichwertig, deshalb passt es hier.
   Auf .index waere es falsch: dort sind die Spalten verschiedene
   Datenfelder und keine Kachelreihe. */
.doors { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); gap: 1px; background: var(--rule); border-block: 1px solid var(--rule); }
.door {
  background: var(--paper); padding: clamp(1.6rem, 4vw, 2.6rem) clamp(1.2rem, 3vw, 2rem);
  display: flex; flex-direction: column; gap: .7rem;
  transition: background .2s ease;
}
a.door:hover { background: var(--paper-2); }
.door h3 { font-size: var(--t-1); font-stretch: var(--w-head); }
.door p  { font-size: var(--t--1); color: var(--fg-mute); line-height: 1.55; flex: 1; }
.door-go { color: var(--teal-lo); }

/* ─── Tuer mit zwei Zielen ─────────────────────────────────────
   Auf /kontakt/ ist .door seit dem 02.08.2026 kein <a> mehr,
   sondern ein <div> mit ZWEI Links darin: die Rufnummer der Praxis
   und ihre Standortseite. Grund ist schlicht, dass <a> kein <a>
   enthalten darf — und die Nummer muss anrufbar sein, ohne dass man
   erst die Standortseite oeffnet.

   Der Flaechen-Hover haengt deshalb oben an `a.door` und nicht mehr
   an `.door`: eine Flaeche, die auf Zeigen reagiert, ohne anklickbar
   zu sein, verspricht etwas, das sie nicht halten kann. Die anderen
   Tueren (Ueber uns, Karriere) sind weiterhin Links und behalten ihn.

   Statt dessen faerbt sich der Block, wenn wirklich einer seiner
   beiden Links angesteuert wird — mit der Maus wie mit der
   Tastatur. */
div.door:has(a:hover),
div.door:focus-within { background: var(--paper-2); }
/* Ohne align-self dehnt der Flex-Container die Nummer auf die volle
   Spaltenbreite; ihre Unterstreichung liefe dann quer durch die
   Kachel, weit ueber die Ziffern hinaus. */
div.door .phone { align-self: start; }

/* ═══ Leistungskacheln auf der Übersicht ══════════════════════
   Der Kunde führt seine Leistungen als Kachelraster mit je einem
   Foto und wollte das hier genauso. Die Übersicht zeigte bis zum
   31.07.2026 nur den Zeilenindex, also kein einziges Bild.

   ABWEICHUNG, bewusst: die Verbotsliste nennt "shadcn-Kartenraster"
   und "Drei-Karten-Reihen". Der Unterschied liegt darin, was eine
   Karte ausmacht. Hier gibt es keinen Schatten, keinen Radius am
   Rahmen, keinen Abstand zwischen schwebenden Kästen: die Kacheln
   sitzen auf einem Haarspalt und teilen sich eine durchgehende
   Fläche, genau wie .doors und .galerie. Es ist dasselbe Vokabular,
   nur mit Bild.

   Der Zeilenindex bleibt: er steht weiterhin auf den Standortseiten
   und trägt dort die Kürzelspalte, nach der man auf dem Rezept
   sucht. Zwei Darstellungen für zwei Zwecke, nicht eine, die beides
   halb kann.                                                       */
/* Die Haarlinien sitzen an den KACHELN, nicht am Raster. Der sonst
   uebliche Weg (gap: 1px plus Rasterhintergrund) funktioniert nur,
   wenn die Kachelzahl die Spaltenzahl teilt. Neun Leistungen in
   vier Spalten lassen in der letzten Reihe drei leere Zellen, und
   dort stand dann eine graue Flaeche ohne Inhalt.

   So bleiben leere Zellen leer, und die Linien stimmen bei jeder
   Spaltenzahl, die auto-fit gerade waehlt.                        */
/* ═══ 17rem AUF 22rem, 05.09.2026 ═══════════════════════════════
   Bei 17rem waehlte auto-fit auf einem 1440er Schirm vier Spalten.
   Neun Kacheln ergeben dann 4 + 4 + 1: „Hausbesuche" stand allein in
   der letzten Reihe, rechts daneben rund 1000 Pixel Leere mit
   sichtbarer Rasterlinie.

   22rem ergibt bei denselben 1440 Pixeln drei Spalten, und 3 x 3
   geht auf. Der Weg ueber die Mindestbreite ist der richtige: die
   Zahl der Spalten soll aus der Kachel folgen, nicht aus einer
   Bildschirmbreite. Auf 900 Pixeln bleiben es zwei Spalten, auf dem
   Telefon eine, dort ist die Waise ohnehin keine.

   WER EINE ZEHNTE LEISTUNG AUFNIMMT, hat wieder eine Waise. Dann
   entweder auf 12 Kacheln gehen oder diesen Wert neu rechnen.      */
.lkarten {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
  border-block-start: 1px solid var(--rule);
}
.lkarte {
  display: flex; flex-direction: column;
  background: var(--paper);
  border-block-end: 1px solid var(--rule);
  border-inline-end: 1px solid var(--rule);
  transition: background .2s ease;
}
.lkarte:hover { background: var(--paper-2); }
[data-tone="tint"] .lkarte { background: var(--paper-2); }
[data-tone="tint"] .lkarte:hover { background: var(--paper); }

.lkarte-bild { position: relative; overflow: hidden; }
.lkarte-bild img {
  display: block; inline-size: 100%; aspect-ratio: 16 / 10; object-fit: cover;
  filter: saturate(.92) contrast(1.04);
  transition: scale .4s var(--ease);
}
.lkarte:hover .lkarte-bild img { scale: 1.03; }

/* Das Kürzel sitzt AUF dem Bild, nicht darunter. Auf dem Rezept
   steht es zuerst, hier soll es zuerst gefunden werden. */
.lkarte-code {
  position: absolute; inset-block-start: 0; inset-inline-start: 0;
  background: var(--ink); color: var(--paper);
  font-family: var(--sans); font-size: var(--t--2); font-weight: 700;
  font-stretch: var(--w-label); letter-spacing: .1em; text-transform: uppercase;
  padding: .4rem .7rem;
}
.lkarte-in {
  display: flex; flex-direction: column; gap: .5rem; flex: 1;
  padding: clamp(1.1rem, 3vw, 1.5rem) clamp(1.1rem, 3vw, 1.5rem) clamp(1.2rem, 3.2vw, 1.6rem);
}
.lkarte-name { font-family: var(--sans); font-size: var(--t-1); font-stretch: var(--w-head); letter-spacing: -.015em; }
.lkarte-desc { font-size: var(--t--1); color: var(--fg-mute); line-height: 1.55; flex: 1; }
.lkarte-go   { font-family: var(--sans); font-size: var(--t--1); font-weight: 600; font-stretch: var(--w-ui); color: var(--teal-lo); }
.lkarte-go span { display: inline-block; transition: transform .2s ease; }
.lkarte:hover .lkarte-go span { transform: translateX(4px); }

@media (prefers-reduced-motion: reduce) {
  .lkarte-bild img, .lkarte-go span { transition: none; }
  .lkarte:hover .lkarte-bild img { scale: 1; }
}

/* ═══ Leistungsbild ═══════════════════════════════════════════
   Ein Foto zur konkreten Behandlung, in der Inhaltsspalte statt
   randlos. Der Grund ist die Quelle: die sechs Aufnahmen aus dem
   Kundenexport sind nur 800 x 500 Pixel. Randlos ueber 1264 Pixel
   gezogen waeren sie sichtbar weich. In der Spalte stehen sie in
   ihrer echten Groesse und bleiben scharf.

   Der Kunde fuehrt auf seiner eigenen Seite je Leistung ein
   eigenes Foto. Das ist die bessere Loesung als sechsmal derselbe
   Trainingsraum, und der Grund, warum diese Bilder hier stehen.  */
.leistungsbild { margin-block: clamp(1.8rem, 4vw, 2.6rem); max-inline-size: 50rem; }
.leistungsbild img {
  display: block; inline-size: 100%; block-size: auto;
  filter: saturate(.92) contrast(1.04);
}
.leistungsbild figcaption {
  font-family: var(--sans); font-size: var(--t--2); font-stretch: var(--w-ui);
  color: var(--fg-mute); line-height: 1.5;
  margin-block-start: .7rem; padding-inline-start: .9rem;
  border-inline-start: 2px solid var(--amber);
}

/* ═══ Google-Bewertung als Sektion ════════════════════════════
   Vorlage ist eine Bewertungskarte, die der Kunde am 31.07.2026
   gezeigt hat: weisse Flaeche, das bunte G, Sterne, Aufruf zum
   Bewerten. Ausdruecklich NICHT im Hochformat der Vorlage, sondern
   quer ueber die Inhaltsbreite.

   ZWEI ABWEICHUNGEN VOM DESIGNSYSTEM, beide bewusst und beide auf
   Kundenwunsch:
   1. Eine deckende weisse Flaeche in einem System, das mit Linien
      trennt. Ein Guetesiegel, das mit dem Untergrund verschwimmt,
      ist keins.
   2. Vier Fremdfarben, die in keinem Token stehen. Das Google-G
      ist eine Marke und darf nicht umgefaerbt werden; ein G in
      --teal waere schlechter als gar keins. Deshalb steht es
      unveraendert im Markup und nirgends sonst.

   Rot, Gelb, Gruen und Blau kommen NUR in diesem einen SVG vor.
   Wer sie woanders sieht, hat einen Fehler gefunden.

   Kein Google-Widget, kein Skript, kein externer Request: das G
   ist Inline-SVG, die Sterne sind dieselben wie in .bewertung.  */
.g-bewertung {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(1.2rem, 3vw, 2.4rem);
  background: #fff; border: 1px solid var(--rule);
  border-radius: var(--radius-btn);
  padding: clamp(1.3rem, 3.5vw, 2rem) clamp(1.4rem, 4vw, 2.6rem);

  /* ═══ KONTRASTFEHLER, gefunden und behoben am 01.08.2026 ═══
     Die Karte ist immer weiss, egal was um sie herum liegt. Im
     Hero liegt sie aber INNERHALB von [data-tone="ink"], und diese
     Regel setzt --fg-mute auf #9AA3A5 und --rule auf --rule-ink,
     beides fuer dunklen Grund gedacht.

     Folge: der Erklaersatz stand mit #9AA3A5 auf Weiss, das sind
     2,5:1. WCAG SC 1.4.3 verlangt 4,5:1 fuer Fliesstext, der Satz
     war also unterschwellig unlesbar, und die Trennlinie in
     --rule-ink war fast schwarz auf Weiss.

     Die Umschaltung wird hier zurueckgedreht, dasselbe Muster wie
     [data-tone="ink"], nur in die andere Richtung: eine helle
     Flaeche innerhalb einer dunklen Sektion. Die Werte sind
     absichtlich die Wurzelwerte im Klartext, denn eine Variable
     kann ihren eigenen Wurzelwert nicht zurueckholen, sobald ein
     Vorfahr sie ueberschrieben hat.
     BEI EINER PALETTENAENDERUNG hier mitziehen, --fg-mute und
     --rule stehen bei den Farbtokens oben.                    ═══ */
  --fg-mute: #5E5A52;
  --rule:    #D8CEBF;

  /* ═══ REAKTION BEIM DARUEBERFAHREN, 01.08.2026 ═══
     Die ganze Karte ist ein <a> auf das Google-Profil und oeffnet
     einen neuen Tab, hatte aber KEINE einzige hover-Regel. Sie
     stand also unter dem Zeiger genauso da wie ohne ihn, und nichts
     verriet, dass sie ueberhaupt anklickbar ist. Das war der
     Einwand.

     ANHEBEN UND KANTE, KEIN SCHLAGSCHATTEN. Das waere der
     naheliegende Griff und ist hier verboten: weiter unten steht
     bei .karte, dass sie „der einzige Ort der Website mit
     Schlagschatten als Gestaltung" ist. Ein zweiter Schatten wuerde
     diesen Satz zur Falschaussage machen. Die Kante in --teal
     traegt die Rueckmeldung genauso und bleibt im System.

     transform statt inset: das Siegel im Hero ist absolut gesetzt,
     eine Verschiebung ueber inset wuerde ein Layout auslesen und
     neu rechnen, transform laeuft auf der Grafikkarte. */
  transition:
    transform    var(--dur-kurz) var(--ease),
    border-color var(--dur-kurz) var(--ease);
}
.g-bewertung:hover {
  transform: translateY(-2px);
  border-color: var(--teal);
}
/* Der Zeiger allein ist zu wenig, wenn jemand mit der Tastatur
   navigiert. Die globale Fokusregel legt den Rahmen darum, das
   Anheben kommt hier dazu, damit beide Wege dieselbe Antwort
   bekommen. */
.g-bewertung:focus-visible { transform: translateY(-2px); }

@media (prefers-reduced-motion: reduce) {
  .g-bewertung { transition: border-color var(--dur-kurz) var(--ease); }
  .g-bewertung:hover, .g-bewertung:focus-visible { transform: none; }
}
.g-logo { flex: none; inline-size: clamp(2.4rem, 5vw, 3.2rem); block-size: auto; }
.g-wert { display: flex; flex-direction: column; gap: .3rem; flex: none; }
.g-zahl {
  font-family: var(--sans); font-weight: 700; font-stretch: var(--w-head);
  font-size: var(--t-2); letter-spacing: -.02em; color: var(--ink);
  line-height: 1;
}
.g-zahl small {
  font-size: var(--t--1); font-weight: 600; color: var(--fg-mute);
  letter-spacing: 0; margin-inline-start: .15rem;
}
.g-bewertung .sterne { color: var(--stern); }
.g-bewertung .sterne svg { inline-size: 5.6rem; block-size: 1.1rem; }
.g-text {
  flex: 1 1 16rem; min-inline-size: 0;
  font-family: var(--sans); font-size: var(--t--1);
  color: var(--fg-mute); line-height: 1.5;
}
.g-text strong { display: block; font-family: var(--sans); font-size: var(--t-0); color: var(--ink); font-stretch: var(--w-head); margin-block-end: .2rem; }
.g-bewertung .btn { flex: none; }

/* IM BILDHERO ist es ein kleines Siegel in der unteren rechten Ecke,
   kein Abschnitt. Ausdrueckliche Vorgabe vom 31.07.2026: der volle
   Block war dort zu gross und hat den Hero uebernommen.

   Uebrig bleibt, was ein Siegel ausmacht: das G, die Zahl, die
   Sterne. Der Aufruf zum Bewerten und der Knopf entfallen; sie
   gehoeren zu einer Sektion, nicht in eine Ecke. Das Markup bleibt
   vollstaendig, damit derselbe Baustein anderswo als ganze Sektion
   funktioniert.                                                    */
.hero .g-bewertung {
  position: absolute; z-index: 2;
  inset-block-end: clamp(1rem, 3vw, 2.2rem);
  inset-inline-end: clamp(1rem, 4vw, 3rem);
  max-inline-size: 25rem; margin: 0;
  padding: .8rem 1rem; gap: .85rem;
  align-items: center;
}
/* Der Knopf entfaellt: das Siegel steht im Bild, nicht in einem
   Handlungsabschnitt. Der Text bleibt, er ist der Unterschied
   zwischen einer Grafik und einem Guetesiegel. */
.hero .g-bewertung .btn { display: none; }
.hero .g-logo { inline-size: 1.7rem; }
.hero .g-wert { flex: none; gap: .25rem; }
.hero .g-zahl { font-size: var(--t-1); }
.hero .g-zahl small { font-size: var(--t--2); }
.hero .g-bewertung .sterne svg { inline-size: 4.6rem; block-size: .9rem; }
.hero .g-bewertung .g-text {
  flex: 1 1 8rem; font-size: var(--t--2); line-height: 1.4;
  border-inline-start: 1px solid var(--rule); padding-inline-start: .8rem;
}
.hero .g-bewertung .g-text strong { font-size: var(--t--1); margin-block-end: .1rem; }

@media (max-width: 60rem) {
  /* Unter 60rem ist die Ecke keine Loesung mehr. Ein absolut
     gesetztes Siegel muesste dort so klein werden, dass es zur
     Grafik verkuemmert, und genau das war der Einwand.

     Es geht deshalb in den Fluss und nimmt die ganze Spaltenbreite:
     ein voller Block mit Marke, Zahl, Sternen und Text, so wie auf
     breiten Schirmen, nur untereinander statt nebeneinander.
     Sichtbar bleibt es dabei allemal, es steht direkt unter den
     beiden Handlungsknoepfen und nicht hinter ihnen. */
  .hero .g-bewertung {
    position: static; max-inline-size: none;
    margin-block-start: clamp(1.6rem, 5vw, 2.4rem);
    padding: .9rem 1.1rem; gap: .8rem 1rem;
  }
  .hero .g-bewertung .g-text {
    border-inline-start: 0; padding-inline-start: 0;
    border-block-start: 1px solid var(--rule); padding-block-start: .7rem;
    flex-basis: 100%; font-size: var(--t--1);
  }
  .hero .g-wert { flex-direction: row; align-items: baseline; gap: .6rem; }
  .hero .g-logo { inline-size: 1.6rem; }
}

@media (max-width: 48rem) {
  /* Der Aufruf rutscht unter die Zahl, statt sich neben ihr auf
     zwei Woerter je Zeile zu quetschen. */
  .g-bewertung { gap: 1rem; }
  .g-text { flex-basis: 100%; }

  /* ─── SIEGEL IM HERO, deutlich kleiner ───────────────────────
     Auf Anweisung vom 01.08.2026. Die Fassung ab 60rem hat die
     Karte in den Fluss geholt und dabei die volle Sektion
     nachgebaut, Trennlinie und Erklaersatz inklusive. Auf einem
     Telefon war das ein Kasten von rund 170px Hoehe direkt unter
     den Handlungsknoepfen, also mehr Platz als die beiden Knoepfe
     selbst.

     WAS BLEIBT, ist das Siegel: das G, die 5,0 und die Sterne in
     einer Zeile, darunter „Bewertungen bei Google". Das ist die
     Aussage.

     WAS ENTFAELLT, und warum das vertretbar ist:
       · Der Erklaersatz. „5,0 mit fuenf Sternen bei Google" sagt
         schon alles, was er erklaert, und er allein war zwei von
         vier Zeilen.
       · Die Trennlinie. Sie hat zwei Gruppen getrennt, von denen
         nach dem Wegfall des Satzes nur noch eine uebrig ist.
       · Das „/ 5" hinter der Zahl, weil fuenf Sterne unmittelbar
         daneben stehen und dasselbe sagen.
     Der Knopf war hier schon vorher aus, siehe .hero .g-bewertung.

     ES IST EINE ANZEIGEENTSCHEIDUNG, KEINE INHALTLICHE: der Satz
     steht auf breiten Schirmen unveraendert und bleibt im Markup.
     Wer ihn auf dem Telefon zurueckhaben will, nimmt die eine
     display-Zeile heraus.                                     */
  .hero .g-bewertung {
    margin-block-start: clamp(1rem, 3.5vw, 1.5rem);
    padding: .55rem .75rem;
    gap: .25rem .5rem;
    align-items: center;
  }
  .hero .g-logo { inline-size: 1.15rem; }
  .hero .g-wert { gap: .45rem; }
  .hero .g-zahl { font-size: var(--t-0); }
  .hero .g-zahl small { display: none; }
  .hero .g-bewertung .sterne svg { inline-size: 3.5rem; block-size: .7rem; }
  .hero .g-bewertung .g-text {
    flex-basis: 100%;
    border-block-start: 0; padding-block-start: 0;
    border-inline-start: 0; padding-inline-start: 0;
    font-size: var(--t--2); line-height: 1.3;
  }
  .hero .g-bewertung .g-text strong {
    font-size: var(--t--2); margin-block-end: 0;
    color: var(--fg-mute); font-weight: 600;
  }
  .hero .g-bewertung .g-erklaerung { display: none; }
}

/* ═══ Galerie ═════════════════════════════════════════════════
   Ein Raster gleich beschnittener Aufnahmen. Der Grund, dass es
   das gibt: die Lieferung vom 31.07.2026 besteht ueberwiegend aus
   HOCHFORMATEN, und die randlose .band ist ein Querformatbaustein.
   Ohne Galerie bleiben rund zwei Drittel der Fotos ungenutzt.

   Alle Kacheln teilen dasselbe Seitenverhaeltnis und werden
   beschnitten. Das ist Absicht: eine Galerie aus gemischten
   Formaten ist ein Flickenteppich, und Mauerwerk-Layouts brauchen
   entweder JavaScript oder eine Spaltenordnung, die von oben nach
   unten statt von links nach rechts liest.

   Getrennt wird wie bei .doors ueber einen Haarspalt, der den
   Rasterhintergrund durchscheinen laesst, nicht ueber Abstand.

   Beschnitt auf 50 Prozent Hoehe statt der 22 Prozent von .roster:
   hier stehen Raeume, keine Gesichter, und Raeume haben ihren
   Inhalt in der Mitte.                                            */
.galerie {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  gap: 1px; background: var(--rule);
  border-block: 1px solid var(--rule);
}
.galerie img {
  display: block; inline-size: 100%; aspect-ratio: 4 / 5; object-fit: cover;
  object-position: 50% 50%;
  filter: saturate(.92) contrast(1.04);
}
.galerie-fuss {
  font-size: var(--t--1); color: var(--fg-mute); line-height: 1.6;
  max-inline-size: 52ch; margin-block-start: clamp(1.2rem, 3vw, 1.8rem);
}

/* Die beiden Media-Queries fuer .galerie sind am 31.07.2026
   entfallen, auto-fit oben macht dasselbe ohne Schwellen. */

/* ═══ Hochband ════════════════════════════════════════════════
   Randloses Band aus HOCHFORMATEN, drei nebeneinander.

   Die Luecke, die es schliesst: rund zwei Drittel der Motive
   sind 2:3, und fuer die gab es bisher nur .galerie. Die sitzt
   aber in der Inhaltsspalte und schneidet auf 4:5 zurecht. Ein
   Hochformat in die randlose .band zu zwingen heisst dagegen,
   einen schmalen Querstreifen herauszuschneiden und ihn
   hochzurechnen: bei 640 Pixel Quellbreite sichtbar matschig.

   Drei Hochformate nebeneinander ergeben zusammen wieder ein
   Querformat, ohne dass eines davon quer beschnitten wird, und
   jede Kachel bleibt unter 640 Pixel breit, also innerhalb der
   Quelle. Genau deshalb steht hier KEINE -1280-Stufe: die gibt
   es fuer diese Motive nicht, und hochgerechnet wird nie.

   auto-fit statt Media-Query, wie bei .doors und .galerie. Bei
   drei Kindern heisst das: drei nebeneinander, solange 16rem je
   Spalte passen, darunter zwei, auf dem Telefon eines. Leere
   Spuren fallen zusammen, die Reihe ist immer gefuellt.        */
.hochband {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: 1px; background: var(--rule);
  border-block: 1px solid var(--rule);
}
/* aspect-ratio statt fester Hoehe: bei einer Spalte auf dem
   Telefon bliebe von einem 2:3-Bild sonst ein Querstreifen
   uebrig. max-block-size deckelt die Hoehe auf sehr breiten
   Schirmen, sonst waere das Band dort hoeher als .band.       */
.hochband img {
  display: block; inline-size: 100%;
  aspect-ratio: 3 / 4; max-block-size: 34rem;
  object-fit: cover; object-position: 50% 42%;
  filter: saturate(.92) contrast(1.04);
}
/* Die Unterschrift steht UNTER dem Band, nicht darin. Der
   deckende Kasten aus .band laege bei drei Bildern zwangslaeufig
   auf einem davon und deckte zu, was er benennt. */
.hochband-fuss {
  font-size: var(--t--1); color: var(--fg-mute); line-height: 1.6;
  max-inline-size: 52ch; margin-block-start: clamp(1.2rem, 3vw, 1.8rem);
}
.hochband-fuss strong {
  font-family: var(--sans); font-weight: 600; font-stretch: var(--w-label);
  text-transform: uppercase; letter-spacing: .12em; font-size: var(--t--2);
  color: var(--fg); display: block; margin-block-end: .4rem;
}

/* ═══ BAND MIT BREITER MITTE ══════════════════════════════════════
   Aufsatz auf .hochband, neu am 01.08.2026 fuer die Ueber-uns-Seite:
   in der Mitte ein Teamfoto, links und rechts die Praxis.

   WARUM EINE EIGENE VARIANTE NOETIG IST: .hochband schneidet jedes
   Bild auf 3/4, also Hochformat. Die Teamaufnahmen sind Querformate
   mit sieben Personen ueber die ganze Breite (team-gruppe-01 ist
   1264x842). Auf 3/4 beschnitten fallen die aeusseren Personen
   heraus, und ein Gruppenfoto, das die Gruppe abschneidet, ist
   schlechter als keins.

   DESHALB 1fr 1.5fr 1fr: die Mitte bekommt die Haelfte mehr Breite,
   damit die Gruppe hineinpasst. Statt aspect-ratio traegt hier eine
   feste Hoehe, sonst waeren die drei Bilder unterschiedlich hoch
   und das Band haette keine gerade Unterkante. Mit block-size plus
   object-fit: cover fuellt jedes Bild seine Spalte und alle drei
   enden auf derselben Linie.

   DIE SPEZIFITAET IST GLEICH wie bei `.hochband img`, beide sind
   (0,2,0). Diese Regeln gewinnen nur, weil sie SPAETER stehen. Wer
   sie nach oben verschiebt, hebt sie auf.                      ═══ */
.hochband-mitte { grid-template-columns: 1fr 1.5fr 1fr; }
.hochband-mitte img {
  aspect-ratio: auto;
  block-size: clamp(17rem, 32vw, 28rem);
  max-block-size: none;
}
/* Gruppenfotos: die Gesichter liegen im oberen Drittel, nicht in
   der Mitte wie bei einem Raum. */
.hochband-mitte img:nth-child(2) { object-position: 50% 35%; }

/* Einspaltig gestapelt ist die breite Mitte gegenstandslos, und ein
   Hochformat waere hier falsch: gestapelt hat jedes Bild die volle
   Breite, 4/3 zeigt dann vom Raum und von der Gruppe mehr als 3/4.
   Reihenfolge bleibt links, Mitte, rechts, das Teamfoto steht also
   in der Mitte des Stapels. */
@media (max-width: 48rem) {
  .hochband-mitte { grid-template-columns: 1fr; }
  .hochband-mitte img { block-size: auto; aspect-ratio: 4 / 3; }
}

/* ═══ Zitat ═══════════════════════════════════════════════════
   Fuer das Gruenderzitat auf der Ueber-uns-Seite. Eine Stufe
   groesser als der Fliesstext, an einer Haarlinie statt in einem
   Kasten, und ohne dekoratives Anfuehrungszeichen.

   Das Zitat trug bis zum 01.08.2026 die Serif und zog seine
   Absetzung daraus. Sie kommt jetzt allein aus Groesse, Haarlinie
   und Zeilenlaenge, deshalb steht hier ausdruecklich Gewicht 400
   gegen die 600 der umliegenden Sans-Elemente.

   HEILMITTELWERBEGESETZ: Hier gehoert ausschliesslich hin, was
   von Haltung und Arbeitsweise handelt. Ein Zitat ueber einen
   Behandlungserfolg faellt unter § 3 HWG, auch wenn es echt ist
   und auch, wenn es von der Inhaberin oder dem Inhaber stammt.  */
.zitat {
  border-inline-start: 2px solid var(--amber);
  padding-inline-start: clamp(1.2rem, 3vw, 2rem);
  max-inline-size: 54ch;
}
.zitat blockquote {
  font-family: var(--sans); font-size: var(--t-2);
  /* Die drei Werte sind der Ersatz fuer die weggefallene Serif:
     400 gegen die 600 der Nachbarschaft, normale Breite gegen die
     108 Prozent der Ueberschriften, und eine Spur Unterschnitt,
     weil Archivo auf dieser Stufe sonst locker laeuft. */
  font-weight: 400; font-stretch: normal; letter-spacing: -.01em;
  line-height: 1.35; margin: 0;
}
.zitat figcaption {
  font-family: var(--sans); font-size: var(--t--2); font-weight: 600;
  font-stretch: var(--w-label); text-transform: uppercase; letter-spacing: .1em;
  color: var(--fg-mute); margin-block-start: 1.2rem;
}

/* ═══ Ansprechpartnerin, nur auf der Kontaktseite ═════════════
   Ein einzelnes Portrait neben Text. .roster taugt dafuer nicht,
   das ist ein Sechserraster, und .crew hat gar kein Bild.

   BEWUSSTE ABWEICHUNG VON DER BILDREGEL: Portraits gehoeren sonst
   ausschliesslich in den Teamzusammenhang der Standortseite. Hier
   steht eines am Anfang, weil genau das der Zweck der Seite ist.
   Wer schreibt, soll sehen, bei wem die Nachricht landet. Vorgabe
   des Kunden vom 31.07.2026.

   Anders als in .roster ist das Bild nicht entsaettigt. Die Reihe
   dort nimmt sich zurueck, bis man hinsieht; hier ist das Gesicht
   der Inhalt und hat keinen Grund, sich zurueckzunehmen.

   Kein Kasten, kein Radius, kein Schatten: getrennt wird mit einer
   Linie, wie ueberall sonst.                                       */
/* Flex mit wrap statt Raster plus Media-Query. Die alte Fassung
   stapelte schon unter 48rem, also auch auf einem 744 Pixel breiten
   Tablet: dort stand ein 176-Pixel-Portrait allein in einer 670
   Pixel breiten Spalte und der Text darunter lief ueber rund 78
   Zeichen. Zwei Spalten passen da muehelos.

   Jetzt entscheidet der Inhalt: der Textblock verlangt 22rem,
   darunter bricht er um. Das ist bei etwa 600 Pixeln, wo der
   Umbruch hingehoert, und es braucht keinen Breakpoint. Dasselbe
   Muster wie .field-row.                                          */
.ansprech {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: clamp(1.4rem, 4vw, 2.8rem);
  border-block-start: 1px solid var(--rule); padding-block-start: clamp(1.6rem, 4vw, 2.4rem);
}
.ansprech img {
  aspect-ratio: 5 / 7; object-fit: cover; object-position: 50% 22%;
  filter: saturate(.92) contrast(1.04);
}
/* Diese beiden Regeln stehen bewusst NACH .ansprech img. Dort stand
   vorher inline-size: 100%, und das hat die Flex-Basis ueberholt:
   das Portrait lief dann ueber die halbe Spalte. */
.ansprech > img { flex: 0 0 14rem; inline-size: 14rem; }
.ansprech > div { flex: 1 1 22rem; min-inline-size: 0; }
.ansprech-name {
  font-family: var(--sans); font-size: var(--t-2); font-weight: 700;
  font-stretch: var(--w-head); letter-spacing: -.015em;
}
.ansprech p { max-inline-size: 46ch; }

@media (max-width: 48rem) {
  /* Unter der schmalen Schwelle steht das Portrait ueber dem Text,
     aber nicht in voller Breite: ein 5:7-Bild ueber die ganze Spalte
     draengt den Text unter die Falz.

     Die Begrenzung gehoert ans Bild, NICHT an die Spalte. Eine
     schmale Spalte nimmt den Text mit und laesst ihn bei vier
     Woertern je Zeile umbrechen.

     Den Umbruch selbst regelt seit dem 31.07.2026 flex-wrap, hier
     steht nur noch die Bildgroesse fuer den gestapelten Zustand. */
  .ansprech > img { flex-basis: 11rem; inline-size: 11rem; }
}

/* ═══ Fußzeile ═════════════════════════════════════════════════ */

/* Die Fusszeile behaelt ihren eigenen, eine Nuance dunkleren
   Grauwert. Ob das Absicht war oder ein Kopierfehler, ist offen. */
.foot { background: var(--ink); color: var(--paper); --fg-mute: #8D9698; }
/* Fuenfte Spalte seit dem 31.07.2026 (Praxis: Ueber uns, Karriere).
   Beide Seiten gehoeren nicht in die Kopfnavigation, die traegt
   schon vier Punkte plus Rufnummer. In der Fusszeile stoeren sie
   niemanden und werden trotzdem gefunden, was fuer eine
   Karriereseite genuegt. */
.foot-in { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr 1fr; gap: clamp(1.5rem, 4vw, 3rem); }
.foot h2 { color: var(--bone); margin-block-end: .9rem; line-height: 1.4; }
.foot ul { list-style: none; display: grid; gap: .45rem; }
/* padding-block vergroessert das Tippziel von rund 24 auf 32 Pixel.
   Bei 380 lagen die Fusszeilenlinks 34 Pixel Mitte zu Mitte
   auseinander und erfuellten SC 2.5.8 nur ueber die
   Abstandsausnahme. */
.foot a  { font-size: var(--t--1); color: var(--fg-mute); padding-block: .25rem; }
.foot a:hover { color: var(--paper); }
.foot-logo img { block-size: 34px; inline-size: auto; margin-block-end: 1rem; }
.foot-tag { font-size: var(--t--1); color: var(--fg-mute); max-inline-size: 34ch; }
.foot-legal { display: flex; gap: 1.4rem; }
.foot-bottom {
  margin-block-start: clamp(2rem, 5vw, 3.5rem); padding-block-start: 1.2rem;
  border-block-start: 1px solid var(--rule);
  display: flex; flex-wrap: wrap; gap: .6rem 1.6rem; justify-content: space-between;
  font-size: var(--t--1); color: var(--fg-mute);
}

/* Mobile Anrufleiste, hält den Hero sauber */
.callbar { display: none; }

/* ═══ Bewegung ═════════════════════════════════════════════════
   Inhalt ist standardmäßig SICHTBAR. Der versteckte Zustand
   existiert nur dort, wo die Animation auch laufen kann.         */

.reveal { opacity: 1; }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal {
      opacity: 0;
      animation: reveal linear both;
      animation-timeline: view();
      animation-range: entry 4% cover 26%;
    }
  }
}
@keyframes reveal { from { opacity: 0; transform: translateY(1.2rem); } to { opacity: 1; transform: none; } }

/* NICHTS IM HERO BEKOMMT .reveal. Eine view()-Zeitachse misst,
   wie weit ein Element in den Scrollport hineingelaufen ist. Was
   beim Laden schon darin steht, ist nie hineingelaufen: die
   Animation steht bei ungescrollter Seite auf einem Teilwert und
   das Element bleibt halbdurchsichtig, bis der Benutzer scrollt.

   Getroffen hat es das Google-Siegel auf allen drei Standort-
   Heros. Es soll DECKEND sein, so steht es im Designsystem, und
   war stattdessen milchig, mit der Behandlungsliege im
   Hintergrund durch die Fläche hindurch. Am Bild gefunden, im
   Quelltext war nichts zu sehen: dort stand nur `class="reveal"`
   wie an sechzig anderen Stellen auch, an denen es richtig ist.

   Die Klasse ist aus dem Markup entfernt. Diese Regel ist das
   Netz darunter, damit der Fehler nicht zurueckkommt.         */
.hero .reveal, .hero-bild .reveal { opacity: 1; animation: none; }

@view-transition { navigation: auto; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }

  /* Die Ziehharmonika brauchte hier eine eigene Zeile, weil das
     blosse Abschalten der Übergänge sie hätte springen statt
     gleiten lassen. Seit dem 01.08.2026 dehnt sich nichts mehr,
     die Zeile ist entfallen. Der Detailblock steht weiter offen:
     ohne Übergang wäre sein Aufklappen ein Sprung. */
  .ort-name { font-stretch: var(--w-wide); }
  .ort-detail { grid-template-rows: 1fr; opacity: 1; translate: none; }
}

@media (prefers-contrast: more) {
  :root { --fg-mute: #3A3730; --rule: #8A8072; --rule-strong: #5E574B; }
}

/* ═══ Schmale Viewports ════════════════════════════════════════ */

@media (max-width: 60rem) {
  .foot-in { grid-template-columns: 1fr 1fr; }

  /* Die Hero-Achse hat feste Zeilenumbrüche, sie kann sich nicht
     selbst aus einer zu engen Spalte helfen. Deshalb hier eine
     Stufe kleiner, statt auf Umbruch zu hoffen. */
  .axis { font-size: var(--t-4); }

  /* Alle fünf Zellen ausdrücklich setzen. Auto-Platzierung neben
     spaltenfesten Kindern ist zu subtil, um sie zu raten. */
  .row { row-gap: .35rem; }
  /* Ein Selektor statt einer Aufzaehlung der Varianten. Vorher
     fehlte .index-tags hier, dessen Fuenf-Spuren-Raster lief damit
     unter 60rem weiter, waehrend die grid-area-Zuweisungen unten
     schon auf drei Spuren rechneten. */
  .index { --row-cols: 4.5rem minmax(0, 1fr) 1.5rem; }
  .row-code { grid-area: 1 / 1 / 2 / 2; }
  .row-name { grid-area: 1 / 2 / 2 / 3; }
  .row-go   { grid-area: 1 / 3 / 2 / 4; }
  .row-desc { grid-area: 2 / 2 / 3 / 4; }
  .row-at   { grid-area: 3 / 2 / 4 / 4; }

  /* Im Ratgeber steht in der ersten Spalte kein Kürzel, sondern ein
     Themenwort. „Rehabilitation" und „Lymphdrainage" passen in keine
     4,5rem breite Spur und schoben sich über den Titel. Auf schmalen
     Geräten steht das Wort deshalb in einer eigenen Zeile darüber. */
  .index-tags { --row-cols: minmax(0, 1fr) 1.5rem; }
  .index-tags .row-code { grid-area: 1 / 1 / 2 / 3; margin-block-end: .3rem; }
  .index-tags .row-name { grid-area: 2 / 1 / 3 / 2; }
  .index-tags .row-go   { grid-area: 2 / 2 / 3 / 3; }
  .index-tags .row-desc { grid-area: 3 / 1 / 4 / 3; }
  .index-tags .row-at   { grid-area: 4 / 1 / 5 / 3; text-align: start; }

  /* Der Weiterlesen-Index trägt kein Datum, also eine Zeile
     weniger als .index-tags. Ohne eigene Regel fiele er auf das
     Fünf-Spuren-Raster von .row zurück, und das Themenwort stünde
     wieder über dem Titel. */
  .index-weiter { --row-cols: minmax(0, 1fr) 1.5rem; }
  .index-weiter .row-code { grid-area: 1 / 1 / 2 / 3; margin-block-end: .3rem; }
  .index-weiter .row-name { grid-area: 2 / 1 / 3 / 2; }
  .index-weiter .row-go   { grid-area: 2 / 2 / 3 / 3; }
  .index-weiter .row-desc { grid-area: 3 / 1 / 4 / 3; }
  .doors    { grid-template-columns: 1fr; }

  /* Die Standortkacheln stapeln hier ebenfalls, die Regeln dafür
     stehen aber weiter oben im Ort-Abschnitt: sie gelten zusätzlich
     für Geräte ohne Zeigegerät und gehören deshalb an eine Stelle. */

  .split  { grid-template-columns: 1fr; }
  /* .roster braucht hier nichts mehr: auto-fit regelt die Spaltenzahl
     seit dem 31.07.2026 selbst, und die Trennung laeuft ueber den
     Haarspalt statt ueber nth-child-Arithmetik. */
}

@media (max-width: 48rem) {
  .foot-in { grid-template-columns: 1fr; }

  /* Auch hier nichts mehr: die 9rem-Untergrenze in .roster ergibt
     auf einem 380er Telefon von selbst zwei Spalten, ohne dass eine
     Breite es vorschreibt. */

  /* Der Keil rückt als Ganzes zusammen, 92 / 92 / 66 statt
     122 / 92 / 66. „Physiotherapie" ist die längste unteilbare Zeile
     und bestimmt, wie weit die Achse hier oben aufmachen darf.

     KORRIGIERT AM 31.07.2026: die Auftaktzeile stand auf --w-head
     (108 %) und lief unterhalb von etwa 340 Pixeln über die
     Inhaltsspalte hinaus, mit waagerechter Bildlaufleiste. Bei 360
     und 380 blieben nur 6 bis 12 Pixel Luft. Die Achse hat feste
     Zeilenumbrüche und kann sich nicht selbst helfen, also muss die
     Breite nachgeben. Auf --w-ui (92 %) trägt „Physiotherapie"
     auch bei 320 Pixeln. */
  .axis-1 { font-stretch: var(--w-ui); }

}

/* ─── Mobilnavigation und Anrufleiste ab 60rem ──────────────────
   Beide Umschaltungen lagen bis zum 31.07.2026 bei 48rem. Damit
   stand auf einem Tablet zwischen 768 und 960 Pixeln die
   Kopfnavigation, deren Untermenues nur ueber :hover und
   :focus-within oeffnen. Auf einem Geraet ohne Zeigegeraet waren
   /leistungen/praevention/, /leistungen/hausbesuch/, /karriere/
   und /ratgeber/ aus dem Kopf heraus nicht erreichbar, nur ueber
   die Fusszeile. Gleichzeitig fehlte die Anrufleiste.

   Die Schwelle wandert deshalb auf die bereits vorhandene zweite
   Stufe. Das fuehrt keinen Breakpoint ein, und es folgt derselben
   Logik wie .orte, das schon (hover: none) mitfragt.

   Der zweite Ausdruck holt Touchgeraete jeder Breite dazu. Ein
   Tablet mit 1024 Pixeln hat sonst dasselbe Problem, nur eine
   Stufe hoeher.                                                   */
@media (max-width: 60rem), (hover: none) {
  .nav { display: none; }
  .burger { display: block; margin-inline-start: auto; }

  .callbar {
    position: fixed; inset-inline: 0; inset-block-end: 0; z-index: 60;
    display: grid; grid-template-columns: 1fr 1fr;
    border-block-start: 1px solid var(--rule);
  }
  .callbar a {
    font-family: var(--sans); font-size: var(--t--1); font-weight: 600;
    font-stretch: var(--w-ui); letter-spacing: .06em; text-transform: uppercase;
    text-align: center; padding-block: .95rem;
  }
  .c-call { background: var(--paper); color: var(--fg); border-inline-end: 1px solid var(--rule); transition: background .18s ease; }
  .c-call:hover { background: var(--paper-2); }
  .c-book { background: var(--teal); color: #fff; transition: background .18s ease; }
  .c-book:hover { background: color-mix(in oklch, var(--teal), black 14%); }
  body { padding-block-end: 3.2rem; }
}
