/* =====================================================================
   lebowski-premium 5.0.1 — Feinschliff

   Eigene Datei statt Eingriff in main.css. Der Grund ist derselbe wie bei
   float.js: main.css stammt byte-identisch aus dem geprueften V4-Prototyp
   (md5 748d7947baf6b14c5b1953fc0e6999e5), und diese Eigenschaft ist an
   mehreren Stellen dokumentiert und getestet. Sie hier aufzugeben, um ein
   halbes Dutzend Regeln unterzubringen, waere der schlechtere Tausch.

   Nebeneffekt, der den Ausschlag gab: Jede visuelle Aenderung dieser Phase
   steht damit an einer Stelle und ist gegen den Befund lesbar, der sie
   ausgeloest hat. Wird eine davon spaeter angezweifelt, ist sie ohne
   Archaeologie im 1700-Zeilen-Stylesheet auffindbar.

   Jeder Abschnitt nennt den Befund, nicht den Geschmack.
   ===================================================================== */


/* ── P0-2 · Mega-Menue: der CTA war praktisch unsichtbar ────────────────
   Befund: Im geoeffneten Mega-Menue stand „Termin anfragen" dunkelblau auf
   dunkelblau.

   Ursache, gemessen: `.mnav` und `.cpanel` setzen beide `--fg-max:#fff`,
   weil sie dunkle Flaechen sind. `.mega` setzt nur `--focus` und
   `--focus-halo` — `--fg-max` fehlt und erbt daher aus `:root` den Wert
   `var(--navy)`. Zusammen mit der spaeteren Regel
   `.cta-request:not(.cta--lead){ background:transparent; color:var(--fg-max) }`
   ergab das navyblauen Text auf navyblauem Grund. Der CTA im Mega-Menue
   traegt kein `cta--lead`, also griff genau diese Regel.

   Das ist ein eigener Fehler aus einer spaeteren Phase: Die
   Zuruecknahme-Regel wurde ergaenzt, ohne die eine dunkle Flaeche zu
   pruefen, die ihre Farbtokens nicht selbst setzt.

   Korrektur in zwei Schritten: erst die fehlenden Tokens nachtragen — das
   heilt zugleich jede andere Komponente im Mega-Menue, die `--fg`,
   `--fg-max` oder `--rule` benutzt —, dann den CTA ausdruecklich nach
   Vorgabe ausformen. */

.mega{
  --fg:rgba(255,255,255,.78);
  --fg-max:#fff;
  --fg-dim:rgba(255,255,255,.62);
  --rule:rgba(255,255,255,.18);
}

/* Ruhezustand: gefuellte Flaeche, weisse Schrift, weisser Pfeil. */
.mega .cta-request,
.mega .cta-request:not(.cta--lead){
  background:var(--accent);
  color:#fff;
  border:2px solid var(--accent);
  font-weight:600;
}

/* Hover und Fokus: Umkehr. Der Rahmen bleibt 2 px breit, damit nichts
   springt — der Layoutsprung war im Auftrag ausdruecklich ausgeschlossen. */
.mega .cta-request:hover,
.mega .cta-request:not(.cta--lead):hover,
.mega .cta-request:focus-visible,
.mega .cta-request:not(.cta--lead):focus-visible{
  background:#fff;
  color:var(--navy-deep);
  border-color:#fff;
}

/* Der Pfeil erbt currentColor und wechselt damit automatisch mit. */
.mega .cta-request:focus-visible{
  outline:3px solid #fff;
  outline-offset:3px;
}

.mega .cta-request:active{ transform:translateY(1px); }

/* Dieselbe Luecke haette jede weitere dunkle Flaeche ohne eigene Tokens
   getroffen. Als Netz: Auf `.mega` und `.cpanel` nie transparent-mit-
   dunkler-Schrift zulassen. */
.cpanel .cta-request:not(.cta--lead){
  background:var(--accent); color:#fff; border-color:var(--accent);
}


/* ── P1 · B3 · Telefon und WhatsApp gleich erkennbar ────────────────────
   Befund: Telefon steht im Kopf, im Hero und als Haupt-CTA. WhatsApp
   erscheint dagegen nur als Textzeile in Aufzaehlungen und geht unter,
   obwohl es fuer „Foto der Situation mitschicken" der praktischere Weg
   ist.

   Korrektur ohne neue Markenflaeche: WhatsApp bekommt dieselbe
   Zeilenhoehe, dasselbe Icongewicht und einen eigenen, ruhigen
   Flaechenakzent — keine grelle gruene Flaeche, die wie ein fremdes
   Widget wirkt. Telefon bleibt der primaere Weg. */

/* `padding-inline-start:.25rem` stand hier bis 19.2/5 und hat nie gewirkt.

   Gemessen mit audit-kaskade.js: `.pline` (0-1-0) verliert gegen
   `.mega__panel .pline{ padding:.6rem 0 }` in main.css (0-2-0). Die
   Kurzschreibweise `padding` dort belegt auch die Startseite der Box, und
   `.pline` kommt im gesamten Bestand ausschliesslich in `.mega__panel` oder
   `.cpanel` vor — der Einzug von 4 px war auf keiner Seite und in keinem
   Zustand sichtbar.

   Entfernt statt nachgeschaerft: Die Flaeche ist in diesem Zustand
   abgenommen worden; einen Einzug nachtraeglich einzufuehren waere eine
   Aenderung ohne Anlass. Eine tote Zeile stehen zu lassen waere eine Luege
   im Quelltext. `position:relative` bleibt, es wird gebraucht. */
.pline{ position:relative; }

.mega__panel .pline,
.cpanel .pline{
  border-bottom:var(--hair) solid rgba(255,255,255,.12);
}
.mega__panel .pline:last-of-type,
.cpanel .pline:last-of-type{ border-bottom:0; }

/* Beide Wege bekommen eine gleich grosse, ruhige Icon-Flaeche. Vorher
   schwebte das Icon ohne Bezugsflaeche neben dem Text und wirkte je nach
   Pfadform unterschiedlich schwer. */
.mega__panel .pline svg,
.cpanel .pline svg{
  width:2.1rem; height:2.1rem; padding:.45rem;
  border-radius:50%; opacity:1;
  background:rgba(255,255,255,.1);
  box-sizing:border-box;
}
.mega__panel .pline:hover svg,
.cpanel .pline:hover svg{ background:rgba(255,255,255,.18); }

/* Fusszeile: die Kontaktliste bekommt die gleiche Behandlung, damit die
   Hierarchie ueber alle Auftritte hinweg dieselbe ist. */
.foot__contact li a .mono{ letter-spacing:.01em; }


/* ── P1 · Teil D · Schwebende Kontaktaktionen ───────────────────────────
   Zwei runde Schaltflaechen rechts unten, ab 1180 px. Darunter uebernimmt
   die mobile Kontaktleiste dieselbe Aufgabe; zwei schwebende Elemente
   gleichzeitig waeren die konkurrierende Doppelung, die der Auftrag
   ausschliesst.

   52 px Durchmesser liegt in der geforderten Spanne und ueberschreitet die
   44-px-Mindestklickflaeche deutlich. */

.lb-float{
  position:fixed;
  right:calc(1.25rem + env(safe-area-inset-right));
  bottom:calc(1.25rem + env(safe-area-inset-bottom));
  z-index:105;                       /* unter Kopf (120), Mobilmenue (115) und Kontaktpanel (118) */
  display:none;
  flex-direction:column;
  gap:.7rem;
  opacity:0;
  transform:translateY(.6rem);
  transition:opacity .24s var(--ez-out),transform .24s var(--ez-out),visibility .24s;
  visibility:hidden;
  pointer-events:none;
}

@media (min-width:1180px){
  .lb-float{ display:flex; }
}

.lb-float[data-show="true"]{
  opacity:1; transform:none; visibility:visible; pointer-events:auto;
}

.lb-float__btn{
  position:relative;
  display:flex; align-items:center; justify-content:center;
  width:52px; height:52px;
  border-radius:50%;
  text-decoration:none;
  border:1px solid transparent;
  box-shadow:0 10px 26px -12px rgba(11,18,30,.55);
  transition:transform .18s var(--ez-out),background-color .18s var(--ez),box-shadow .18s var(--ez);
}
.lb-float__btn svg{ width:1.35rem; height:1.35rem; }

