/* ═══════════════════════════════════════════════════════════════════════════
   WEBAGENTUR SCHERZINGER — Design-System
   ═══════════════════════════════════════════════════════════════════════════

   Gestaltungsabsicht, damit spätere Änderungen sie nicht versehentlich
   zerlegen:

   Die Marke ist dunkel. Das WS-Monogramm ist gebürstetes Chrom mit einem
   goldenen Balken auf fast schwarzem Grund, und das „M" in WEBAGENTUR ist das
   Holstentor. Eine helle Seite unter diesem Zeichen wären zwei Auftritte statt
   einem — deshalb ist die ganze Seite schwarz.

   Das ist zugleich die stärkste Abgrenzung: Wer in Lübeck „Webagentur" sucht,
   findet helle, blaue, austauschbare Seiten. Eine schwarze mit Chrom und Gold
   merkt man sich.

   Drei Regeln tragen das Ganze:

   1. WENIG GOLD. Es markiert genau vier Dinge: den Preis, die primäre Aktion,
      die Akzentkante am Antwortblock und das Signet. Sonst nirgends. Eine
      Akzentfarbe, die überall ist, betont nichts.

   2. TYPOGRAFIE STATT DEKORATION. Keine Illustrationen, keine Icon-Wolken.
      Hierarchie entsteht aus Größe, Gewicht und Weißraum. Auf schwarzem Grund
      wirkt Schrift schwerer als auf weißem — deshalb sind die Gewichte hier
      eine Stufe leichter und die Laufweiten eine Spur offener als üblich.

   3. DREI FLÄCHEN ALS KAPITEL. Grund (#08090C), Karte (#0E1014), erhöhte
      Fläche (#14161B). Die Unterschiede sind klein und sollen es sein: Auf
      Schwarz trennt schon ein Hauch, und starke Sprünge wirken fleckig.

   Der Preis steht above the fold. Das ist die zentrale Vorgabe des Inhabers
   und der Grund, warum der Hero kompakt bleibt statt bildschirmfüllend.

   ── Farben: gemessen, nicht gewählt ──
   Alle Marken-Farbwerte stammen aus den Logodateien unter static/img/marke/
   (Pixelmessung, nicht Augenmaß). Wer sie ändert, ändert die Marke.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ── Schriften ──────────────────────────────────────────────────────────────
   Selbst gehostet aus static/fonts/, nicht von Google. Zwei Gründe: Ohne
   Verbindung zu Google-Servern braucht diese Seite kein Einwilligungsbanner
   (und die Datenschutzerklärung sagt das ausdrücklich zu), und der Font-Request
   startet parallel zum CSS statt danach.

   font-display: optional statt swap — mit swap tauscht der Browser die Schrift
   mitten im Seitenaufbau, der Text ändert seine Breite und schiebt das
   Hero-Formular nach unten (CLS). Mit optional wird der Webfont nur benutzt,
   wenn er im ersten Moment schon da ist; sonst bleibt für diesen Aufruf der
   Fallback. Beide Schriften sind preloaded und zusammen unter 55 KB. */

@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: optional;
  src: url("../fonts/instrumentsans-latin.fa41c43a3d8e.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: optional;
  src: url("../fonts/instrumentsans-latin-ext.1ff13d113ba4.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url("../fonts/instrumentserif-latin.9b8dd1ecf641.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url("../fonts/instrumentserif-latin-ext.b160c869d0b2.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Metrisch angepasste Fallbacks. Arial ist schmaler als Instrument Sans — beim
   Umschalten springt der Text. size-adjust skaliert Arial auf dieselbe mittlere
   Zeichenbreite; die vertikalen Overrides bilden die Metriken des WEBFONTS nach,
   geteilt durch size-adjust (nicht Arials eigene — damit wird die Zeilenbox zu
   niedrig und der Sprung größer).
   Zahlen aus den echten Fontdaten (fontTools), Skript in docs/.
   ⚠ Beim Austausch einer Schriftdatei MÜSSEN sie neu berechnet werden. */
@font-face {
  font-family: 'Instrument Sans Fallback';
  src: local('Arial'), local('Helvetica'), local('Liberation Sans');
  size-adjust: 127.89%;
  ascent-override: 75.85%;
  descent-override: 19.55%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Instrument Serif Fallback';
  src: local('Times New Roman'), local('Times'), local('Liberation Serif');
  size-adjust: 105.24%;
  ascent-override: 94.07%;
  descent-override: 29.46%;
  line-gap-override: 0%;
}


/* ── Tokens ─────────────────────────────────────────────────────────────────
   Keine Farbe, kein Abstand und keine Schriftgröße wird außerhalb dieses Blocks
   als Rohwert geschrieben. Wer einen Wert direkt ins Regelwerk tippt, nimmt ihn
   aus dem System heraus — und beim nächsten Feinschliff stimmt genau diese eine
   Stelle nicht mehr.

   Jede Kombination unten ist mit `python manage.py check_kontrast` gerechnet.
   Die schwächste Textpaarung liegt bei 5,9:1, die stärkste bei 19,4:1. */

:root {
  color-scheme: dark;

  /* Grundflächen — die Abstufungen sind absichtlich klein. Auf Schwarz trennt
     schon ein Hauch; große Sprünge wirken fleckig. */
  --ws-grund:        #08090C;   /* Seitengrund, aus dem Logo gemessen */
  --ws-grund-2:      #0E1014;   /* Karten */
  --ws-grund-3:      #14161B;   /* erhöhte Flächen, Abschnittswechsel */
  --ws-linie:        #2A2E36;
  --ws-linie-stark:  #666E7A;   /* 3,5:1 auch auf grund-3 — WCAG 1.4.11
                                   verlangt das fuer Feldrahmen */

  /* Chrom — die Textfarben. Aus dem Verlauf des Monogramms gemessen. */
  --ws-chrom:        #FCFCFB;   /* 19,4:1 — Überschriften, Haupttext */
  --ws-chrom-2:      #B9BCC2;   /* 10,5:1 — Fließtext, sekundär */
  --ws-chrom-3:      #8A8F98;   /*  6,1:1 — Meta, Labels, Platzhalter */

  /* Gold — der einzige Akzent. Sparsam einsetzen. */
  --ws-gold:         #E1B565;   /* 10,4:1 — Preiszahl, Links, primärer Knopf */
  --ws-gold-2:       #BE954B;   /*  7,2:1 — Linien, Rahmen, Hover */
  --ws-gold-3:       #9C7D46;   /* dunkelste Stufe, nur für Rahmen/Verläufe */
  --ws-gold-hauch:   #17130C;   /* getönte Fläche, ~6 % Gold auf Grund */

  /* Die Leiste über einem Referenz-Screenshot. Etwas heller als jede
     Kapitelfläche, weil sie eine fremde Oberfläche einrahmt und erkennbar
     nicht Teil dieser Seite ist. */
  --ws-browser:      #191C22;

  /* Zustandsfarben. Auf dunklem Grund brauchen sie mehr Helligkeit als üblich,
     sonst verschwinden sie. */
  --ws-gut:          #6FCB9B;
  --ws-gut-grund:    #0D1A14;
  --ws-fehler:       #F09490;
  --ws-fehler-grund: #1E1110;

  /* Abstände — eine Skala, keine Zufallswerte. */
  --ws-1:  0.25rem;   --ws-2:  0.5rem;    --ws-3:  0.75rem;
  --ws-4:  1rem;      --ws-5:  1.5rem;    --ws-6:  2rem;
  --ws-7:  3rem;      --ws-8:  4rem;      --ws-9:  6rem;      --ws-10: 8rem;

  /* Typografie. clamp() skaliert fluide zwischen 360 px und 1440 px Viewport. */
  --ws-schrift:       'Instrument Sans', 'Instrument Sans Fallback', system-ui, sans-serif;
  --ws-schrift-serif: 'Instrument Serif', 'Instrument Serif Fallback', Georgia, serif;

  --ws-t-xs:   0.8125rem;
  --ws-t-sm:   0.875rem;
  --ws-t-base: 1rem;
  --ws-t-lg:   clamp(1.0625rem, 0.99rem + 0.32vw, 1.1875rem);
  --ws-t-xl:   clamp(1.25rem, 1.14rem + 0.48vw, 1.5rem);
  --ws-t-2xl:  clamp(1.5rem, 1.32rem + 0.8vw, 1.9375rem);
  --ws-t-3xl:  clamp(1.875rem, 1.55rem + 1.45vw, 2.625rem);
  --ws-t-4xl:  clamp(2.25rem, 1.7rem + 2.4vw, 3.5rem);
  --ws-t-5xl:  clamp(2.75rem, 1.9rem + 3.8vw, 4.75rem);

  --ws-radius:    10px;
  --ws-radius-sm: 6px;
  --ws-radius-lg: 16px;

  /* Auf schwarzem Grund tragen Schatten nicht — sie sind unsichtbar. Tiefe
     entsteht hier über Flächenhelligkeit und Hairlines. Was bleibt, ist ein
     Schein für die helle Karte im Hero, wo ein echter Helligkeitssprung ist. */
  --ws-schein: 0 2px 8px rgba(0,0,0,.5), 0 12px 40px rgba(0,0,0,.45);
  --ws-schein-gold: 0 0 0 1px rgba(225,181,101,.22), 0 8px 32px rgba(225,181,101,.08);

  --ws-breite:     1180px;
  --ws-breite-eng: 760px;

  --ws-tempo:  180ms;
  --ws-kurve:  cubic-bezier(0.16, 1, 0.3, 1);
}


/* ── Reset & Basis ──────────────────────────────────────────────────────── */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;   /* damit ein Sprung nicht unter der Navi landet */
}

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

body {
  margin: 0;
  font-family: var(--ws-schrift);
  font-size: var(--ws-t-base);
  line-height: 1.65;
  color: var(--ws-chrom-2);
  background: var(--ws-grund);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;   /* kein seitliches Wischen auf dem Handy */
}

h1, h2, h3, h4 {
  margin: 0;
  color: var(--ws-chrom);
  /* Auf schwarzem Grund wirkt Schrift schwerer als auf weißem. 600 statt 700,
     und eine Spur mehr Laufweite, sonst läuft sie zu. */
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

p { margin: 0 0 var(--ws-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--ws-gold); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--ws-chrom); }

img, svg, video { max-width: 100%; height: auto; display: block; }

ul, ol { margin: 0 0 var(--ws-4); padding-left: 1.25em; }
li { margin-bottom: var(--ws-2); }

hr { border: 0; border-top: 1px solid var(--ws-linie); margin: var(--ws-7) 0; }

strong, b { color: var(--ws-chrom); font-weight: 600; }

/* Ein sichtbarer, ruhiger Fokusring. :focus-visible statt :focus — sonst sieht
   ihn auch, wer mit der Maus klickt, und das wirkt wie ein Fehler. */
:focus-visible {
  outline: 2px solid var(--ws-gold);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection { background: var(--ws-gold); color: var(--ws-grund); }

.ws-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

.ws-skip {
  position: absolute; top: -100px; left: var(--ws-4); z-index: 200;
  background: var(--ws-gold); color: var(--ws-grund);
  padding: var(--ws-3) var(--ws-5); border-radius: var(--ws-radius);
  text-decoration: none; font-weight: 600;
}
.ws-skip:focus { top: var(--ws-3); color: var(--ws-grund); }


/* ── Layout-Primitive ───────────────────────────────────────────────────── */

.ws-huelle {
  width: 100%; max-width: var(--ws-breite);
  margin-inline: auto; padding-inline: var(--ws-5);
}
.ws-huelle--eng { max-width: var(--ws-breite-eng); }

.ws-abschnitt { padding-block: var(--ws-9); }
.ws-abschnitt--knapp { padding-block: var(--ws-7); }

/* Die Kapitelflächen. Der Unterschied ist klein und soll es sein. */
.ws-flaeche-ton  { background: var(--ws-grund-2); }
.ws-flaeche-tief { background: var(--ws-grund-3); }

/* `.ws-band` war früher der dunkle Kontrast zur hellen Seite. Jetzt ist die
   ganze Seite dunkel — das Band ist die *erhöhte* Fläche mit Goldkante.
   Der Klassenname bleibt, damit die Templates unverändert funktionieren. */
.ws-band {
  background: var(--ws-grund-3);
  border-top: 1px solid var(--ws-linie);
  border-bottom: 1px solid var(--ws-linie);
  position: relative;
}
/* Ein Goldfaden am oberen Rand — das einzige Zierelement der Seite. */
.ws-band::before {
  content: ""; position: absolute; top: -1px; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg,
    transparent, var(--ws-gold-2) 22%, var(--ws-gold) 50%, var(--ws-gold-2) 78%, transparent);
  opacity: .55;
}

/* Feine Trennung, wo zwei gleiche Flächen aufeinanderstoßen. */
.ws-flaeche-ton + .ws-flaeche-ton { border-top: 1px solid var(--ws-linie); }


/* ── Abschnitts-Kopf ────────────────────────────────────────────────────────
   Feste Einheit: Eyebrow mit Akzentlinie, Titel, Untertitel. Überall dieselbe,
   damit die Seite einen erkennbaren Takt bekommt. */

.ws-kopf { max-width: 46rem; margin-bottom: var(--ws-7); }
.ws-kopf--mitte { margin-inline: auto; text-align: center; }

.ws-eyebrow {
  display: inline-flex; align-items: center; gap: var(--ws-3);
  font-size: var(--ws-t-xs); font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ws-gold);
  margin-bottom: var(--ws-4);
}
.ws-eyebrow::before {
  content: ""; width: 1.75rem; height: 1px; flex: none;
  background: var(--ws-gold-2);
}
.ws-kopf--mitte .ws-eyebrow::before { display: none; }

.ws-kopf h2 { font-size: var(--ws-t-3xl); margin-bottom: var(--ws-4); }
.ws-kopf p  { font-size: var(--ws-t-lg); color: var(--ws-chrom-2); line-height: 1.6; }

/* Serif nur für große Überschriften. Sie ist der einzige Zierrat der Seite und
   trägt den handwerklichen Ton — nie in Fließtext oder UI. */
.ws-serif {
  font-family: var(--ws-schrift-serif);
  font-weight: 400;
  letter-spacing: -0.008em;
}


/* ── Knöpfe ─────────────────────────────────────────────────────────────────
   Eine primäre Aktion je Ansicht. Die sekundäre ist deutlich leiser — zwei
   gleich laute Knöpfe nebeneinander sind keine Wahl, sondern eine Zögerpause. */

.ws-knopf {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--ws-2);
  padding: 0.8125rem var(--ws-5);
  min-height: 48px;                 /* Touch-Ziel, nicht unterschreiten */
  font-family: inherit;
  font-size: var(--ws-t-base); font-weight: 600; line-height: 1.2;
  border: 1px solid transparent; border-radius: var(--ws-radius);
  text-decoration: none; cursor: pointer;
  transition: background var(--ws-tempo) ease, border-color var(--ws-tempo) ease,
              transform var(--ws-tempo) var(--ws-kurve), box-shadow var(--ws-tempo) ease;
}