/* Telefon in der Markenfarbe — derselbe Ton wie der primaere CTA. */
.lb-float__btn--tel{ background:var(--accent); color:#fff; border-color:var(--accent); }
.lb-float__btn--tel:hover{ background:var(--accent-hover); border-color:var(--accent-hover); }

/* WhatsApp eindeutig unterscheidbar, aber ohne grosse Fremdflaeche: helle
   Flaeche, dunkler Rand, Markenfarbe im Icon. Die Unterscheidung ruht damit
   nicht allein auf der Farbe — Form und Icon tragen sie mit. */
.lb-float__btn--wa{ background:#fff; color:var(--navy-deep); border-color:var(--navy-deep); }
.lb-float__btn--wa:hover{ background:var(--mint); }

.lb-float__btn:hover{ transform:translateY(-2px); box-shadow:0 14px 30px -12px rgba(11,18,30,.6); }
.lb-float__btn:active{ transform:translateY(0); }

.lb-float__btn:focus-visible{
  outline:3px solid var(--accent);
  outline-offset:3px;
}

/* Beschriftung erscheint links daneben, ohne das Layout zu bewegen. */
.lb-float__tip{
  position:absolute; right:calc(100% + .6rem); top:50%;
  transform:translateY(-50%) translateX(.3rem);
  white-space:nowrap;
  background:var(--navy-deep); color:#fff;
  font-size:.8rem; font-weight:600; letter-spacing:.01em;
  padding:.35rem .65rem; border-radius:var(--r-1);
  opacity:0; pointer-events:none;
  transition:opacity .16s var(--ez),transform .16s var(--ez-out);
}
.lb-float__btn:hover .lb-float__tip,
.lb-float__btn:focus-visible .lb-float__tip{
  opacity:1; transform:translateY(-50%) translateX(0);
}

/* Auf der Anfrage-Seite tritt die Gruppe ganz zurueck: dort ist der
   Assistent die Handlung, und ein schwebender Nebenweg lenkt ab. Die
   Skriptseite nimmt sie zusaetzlich zurueck, sobald das Formular im Bild
   ist — das hier greift auch ohne Skript. */
.page-template-anfrage .lb-float{ display:none; }

@media (prefers-reduced-motion:reduce){
  .lb-float,
  .lb-float__btn,
  .lb-float__tip{ transition:none; }
  .lb-float__btn:hover{ transform:none; }
}


/* ── P1 · B2 · Anfrageassistent: ruhiger und klarer ─────────────────────
   Befund des Betreibers: zu viele Rahmen, schwache Trennung zwischen
   Frage, Auswahl und Erklaerung, Auswahlfelder wie Tabellenzellen,
   Primaer- und Sekundaeraktion nicht klar genug unterschieden.

   Wichtige Einschraenkung, die hier festgehalten gehoert: Das Formular
   wird von `lebowski-core` erzeugt, und dieser Auftrag verbietet jede
   Aenderung am Plugin. Alles, was Markup oder Skriptlogik betrifft —
   insbesondere die gleichzeitige Sichtbarkeit von Fallback und
   Schrittansicht —, ist damit hier nicht zu loesen und bleibt als offener
   Punkt dokumentiert. Was von der Themeseite aus geht, ist die
   Darstellung. Das Theme laedt sein CSS nach dem Plugin (Prioritaet 100
   gegen 20), diese Regeln greifen also. */

.form{ --lb-form-gap:1.35rem; }

/* Weniger Linien. Vorher trug jede Feldgruppe einen eigenen Rahmen, was
   zusammen mit den Feldrahmen ein Gitter ergab. */
.form fieldset{
  border:0; padding:0; margin:0 0 var(--lb-form-gap);
}

/* Frage, Erklaerung und Auswahl bekommen sichtbar verschiedene Gewichte.
   Vorher standen sie im selben Grau nebeneinander. */
.form legend{
  font-size:var(--fs-md); font-weight:650; color:var(--fg-max);
  letter-spacing:-.01em; padding:0; margin-bottom:.35rem;
}
.form .hint,
.form .desc,
.form small{
  display:block; color:var(--fg-dim); font-size:.9rem; line-height:1.5;
  margin-bottom:.8rem; max-width:62ch;
}

/* Auswahlkarten statt Tabellenzellen: gleiche Hoehe, ruhiger Rahmen,
   deutlicher Zustandswechsel. */
.form label:has(input[type="radio"]),
.form label:has(input[type="checkbox"]){
  display:flex; align-items:center; gap:.7rem;
  min-height:52px; padding:.7rem .95rem;
  border:1px solid var(--line); border-radius:var(--r-1);
  background:var(--white);
  cursor:pointer;
  transition:border-color .16s var(--ez),background-color .16s var(--ez),box-shadow .16s var(--ez);
}
.form label:has(input[type="radio"]):hover,
.form label:has(input[type="checkbox"]):hover{
  border-color:var(--accent); background:var(--mint);
}
.form label:has(input:checked){
  border-color:var(--accent);
  background:var(--mint);
  box-shadow:inset 0 0 0 1px var(--accent);
}
.form label:has(input:focus-visible){
  outline:3px solid var(--accent); outline-offset:2px;
}

/* Einheitliche Feldhoehen. Vorher unterschieden sich Text-, Auswahl- und
   Textfeld um mehrere Pixel, was die Spalten unruhig machte. */
.form input[type="text"],
.form input[type="tel"],
.form input[type="email"],
.form input[type="number"],
.form select{
  min-height:52px;
}
.form textarea{ min-height:9rem; line-height:1.55; }

/* Primaeraktion dominant, Zurueck sichtbar sekundaer. */
.form__nav{ display:flex; align-items:center; gap:.8rem; margin-top:var(--sp-5); }
.form__nav .cta-request{ font-weight:650; }
.form__nav [data-back]{
  background:transparent; border:1px solid var(--line); color:var(--fg);
  font-weight:500;
}
.form__nav [data-back]:hover{ border-color:var(--steel); background:var(--mint); }

/* Fortschritt praesenter. Der Schritt war vorher eine Nebenangabe. */
.steps-bar{ margin-bottom:var(--sp-5); }
.form .step-of{
  font-weight:650; color:var(--fg-max); letter-spacing:.01em;
}

/* Zusammenfassung als eigener Abschlusszustand kennzeichnen. */
.form .summary{
  background:var(--mint); border:1px solid var(--line);
  border-radius:var(--r-1); padding:var(--sp-5);
  margin-block:var(--sp-4);
}

/* Datenschutzhinweis lesbar, aber nicht dominant. */
.form .gate{ margin-top:var(--sp-4); }
.form .gate > *:not(.mono){ font-size:.92rem; line-height:1.55; color:var(--fg); }


/* ── P2 · Teil G · Typografie ───────────────────────────────────────────
   Befund: Mehrere Mikrotexte blieben klein, weil sie im Prototyp klein
   waren — nicht, weil sie sekundaer sind. Betroffen sind vor allem die
   Beschreibungen unter Navigationseintraegen und die Zeilen in
   Aufzaehlungen, die tatsaechlich gelesen werden muessen.

   Der Auftrag nennt das ausdruecklich: keine Schrift bleibt klein, nur
   weil sie es im Prototyp war. */

.mega__cols li small{ font-size:.82rem; line-height:1.45; color:rgba(255,255,255,.62); }
.mega__track a{ font-size:.95rem; }

/* Zeilenlaenge begrenzen. Ab 1440 px liefen Fliesstexte deutlich ueber die
   gut lesbaren 75 Zeichen hinaus. */
.prose p,
.lead{ max-width:72ch; }

/* Fusszeile: die Dichte war hoch und der Kontrast am unteren Rand des
   Zulaessigen. */
.foot{ font-size:.95rem; }
.foot a:not(.cta-request):not(.cta-call):not(.cta-depth){ line-height:1.7; }


/* ── P2 · B4 · Wissensbereich ───────────────────────────────────────────
   Befund: Artikelzeilen und Clusterzeilen sahen aus wie Tabellenzeilen.
   Klickbarkeit war nur am Cursor erkennbar, nicht an der Flaeche. */

.index li a{
  display:block; padding:var(--sp-4);
  border:1px solid transparent; border-radius:var(--r-1);
  transition:border-color .16s var(--ez),background-color .16s var(--ez),transform .16s var(--ez-out);
}
.index li a:hover{
  border-color:var(--line); background:var(--mint); transform:translateY(-1px);
}
.index li a:focus-visible{ outline:3px solid var(--accent); outline-offset:2px; }
.sf-navy .index li a:hover,
.sf-deep .index li a:hover,
.sf-slate .index li a:hover{
  background:rgba(255,255,255,.07); border-color:rgba(255,255,255,.2);
}

/* Lange Tabellen mobil: waagerechtes Scrollen im Element statt im
   Dokument. Ohne das entstand auf 360 px ein Overflow der ganzen Seite. */
@media (max-width:767px){
  .prose table,
  .ledger,
  .matrix{ display:block; overflow-x:auto; -webkit-overflow-scrolling:touch; }
}

@media (prefers-reduced-motion:reduce){
  .index li a:hover{ transform:none; }
}


/* ── 5.0.2 · P2-1 · Breite Tabellen und Listen ──────────────────────────
   Befund aus dem DOM-Audit: Bei 320 px sind die Bausteintabellen auf
   /fenster/, /haustueren/ und /schiebeelemente/ zwischen 670 und 813 px
   breit. `.matrix` scrollte zwar bereits waagerecht, war aber **nicht per
   Tastatur erreichbar** — ein Scrollbereich ohne Fokus ist für alle
   unbenutzbar, die keine Maus und keinen Finger benutzen (WCAG 2.1.1).

   Die Markup-Seite ergänzt `tabindex="0"`, `role="region"` und eine
   Beschriftung. Hier kommt dazu, was man sehen muss: ein Fokusrahmen und
   ein Hinweis, dass es rechts weitergeht. */

.matrix,
.ledger{
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain;
  scrollbar-width:thin;
}

/* Ohne sichtbaren Fokus wäre der Tastaturzugang zwar vorhanden, aber
   unauffindbar. */
.matrix:focus-visible,
.ledger:focus-visible{
  outline:3px solid var(--accent);
  outline-offset:2px;
}

/* Ein schmaler Verlauf am rechten Rand zeigt an, dass Inhalt folgt. Er
   verschwindet, sobald bis ans Ende gescrollt wurde — deshalb an den
   Scrollcontainer gehängt und nicht an eine feste Position. */
@media (max-width:767px){
  .matrix,
  .ledger{
    background-image:linear-gradient(to right, transparent calc(100% - 2.5rem), rgba(11,18,30,.06) 100%);
    background-attachment:local;
  }
}

/* Die Zeilen dürfen innerhalb des Scrollbereichs ihre Breite behalten —
   sonst quetscht Flexbox sie auf die Containerbreite und der Scroll läuft
   ins Leere. */
.ledger__row{ min-width:max-content; }

@media (prefers-reduced-motion:reduce){
  .matrix,
  .ledger{ scroll-behavior:auto; }
}

/* ═══════════════════════════════════════════════════════════════════════
   5.1.0 · Phase 19 — Reparatur & Service
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Problemfinder ─────────────────────────────────────────────────────
   Der Baustein steht auf sf-navy und erbt von dort --fg, --fg-max, --rule
   und --focus. Es kommt keine neue Markenfarbe dazu; die Reparaturseite
   soll nicht nach Notdienst aussehen, sondern wie der Rest der Website. */

.finder{ display:block; }

/* Die Schnellauswahl ist reine Zugabe. Ohne JavaScript tun die Knöpfe
   nichts, also erscheinen sie dann auch nicht. */
html.no-js .finder__rail{ display:none; }

.finder__rail{ margin-bottom:var(--sp-7); }

.finder__chips{
  display:flex; flex-wrap:wrap; gap:var(--sp-2);
}

.finder__chip{
  font:inherit; font-size:var(--fs-sm); line-height:1.25;
  min-height:44px; padding:.6rem 1rem; cursor:pointer;
  background:transparent; color:var(--fg);
  border:var(--hair) solid var(--rule); border-radius:var(--r-1);
  transition:background .18s ease, color .18s ease, border-color .18s ease;
}
.finder__chip:hover{ color:var(--fg-max); border-color:var(--fg-max); }
.finder__chip[data-aktiv="true"]{
  background:#fff; color:var(--navy); border-color:#fff; font-weight:500;
}

/* ── Die Felder selbst ────────────────────────────────────────────────── */

.finder__list{ border-top:2px solid var(--rule); }

.finder__i{ border-bottom:var(--hair) solid var(--rule); }

.finder__i > summary{
  display:grid; grid-template-columns:3.25rem minmax(0,1fr) 1.5rem;
  align-items:baseline; gap:var(--sp-3);
  padding:var(--sp-5) 0; cursor:pointer; list-style:none;
  font-size:var(--fs-h3); font-weight:600; color:var(--fg-max);
  letter-spacing:-.012em; line-height:1.32;
  overflow-wrap:break-word; hyphens:auto;
}
.finder__i > summary::-webkit-details-marker{ display:none; }
.finder__i > summary::after{
  content:"+"; font-family:var(--mono); font-size:1.5rem; line-height:1;
  color:var(--fg-dim); justify-self:end;
}
.finder__i[open] > summary::after{ content:"–"; }
.finder__i > summary:hover{ color:var(--accent-lift); }

.finder__n{
  font-family:var(--mono); font-size:var(--fs-mono); letter-spacing:.14em;
  color:var(--accent-lift); font-weight:400;
}

.finder__a{ padding-bottom:var(--sp-6); }
.finder__a > .copy{ max-width:var(--measure); }

.finder__cols{
  display:grid; gap:var(--sp-5); margin-top:var(--sp-6);
  grid-template-columns:minmax(0,1fr);
}
@media (min-width:760px){
  .finder__cols{ grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--sp-6); }
}
.finder__col ul{ list-style:none; margin:0; padding:0; }
.finder__col li{
  font-size:var(--fs-sm); line-height:1.55; color:var(--fg);
  padding-left:1.1rem; position:relative; margin-top:.55rem;
}
.finder__col li::before{
  content:"—"; position:absolute; left:0; top:0;
  font-family:var(--mono); color:var(--accent-lift); opacity:.8;
}
.finder__col li:first-child{ margin-top:0; }

.finder__hint{ margin-top:var(--sp-5); }

@media (prefers-reduced-motion:reduce){
  .finder__chip{ transition:none; }
}

/* ── Dringlichkeit: drei Kacheln statt vier ────────────────────────────
   main.css benennt vier Rasterflächen. Bei drei Einträgen bliebe unten
   rechts ein leeres Feld in Linienfarbe stehen. */
@media (min-width:760px){
  .aspects[data-n="3"]{
    grid-template-columns:repeat(3,minmax(0,1fr));
    grid-template-areas:none;
  }
  .aspects[data-n="3"] > *{ grid-area:auto; }
  .aspects[data-n="3"] .aspect--lead{ min-height:12rem; }
  .aspects[data-n="3"] .aspect--lead h3{
    font-size:clamp(1.2rem,1.05rem + .6vw,1.6rem);
  }
}
@media (min-width:1100px){
  .aspects[data-n="3"] .aspect{ min-height:16rem; }
}

/* ── Schnellzugriff auf der Startseite mit fünf Einträgen ──────────────
   main.css schaltet bei 1024px auf vier Spalten. Der fünfte Eintrag stünde
   sonst allein in einer zweiten Zeile — genau das „Verstecken in einer
   kleinen Karte“, das Teil B4 ausschließt. */
@media (min-width:1024px){
  .rail[data-n="5"]{ grid-template-columns:repeat(5,minmax(0,1fr)); }
}

/* ── Die fünfte Kachel im Elementgruppen-Picker ────────────────────────
   Die Auswahl auf /leistungen/ hatte vier Einträge; mit Reparatur & Service
   sind es fünf. main.css schaltet bei 1100px auf vier Spalten — damit stünde
   die fünfte Kachel allein in einer zweiten Reihe und wäre optisch entweder
   abgehängt oder überbetont. Zwei zusätzliche Stufen lösen das ohne Eingriff
   in main.css: drei Spalten ab 900px (3+2) und fünf ab 1360px (eine Reihe). */
@media (min-width:900px){
  .picker{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}
@media (min-width:1360px){
  .picker{ grid-template-columns:repeat(5,minmax(0,1fr)); }
}

/* ── Kopfzeile: sieben Hauptpunkte müssen hineinpassen ─────────────────
   Gemessener Befund, gefunden beim Abschlussaudit von Phase 19:

   Der Kopf-CTA „Termin anfragen" ragte über den rechten Rand hinaus und
   war wegen body{overflow-x:clip} abgeschnitten und nicht anklickbar.
   Nicht erst seit Phase 19 — schon mit sechs Hauptpunkten fehlten bei
   1180, 1440 und 1920 px zwischen 26 und 67 px. Mit dem siebten Punkt
   wurden daraus 177 bis 264 px, und der wichtigste Knopf der Kopfzeile
   verschwand vollständig.

   Warum es niemandem auffiel: Die Überlaufprüfung meldete seit Phase 18
   dauerhaft dieselben sechs Ansichten wegen eines bewusst neben der Bühne
   geparkten Off-Canvas-Panels. In diesem Rauschen ging ein echter Befund
   unter — der Grund, warum dieselbe Prüfung jetzt echte Scrollbarkeit
   misst statt rechnerischer Breite.

   Der Platz kommt aus drei Quellen, in dieser Reihenfolge:

   1. Die Telefonnummer im Kopf verliert ihren Text. Das Symbol bleibt, ist
      44 px groß, führt weiter direkt auf tel: und trägt seinen
      Zugänglichkeitsnamen. Die Nummer selbst steht weiterhin im
      Kontaktpanel, in der schwebenden Aktion, auf jeder Leistungsseite und
      im Fuß — sie war im Kopf die am häufigsten wiederholte Angabe der
      ganzen Seite.
   2. Innenabstände von Navigation, Marke und CTA werden knapper.
   3. Unter 1340 px entfällt zusätzlich der Panelknopf; das Panel ist über
      „Kontakt" in der Servicezeile darüber weiterhin erreichbar.

   Gemessen bei 1180, 1200, 1260, 1280, 1300, 1320, 1339, 1340, 1366, 1380,
   1400, 1439, 1440, 1500, 1520, 1600, 1728 und 1920 px: Navigation
   einzeilig, Klickfläche 44 px.

   ── Berichtigung 19.2/5 ────────────────────────────────────────────────

   Der Satz „CTA vollständig innerhalb der Hülle" stand hier und war
   falsch. Nachgemessen über alle 43 Ziele, Kriterium rechte Kante gegen
   `window.innerWidth`:

       1179 px   innerhalb
       1180 px   11 px über, auf 42 von 43 Zielen
       1185 px    6 px über
       1189 px    2 px über
       1190 px    1 px über
       1200 px   innerhalb

   Bei 1180 px schaltet der Kopf in die Desktopform; dort brauchen Marke,
   sieben Navigationspunkte, Telefonsymbol und „Termin anfragen" mehr Platz,
   als zwischen die Ränder passt. Und weil `body{ overflow-x:clip }` gilt,
   war das kein Querlauf, sondern ein Schnitt: Die Schaltfläche war nicht
   wegzuscrollen, sie war weg.

   Der Kommentar behauptete eine Messung, die das Ergebnis nicht trägt.
   Genau die Sorte Aussage, die dieser Durchgang aussortieren soll —
   deshalb steht die Berichtigung hier und nicht nur im Bericht.

   `tests/mobile-audit.js` maß 1024 und danach 1280. Der Umschaltpunkt liegt
   dazwischen; man kann sorgfältig um einen Fehler herum messen. 1180 und
   1200 stehen deshalb ab jetzt dauerhaft in der Messreihe. */

@media (min-width:1180px){
  .head__main .head__tel .num{ display:none; }
  .head__main .mainnav a,
  .head__main .mainnav button{ padding:0 .45rem; }
  .head__main > .shell{ gap:.5rem; }
  .head__main .head__cta{ padding:.5rem .9rem; margin-left:.35rem; }
  .logo > .logo__full{ height:38px; }
}

@media (min-width:1180px) and (max-width:1439px){
  .head__main .mainnav a,
  .head__main .mainnav button{ padding:0 .35rem; }
  .head__main > .shell{ gap:.4rem; }
  .head__main .head__cta{ padding:.5rem .75rem; }
  .logo > .logo__full{ height:34px; }
}

/* Der Innenabstand der Kopfhülle im Band 1180–1279 px.

   Die 11 px fehlen genau dort, wo `--pad` mit der Fensterbreite mitwächst:
   `clamp(1.25rem,.35rem + 3.8vw,4.25rem)` ergibt bei 1180 px 50,44 px je
   Seite. 2.25rem sind 36 px; das gibt 28,88 px frei, gebraucht werden 11.

   Warum hier und nicht woanders:

   Nicht am Umschaltpunkt. `1180px` schaltet nicht nur den Kopf, sondern
   auch `.process` und `.track` auf vier Spalten. Den Punkt zu verschieben
   hieße, Inhaltsraster zu bewegen, um ein Kopfproblem zu lösen.

   Nicht an den Navigationsabständen. Die stehen in diesem Band schon auf
   `.35rem`. Weiter zu verkleinern hieße, die Klickflächen anzugreifen, und
   die liegen mit 44 px auf der WCAG-Grenze.

   Sondern am Innenabstand. Der Kopf ist die einzige vollbreite dunkle
   Fläche der Seite; ein schmalerer Innenabstand fällt dort nicht auf, und
   er betrifft ausschließlich `.head__main > .shell` — keine andere Hülle. */
@media (min-width:1180px) and (max-width:1279px){
  .head__main > .shell{ padding-inline:2.25rem; }
}

@media (min-width:1180px) and (max-width:1339px){
  .head__main .mainnav a,
  .head__main .mainnav button{ padding:0 .3rem; font-size:.9rem; }
  .head__main [data-cpanel]{ display:none; }
  .logo > .logo__full{ height:32px; }
}

/* ═══════════════════════════════════════════════════════════════════════
   5.1.1 · Mobiler UX-Durchgang
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Marke: hell und transparent statt dunkel auf mint ─────────────────
   Befund: Auf dem Handy stand die Marke als 26 px kleines Symbol in einem
   42 px breiten hellen Rechteck auf dunkelblauem Grund. Die Wortmarke fehlte
   ganz; was blieb, wirkte wie ein aufgeklebtes Schild.

   Ursache: Die Originalmarke ist für hellen Grund gezeichnet. Die mint
   Schutzfläche war die Notlösung dafür.

   Gewählte Variante nach dem Vergleich in docs/LOGO_VARIANTEN.md: die
   vollständige helle Wortmarke ohne Slogan. Sie behält Symbol, „LEBOWSKI"
   und „Fenster & Türen" — also die ganze Markenaussage — und ist bei 44 px
   Höhe deutlich lesbar. Die noch lesbarere Nebeneinander-Fassung wurde
   geprüft und verworfen: Sie verliert die Unterzeile und lässt das Symbol
   auf Punktgröße schrumpfen.

   Höhen: 44 px mobil, 46 px ab Tablet, 48 px ab Desktop. Die Kopfhöhe von
   60 px bleibt unverändert. */

.logo{
  background:transparent;
  padding:0;
  justify-content:flex-start;
}
.logo:hover,
.logo:focus-visible{ background:transparent; }
.logo > .logo__hell{ display:block; width:auto; height:44px; }

@media (min-width:768px){
  .logo > .logo__hell{ height:46px; }
}
@media (min-width:1180px){
  .logo{ padding:0; }
  .logo > .logo__hell{ height:48px; }
}

/* Der Fokusring braucht ohne Schutzfläche einen eigenen Abstand, sonst
   klebt er am Symbol. */
.logo:focus-visible{ outline-offset:4px; }

/* Fuß: dort ist Platz, dort trägt der Slogan. */
.logo--foot{ padding:0; margin-bottom:1.35rem; }
.logo--foot > .logo__hell{ height:64px; }

/* ── Vergleichstabellen auf dem Handy ──────────────────────────────────
   Befund: Bei 320 px mussten die Fehlerbild-Tabelle 668 px und die
   Reparatur/Austausch-Tabelle 290 px waagerecht gescrollt werden. Technisch
   möglich, praktisch unbrauchbar: Wer die vierte Spalte liest, sieht die
   Zeilenbeschriftung nicht mehr.

   Lösung ohne zweites Markup: Dieselbe Tabelle wird per CSS zu Karten. Eine
   Karte je Zeile, Zeilenbeschriftung als Kartenkopf, Spaltenbeschriftung vor
   jedem Wert. Die Tabellensemantik trägt matrix.php über ARIA-Rollen; der
   Kopfbereich wird nur optisch versteckt, nicht ausgeblendet, damit die
   Spaltenzuordnung im Zugänglichkeitsbaum erhalten bleibt. */

.matrix__label{ display:none; }

@media (max-width:559px){
  .tabelle[data-mobil="karten"] .tabelle__scroll{ overflow:visible; }
  .tabelle[data-mobil="karten"] .matrix{
    overflow:visible; border:0; background:transparent;
  }
  .tabelle[data-mobil="karten"] .matrix table{
    display:block; min-width:0; width:100%;
  }

  /* Optisch versteckt, im Zugänglichkeitsbaum vorhanden. */
  .tabelle[data-mobil="karten"] .matrix thead{
    position:absolute; width:1px; height:1px; margin:-1px;
    overflow:hidden; clip-path:inset(50%); white-space:nowrap;
  }

  .tabelle[data-mobil="karten"] .matrix tbody{ display:block; }

  .tabelle[data-mobil="karten"] .matrix tbody tr{
    display:block;
    background:var(--white);
    border:var(--hair) solid var(--rule);
    border-top:3px solid var(--navy);
    margin-bottom:var(--sp-4);
  }
  .sf-navy .tabelle[data-mobil="karten"] .matrix tbody tr,
  .sf-deep .tabelle[data-mobil="karten"] .matrix tbody tr{
    background:rgba(255,255,255,.05); border-top-color:var(--accent-lift);
  }

  /* Symptom beziehungsweise Kriterium als Kartenkopf. */
  .tabelle[data-mobil="karten"] .matrix tbody th[scope="row"]{
    display:block; width:auto;
    padding:var(--sp-4) var(--sp-4) var(--sp-3);
    font-size:var(--fs-h4); font-weight:600; line-height:1.3;
    color:var(--fg-max); border-bottom:var(--hair) solid var(--rule);
  }

  .tabelle[data-mobil="karten"] .matrix tbody td{
    display:block; padding:var(--sp-3) var(--sp-4);
    border-bottom:var(--hair) solid var(--rule);
  }
  .tabelle[data-mobil="karten"] .matrix tbody td:last-child{ border-bottom:0; }

  .tabelle[data-mobil="karten"] .matrix__label{
    display:block; margin-bottom:.2rem;
    font-family:var(--mono); font-size:var(--fs-mono); letter-spacing:.1em;
    text-transform:uppercase; color:var(--fg-dim); font-weight:500;
  }
  .tabelle[data-mobil="karten"] .matrix__wert{
    display:block; font-size:var(--fs-sm); line-height:1.55; color:var(--fg);
  }

}

/* Die vierspaltige Materialtabelle bleibt waagerecht scrollbar — vier
   Materialien nebeneinander zu vergleichen ist ihr Zweck. Dafür bekommt sie
   drei Dinge: einen sichtbaren Hinweis, eine stehende erste Spalte und
   Scroll-Rasterung, damit man Spalte für Spalte weiterwischt. */
@media (max-width:767px){
  .tabelle[data-mobil="scroll"] .tabelle__scroll{
    scroll-snap-type:x proximity;
  }
  .tabelle[data-mobil="scroll"] .matrix table{
    min-width:calc(7.5rem + var(--cols,2) * 9.5rem);
  }
  .tabelle[data-mobil="scroll"] .matrix th[scope="row"]{
    position:sticky; left:0; z-index:1;
    background:var(--white); border-right:var(--hair) solid var(--rule);
    scroll-snap-align:start;
  }
  .sf-navy .tabelle[data-mobil="scroll"] .matrix th[scope="row"],
  .sf-deep .tabelle[data-mobil="scroll"] .matrix th[scope="row"]{ background:var(--navy); }
  .tabelle[data-mobil="scroll"] .matrix td{ scroll-snap-align:start; }
  .tabelle[data-mobil="scroll"] .matrix thead th{ position:sticky; top:0; }
}

@media (prefers-reduced-motion:reduce){
  .tabelle[data-mobil="scroll"] .tabelle__scroll{ scroll-snap-type:none; }
}

/* Der Wischhinweis erscheint nur dort, wo tatsächlich gewischt werden muss:
   in der Scrollfassung und nur solange sie schmal genug ist. Er steht als
   Kind von .tabelle neben .tabelle__scroll, nicht als Geschwister von
   .tabelle. */
.tabelle .tabelle__hint{ display:none; }
@media (max-width:767px){
  .tabelle[data-mobil="scroll"] .tabelle__hint{ display:flex; }
}

/* ── Sprungleiste, Kopfziele und Dock ──────────────────────────────────
   Drei kleine, gemessene Korrekturen aus dem mobilen Durchgang.

   1. Sprungziele landeten unter dem klebenden Stapel. Der besteht aus zwei
      Teilen: Kopf und Sprungleiste. `scroll-padding-top` am html-Element
      kennt nur den Kopf (--hd + Luft). Die Leiste kam ungerechnet dazu,
      gemessen 61 px — genau um diesen Betrag war der obere Rand des
      angesprungenen Abschnitts verdeckt.

      Warum `scroll-margin-top` am Ziel und nicht ein groesseres
      `scroll-padding-top`: Die Zugabe darf nur dort gelten, wo es die
      Leiste ueberhaupt gibt. Der Geschwisterselektor leistet genau das
      ohne :has() und ohne JavaScript — die Leiste steht im Markup vor den
      Abschnitten, auf die sie zeigt. Seiten ohne Leiste bleiben unberuehrt.

   2. Telefon und Kontaktwege im Kopf waren 39 x 44 px. Die Hoehe stimmte,
      die Breite nicht: Bei ausgeblendeter Nummer bleibt nur das 17 px
      breite Symbol plus zweimal .7rem Innenabstand. 44 px sind gefordert.

   3. Das Dock ist 61 px hoch — 60 px Schaltflaeche plus 1 px Oberkante.
      Der Freiraum am Seitenende rechnete nur mit 60 px. Die Folge war
      genau eine Pixelzeile: Die Unterkante von „Impressum" und
      „Datenschutz" lag unter dem Dockrand. Klein, aber es ist die
      Fusszeile mit den Pflichtangaben. */

.jumpbar ~ .band[id]{ scroll-margin-top:61px; }

.head__tel{ min-width:44px; justify-content:center; }

/* ── 5.2.1 · Kopfzeile auf 320 px ──────────────────────────────────────
   Der Audit ueber alle Ziele fand auf 42 von 43 Seiten 18 px waagerechten
   Ueberlauf — ausschliesslich auf 320 px, ab 360 px nichts. Ursache ist die
   Kopfzeile:

     Logo 120 + Luecke 16 + (leere Navigation) + 16 + Telefon 44 + 16
     + Kontakt 44 + 16 + Menue 46  =  318 px in 280 px Inhaltsbreite

   Und die Ursache der Ursache steht drei Zeilen weiter oben: Die
   Kopfziele wurden im mobilen Durchgang von 39 auf 44 px verbreitert, weil
   39 px zu klein zum Treffen sind. Das war richtig und hat die Zeile um
   10 px verlaengert. Die Korrektur einer Bedienbarkeit hat hier eine
   Darstellung gebrochen — auf einer Breite, die im damaligen Durchgang
   nicht gemessen wurde.

   Zurueckgenommen wird deshalb nichts von den Zielgroessen. Geholt wird der
   Platz bei den Zwischenraeumen und beim Logo, und nur auf den schmalsten
   Geraeten. */
@media (max-width:359px){
  .head__main .shell{ gap:var(--sp-2); }
  .head__main .logo{ padding-inline:.35rem; }
  .head__main .logo > img{ height:24px; }
}

/* Dieselbe Zeile ein zweites Mal, aus einem anderen Grund: bei 200 %
   Textgröße auf 320 px lief sie um 8 px über — auf 42 von 43 Zielen.

   Der Seitenrand `--pad` hat auf schmalen Geräten einen Boden von 1.25rem.
   Ein rem-Boden ist eine Länge, die mit der Schrift wächst; bei doppelter
   Textgröße wurden aus 20 px links und rechts jeweils 40 px, und dieselben
   Schaltflächen passten nicht mehr nebeneinander.

   `min(1.25rem, 6.25vw)` ändert bei normaler Schriftgröße nichts: 6.25 %
   von 320 px sind exakt 20 px, und unterhalb von 400 px steht die Klammer
   ohnehin auf ihrem Boden. Bei doppelter Textgröße greift die zweite
   Hälfte und hält den Rand bei 20 px fest. Die Zielgrößen von 44 px bleiben
   dabei unangetastet — sie sind der Grund, warum es eng ist, und nicht das
   Problem. */
@media (max-width:400px){
  :root{ --pad:min(1.25rem,6.25vw); }
  .head__main .shell{ gap:min(var(--sp-2),2.5vw); }
}

/* Der Hinweiskasten `.gate` ist eine Flexzeile aus Etikett und Text ohne
   Umbruch. Solange das Etikett „Prüfhinweis" hiess, passte die Zeile auf
   320 px. Im Abschlussdurchgang wurde daraus „Technische Angaben
   projektbezogen" — kundenverstaendlicher, aber 60 px laenger, und die
   Zeile lief um 7 px aus dem Bild.

   Das ist ein selbst erzeugter Fehler, und er ist typisch: Eine
   Textaenderung wirkt wie Inhalt und ist in Wahrheit auch Layout. Deshalb
   bricht die Zeile jetzt um, statt sich auf eine Textlaenge zu verlassen. */
.gate{ flex-wrap:wrap; }

@media (max-width:1179px){
  body{ padding-bottom:calc(61px + env(safe-area-inset-bottom)); }
}

/* Die Leiste scrollt auch auf dem Desktop waagerecht (gemessen 1528 px
   Inhalt bei 1319 px Platz). Ein weicher Auslauf am rechten Rand zeigt,
   dass es weitergeht — ohne einen zusaetzlichen Hinweistext, der auf jeder
   langen Seite dauerhaft Hoehe kosten wuerde. Der Auslauf liegt ueber der
   Leiste und darf keine Klicks abfangen. */
.jumpbar{ position:sticky; }
.jumpbar::after{
  content:""; position:absolute; inset:0 0 0 auto; width:2.5rem; pointer-events:none;
  background:linear-gradient(to right,rgba(255,255,255,0),rgba(255,255,255,.94));
}

/* ── Problemfinder: Auswahl zurücksetzen ───────────────────────────────
   Der Knopf traegt `hidden`, solange nichts offen ist. Deshalb steht die
   Anzeigeart hier hinter :not([hidden]) — eine unbedingte display-Regel
   wuerde `hidden` aushebeln, und der Knopf stuende immer da.

   Er ist bewusst zurueckhaltender gezeichnet als die Chips: Er ist der
   Rueckweg, nicht die Hauptsache. */
.finder__reset:not([hidden]){
  display:inline-flex; align-items:center; margin-top:var(--sp-4);
  font:inherit; font-size:var(--fs-sm); line-height:1.25;
  min-height:44px; padding:.6rem 1rem; cursor:pointer;
  background:transparent; color:var(--fg-dim);
  border:var(--hair) dashed var(--rule); border-radius:var(--r-1);
  transition:color .18s ease, border-color .18s ease;
}
.finder__reset:hover{ color:var(--fg-max); border-color:var(--fg-max); }
.sf-navy .finder__reset,.sf-deep .finder__reset{ color:rgba(255,255,255,.72); }
.sf-navy .finder__reset:hover,.sf-deep .finder__reset:hover{ color:#fff; border-color:#fff; }
@media (prefers-reduced-motion:reduce){ .finder__reset{ transition:none; } }

/* ── 5.2.0 · QR-Landingpage /karte/ ────────────────────────────────────
   Eigene Vorlage, eigene Umgebung. Die Regeln hier gelten ausschliesslich
   unter .karte und koennen deshalb nichts an der uebrigen Website
   verstellen.

   Zwei Entscheidungen, die man sehen sollte:

   Der Kopf klebt nicht. Auf 320 px sind 60 px klebender Kopf ein Zehntel
   des Bildes, dauerhaft belegt — auf einer Seite, deren einziger Zweck
   drei Schaltflaechen sind. Er scrollt mit und gibt den Platz frei.

   Die Sofortaktionen stehen untereinander statt nebeneinander. Vier
   Schaltflaechen nebeneinander waeren bei 320 px je 68 px breit; das ist
   bedienbar, aber nicht mit dem Daumen einer Hand. Untereinander ist jede
   volle Breite und damit sicher zu treffen. */

.karte__kopf{ background:var(--navy); padding-block:.9rem; }
.karte__kopf .shell{ display:flex; align-items:center; }

/* Der Hero fuellt bei jedem Geraet den ersten Bildschirm, ohne ihn zu
   sprengen: min-height statt fester Hoehe, damit laengerer Text nicht
   abgeschnitten wird. */
.karte .band:first-of-type{ padding-block:var(--sp-7); }

/* Sofortaktionen: volle Breite, grosse Ziele, klare Reihenfolge. */
.karte .band:first-of-type .cta-row{
  display:grid; grid-template-columns:1fr; gap:var(--sp-3); margin-top:var(--sp-6);
}
.karte .band:first-of-type .cta-row > a{
  width:100%; justify-content:center; min-height:56px; font-size:var(--fs-base);
}
@media (min-width:600px){
  .karte .band:first-of-type .cta-row{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}

/* Die erste Aktion ist der Anruf und traegt deshalb die Signalfarbe. */
.karte .band:first-of-type .cta-row > a:first-child{
  background:var(--accent); color:#fff; border-color:var(--accent);
}

.karte__fuss{
  background:var(--navy-deep); color:rgba(255,255,255,.72);
  padding-block:var(--sp-6); margin-top:var(--sp-7);
  padding-bottom:calc(var(--sp-6) + env(safe-area-inset-bottom));
}
.karte__fuss .shell{ display:flex; flex-wrap:wrap; gap:var(--sp-3) var(--sp-5); align-items:center; }
.karte__fuss nav{ display:flex; flex-wrap:wrap; gap:0 var(--sp-5); }
.karte__fuss a{
  display:inline-flex; align-items:center; min-height:44px;
  color:rgba(255,255,255,.82); text-decoration:none; font-size:var(--fs-sm);
}
.karte__fuss a:hover,.karte__fuss a:focus-visible{ color:#fff; text-decoration:underline; text-underline-offset:3px; }
.karte__fuss p{ margin:0; margin-left:auto; font-size:var(--fs-sm); color:rgba(255,255,255,.55); }

/* Kein Dock, keine schwebenden Aktionen — die Vorlage laedt sie gar nicht
   erst. Diese Regel ist die Absicherung fuer den Fall, dass ein Plugin sie
   nachtraeglich einhaengt. */
.karte .dock,.karte .float-contact{ display:none !important; }

/* ── 5.2.1 · gemessene Nachbesserung auf schmalen Geraeten ─────────────
   Gemessen wurde, wo die erste Hauptaktion beginnt:

       320 px   Y = 532        sichtbarer Bereich rund 568 px
       360 px   Y = 438
       390 px   Y = 439

   Auf 320 px steht „Anrufen" damit 36 px vor dem unteren Bildrand. Das ist
   formal im Bild und praktisch nicht da.

   Die Ueberschrift ist auf der uebrigen Website eine Schauflaeche und darf
   das auch sein. Auf dieser Seite ist sie eine Begruessung vor vier
   Schaltflaechen. Sie faellt hier deshalb kleiner aus als sonst — nicht,
   weil kleine Schrift besser waere, sondern weil der Zweck der Seite
   darunter steht.

   Der feste Zeilenumbruch im Titel ist entfallen. Der erste Versuch liess
   ihn im Inhalt stehen und blendete ihn hier mit `display:none` aus — auf
   dem Screenshot stand daraufhin „Schön, dass Sieunsere Karte". Ein
   ausgeblendetes <br> hinterlaesst kein Leerzeichen. Die Messung fand das
   nicht; sie zaehlt Pixel, nicht Woerter. Statt eines festen Umbruchs
   verteilt `text-wrap:balance` die Zeilen auf jeder Breite selbst. */
.karte .b-intro .t-h1{ text-wrap:balance; }

@media (max-width:599px){
  .karte .band:first-of-type{ padding-block:var(--sp-6) var(--sp-7); }
  .karte .b-intro .t-h1{
    font-size:clamp(1.85rem,1.35rem + 2.2vw,2.4rem); line-height:1.1;
    margin-bottom:var(--sp-4);
  }
  .karte .b-intro .lead{ font-size:1.05rem; line-height:1.45; }
  .karte .b-intro .lead.mt-5{ margin-top:var(--sp-4); }
  .karte .band:first-of-type .cta-row{ margin-top:var(--sp-5); }
  .karte .band:first-of-type .cta-row > a{ min-height:52px; }
}

/* Querformat auf dem Telefon. Wer die Visitenkarte scannt, haelt das Geraet
   nicht immer hochkant — und 390 px Hoehe sind fuer Ueberschrift, Vorspann
   und Schaltflaeche zu wenig. Gemessen: erste Aktion bei Y = 396 auf
   844x390, also 6 px unter dem Bildrand. Hier zaehlt die Hoehe, nicht die
   Breite, deshalb greift die Regel ueber max-height. */
@media (orientation:landscape) and (max-height:520px){
  .karte .band:first-of-type{ padding-block:var(--sp-5); }
  .karte .b-intro .t-h1{ font-size:clamp(1.7rem,1.2rem + 1.6vw,2.2rem); line-height:1.1; margin-bottom:var(--sp-3); }
  .karte .b-intro .lead{ font-size:1rem; line-height:1.4; }
  .karte .b-intro .lead.mt-5{ margin-top:var(--sp-3); }
  .karte .band:first-of-type .cta-row{ margin-top:var(--sp-4); }
}

/* ── 5.2.1 · 200 % Textgröße auf 320 px ───────────────────────────────
   WCAG 1.4.4 verlangt, dass Text auf das Doppelte vergroessert werden kann,
   ohne dass Inhalt verlorengeht. Auf einem 320-px-Geraet bleiben dann rund
   240 px Inhaltsbreite — und „Ansprechpartner" ist bei doppelter Schrift
   322 px breit. Gemessen wurden 49 px waagerechter Ueberlauf.

   main.css faengt das in Abschnitt 14.11 fuer Ueberschriften ab. Fliesstext
   stand nicht dabei, und bei normaler Schriftgroesse faellt das auch nie
   auf. Bei doppelter faellt es sofort auf.

   Zwei Ursachen, zwei Regeln:

   Erstens Raster ohne feste Spalte. `.picker` und `.ckl__i` haben unterhalb
   ihres Umbruchpunktes gar keine `grid-template-columns`. Die implizite
   Spalte ist `auto` und damit mindestens so breit wie der laengste
   unteilbare Inhalt — sie sprengt den Rahmen, statt ihn einzuhalten. Eine
   ausdrueckliche `minmax(0,1fr)` verhindert das. Die Regeln stehen in
   `max-width`-Abfragen, damit sie die Mehrspaltigkeit weiter oben nicht
   ueberschreiben; refine.css laedt nach main.css und wuerde sie sonst
   stillschweigend aushebeln.

   Zweitens Fliesstext, der nicht umbrechen darf. `overflow-wrap:break-word`
   greift ausschliesslich dann, wenn ein Wort sonst ueberliefe — bei
   normaler Schriftgroesse aendert die Regel nichts. */
@media (max-width:639px){
  .picker,.rail{ grid-template-columns:minmax(0,1fr); }
}
@media (max-width:819px){
  .ckl__i{ grid-template-columns:minmax(0,1fr); }
}

/* Die Regel steht am body und wird vererbt. Eine Liste einzelner Auswahlen
   waere wieder eine Liste, die nur kennt, was sie schon kennt — genau der
   Fehler, den der vorige Durchgang mit der Wortliste gemacht hat. */
body{ overflow-wrap:break-word; }

/* Rasterspalten mit einer Mindestbreite in rem sind derselbe Fehler wie der
   Innenabstand in rem, nur schwerer zu sehen:

     .brief__side  grid-template-columns: repeat(auto-fit, minmax(11.5rem,1fr))

   Bei normaler Schrift sind 11.5rem 184 px und passen in 280 px
   Inhaltsbreite. Bei 200 % Textgröße sind es 368 px — die Spalte ist dann
   breiter als der Bildschirm, und `auto-fit` kann daran nichts ändern, weil
   die Mindestbreite eine Zusage ist.

   `min(11.5rem, 100%)` macht daraus eine Zusage mit Rückfallebene: so breit,
   wie gewünscht, aber nie breiter als der Platz. Bei normaler Schrift ändert
   die Regel nichts.

   Betroffen sind drei Stellen in main.css; alle drei stehen hier. */
.brief__side{ grid-template-columns:repeat(auto-fit,minmax(min(11.5rem,100%),1fr)); }
.swatches{ grid-template-columns:repeat(auto-fill,minmax(min(6.5rem,100%),1fr)); }
.fam-c .b-intro .facts{ grid-template-columns:repeat(auto-fit,minmax(min(12rem,100%),1fr)); }

/* Listeneinträge und Flexzeilen bei starker Textvergrößerung.

   `overflow-wrap:break-word` am body bricht ein zu langes Wort beim
   Zeichnen, ändert aber nichts an der Breite, mit der ein Flex- oder
   Rasterkind *rechnet*. Genau daran hingen zuletzt 42 Ziele: Ein
   Listeneintrag mit `display:flex` schrumpft nie unter seinen längsten
   Bestandteil, und bei doppelter Schrift ist der breiter als das Gerät.

   `anywhere` rechnet mit, `min-width:0` erlaubt das Schrumpfen. Beides
   greift nur unterhalb von 400 px und nur, wenn der Text sonst nicht
   passte — bei normaler Schriftgröße ist die Regel wirkungslos. */
@media (max-width:400px){
  li,dd,dt,p,figcaption,td,th,summary,.copy{ overflow-wrap:anywhere; }
  /* main.css setzt `.qa summary{ overflow-wrap:break-word }`. Das ist
     spezifischer als ein blosses `summary` und gewinnt trotz spaeterer
     Datei — die Regel oben lief deshalb ins Leere. Gemessen: 369 px
     Inhalt in 280 px Kasten. */
  .qa summary,.qa summary *{ overflow-wrap:anywhere; }

  /* Dieselbe Ursache, zweiter Fall — und der Kommentar darueber hat ihn
     schon beschrieben, ohne ihn mitzuloesen.

     main.css setzt `.t-mega,.t-h1 … .t-h4,.scape__title{
     overflow-wrap:break-word }`. Eine Klasse (0-1-0) schlaegt das blosse
     `p` (0-0-1) aus der Regel oben, obwohl diese Datei spaeter kommt.
     Betroffen sind `p.t-h3` und `p.t-h4`: Absaetze, die eine
     Ueberschriftenklasse tragen.

     Der Unterschied ist nicht kosmetisch. `break-word` bricht ein zu langes
     Wort beim Zeichnen; `anywhere` aendert zusaetzlich die Breite, mit der
     ein Flex- oder Rasterkind RECHNET. An genau dieser Unterscheidung hingen
     in diesem Projekt schon einmal 42 Ziele. Dass heute nichts uebertritt,
     ist deshalb kein Argument: Die Falle ist scharf und wurde nur nicht
     ausgeloest.

     Bei gleicher Spezifitaet gewinnt die spaetere Datei — deshalb genuegt
     es, dieselben Selektoren hier zu wiederholen. `hyphens:auto` bleibt
     unberuehrt. */
  .t-mega,.t-h1,.t-h2,.t-h3,.t-h4,.scape__title,
  .t-mega *,.t-h1 *,.t-h2 *,.t-h3 *,.t-h4 *{ overflow-wrap:anywhere; }
  li > *,button > *,.pline,.pline > *{ min-width:0; }

  /* Das Sicherheitsnetz. `:where()` hat keine Spezifität und kann deshalb
     keine gewollte Regel überstimmen; `min-width:0` erlaubt nur das
     Schrumpfen und macht nichts breiter. Tabellen sind ausgenommen — sie
     liegen ohnehin in einem Bereich mit eigenem Querlauf, und dort ist
     Schrumpfen falsch. */
  main :where(div,section,ul,ol,dl,li,figure,article,aside,details,a,label) > :not(table){ min-width:0; }

  /* Ein Aufzählungszeichen ist kein Textblock. `.split__m` trägt einen
     Geviertstrich und war nach dem Netz oben 6 px breit bei 21 px Inhalt —
     der Strich stand halb im Nachbarn. Marker behalten ihre Breite. */
  .split__m,.track__n,.ckl__n,.co__n{ flex:none; min-width:max-content; }

  /* `.line__k{ flex:0 0 9rem }` ist dieselbe Falle in Flex-Form: eine feste
     Basis in rem. Bei doppelter Schrift sind 9rem 288 px in 280 px Platz.
     `min()` deckelt die Basis, ohne sie bei normaler Schrift zu verändern —
     9rem sind dort 144 px und liegen weit unter 100 %. */
  .line__k{ flex-basis:min(9rem,100%); }

  /* Die Schaltflächen sind Flexzeilen aus Text und Pfeil. Sie schrumpfen
     mit `min-width:0`, aber der Text darin rechnet weiter mit seinem
     längsten Wort, solange er nicht umbrechen darf. */
  .cta-request,.cta-call,.cta-depth,.cta-text,.cta-jump{
    min-width:0; overflow-wrap:anywhere;
  }
}

/* Der Kicker ist eine Flexzeile aus Strich und Text. Ein Flex-Kind
   schrumpft ohne Zutun nie unter seine Inhaltsbreite, und `break-word`
   aendert daran nichts — es bricht beim Zeichnen, nicht beim Rechnen.
   `anywhere` rechnet mit. Bei einem kurzen Mono-Etikett ist das
   vertretbar; im Fliesstext waere es das nicht. */
.kicker{ flex-wrap:wrap; overflow-wrap:anywhere; }
/* Ein Flex-Kind schrumpft ohne `min-width:0` nie unter seine Inhaltsbreite.
   „Einsatzgebiet ansehen" mass damit 291 px in einem 240 px breiten
   Fenster. */
.cta-row > *{ min-width:0; }
.cta-row .cta-text{ overflow-wrap:anywhere; }

/* Abstandsmarken in rem wachsen mit der Textgroesse — auch dann, wenn der
   Bildschirm nicht mitwaechst. Bei 200 % Text auf 320 px wurde aus
   `padding:var(--sp-6)` beidseitig 2x64 px. Die Innenabstaende einer
   Auswahlkarte belegten damit die gesamte verfuegbare Breite, und der
   Inhalt schob die Karte 108 px aus dem Bild.
   `min()` deckelt den Abstand an der Bildschirmbreite, ohne ihn bei
   normaler Schriftgroesse zu veraendern: auf 1440 px sind 7 vw rund 100 px
   und damit weit ueber --sp-6, auf 320 px sind es 22 px. */
.picker__item{ padding:min(var(--sp-6),7vw); }

/* Bei 200 % Textgroesse auf 320 px lief „info@lebowski-fenster.de" um
   108 px aus der Schaltflaeche heraus und erzwang waagerechtes Scrollen.
   Eine E-Mail-Adresse darf umbrechen; eine Rufnummer soll es nicht, und
   sie muss es bei diesen Laengen auch nicht. `min-width:0` ist noetig,
   weil ein Flex-Kind sonst nie unter seine Inhaltsbreite schrumpft. */
.cta-call{ min-width:0; }
.cta-call > *{ min-width:0; }
.cta-call .num{ overflow-wrap:anywhere; }

/* Auf dem Screenshot stand „INFO@LEBOWSKI-FENSTER.DE".
   `.cta-call > :first-child` in main.css setzt `text-transform:uppercase`
   und war fuer die Beschriftung gedacht. lebowski_ctas() gibt die
   Beschriftung aber als blossen Textknoten aus; das erste *Element* ist
   `<span class="num">`. Der Selektor trifft damit genau das Gegenteil
   dessen, was er meint.
   Bei Rufnummern faellt das nicht auf — Ziffern haben keine Grossform. Bei
   einer E-Mail-Adresse schon: sie sieht aus wie eine andere Adresse und
   liest sich schlechter. Korrigiert wird hier nur die Wirkung; der
   Selektor in main.css bleibt, weil er die uebrige Auszeichnung
   (Mono, Laufweite, Farbe) korrekt setzt. */
.cta-call .num{ text-transform:none; }

/* Die Schlussverweise sind auf dieser Seite keine Verweise im Fliesstext,
   sondern eine Reihe eigenstaendiger Ziele — gemessen 30 px hoch. Die
   Ausnahme fuer Textlinks in WCAG 2.5.8 greift nur innerhalb eines Satzes;
   hier greift sie nicht. Die Regel steht bewusst auf `.cta-row .cta-text`
   und nicht auf `.cta-text`: in templates/anfrage.php steht derselbe Link
   mitten in einem Satz, und dort waere eine Mindesthoehe falsch. */
.cta-row .cta-text{ min-height:44px; align-items:center; }


/* ═══════════════════════════════════════════════════════════════════════
   5.2.2 · Kopfversatz — eine Variable, zwei Bedeutungen
   ═══════════════════════════════════════════════════════════════════════

   Befund, gemessen am offenen Kontaktpanel bei 1458 px:

       .head            120,8 px hoch   (z-index 120)
         .head__util     44,8 px
         .head__main     76,0 px
       .cpanel          top 76,0 px     (z-index 118)
       .cpanel__close   84 – 128 px     verdeckt
       .col-title       108 – 140 px    verdeckt

   `--hd` ist die Hoehe der Kopf-*Hauptzeile*. Genau so wird sie in
   `.head__main .shell{ min-height:var(--hd) }` verwendet, und das ist
   richtig. Ab 1180 px wird zusaetzlich `.head__util` sichtbar — 44 px
   Mindesthoehe plus Haarlinie — und liegt innerhalb desselben sticky
   `.head`. `--hd` waechst dabei nicht mit.

   Vier Regeln benutzen `var(--hd)` aber in der anderen Bedeutung:
   „Abstand vom Viewportrand bis unter den Kopf". Sie sitzen ab 1180 px
   alle um dieselben 44,8 px zu hoch:

       .cpanel{ top:var(--hd) }                       main.css 458
       .jumpbar{ top:var(--hd) }                      main.css 622
       html{ scroll-padding-top:calc(var(--hd)+1.5rem) }  main.css 91
       .mnav{ inset:var(--hd) 0 0 }                   main.css 426

   Beim Kontaktpanel ist die Folge sichtbar: Der Kopf liegt mit z-index
   120 ueber dem Panel mit 118 und malt dessen oberste 44,8 px zu — also
   Schliessen-Button und Ueberschrift.

   `--hd` wird deshalb NICHT umgedeutet; das wuerde die Hauptzeile
   aufblaehen. Stattdessen ein zweites Token fuer die zweite Bedeutung.
   Ein blosser Abstandszuschlag am Panel waere die falsche Korrektur: Er
   verdeckt den Fehler und laesst Sprungleiste und Ankerziele stehen. */

:root{ --hd-off:var(--hd); }
@media (min-width:1180px){
  :root{ --hd-off:calc(var(--hd) + 44px + var(--hair)); }
}

/* Oben und unten gebunden — dieselbe Bindung, die `.mnav` seit jeher
   hat. Ohne sie laeuft das Panel bei 1024x600, im Querformat und bei
   150 % Zoom unten aus dem Viewport, ohne dass etwas scrollt.
   `overscroll-behavior:contain` verhindert, dass das Scrollen am Ende
   des Panels auf die Seite dahinter durchschlaegt. */
.cpanel{
  top:var(--hd-off);
  bottom:0;
  overflow-y:auto;
  overscroll-behavior:contain;
}

/* Dieselbe Ursache, zwei weitere Symptome. Gemessen: Sprungleiste bei
   top 76 px, Kopfunterkante 120,8 px. */
.jumpbar{ top:var(--hd-off); }
html{ scroll-padding-top:calc(var(--hd-off) + 1.5rem); }

/* Heute ohne sichtbare Wirkung — `.mnav` laeuft nur unter 1180 px, wo
   `--hd-off` und `--hd` gleich sind. Steht hier, damit eine spaetere
   Verschiebung des Breakpoints nicht denselben Fehler neu erzeugt. */
.mnav{ inset:var(--hd-off) 0 0; }