/* Gold auf Schwarz, dunkler Text darauf: 10,4:1. */
.ws-knopf--primaer {
  background: var(--ws-gold);
  color: var(--ws-grund);
  border-color: var(--ws-gold);
}
.ws-knopf--primaer:hover {
  background: #D5A954; border-color: #D5A954; color: var(--ws-grund);
  transform: translateY(-1px);
  box-shadow: 0 6px 24px rgba(225, 181, 101, .18);
}
.ws-knopf--primaer:active { transform: translateY(0); }

.ws-knopf--sekundaer {
  background: transparent; color: var(--ws-chrom);
  border-color: var(--ws-linie-stark);
}
.ws-knopf--sekundaer:hover {
  background: var(--ws-grund-3); color: var(--ws-chrom);
  border-color: var(--ws-gold-2);
}

/* Auf der hellen Formularkarte kehrt sich das um. */
.ws-knopf--hell { background: var(--ws-chrom); color: var(--ws-grund); }
.ws-knopf--hell:hover { background: #fff; color: var(--ws-grund); transform: translateY(-1px); }

.ws-knopf--breit { width: 100%; }
.ws-knopf--klein { padding: 0.55rem var(--ws-4); min-height: 40px; font-size: var(--ws-t-sm); }
.ws-knopf[disabled], .ws-knopf[aria-disabled="true"] {
  opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none;
}

.ws-weiter {
  display: inline-flex; align-items: center; gap: var(--ws-2);
  font-weight: 600; text-decoration: none; color: var(--ws-gold);
}
.ws-weiter::after { content: "→"; transition: transform var(--ws-tempo) var(--ws-kurve); }
.ws-weiter:hover::after { transform: translateX(3px); }


/* ── Navigation ─────────────────────────────────────────────────────────── */

.ws-nav {
  position: sticky; top: 0; z-index: 100;
  background: rgba(8, 9, 12, 0.88);
  backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid var(--ws-linie);
}
.ws-nav__innen { display: flex; align-items: center; gap: var(--ws-5); min-height: 68px; }

.ws-nav__logo { flex: none; display: flex; align-items: center; gap: var(--ws-3); text-decoration: none; }
.ws-nav__logo img { height: 30px; width: auto; }
/* Die Wortmarke ist echter Text, kein Bild: skaliert mit, ist lesbar für
   Suchmaschinen und Screenreader, und kostet kein einziges Byte extra. */
.ws-nav__wort { display: flex; flex-direction: column; line-height: 1.05; }
.ws-nav__wort b {
  font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.22em;
  color: var(--ws-chrom-3); text-transform: uppercase;
}
.ws-nav__wort span {
  font-size: 0.9375rem; font-weight: 600; letter-spacing: 0.1em;
  color: var(--ws-gold); text-transform: uppercase;
}

.ws-nav__liste {
  display: flex; align-items: center; gap: var(--ws-1);
  margin: 0 0 0 auto; padding: 0; list-style: none;
}
.ws-nav__liste li { margin: 0; }
.ws-nav__liste a {
  display: block; padding: var(--ws-2) var(--ws-3);
  font-size: var(--ws-t-sm); font-weight: 500;
  color: var(--ws-chrom-2); text-decoration: none;
  border-radius: var(--ws-radius-sm);
  transition: color var(--ws-tempo) ease, background var(--ws-tempo) ease;
}
.ws-nav__liste a:hover { color: var(--ws-chrom); background: var(--ws-grund-3); }
.ws-nav__liste a[aria-current="page"] { color: var(--ws-gold); font-weight: 600; }

/* ⚠ Der Knopf in der Navigation ist AUCH ein `.ws-nav__liste a`.
   `.ws-nav__liste a` hat Spezifität (0,2,1) und schlägt `.ws-knopf--primaer`
   (0,1,0): Der Knopftext wurde dadurch schon einmal in der falschen Farbe
   gerendert und war unlesbar. Deshalb hier ausgeschrieben — ein !important in
   der Navigation würde dieselbe Falle beim nächsten Zustand aufmachen. */
.ws-nav__liste a.ws-knopf { color: var(--ws-grund); }
.ws-nav__liste a.ws-knopf--primaer { background: var(--ws-gold); }
.ws-nav__liste a.ws-knopf--primaer:hover { background: #D5A954; color: var(--ws-grund); }
.ws-nav__liste a.ws-knopf--sekundaer { color: var(--ws-chrom); background: transparent; }

/* ⚠ Ausgeschrieben als `.ws-nav__liste a.ws-nav__tel` — die dritte Stelle in
   dieser Datei, an der dieselbe Falle zuschnappt.

   `.ws-nav__liste a` hat Spezifitaet (0,2,1) und setzt `display: block`. Ein
   blankes `.ws-nav__tel` mit `display: inline-flex` (0,1,0) verliert dagegen.
   Das Ergebnis war kein Layoutfehler, den man als solchen erkennt, sondern ein
   Hoerer-Icon, das UEBER der Nummer stand: 115x54 px statt einer Zeile,
   gemessen am 01.09.2026 bei 1440 px. Es sah aus wie Absicht.

   Dieselbe Falle wie beim Knopf zwanzig Zeilen weiter oben und beim
   `display: none` im 1.280-px-Block. Wer hier eine Eigenschaft ergaenzt,
   schreibt den Elternselektor mit. */
.ws-nav__liste a.ws-nav__tel {
  display: inline-flex; align-items: center; gap: var(--ws-2);
  flex-wrap: nowrap; white-space: nowrap;
  font-size: var(--ws-t-sm); font-weight: 600;
  color: var(--ws-chrom); text-decoration: none;
  padding: var(--ws-2) var(--ws-3);
}
.ws-nav__liste a.ws-nav__tel:hover { color: var(--ws-gold); background: none; }

.ws-nav__schalter {
  display: none; margin-left: auto;
  background: none; border: 1px solid var(--ws-linie-stark);
  border-radius: var(--ws-radius-sm);
  width: 44px; height: 44px; cursor: pointer;
  align-items: center; justify-content: center;
  color: var(--ws-chrom);
}


/* ── Hero ───────────────────────────────────────────────────────────────────
   Der wichtigste Abschnitt. Links das Angebot in Worten und Zahlen, rechts das
   Formular als helle Insel.

   Der Hintergrund ist ein Foto (gebürsteter Stahl, Goldlicht von rechts oben,
   Lübecker Backsteingiebel im Schatten am unteren Rand). Die linke Bildhälfte
   ist bewusst fast leer und sehr dunkel — dort steht die Überschrift, und dort
   wurde der Kontrast gemessen: Weiß erreicht auf der hellsten Stelle links
   15,9:1, Gold 10,1:1.

   Bewusst NICHT bildschirmfüllend. Ein 100vh-Hero mit Scroll-Pfeil würde genau
   das aus dem Blick schieben, weswegen die Leute hier sind: den Preis. */

.ws-hero {
  position: relative;
  background-color: var(--ws-grund);
  color: var(--ws-chrom-2);
  overflow: hidden;
  padding-block: var(--ws-8) var(--ws-9);
  border-bottom: 1px solid var(--ws-linie);
}

/* Das Bild als eigene Ebene statt als background-image am Abschnitt: So kann
   `<picture>` im Markup die passende Größe wählen und der Browser lädt nicht
   für ein Handy die 2560er-Fassung. */
.ws-hero__bild {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 78% 34%;
  pointer-events: none;
  user-select: none;
  /* ⚠ Gespiegelt — und das ist kein Effekt, sondern eine Korrektur.
     Das Bild ist so gebaut, dass die linke Hälfte fast leer ist und das
     Goldlicht rechts einfällt. In diesem Layout liegt rechts aber das
     Formular: gemessen bleiben zwischen Text und Karte 64 px frei, rechts
     daneben 66 px. Ungespiegelt lag damit der einzige interessante Teil des
     Bildes vollständig hinter einer weißen Karte — es hätte auch fehlen
     können. Gespiegelt fällt das Licht von links in die große freie Fläche
     hinter der Überschrift. */
  transform: scaleX(-1);
}
/* Ein Schleier über dem Bild. Er senkt die Helligkeit dort, wo Text steht, und
   lässt die rechte Bildhälfte durchscheinen. Ohne ihn hinge die Lesbarkeit vom
   Bildausschnitt ab — und der ändert sich mit jeder Fensterbreite. */
.ws-hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    /* Waagerecht: rechts deckend (dort liegt die helle Formularkarte und
       braucht ruhigen Grund), nach links durchlässiger, damit die Stahl-
       struktur und das Goldlicht sichtbar werden.
       Nachgemessen: Weiß erreicht unter der Überschrift weiterhin über 12:1,
       Gold über 8:1. */
    linear-gradient(90deg,
      rgba(8,9,12,.62) 0%, rgba(8,9,12,.74) 26%,
      rgba(8,9,12,.88) 46%, rgba(8,9,12,.96) 62%, var(--ws-grund) 100%),
    /* Senkrecht: oben ein wenig gegen die Navigation, unten für den Übergang
       in den nächsten Abschnitt. */
    linear-gradient(to bottom, rgba(8,9,12,.45) 0%, transparent 18%,
                    transparent 66%, rgba(8,9,12,.8) 100%);
}
/* ⚠ Reihenfolge der Ebenen — hier steckte ein Fehler, der das Bild
   unsichtbar machte.

   `.ws-hero > *` hob JEDES direkte Kind auf z-index 1 — auch das <picture>.
   Damit lag das Bild ueber dem Schleier (`::after` hat z-index auto), der
   Schleier wirkte gar nicht, und was man sah, war das nackte Bild an seiner
   dunkelsten Stelle. Es sah aus wie eine schwarze Flaeche.

   Drei Ebenen, ausdruecklich benannt statt durch einen Sammelselektor:
     0  das Bild
     1  der Schleier (::after)
     2  der Inhalt */
.ws-hero > picture { position: absolute; inset: 0; z-index: 0; }
.ws-hero::after { z-index: 1; }
.ws-hero > .ws-huelle { position: relative; z-index: 2; }

.ws-hero__raster {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: var(--ws-8);
  align-items: start;
}

.ws-hero h1 {
  font-size: var(--ws-t-5xl);
  line-height: 1.03;
  margin-bottom: var(--ws-5);
  max-width: 14ch;
  color: var(--ws-chrom);
}
/* Die Zahl ist der Blickfang der Seite. Gold, 10,4:1 auf dem Grund. */
.ws-hero h1 .ws-zahl { color: var(--ws-gold); white-space: nowrap; }

.ws-hero__sub {
  font-size: var(--ws-t-lg);
  color: var(--ws-chrom-2);
  max-width: 40ch;
  margin-bottom: var(--ws-6);
}

/* Die Preise als Zeilen, nicht als Karten. Karten würden gleichwertige Pakete
   suggerieren — es ist ein Weg mit einer Verzweigung. */
.ws-hero__preise {
  display: flex; flex-wrap: wrap; gap: var(--ws-3);
  margin-bottom: var(--ws-6); padding: 0; list-style: none;
}
.ws-hero__preis {
  flex: 1 1 12rem; margin: 0;
  padding: var(--ws-4);
  background: rgba(20, 22, 27, .72);
  border: 1px solid var(--ws-linie);
  border-radius: var(--ws-radius);
  backdrop-filter: blur(6px);
}
.ws-hero__preis b {
  display: block;
  font-size: var(--ws-t-2xl); font-weight: 600;
  letter-spacing: -0.02em; line-height: 1.1;
  color: var(--ws-chrom);
  font-variant-numeric: tabular-nums;
}
/* Der Zusatz „+ 250 €/Monat" gehört optisch zur Zahl davor, nicht daneben —
   sonst liest jemand „500 €" und übersieht die Fortsetzung. */
.ws-hero__preis b small {
  font-size: 0.5em; font-weight: 600; letter-spacing: 0;
  white-space: nowrap; color: var(--ws-gold);
}
.ws-hero__preis span {
  display: block; margin-top: var(--ws-1);
  font-size: var(--ws-t-xs); line-height: 1.4; color: var(--ws-chrom-3);
}

.ws-hero__vertrauen {
  display: flex; flex-wrap: wrap; gap: var(--ws-2) var(--ws-5);
  margin: 0; padding: 0; list-style: none;
  font-size: var(--ws-t-sm); color: var(--ws-chrom-3);
}
.ws-hero__vertrauen li { display: flex; align-items: center; gap: var(--ws-2); margin: 0; }
.ws-hero__vertrauen svg { flex: none; color: var(--ws-gold); }


/* ── Angebotskarte (Formular im Hero) ───────────────────────────────────────
   Helle Insel auf dunklem Grund. Der Kontrastsprung macht sie zum dominanten
   Element — und genau dort soll die Handlung passieren.

   ⚠ Innerhalb dieser Karte gelten HELLE Regeln. Alles, was hier drinsteht,
   erbt sonst die dunklen Textfarben der Seite und ist unlesbar. Wer der Karte
   ein neues Element hinzufügt, prüft seine Farbe hier. */

.ws-karte-anfrage {
  background: #FFFFFF;
  color: #16191F;
  border-radius: var(--ws-radius-lg);
  box-shadow: var(--ws-schein);
  overflow: hidden;
}
.ws-karte-anfrage__kopf {
  padding: var(--ws-5) var(--ws-5) var(--ws-4);
  border-bottom: 1px solid #DCD5CA;
  background: #FAF6EF;
}
.ws-karte-anfrage__kopf h2 { font-size: var(--ws-t-xl); margin-bottom: var(--ws-2); color: #16191F; }
.ws-karte-anfrage__kopf p  { font-size: var(--ws-t-sm); color: #55606F; margin: 0; }
.ws-karte-anfrage__leib { padding: var(--ws-5); }
.ws-karte-anfrage__fuss {
  padding: var(--ws-3) var(--ws-5) var(--ws-5);
  font-size: var(--ws-t-xs); color: #616A76; line-height: 1.5;
}
.ws-karte-anfrage__fuss a { color: #8A5A22; }

.ws-karte-anfrage strong, .ws-karte-anfrage b { color: #16191F; }
.ws-karte-anfrage .ws-knopf--primaer {
  background: #16191F; color: #FFFFFF; border-color: #16191F;
}
.ws-karte-anfrage .ws-knopf--primaer:hover {
  background: #000; border-color: #000; color: #FFFFFF;
  box-shadow: 0 6px 20px rgba(0,0,0,.18);
}


/* ── Formulare ──────────────────────────────────────────────────────────── */

.ws-feld { margin-bottom: var(--ws-4); }
.ws-feld:last-of-type { margin-bottom: var(--ws-5); }

.ws-feld label {
  display: block; margin-bottom: var(--ws-2);
  font-size: var(--ws-t-sm); font-weight: 600; color: var(--ws-chrom);
}
.ws-feld__pflicht { color: var(--ws-gold); }

.ws-feld input[type="text"], .ws-feld input[type="email"],
.ws-feld input[type="tel"], .ws-feld select, .ws-feld textarea {
  width: 100%;
  padding: 0.75rem var(--ws-4);
  min-height: 48px;
  font-family: inherit; font-size: var(--ws-t-base);
  color: var(--ws-chrom); background: var(--ws-grund-3);
  border: 1px solid var(--ws-linie-stark);
  border-radius: var(--ws-radius);
  transition: border-color var(--ws-tempo) ease, box-shadow var(--ws-tempo) ease;
}
.ws-feld textarea { min-height: 7rem; resize: vertical; line-height: 1.6; }
.ws-feld input:focus, .ws-feld select:focus, .ws-feld textarea:focus {
  outline: none; border-color: var(--ws-gold);
  box-shadow: 0 0 0 3px rgba(225, 181, 101, .16);
}
.ws-feld input::placeholder, .ws-feld textarea::placeholder { color: var(--ws-chrom-3); }

.ws-feld select {
  appearance: none;
  /* Ohne das schneidet der Browser den Optionstext hart ab — gemessen an
     „Ich weiss noch nicht — bitte beraten Sie m". Mit Auslassungspunkten
     liest sich dieselbe Stelle als Kuerzung und nicht als Fehler. */
  text-overflow: ellipsis;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' fill='none' stroke='%238A8F98' stroke-width='2'%3E%3Cpath d='M1 1l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right var(--ws-4) center;
  padding-right: var(--ws-8);
}

/* In der hellen Karte: helle Felder. */
.ws-karte-anfrage .ws-feld label { color: #16191F; }
.ws-karte-anfrage .ws-feld__pflicht { color: #8A5A22; }
.ws-karte-anfrage .ws-feld input,
.ws-karte-anfrage .ws-feld select,
.ws-karte-anfrage .ws-feld textarea {
  color: #16191F; background: #FFFFFF; border-color: #94897D;
}
.ws-karte-anfrage .ws-feld input:focus,
.ws-karte-anfrage .ws-feld select:focus,
.ws-karte-anfrage .ws-feld textarea:focus {
  border-color: #8A5A22; box-shadow: 0 0 0 3px rgba(138, 90, 34, .14);
}
.ws-karte-anfrage .ws-feld input::placeholder,
.ws-karte-anfrage .ws-feld textarea::placeholder { color: #7C8493; }
/* ⚠ Hier steckte ein Fehler, der das wichtigste Formularfeld der Seite
   unbrauchbar aussehen liess — live, seit dem Livegang.

   Die Regel darueber setzt `background: #FFFFFF` als KURZSCHREIBWEISE. Die
   setzt nicht nur die Farbe, sondern alle background-Eigenschaften zurueck,
   also auch `background-repeat: no-repeat` und `background-position` aus
   `.ws-feld select`. Diese Regel hier holte danach nur das Bild zurueck — und
   ein nicht wiederholtes Pfeilchen wurde zu einem gekachelten Zickzackmuster
   ueber das ganze Feld. Der Platzhaltertext lag durchgestrichen darin.

   Gemessen am 01.09.2026 im Auswahlfeld „Worum geht es?" der Angebotskarte.
   Wer hier eine weitere background-Eigenschaft braucht, schreibt sie ebenfalls
   aus — die Kurzschreibweise oben nimmt jede zurueck. */
.ws-karte-anfrage .ws-feld select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' fill='none' stroke='%237C8493' stroke-width='2'%3E%3Cpath d='M1 1l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--ws-4) center;
}
.ws-karte-anfrage .ws-feld__hinweis { color: #616A76; }
.ws-karte-anfrage :focus-visible { outline-color: #8A5A22; }

.ws-feld__hinweis { margin: var(--ws-2) 0 0; font-size: var(--ws-t-xs); color: var(--ws-chrom-3); }
.ws-feld--fehler input, .ws-feld--fehler select, .ws-feld--fehler textarea { border-color: var(--ws-fehler); }
.ws-feld__fehler { margin: var(--ws-2) 0 0; font-size: var(--ws-t-sm); font-weight: 500; color: var(--ws-fehler); }
.ws-karte-anfrage .ws-feld__fehler { color: #A32E28; }
.ws-karte-anfrage .ws-feld--fehler input { border-color: #A32E28; }

/* Honeypot. Nicht display:none und nicht type="hidden" — beides erkennen Bots.
   Für Menschen unerreichbar, für einen Bot sichtbar wie jedes andere Feld. */
.ws-hp {
  position: absolute !important; left: -9999px !important;
  width: 1px; height: 1px; opacity: 0; pointer-events: none;
}

.ws-meldung {
  padding: var(--ws-4) var(--ws-5);
  border-radius: var(--ws-radius); border: 1px solid;
  margin-bottom: var(--ws-5); font-size: var(--ws-t-sm);
}
.ws-meldung--gut    { background: var(--ws-gut-grund);    border-color: #1F5138; color: var(--ws-gut); }
.ws-meldung--fehler { background: var(--ws-fehler-grund); border-color: #5A2A28; color: var(--ws-fehler); }


/* ── Karten & Raster ────────────────────────────────────────────────────── */

.ws-raster { display: grid; gap: var(--ws-5); }
.ws-raster--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ws-raster--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.ws-karte {
  position: relative;
  padding: var(--ws-6);
  background: var(--ws-grund-2);
  border: 1px solid var(--ws-linie);
  border-radius: var(--ws-radius);
  transition: transform var(--ws-tempo) var(--ws-kurve),
              border-color var(--ws-tempo) ease, background var(--ws-tempo) ease;
}
.ws-karte:hover {
  transform: translateY(-2px);
  border-color: var(--ws-linie-stark);
  background: var(--ws-grund-3);
}
.ws-karte h3 { font-size: var(--ws-t-xl); margin-bottom: var(--ws-3); }
.ws-karte p  { color: var(--ws-chrom-2); }

/* Akzentkante statt eingefärbter Fläche — hebt hervor, ohne laut zu werden. */
.ws-karte--akzent { border-left: 2px solid var(--ws-gold-2); }

.ws-karte__nummer {
  font-family: var(--ws-schrift-serif);
  font-size: var(--ws-t-2xl); color: var(--ws-gold);
  line-height: 1; margin-bottom: var(--ws-3); display: block;
}

.ws-haken { list-style: none; padding: 0; margin: 0; }
.ws-haken li {
  position: relative; padding-left: 1.85rem; margin-bottom: var(--ws-3);
  color: var(--ws-chrom-2);
}
.ws-haken li::before {
  content: ""; position: absolute; left: 0; top: 0.45em;
  width: 1.05rem; height: 1.05rem; background: var(--ws-gold);
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M7.6 14.2 3.9 10.5l1.4-1.4 2.3 2.3 7-7 1.4 1.4z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.ws-karte-anfrage .ws-haken li { color: #55606F; }
.ws-karte-anfrage .ws-haken li::before { background: #8A5A22; }


/* ── Preistafel ─────────────────────────────────────────────────────────────
   Zwei Wege nebeneinander. Der empfohlene ist hervorgehoben — nicht mit einem
   „BELIEBT"-Fähnchen, das niemand glaubt, sondern über Rahmen und Fläche. */

.ws-preise { display: grid; gap: var(--ws-5); grid-template-columns: repeat(2, minmax(0, 1fr)); }

.ws-preis {
  display: flex; flex-direction: column;
  padding: var(--ws-6);
  background: var(--ws-grund-2);
  border: 1px solid var(--ws-linie);
  border-radius: var(--ws-radius-lg);
}
.ws-preis--empfohlen {
  border-color: var(--ws-gold-2);
  background: linear-gradient(180deg, var(--ws-gold-hauch), var(--ws-grund-2) 42%);
  box-shadow: var(--ws-schein-gold);
}
.ws-preis__marke {
  align-self: flex-start;
  font-size: var(--ws-t-xs); font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ws-gold);
  border: 1px solid var(--ws-gold-3);
  padding: var(--ws-1) var(--ws-3);
  border-radius: 999px; margin-bottom: var(--ws-4);
}
.ws-preis h3 { font-size: var(--ws-t-lg); color: var(--ws-chrom-2); font-weight: 600; margin-bottom: var(--ws-2); }

.ws-preis__betrag { display: flex; align-items: baseline; gap: var(--ws-2); margin-bottom: var(--ws-2); flex-wrap: wrap; }
.ws-preis__betrag b {
  font-size: var(--ws-t-4xl); font-weight: 600;
  letter-spacing: -0.03em; line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--ws-gold);
}
.ws-preis__betrag span { font-size: var(--ws-t-base); color: var(--ws-chrom-3); }

.ws-preis__ust { font-size: var(--ws-t-xs); color: var(--ws-chrom-3); margin-bottom: var(--ws-5); }
.ws-preis__liste { flex: 1; margin-bottom: var(--ws-5); }
.ws-preis .ws-knopf { margin-top: auto; }

/* Bei Preisen ist eine Tabelle ehrlicher als Karten: man kann sie vergleichen. */
.ws-tabelle { width: 100%; border-collapse: collapse; font-size: var(--ws-t-sm); }
.ws-tabelle th, .ws-tabelle td {
  text-align: left; padding: var(--ws-3) var(--ws-4);
  border-bottom: 1px solid var(--ws-linie);
}
.ws-tabelle th { font-weight: 500; color: var(--ws-chrom-2); }
.ws-tabelle td:last-child {
  text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ws-chrom);
}
.ws-tabelle tr:last-child th, .ws-tabelle tr:last-child td { border-bottom: 0; }

/* Tabellen dürfen die Seite nie horizontal schieben — sie scrollen selbst. */
.ws-scrollbar { overflow-x: auto; -webkit-overflow-scrolling: touch; }


/* ── Antwort-zuerst-Block ───────────────────────────────────────────────────
   Steht auf jeder Unterseite direkt unter der H1 und beantwortet deren Frage in
   zwei bis vier Sätzen, bevor irgendetwas erklärt wird.

   Zwei Gründe: Menschen lesen die ersten Zeilen und entscheiden dann. Und
   KI-Antwortsysteme zitieren genau solche Blöcke — `.ws-antwort-text` ist das
   speakable-Ziel im Schema. Wer hier einen Werbesatz hinschreibt, verschenkt
   die wertvollste Stelle der Seite. */

.ws-antwort {
  padding: var(--ws-5) var(--ws-6);
  background: var(--ws-gold-hauch);
  border-left: 2px solid var(--ws-gold);
  border-radius: 0 var(--ws-radius) var(--ws-radius) 0;
  margin-bottom: var(--ws-7);
}
.ws-antwort-text {
  font-size: var(--ws-t-lg); line-height: 1.6;
  color: var(--ws-chrom); margin: 0;
}


/* ── Referenzen ─────────────────────────────────────────────────────────────
   Der frühere Block `.ws-referenz*` stand hier: graue Textkacheln ohne Bild.
   Er ist am 01.09.2026 entfallen, weil die Referenzen seitdem als
   `.ws-schau*`-Schaufenster mit echtem Screenshot im Browserrahmen laufen
   (Erweiterungsblock am Dateiende). Mit ihm ging das letzte Text-Icon der
   Seite (`content: "↗"`); dafür gibt es `pfeil-extern` im Icon-Bauteil. */


/* ── Ablauf (nummerierte Schritte) ──────────────────────────────────────── */

.ws-ablauf { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--ws-5); }
.ws-ablauf li { display: grid; grid-template-columns: 2.75rem 1fr; gap: var(--ws-4); align-items: start; margin: 0; }
.ws-ablauf__nr {
  display: flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem;
  font-family: var(--ws-schrift-serif); font-size: var(--ws-t-lg);
  color: var(--ws-gold);
  background: var(--ws-gold-hauch);
  border: 1px solid var(--ws-gold-3);
  border-radius: 50%;
}
/* Die Schrittüberschriften sind je nach Umgebung h3 oder h4 — auf der
   Kontaktseite stehen sie unter einer h3. Optisch gleich; die Ebene richtet
   sich nach dem Dokument, nicht nach dem Aussehen. */
.ws-ablauf h3, .ws-ablauf h4 { font-size: var(--ws-t-base); margin: 0 0 var(--ws-1); font-weight: 600; }
.ws-ablauf p { font-size: var(--ws-t-sm); color: var(--ws-chrom-2); margin: 0; }


/* ── FAQ ────────────────────────────────────────────────────────────────────
   <details>/<summary> statt JavaScript. Der Text steht damit im HTML, auch wenn
   er zugeklappt ist — GPTBot, ClaudeBot, PerplexityBot und CCBot rendern kein
   JavaScript. Eine FAQ, die per Skript aufklappt, existiert für sie nicht. */

.ws-faq { border-top: 1px solid var(--ws-linie); }
.ws-faq details { border-bottom: 1px solid var(--ws-linie); }
.ws-faq summary {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--ws-4); padding: var(--ws-5) 0;
  font-size: var(--ws-t-lg); font-weight: 600; color: var(--ws-chrom);
  cursor: pointer; list-style: none;
}
.ws-faq summary::-webkit-details-marker { display: none; }
.ws-faq summary::after {
  content: ""; flex: none; width: 0.7rem; height: 0.7rem;
  border-right: 2px solid var(--ws-gold); border-bottom: 2px solid var(--ws-gold);
  transform: rotate(45deg) translateY(-25%);
  transition: transform var(--ws-tempo) var(--ws-kurve);
}
.ws-faq details[open] summary::after { transform: rotate(-135deg) translateY(-25%); }
.ws-faq summary:hover { color: var(--ws-gold); }
.ws-faq__antwort { padding: 0 0 var(--ws-5); color: var(--ws-chrom-2); max-width: 62ch; }


/* ── Über mich ──────────────────────────────────────────────────────────── */

.ws-person { display: grid; grid-template-columns: 220px 1fr; gap: var(--ws-7); align-items: start; }
/* Der Bildrahmen selbst heisst seit dem 01.09.2026 `.ws-portrait` und steht
   weiter unten — er wird auch auf der Startseite gebraucht, und ein
   Bauteil, das an zwei Orten vorkommt, gehoert nicht in den Block einer
   einzelnen Seite. `.ws-person` ist nur noch das Raster. */


/* ── Fußzeile ───────────────────────────────────────────────────────────────
   Trägt die vollständige Anschrift. Das ist kein Zierrat: Name, Adresse und
   Telefonnummer auf jeder Seite in identischer Schreibweise sind das
   NAP-Signal, an dem Google Website und Unternehmensprofil verknüpft. */

.ws-fuss {
  background: var(--ws-grund-2);
  border-top: 1px solid var(--ws-linie);
  color: var(--ws-chrom-2);
  padding-block: var(--ws-8) var(--ws-6);
}
.ws-fuss__raster { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: var(--ws-6); margin-bottom: var(--ws-7); }
.ws-fuss h2 {
  font-size: var(--ws-t-xs); font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ws-gold); margin-bottom: var(--ws-4);
}
.ws-fuss ul { list-style: none; padding: 0; margin: 0; }
.ws-fuss li { margin-bottom: var(--ws-2); font-size: var(--ws-t-sm); }
.ws-fuss a { color: var(--ws-chrom-2); text-decoration: none; }
.ws-fuss a:hover { color: var(--ws-gold); text-decoration: underline; }
.ws-fuss__logo { height: 34px; width: auto; margin-bottom: var(--ws-4); }
.ws-fuss__ende {
  border-top: 1px solid var(--ws-linie); padding-top: var(--ws-5);
  display: flex; flex-wrap: wrap; gap: var(--ws-3) var(--ws-5);
  justify-content: space-between; font-size: var(--ws-t-xs); color: var(--ws-chrom-3);
}
/* <address> kursiviert von Haus aus — hier sind es Kontaktdaten, kein Zitat. */
.ws-adresse { font-style: normal; }


/* ── Eintritts-Animation ────────────────────────────────────────────────────
   Nur opacity und transform — beides läuft auf dem Compositor und erzwingt kein
   Layout. Ohne JavaScript bleibt der Inhalt sichtbar: Die Regel greift erst,
   wenn das Skript die Klasse gesetzt hat. */

.ws-js [data-ws-reveal] {
  opacity: 0; transform: translateY(14px);
  transition: opacity 460ms var(--ws-kurve), transform 460ms var(--ws-kurve);
}
.ws-js [data-ws-reveal].ist-da { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .ws-js [data-ws-reveal] { opacity: 1; transform: none; transition: none; }
}


/* ── Hilfsklassen ───────────────────────────────────────────────────────────
   Bewusst wenige. Ein Utility-Wildwuchs hebelt das Token-System genauso aus
   wie ein Inline-Style, nur unauffälliger. */

.ws-nachsatz { margin-top: var(--ws-5); font-size: var(--ws-t-sm); color: var(--ws-chrom-3); }
.ws-titel-mittel { font-size: var(--ws-t-3xl); margin-bottom: var(--ws-4); }
.ws-block-titel  { font-size: var(--ws-t-2xl); margin-bottom: var(--ws-4); }
.ws-aktionen     { display: flex; flex-wrap: wrap; gap: var(--ws-3); margin-top: var(--ws-6); }
.ws-lesebreite   { max-width: var(--ws-breite-eng); }
.ws-abstand-oben { margin-top: var(--ws-7); }

/* Brotkrume — speist sich aus derselben Liste wie die BreadcrumbList im Schema,
   damit Anzeige und Markup nicht auseinanderlaufen. */
.ws-brotkrumen { margin-bottom: var(--ws-5); font-size: var(--ws-t-sm); }
.ws-brotkrumen ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ws-2); list-style: none; margin: 0; padding: 0; }
.ws-brotkrumen li { margin: 0; display: flex; align-items: center; gap: var(--ws-2); }
.ws-brotkrumen li + li::before { content: "/"; color: var(--ws-linie-stark); }
.ws-brotkrumen a { color: var(--ws-chrom-3); text-decoration: none; }
.ws-brotkrumen a:hover { color: var(--ws-gold); text-decoration: underline; }
.ws-brotkrumen [aria-current] { color: var(--ws-chrom-2); }

/* Schluss-CTA */
.ws-cta { display: grid; grid-template-columns: 1fr auto; gap: var(--ws-7); align-items: center; }
.ws-cta h2 { font-size: var(--ws-t-3xl); margin-bottom: var(--ws-3); }
.ws-cta p { max-width: 52ch; margin: 0; color: var(--ws-chrom-2); }
.ws-cta__aktionen { display: flex; flex-direction: column; gap: var(--ws-3); min-width: 15rem; }

/* Ortsliste — Textlinks statt Karten. Zwölf Karten für zwölf Ortsnamen wären
   viel Fläche für wenig Information. */
.ws-orte { display: flex; flex-wrap: wrap; gap: var(--ws-2); }
.ws-orte a {
  padding: var(--ws-2) var(--ws-4);
  font-size: var(--ws-t-sm); font-weight: 500;
  color: var(--ws-chrom-2); text-decoration: none;
  background: var(--ws-grund-2);
  border: 1px solid var(--ws-linie);
  border-radius: 999px;
  transition: background var(--ws-tempo) ease, color var(--ws-tempo) ease, border-color var(--ws-tempo) ease;
}
.ws-orte a:hover { background: var(--ws-gold-hauch); color: var(--ws-gold); border-color: var(--ws-gold-3); }

/* Fließtext-Block */
.ws-text { max-width: 68ch; }
.ws-text h2 { font-size: var(--ws-t-2xl); margin: var(--ws-7) 0 var(--ws-4); }
.ws-text h3 { font-size: var(--ws-t-lg); margin: var(--ws-6) 0 var(--ws-3); }
.ws-text > :first-child { margin-top: 0; }

/* Rechtstexte */
.ws-rechtstext { max-width: var(--ws-breite-eng); }
.ws-rechtstext h2 { font-size: var(--ws-t-xl); margin: var(--ws-7) 0 var(--ws-4); }
.ws-rechtstext h3 { font-size: var(--ws-t-base); margin: var(--ws-5) 0 var(--ws-2); }
.ws-rechtstext > :first-child { margin-top: 0; }
.ws-rechtstext p, .ws-rechtstext li { color: var(--ws-chrom-2); }
.ws-rechtstext address { font-style: normal; }

/* Seitenkopf der Unterseiten — heller als der Hero, damit die Startseite ihren
   Rang behält. */
.ws-seitenkopf {
  padding-block: var(--ws-8) var(--ws-6);
  background: var(--ws-grund-2);
  border-bottom: 1px solid var(--ws-linie);
  position: relative;
}
.ws-seitenkopf::after {
  content: ""; position: absolute; bottom: -1px; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, var(--ws-gold-2), transparent 42%);
  opacity: .5;
}
.ws-seitenkopf h1 { font-size: var(--ws-t-4xl); margin-bottom: var(--ws-4); max-width: 22ch; }
.ws-seitenkopf__sub { font-size: var(--ws-t-lg); color: var(--ws-chrom-2); max-width: 60ch; margin: 0; }

/* Kennzahlen */
.ws-fakten { display: flex; flex-wrap: wrap; gap: var(--ws-6); margin: 0; padding: 0; list-style: none; }
.ws-fakten li { margin: 0; }
.ws-fakten b {
  display: block; font-size: var(--ws-t-2xl); font-weight: 600;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--ws-gold);
}
.ws-fakten span { font-size: var(--ws-t-sm); color: var(--ws-chrom-3); }


/* ── Responsiv ──────────────────────────────────────────────────────────────
   Alle Breakpoints stehen hier und nicht verstreut in den Komponenten. */

@media (max-width: 1080px) {
  .ws-hero__raster { grid-template-columns: 1fr; gap: var(--ws-7); }
  .ws-hero h1 { max-width: 18ch; }
  /* Einspaltig, aber noch breit: Ein Formular ueber die volle Breite eines
     1.000-px-Fensters ist unangenehm zu lesen. Unter 820 px faellt die Grenze
     weg — siehe unten. */
  .ws-karte-anfrage { max-width: 32rem; }
  .ws-fuss__raster { grid-template-columns: 1fr 1fr; gap: var(--ws-6); }
}

/* ── Navigation: eigener Umschaltpunkt bei 1.099 px ─────────────────────────
   Die Navigation klappt frueher ins Menue als das uebrige Layout (860 px), und
   das ist gemessen und nicht geschaetzt.

   Zwischen 861 und 1.024 px reicht die Breite fuer sieben Punkte, den
   Telefonlink und den Knopf nicht mehr — in der Ersatzschrift fehlten dort bis
   zu 200 px. Vorher fiel das nicht auf, weil die Texte umbrachen: „SEO & GEO"
   stand dann auf zwei Zeilen. Seit `white-space: nowrap` das verhindert, wird
   aus dem Umbruch ein horizontaler Ueberlauf, und der ist schlimmer — die
   ganze Seite laesst sich dann seitlich schieben.

   1.099 px ist die Grenze, ab der es auch mit der Ersatzschrift sicher passt.
   Praktisch heisst das: iPad quer (1.024) und kleine Notebooks bekommen das
   Menue, ab 1.100 px steht die Leiste offen. */
@media (max-width: 1099px) {
  .ws-nav__liste, .ws-nav__tel { display: none; }
  .ws-nav__schalter { display: inline-flex; }
  .ws-nav__liste.ist-offen {
    display: flex; flex-direction: column; align-items: stretch;
    position: absolute; left: 0; right: 0; top: 100%;
    background: var(--ws-grund-2);
    border-bottom: 1px solid var(--ws-linie);
    box-shadow: var(--ws-schein);
    padding: var(--ws-3) var(--ws-5) var(--ws-5); gap: 0;
  }
  .ws-nav__liste.ist-offen a { padding: var(--ws-4) var(--ws-2); font-size: var(--ws-t-base); }
  .ws-nav__liste.ist-offen li + li { border-top: 1px solid var(--ws-linie); }

}

@media (max-width: 820px) {
  /* ⚠ Gemessen am 01.09.2026 auf einem iPad hoch (768 px): Die Angebotskarte
     stand mit 512 px in einer 720 px breiten Spalte, rechts daneben 208 px
     leer — waehrend die Preiskacheln darueber die volle Breite nutzten. Das
     sah nach einem Rasterfehler aus, nicht nach Absicht. Ab hier nimmt die
     Karte die Spaltenbreite. */
  .ws-karte-anfrage { max-width: none; }
}

@media (max-width: 860px) {
  .ws-raster--2, .ws-raster--3, .ws-preise { grid-template-columns: 1fr; }
  .ws-person { grid-template-columns: 1fr; gap: var(--ws-5); }
  /* Derselbe Wert wie im Erweiterungsblock unten (`.ws-portrait`, 168 px).
     Zwei verschiedene Breiten waeren nicht nur uneinheitlich, sondern falsch:
     `portrait.html` deklariert fuer diesen Bereich `sizes="… 168px"`, und der
     Browser laedt danach die Datei aus. */
  .ws-person > .ws-portrait { max-width: 168px; }
  .ws-abschnitt { padding-block: var(--ws-8); }
  .ws-cta { grid-template-columns: 1fr; gap: var(--ws-5); }
  .ws-cta__aktionen { flex-direction: row; min-width: 0; }
  .ws-cta__aktionen .ws-knopf { flex: 1; }
  /* Auf schmalen Bildschirmen zeigt der Bildausschnitt sonst nur die dunkle
     linke Hälfte — das Goldlicht, das die Seite trägt, wäre unsichtbar. */
  .ws-hero__bild { object-position: 84% 28%; }
}

@media (max-width: 620px) {
  .ws-huelle { padding-inline: var(--ws-4); }
  .ws-hero { padding-block: var(--ws-6) var(--ws-7); }
  .ws-hero h1 { max-width: none; }
  /* Untereinander: nebeneinander wäre jede Zahl so klein, dass sie ihren
     Zweck verliert. */
  .ws-hero__preise { flex-direction: column; gap: var(--ws-2); }
  .ws-hero__preis { display: flex; align-items: flex-start; gap: var(--ws-3); padding: var(--ws-3) var(--ws-4); }
  .ws-hero__preis b { font-size: var(--ws-t-xl); }
  .ws-hero__preis span { margin-top: 0; line-height: 1.35; }
  .ws-karte { padding: var(--ws-5); }
  .ws-preis { padding: var(--ws-5); }
  .ws-antwort { padding: var(--ws-4) var(--ws-5); }
  .ws-fuss__raster { grid-template-columns: 1fr; gap: var(--ws-5); }
  .ws-abschnitt { padding-block: var(--ws-7); }
  .ws-cta__aktionen { flex-direction: column; }
  .ws-seitenkopf { padding-block: var(--ws-6) var(--ws-5); }
}

/* Touch-Geräte: Tippziele auf 44 px. Über `pointer: coarse` statt über die
   Fensterbreite — ein schmales Desktop-Fenster ist kein Handy. */
@media (pointer: coarse) {
  .ws-weiter { min-height: 44px; align-items: center; }
  .ws-fuss li { margin-bottom: 0; }
  .ws-fuss li a { display: inline-flex; align-items: center; min-height: 44px; }
  .ws-brotkrumen li { min-height: 36px; align-items: center; }
  .ws-karte-anfrage__fuss a, .ws-nachsatz a { display: inline-block; padding-block: var(--ws-2); }
}

@media print {
  .ws-nav, .ws-karte-anfrage, .ws-fuss, .ws-hero__bild { display: none; }
  body { color: #000; background: #fff; }
  .ws-hero::after { display: none; }
  /* Beim Druck feuert kein IntersectionObserver. Ohne diese Zeile druckt die
     Seite die Überschriften mit leeren Flächen darunter — genau so sah sie im
     Messlauf vom 01.09.2026 aus. */
  .ws-js [data-ws-reveal] { opacity: 1 !important; transform: none !important; }
}

/* ── Kennzahlenband der Ortsseiten ──────────────────────────────────────────
   Jede Zahl trägt ihre Quelle sichtbar mit sich. Das ist kein Kleingedrucktes,
   sondern der Grund, warum die Zahl überhaupt etwas wert ist: Eine Zahl ohne
   Herkunft ist auf einer Seite, die Dienstleistungen verkauft, eine Behauptung.
   Wer eine Zahl ergänzt und die Quelle weglässt, macht die anderen mit
   wertlos. */
.ws-zahlenband {
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  background: var(--ws-linie);
  border: 1px solid var(--ws-linie);
  border-radius: var(--ws-radius);
  overflow: hidden;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ws-zahlenband li { background: var(--ws-grund-2); padding: var(--ws-4) var(--ws-5); margin: 0; }
.ws-zahlenband b {
  display: block;
  font-size: var(--ws-t-2xl); font-weight: 600;
  letter-spacing: -0.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--ws-gold);
}
.ws-zahlenband span {
  display: block; margin-top: var(--ws-1);
  font-size: var(--ws-t-sm); line-height: 1.4; color: var(--ws-chrom-2);
}
.ws-zahlenband cite {
  display: block; margin-top: var(--ws-2);
  font-size: 0.75rem; font-style: normal; line-height: 1.35;
  color: var(--ws-chrom-3);
}
@media (max-width: 620px) {
  .ws-zahlenband { grid-template-columns: 1fr 1fr; }
  .ws-zahlenband li { padding: var(--ws-3) var(--ws-4); }
  .ws-zahlenband b { font-size: var(--ws-t-xl); }
}

/* ── Ratgeberseiten ─────────────────────────────────────────────────────────
   Lange Lesetexte. Alles hier dient einem Zweck: dass jemand tausend Wörter am
   Stück liest, ohne die Zeile zu verlieren. */

/* Standdatum unter der H1. Leise, aber vorhanden — bei einem Text über
   Gesetzeslage und Marktzahlen ist das Datum Teil der Aussage. */
.ws-stand {
  margin-top: var(--ws-4);
  font-size: var(--ws-t-sm); color: var(--ws-chrom-3);
  font-variant-numeric: tabular-nums;
}

/* Der Fliesstext. Die Zeilenlänge deckelt --ws-breite-eng bereits auf rund
   70 Zeichen; hier geht es um den vertikalen Rhythmus.

   Warum `margin` und nicht `gap`: Die Abstände sind hier absichtlich NICHT
   gleich. Eine H2 braucht mehr Luft über sich als unter sich, sonst schwebt sie
   zwischen den Blöcken, statt den folgenden anzuführen. Das lässt sich mit
   einem einzigen `gap` nicht ausdrücken. */
.ws-fliess > * + * { margin-top: var(--ws-4); }
.ws-fliess h2 {
  margin-top: var(--ws-8);
  font-size: var(--ws-t-2xl); line-height: 1.2; letter-spacing: -0.02em;
  color: var(--ws-chrom);
  text-wrap: balance;
}
.ws-fliess > h2:first-child { margin-top: 0; }
.ws-fliess h2 + p { margin-top: var(--ws-4); }
.ws-fliess p {
  font-size: var(--ws-t-lg); line-height: 1.7; color: var(--ws-chrom-2);
}
.ws-fliess strong { color: var(--ws-chrom); font-weight: 600; }

/* Aufzählung ohne Haken: Die Haken auf den Leistungsseiten heissen „das ist
   enthalten". Hier zählt eine Liste Faktoren auf, von denen mancher gegen den
   Leser spricht — ein Haken davor wäre eine falsche Zusage. */
.ws-punkte { margin: var(--ws-5) 0 0; padding: 0; list-style: none; }
.ws-punkte li {
  position: relative;
  padding-left: var(--ws-5);
  font-size: var(--ws-t-base); line-height: 1.65; color: var(--ws-chrom-2);
}
.ws-punkte li + li { margin-top: var(--ws-3); }
.ws-punkte li::before {
  content: ""; position: absolute;
  left: 0; top: 0.72em;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--ws-gold-3);
}

/* Tabellenrahmen: scrollt selbst, statt die Seite zu schieben.

   `tabindex="0"` im Template macht ihn mit der Tastatur erreichbar — ohne das
   kommt man an den abgeschnittenen rechten Teil nur mit der Maus, und die Seite
   fällt bei WCAG 2.1.1 durch. Wer fokussierbar macht, muss den Fokus auch
   zeigen; darum der Ring. */
.ws-tabellenrahmen {
  margin-top: var(--ws-5);
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--ws-linie);
  border-radius: var(--ws-radius);
  background: var(--ws-grund-2);
}
.ws-tabellenrahmen:focus-visible {
  outline: 2px solid var(--ws-gold); outline-offset: 2px;
}

/* Textvariante: Die Grundform `.ws-tabelle` ist eine Preistabelle — letzte
   Spalte rechtsbündig, `nowrap`, fett. Für Fliesstextzellen ist genau das
   falsch: Der Text bricht dann nicht um und schiebt die Tabelle ins Endlose. */
.ws-tabelle--text td:last-child {
  text-align: left; white-space: normal;
  font-weight: 400; color: var(--ws-chrom-2);
}
.ws-tabelle--text { min-width: 34rem; }
.ws-tabelle--text th[scope="row"] {
  color: var(--ws-chrom); font-weight: 600;
  vertical-align: top;
}
.ws-tabelle--text thead th {
  background: var(--ws-grund-3);
  font-size: var(--ws-t-xs); text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ws-chrom-3);
  white-space: nowrap;
}
.ws-tabelle--text td { vertical-align: top; }

/* Quellenverzeichnis. Nummeriert, weil die Nummer hier etwas bedeutet: Sie ist
   die Zählung, die im Seitenkopf angekündigt wird („5 Quellen am Seitenende"). */
.ws-quellen {
  margin: var(--ws-5) 0 0; padding-left: var(--ws-5);
  font-size: var(--ws-t-sm); line-height: 1.6;
}
.ws-quellen li { margin-top: var(--ws-3); color: var(--ws-chrom-3); }
.ws-quellen li::marker { color: var(--ws-gold-3); font-variant-numeric: tabular-nums; }
.ws-quellen a { color: var(--ws-chrom-2); text-decoration: underline;
                text-underline-offset: 2px; text-decoration-color: var(--ws-linie-stark); }
.ws-quellen a:hover { color: var(--ws-gold); text-decoration-color: var(--ws-gold-3); }
.ws-quellen span { display: block; margin-top: 2px; font-size: var(--ws-t-xs); }

/* Karte, die als Ganzes ein Link ist. Kein <a> um eine Karte mit eigenen Links
   darin — das wäre verschachteltes Interaktives und in keinem Screenreader
   sinnvoll bedienbar. Deshalb tragen diese Karten bewusst keinen zweiten Link. */
.ws-karte--link {
  display: flex; flex-direction: column; gap: var(--ws-2);
  text-decoration: none; color: inherit;
  transition: border-color var(--ws-tempo) var(--ws-kurve),
              transform var(--ws-tempo) var(--ws-kurve);
}
.ws-karte--link:hover { border-color: var(--ws-gold-3); transform: translateY(-2px); }
.ws-karte--link:focus-visible { outline: 2px solid var(--ws-gold); outline-offset: 3px; }
.ws-karte--link h2, .ws-karte--link h3 { font-size: var(--ws-t-xl); line-height: 1.25; }
.ws-karte--link .ws-weiter { margin-top: auto; padding-top: var(--ws-3); }

@media (prefers-reduced-motion: reduce) {
  .ws-karte--link, .ws-karte--link:hover { transform: none; transition: none; }
}

@media (max-width: 620px) {
  .ws-fliess h2 { margin-top: var(--ws-7); font-size: var(--ws-t-xl); }
  .ws-fliess p { font-size: var(--ws-t-base); }
}

/* ── Tippziele auf Touch-Geräten ────────────────────────────────────────────
   Gemessen mit `tools/check_mobil.py` auf 375 px: Die Brotkrumen kamen auf
   23 px Höhe, die Rechtstextlinks in der Fusszeile auf 16 px. Beides erfüllt
   WCAG 2.5.8 formal (24 px, und für Links im Fliesstext gilt ohnehin die
   Inline-Ausnahme) — trifft man aber mit dem Daumen zuverlässig daneben.

   Der Trick ist `padding` plus gleich grosses negatives `margin`: Die
   Trefferfläche wächst, die sichtbare Position bleibt auf den Pixel dieselbe.
   Ohne das negative Margin würde die Fusszeile sichtbar auseinanderfallen.

   Alles hier steht in `pointer: coarse`, gilt also nur für Finger. Mit einer
   Maus trifft man 16 px genau, und grössere unsichtbare Flächen würden dort
   nur die Hover-Bereiche überlappen lassen. */
@media (pointer: coarse) {
  .ws-brotkrumen a,
  .ws-fuss__ende a,
  .ws-quellen a {
    display: inline-block;
    padding-block: 13px;
    margin-block: -13px;
  }

  /* Die Ortsliste steht schon bei 41 px. Die fehlenden drei holt sie sich
     ohne Umbruch, weil sie ohnehin umbrechend gesetzt ist. */
  .ws-orte a { padding-block: 12px; }

  /* Einzelne Weiterfuehr- und Kontaktlinks lagen bei 39 px. Auch hier gilt:
     Padding rein, Margin wieder raus, damit sich sichtbar nichts verschiebt.

     Diese Aufzaehlung ist absichtlich eine Liste einzelner Klassen und kein
     pauschales `a`. Ein Link mitten im Fliesstext darf diese Flaeche NICHT
     bekommen — er wuerde die Zeilenabstaende des Absatzes auseinanderziehen,
     in dem er steht, und nebenbei die Trefferflaechen benachbarter Zeilen
     ueberlappen. Genau dafuer gibt es in WCAG 2.5.8 die Inline-Ausnahme. */
  .ws-weiter,
  .ws-adresse a,
  .ws-nachsatz a,
  .ws-karte-anfrage__fuss a {
    display: inline-block;
    padding-block: 11px;    /* 22 px zur Textzeile ergeben die vollen 44 */
    margin-block: -11px;
  }
}

/* Was hier bewusst NICHT steht — geprüft mit `tools/check_mobil.py`, und die
   verbleibenden Meldungen sind Absicht:

   • Links mitten im Fliesstext ("Wie das abgerechnet wird" auf der Startseite,
     die Gesetzesverweise auf der BFSG-Seite) bleiben bei 39 bis 42 px. WCAG
     2.5.8 nimmt Links im Fliesstext ausdruecklich aus, und zwar aus gutem
     Grund: Eine vergroesserte Trefferflaeche wuerde hier die Flaechen der
     Zeilen darueber und darunter ueberlappen. Man traefe dann zuverlaessiger
     daneben als vorher.

   • Das Logo in der Navigation misst 201 x 30 px. Die Hoehe liegt unter 44,
     die Flaeche mit rund 6.000 px² aber weit ueber der eines 44er-Quadrats,
     und daneben liegt nichts Anklickbares. Hoeher machen hiesse die
     Navigationsleiste hoeher machen. */

/* Die Quellenzeile sitzt am unteren Rand ihrer Zelle, nicht direkt unter dem
   Text. Grund: Die Beschreibungen sind unterschiedlich lang („Einwohner" gegen
   „Einzelhandelsbetriebe mit 48.505 m² Verkaufsfläche"), und ohne das steht
   jede Quelle auf einer anderen Höhe. Das liest sich wie ein Satzfehler. */
.ws-zahlenband li { display: flex; flex-direction: column; }
.ws-zahlenband cite { margin-top: auto; padding-top: var(--ws-2); }

/* ── Navigation: Platz für den Ratgeber-Punkt ───────────────────────────────
   Mit dem sechsten Textpunkt braucht die Leiste mehr Breite, als die Hülle
   hergibt — allerdings nur in der Ersatzschrift. Gemessen bei 1440 px:

       eigene Schrift (Instrument Sans)   1.024 px   passt in 1.180
       Ersatzschrift (System-Sans)        1.204 px   passt NICHT

   Das ist kein Testartefakt. `font-display: optional` heisst: Ist die Schrift
   nicht binnen rund 100 ms da, bleibt die Ersatzschrift für diesen Besuch
   stehen — dauerhaft. Wer die Seite über eine schlechte Mobilverbindung
   aufruft, sieht also genau die Fassung, in der die Navigation umbricht. Die
   metrische Anpassung (`size-adjust: 127.89%`) gleicht die Höhe an, nicht
   jede Buchstabenbreite; ein Rest bleibt und muss Platz haben.

   Drei Massnahmen, zusammen rund 170 px: */

/* 1. Kein Umbruch innerhalb eines Knopftextes. „SEO & GEO" auf zwei Zeilen
      sieht nach Fehler aus, nicht nach knappem Platz. */
.ws-nav__liste a { white-space: nowrap; }

/* 2. Etwas engeres Innenpolster. 3 px je Seite mal acht Punkte sind 48 px —
      unsichtbar im Ergebnis, entscheidend in der Summe. Die Trefferfläche
      bleibt über 44 px hoch, das Polster ändert sich nur seitlich. */
.ws-nav__liste a { padding-inline: 9px; }

/* 3. Unter 1.320 px verschwindet die Telefonnummer aus der Leiste (144 px).
      Sie geht dabei nicht verloren: Sie steht seit dem 01.09.2026 zusaetzlich
      in der Meta-Leiste darueber, dazu in der Fusszeile jeder Seite, im
      Kontaktbereich und im Unternehmensprofil. In der Leiste daneben steht
      weiterhin der Knopf, der zum selben Ziel fuehrt.

      ⚠ Die Grenze lag bis zum 01.09.2026 bei 1.280 px und galt fuer einen
      121 px breiten Link. Seit der Telefonlink richtig als eine Zeile rendert
      (vorher stand das Icon ueber der Nummer — siehe die Spezifitaetsnotiz
      oben), ist er 144 px breit, und bei 1.281 px lief die Leiste in der
      Ersatzschrift um 2 px ueber. Wer die Breite dieses Links aendert, prueft
      diese Zahl mit `tools/check_mobil.py` nach. */
@media (max-width: 1320px) {
  /* ⚠ Ausgeschrieben als `.ws-nav__liste a.ws-nav__tel`, nicht als
     `.ws-nav__tel`. Genau dieselbe Falle wie beim Knopf zwanzig Zeilen weiter
     oben: `.ws-nav__liste a` hat Spezifität (0,2,1) und setzt `display: block`.
     Ein blankes `.ws-nav__tel` (0,1,0) verliert dagegen — die Regel stand hier
     zuerst so, sah richtig aus und tat nachweislich nichts. */
  .ws-nav__liste a.ws-nav__tel { display: none; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   DURCHGANG „VERTRAUEN" — 01.09.2026
   ───────────────────────────────────────────────────────────────────────────
   Alles unter dieser Linie beantwortet eine einzige Frage: Warum sollte jemand
   diesem Betrieb 800 € geben, den er nicht kennt?

   Die Antwort ist nicht mehr Gestaltung, sondern mehr Beleg. Deshalb steht
   hier kein einziges Zierelement — jedes Bauteil trägt entweder eine Zahl mit
   Quelle, ein Gesicht oder einen Screenshot einer Seite, die wirklich läuft.

   Die drei Regeln von oben gelten unverändert weiter. Besonders die erste:
   WENIG GOLD. Keine der neuen Kennzahlen ist golden. Gold markiert weiterhin
   nur den Preis, die primäre Aktion, die Akzentkante und das Signet — eine
   Zahlenreihe in Gold hätte den Preis im Hero entwertet, und der ist das
   Einzige, worauf der Blick zuerst fallen soll.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ── Icons ──────────────────────────────────────────────────────────────────
   Das Bauteil liegt in templates/components/icon.html; hier steht nur, wie es
   sich im Fluss verhält. `flex: none` verhindert, dass ein Icon in einer engen
   Flexzeile gestaucht wird — ein zusammengedrücktes 24er-Raster sieht aus wie
   ein Ladefehler. */

.ws-icon { flex: none; }
.ws-icon--flagge { border-radius: 2px; color: var(--ws-chrom-3); }


/* ── Meta-Leiste über der Navigation ────────────────────────────────────────
   Das Erste im Blickfeld, und absichtlich das Leiseste.

   Sie steht VOR der klebenden Navigation und scrollt weg. Klebrig wäre sie
   38 px, die auf einem Handy dauerhaft für die Seite fehlen — und ihr Inhalt
   ist ein Erstkontakt-Signal, kein Bedienelement, das man ständig braucht.

   Warum überhaupt: „Aus Deutschland" ist bei einer Dienstleistung, die man im
   Netz einkauft, ein echtes Argument. Es steht bisher nur im Impressum. */

.ws-meta {
  background: var(--ws-grund);
  border-bottom: 1px solid var(--ws-linie);
}
.ws-meta__innen {
  display: flex; align-items: center; gap: var(--ws-5);
  min-height: 38px; padding-block: var(--ws-1);
}
.ws-meta__liste {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--ws-1) var(--ws-5);
  margin: 0; padding: 0; list-style: none;
}
.ws-meta__liste li {
  display: inline-flex; align-items: center; gap: var(--ws-2); margin: 0;
  font-size: var(--ws-t-xs); line-height: 1.3; color: var(--ws-chrom-3);
}
.ws-meta__liste li b { font-weight: 600; color: var(--ws-chrom-2); }
.ws-meta__tel {
  margin-left: auto; display: inline-flex; align-items: center; gap: var(--ws-2);
  padding-block: var(--ws-2);
  font-size: var(--ws-t-xs); font-weight: 600;
  color: var(--ws-chrom-2); text-decoration: none; white-space: nowrap;
}
.ws-meta__tel:hover { color: var(--ws-gold); }


/* ── Kennzahlen im Hero ─────────────────────────────────────────────────────
   Drei Zahlen unter der Häkchenliste, abgetrennt durch eine Haarlinie. Sie
   beantworten die Frage, die der Preis aufwirft: Hat der das schon mal
   gemacht?

   Die Zahl steht in der Serif — dieselbe Schrift wie die Überschriften, aber
   in Chrom statt Gold. Damit gehört sie sichtbar zur Seite und tritt trotzdem
   nicht mit dem Preis in Konkurrenz. */

.ws-belege {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: var(--ws-3) var(--ws-6);
  margin: var(--ws-5) 0 0; padding: var(--ws-4) 0 0; list-style: none;
  border-top: 1px solid var(--ws-linie);
}
.ws-belege li {
  display: flex; align-items: baseline; gap: var(--ws-2); margin: 0;
  font-size: var(--ws-t-sm); color: var(--ws-chrom-3);
}
.ws-belege b {
  font-family: var(--ws-schrift-serif); font-weight: 400;
  font-size: var(--ws-t-xl); line-height: 1;
  letter-spacing: -0.01em; color: var(--ws-chrom);
  font-variant-numeric: tabular-nums;
}


/* ── Kundenband unter dem Hero ──────────────────────────────────────────────
   Der klassische Logo-Streifen, nur ohne Logos: fünf Namen, jeder verlinkt auf
   eine laufende Seite. Fremde Logos ohne schriftliche Erlaubnis auf die eigene
   Seite zu stellen, ist markenrechtlich heikel; ein Name mit Link ist es
   nicht — und er ist der stärkere Beleg, weil man ihn anklicken kann.

   Warum unter dem Hero und nicht darin: Der Hero trägt schon Überschrift,
   Preis, zwei Karten, drei Häkchen und die Kennzahlen. Eine sechste Zeile
   hätte den Preis unter die Falte geschoben — und genau das darf nicht
   passieren. */

.ws-kundenband {
  background: var(--ws-grund-2);
  border-bottom: 1px solid var(--ws-linie);
}
.ws-kundenband__innen {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--ws-2) var(--ws-4);
  padding-block: var(--ws-4);
}
.ws-kundenband__titel {
  font-size: var(--ws-t-xs); font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ws-chrom-3); margin: 0;
}
.ws-kundenband__liste {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--ws-2) var(--ws-4);
  margin: 0; padding: 0; list-style: none;
}
.ws-kundenband__liste li { margin: 0; }
.ws-kundenband__liste a {
  display: inline-flex; align-items: center; gap: var(--ws-1);
  padding-block: var(--ws-1);
  font-size: var(--ws-t-sm); font-weight: 500;
  color: var(--ws-chrom-2); text-decoration: none;
  border-bottom: 1px solid var(--ws-linie);
  transition: color var(--ws-tempo) ease, border-color var(--ws-tempo) ease;
}
.ws-kundenband__liste a:hover { color: var(--ws-gold); border-bottom-color: var(--ws-gold-3); }
.ws-kundenband__weiter {
  margin-left: auto; display: inline-flex; align-items: center; gap: var(--ws-2);
  font-size: var(--ws-t-sm); font-weight: 600; color: var(--ws-gold);
  text-decoration: none; white-space: nowrap;
}
.ws-kundenband__weiter:hover { color: var(--ws-gold-2); }


/* ── Vorstellung: das Gesicht direkt nach dem Hero ──────────────────────────
   Die Seite verspricht „Sie sprechen mit mir". Bis zu diesem Durchgang stand
   das Gesicht auf Unterseite vier. Menschen kaufen bei Menschen — und bei
   einem Einzelunternehmen ist der Mensch das Produkt.

   Die Fläche ist `--ws-gold-hauch`: derselbe warme, fast schwarze Ton wie im
   Antwortblock. Er hebt den Abschnitt als eigenes Kapitel heraus, ohne eine
   vierte Grundfläche einzuführen. */

.ws-vorstellung { background: var(--ws-gold-hauch); border-block: 1px solid var(--ws-linie); }
.ws-vorstellung__innen {
  display: grid; grid-template-columns: 232px minmax(0, 1fr);
  gap: var(--ws-7); align-items: center;
}
.ws-vorstellung__text > p {
  font-size: var(--ws-t-lg); line-height: 1.65; color: var(--ws-chrom-2);
  max-width: 58ch;
}
.ws-vorstellung__name {
  font-size: var(--ws-t-2xl); margin: 0 0 var(--ws-1); color: var(--ws-chrom);
}
/* ⚠ Ausgeschrieben mit dem Elternselektor, nicht als blanke Klasse.
   `.ws-vorstellung__text > p` darueber hat Spezifitaet (0,1,1) und schlaegt
   eine Klasse allein (0,1,0) — die Rollenzeile rendert sonst in
   Fliesstextgroesse und -farbe, obwohl hier etwas anderes steht. Dieselbe
   Falle wie beim Knopf in der Navigation (CSS-Regel 7). */
.ws-vorstellung__text > p.ws-vorstellung__rolle {
  font-size: var(--ws-t-sm); color: var(--ws-chrom-3);
  margin: 0 0 var(--ws-5);
}
.ws-vorstellung .ws-weiter { margin-top: var(--ws-5); }


/* ── Porträtrahmen ──────────────────────────────────────────────────────────
   4:5 statt quadratisch: Ein Gesicht füllt ein Hochformat besser aus, und die
   Seite hat sonst nirgends ein Bild dieser Art — es soll als Person lesbar
   sein, nicht als Kachel.

   Solange kein Foto vorliegt, steht hier das Signet auf getönter Fläche mit
   einer feinen Goldkante. Das ist bewusst KEIN Text „Foto folgt" mehr: Ein
   sichtbarer Platzhalter auf einer Verkaufsseite sagt dem Interessenten, dass
   hier etwas unfertig ist — und das überträgt er auf die Arbeit. Ein
   gestaltetes Markenfeld sagt gar nichts, und das ist besser. */

.ws-portrait {
  position: relative; aspect-ratio: 4 / 5; overflow: hidden;
  border-radius: var(--ws-radius-lg);
  border: 1px solid var(--ws-linie);
  background: var(--ws-grund-2);
}
.ws-portrait img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ws-portrait--leer {
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(120% 90% at 50% 18%, var(--ws-grund-3), var(--ws-grund) 72%);
  box-shadow: inset 0 0 0 1px rgba(156, 125, 70, .34);
}
.ws-portrait--leer img {
  width: 46%; height: auto; object-fit: contain; opacity: .62;
}


/* ── Werdegang ──────────────────────────────────────────────────────────────
   Vier Stationen als Zeitachse auf /ueber-mich/. Jede steht sinngleich im
   öffentlichen GitHub-Profil — wer hier eine hinzufügt, fügt sie dort auch
   hinzu, sonst widersprechen sich zwei Selbstdarstellungen desselben Betriebs.

   Die Achse ist eine 1-px-Linie, kein Balken. Auf schwarzem Grund trägt schon
   ein Hauch; ein kräftiger Strich neben vier kurzen Absätzen wirkt wie ein
   Diagramm, das keines ist. */

.ws-werdegang { list-style: none; margin: var(--ws-6) 0 0; padding: 0; }
.ws-werdegang li {
  position: relative; margin: 0;
  padding: 0 0 var(--ws-6) var(--ws-6);
  border-left: 1px solid var(--ws-linie);
}
.ws-werdegang li:last-child { border-left-color: transparent; padding-bottom: 0; }
.ws-werdegang li::before {
  content: ""; position: absolute; left: -4px; top: 7px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ws-gold-3);
}
.ws-werdegang__jahr {
  display: block; font-size: var(--ws-t-xs); font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ws-chrom-3); margin-bottom: var(--ws-1);
  font-variant-numeric: tabular-nums;
}
.ws-werdegang h3 { font-size: var(--ws-t-lg); margin: 0 0 var(--ws-2); }
.ws-werdegang p { font-size: var(--ws-t-sm); color: var(--ws-chrom-2); margin: 0; max-width: 62ch; }


/* ── Schaufenster: Referenz mit Screenshot ──────────────────────────────────
   Bis hierher waren fünf gebaute Websites fünf graue Textkacheln. Das stärkste
   Argument des Betriebs lag ungenutzt herum.

   Der Browserrahmen ist kein Schmuck, sondern die Aussage: Was du siehst, ist
   eine Seite im Netz, und dort oben steht ihre Adresse. Ein Screenshot ohne
   Rahmen ist ein Bild; mit Rahmen und Adresse ist er ein Beleg.

   Der frühere Satz auf /referenzen/ — „einen Screenshot kann jeder zeigen" —
   war richtig, solange es keinen gab. Jetzt steht dort beides: Das Bild zeigt,
   wie es aussieht, der Link beweist, dass es läuft. */

.ws-schaufenster { display: grid; gap: var(--ws-5); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ws-schaufenster > .ws-schau--gross { grid-column: 1 / -1; }

.ws-schau {
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--ws-grund-2);
  border: 1px solid var(--ws-linie);
  border-radius: var(--ws-radius-lg);
  transition: transform var(--ws-tempo) var(--ws-kurve),
              border-color var(--ws-tempo) ease;
}
.ws-schau:hover { transform: translateY(-2px); border-color: var(--ws-gold-3); }

.ws-schau__bild { display: block; text-decoration: none; background: var(--ws-browser); }
.ws-schau__bild img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16 / 10; object-fit: cover; object-position: top center;
  border-top: 1px solid var(--ws-linie);
}
.ws-schau--gross .ws-schau__bild img { aspect-ratio: 21 / 9; }

/* Die Adresszeile. Die drei Punkte sind bewusst grau und nicht bunt — eine
   Ampel aus Rot/Gelb/Grün würde ein fremdes Betriebssystem zitieren und
   fiele auf dieser Seite als einzige Buntfarbe auf. */
.ws-browserleiste {
  display: flex; align-items: center; gap: var(--ws-2);
  padding: var(--ws-2) var(--ws-3);
  background: var(--ws-browser);
}
.ws-browserleiste i {
  flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: var(--ws-linie-stark);
}
.ws-browserleiste em {
  flex: 1; min-width: 0; margin-left: var(--ws-2);
  font-style: normal; font-size: var(--ws-t-xs);
  color: var(--ws-chrom-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.ws-schau__leib { display: flex; flex-direction: column; flex: 1; padding: var(--ws-5) var(--ws-6); }
.ws-schau__branche {
  font-size: var(--ws-t-xs); font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ws-gold); margin-bottom: var(--ws-2);
}
/* h2 oder h3, je nach Dokumentkontext — optisch gleich, semantisch richtig.
   Dieselbe Doppelung wie bei `.ws-ablauf h3, .ws-ablauf h4`. */
.ws-schau h2, .ws-schau h3 { font-size: var(--ws-t-lg); margin: 0 0 var(--ws-1); }
.ws-schau h2 a, .ws-schau h3 a { color: inherit; text-decoration: none; }
.ws-schau h2 a:hover, .ws-schau h3 a:hover { color: var(--ws-gold); }
.ws-schau__ort { font-size: var(--ws-t-sm); color: var(--ws-chrom-3); margin: 0 0 var(--ws-4); }
.ws-schau__was { font-size: var(--ws-t-sm); color: var(--ws-chrom-2); margin: 0 0 var(--ws-3); }
.ws-schau__punkt { font-size: var(--ws-t-sm); color: var(--ws-chrom); font-weight: 500; margin: 0; }
/* `margin-top: auto` schiebt Umfang und Link an den unteren Rand. Ohne das
   stehen sie bei unterschiedlich langen Beschreibungen auf verschiedenen
   Hoehen — bei drei Karten nebeneinander liest sich das wie ein Satzfehler. */
.ws-schau__umfang {
  margin: auto 0 0; padding-top: var(--ws-4);
  border-top: 1px solid var(--ws-linie);
  font-size: var(--ws-t-xs); color: var(--ws-chrom-3);
}
.ws-schau__url {
  margin-top: var(--ws-3);
  display: inline-flex; align-items: center; gap: var(--ws-2);
  font-size: var(--ws-t-sm); font-weight: 600; color: var(--ws-gold);
  text-decoration: none;
}
.ws-schau__url:hover { color: var(--ws-gold-2); }


/* ── Zeichen auf einer Leistungskarte ───────────────────────────────────────
   Ein Chip, kein freistehendes Icon. Freistehend saehe es aus wie ein
   Aufzaehlungspunkt, der seine Liste verloren hat; im Feld ist es ein Teil der
   Karte. Chrom, nicht Gold — auf derselben Karte sitzt unten schon ein
   goldener Weiterlesen-Link. */

.ws-karte__zeichen {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem; margin: 0 0 var(--ws-4);
  color: var(--ws-chrom-2);
  background: var(--ws-grund-3);
  border: 1px solid var(--ws-linie);
  border-radius: var(--ws-radius);
}


/* ── Zusicherungen am Schlussband ───────────────────────────────────────────
   Sie standen bisher klein unter dem Hero-Formular — an der Stelle, an der
   jemand noch gar nicht überlegt, ob er anfragt. Am Schluss steht er kurz vor
   der Entscheidung; dort tragen sie mehr.

   Die Icons sind chromfarben, nicht golden. Im selben Band steht der primäre
   Knopf in Gold, und zwei goldene Dinge nebeneinander heben sich gegenseitig
   auf. */

.ws-zusicherung { list-style: none; margin: var(--ws-5) 0 0; padding: 0; display: grid; gap: var(--ws-3); }
.ws-zusicherung li {
  display: flex; align-items: flex-start; gap: var(--ws-3); margin: 0;
  font-size: var(--ws-t-sm); color: var(--ws-chrom-2);
}
.ws-zusicherung .ws-icon { color: var(--ws-chrom-3); margin-top: 1px; }


/* ── Ablaufschritt mit Zeitangabe ───────────────────────────────────────────
   Die vier Schritte hatten eine Nummer und einen Satz. Was fehlte, war die
   Frage, die jeder stellt: Wie lange dauert das? Die Angaben kommen aus
   zusagen.py, nicht aus dem Template. */

.ws-ablauf__dauer {
  display: inline-flex; align-items: center; gap: var(--ws-1);
  margin-left: var(--ws-2);
  font-size: var(--ws-t-xs); font-weight: 500; color: var(--ws-chrom-3);
  white-space: nowrap;
}


/* ── Responsiv für alles hier ───────────────────────────────────────────────
   Eigener Block, weil die Breakpoints oben eine geschlossene Einheit sind und
   ein Nachtrag dort schwerer zu lesen wäre als hier.

   ⚠ Damit existieren mehrere Breiten DOPPELT: 620 px, `pointer: coarse` und
   `print` stehen sowohl im Responsiv-Block oben als auch hier. Das ist die
   Folge von CSS-Regel 9 (neue Regeln ans Dateiende) und beabsichtigt — aber
   wer eine Breite ändert, sucht beide Stellen. `.ws-hero__preis` wird
   inzwischen an zwei 620-px-Stellen eingestellt, rund 700 Zeilen auseinander. */

@media (max-width: 980px) {
  .ws-vorstellung__innen { grid-template-columns: 180px minmax(0, 1fr); gap: var(--ws-6); }
}

/* Die Meta-Leiste wird in drei Stufen kürzer.

   Sie darf unter keinen Umständen umbrechen: Aus 38 px würden 60 px, die
   Navigation rutschte mit nach unten, und der Hero verlöre auf einem Gerät
   Platz, auf dem er ohnehin knapp ist. Gemessen am 01.09.2026 auf einem
   iPad hoch (768 px) — dort stand „Angebot kostet nichts" in der zweiten
   Zeile. Alles, was hier wegfällt, steht anderswo auf der Seite: die
   Antwortzeit im Hero und im Schlussband, die Zusage unter dem Formular,
   der Ort im Hero, in der Fußzeile und im Impressum. */
@media (max-width: 900px) {
  /* Stufe 1 — die schwächste der drei Angaben geht zuerst. */
  .ws-meta__liste li:nth-child(3) { display: none; }
  .ws-meta__liste li { white-space: nowrap; }
}

@media (max-width: 720px) {
  /* Stufe 2 — nur noch Herkunft und Telefon. */
  .ws-meta__liste li + li { display: none; }
  .ws-meta__innen { gap: var(--ws-3); }
  .ws-schaufenster { grid-template-columns: 1fr; }
  .ws-schau--gross .ws-schau__bild img { aspect-ratio: 16 / 10; }
  .ws-vorstellung__innen { grid-template-columns: 1fr; gap: var(--ws-5); }
  .ws-portrait { max-width: 168px; }
  .ws-kundenband__weiter { margin-left: 0; }
}

@media (max-width: 620px) {
  /* ⚠ Gemessen am 01.09.2026: „Lübeck-Kücknitz, Deutschland" plus
     Telefonnummer schoben die Seite bei 360 px um 58 px nach rechts — in der
     ERSATZSCHRIFT, also genau bei dem Besucher, dessen Verbindung zu langsam
     für den Webfont war. Auf dem Entwicklungsrechner ist das nie zu sehen.

     Unter 620 px bleibt darum nur die Flagge und „Deutschland" stehen. Der Ort
     geht nicht verloren: Er steht im Hero, in der Fußzeile, im Impressum und
     im Unternehmensprofil. Das Herkunftssignal — worum es hier geht — trägt
     das Land, nicht der Stadtteil. */
  .ws-meta__ort { display: none; }

  /* ⚠ Der Grund für die 190-px-Leerflächen in den Preiskarten auf dem Handy.
     Oben steht `flex: 1 1 12rem` — in einer Zeile ist 12rem eine Mindest-
     BREITE. Sobald der Block hier auf `flex-direction: column` umschaltet,
     wird aus derselben Angabe eine Mindest-HÖHE von 192 px, und die Karte
     zieht sich um den Text herum auf. Gemessen am 01.09.2026: Das Formular
     begann dadurch erst 340 px weiter unten als nötig.
     `flex: 0 0 auto` gibt der Karte ihre eigene Höhe zurück. */
  .ws-hero__preis { flex: 0 0 auto; flex-wrap: wrap; }
  /* „800 €" brach bei 360 px zwischen Zahl und Zeichen um, weil die
     Beschreibung daneben den Platz nahm. `nowrap` haelt den Betrag zusammen;
     `flex-wrap` am Elternteil sorgt dafuer, dass die Beschreibung notfalls
     eine Zeile tiefer rutscht, statt seitlich herauszulaufen. */
  .ws-hero__preis b { white-space: nowrap; }
  .ws-belege { gap: var(--ws-2) var(--ws-4); }
  .ws-belege li { font-size: var(--ws-t-xs); }
  .ws-belege b { font-size: var(--ws-t-lg); }
  .ws-schau__leib { padding: var(--ws-5); }
}

/* Tippziele auf Touch-Geräten — dieselbe Begründung wie im Block oben. */
@media (pointer: coarse) {
  .ws-kundenband__liste a { min-height: 32px; }
  .ws-meta__tel { min-height: 32px; }
}

/* Im Druck sind ein Browserrahmen und ein leeres Porträtfeld nur Tinte. */
@media print {
  .ws-meta, .ws-browserleiste, .ws-portrait--leer { display: none; }
}
