/* ==========================================================================
   Wenicker Digitalagentur – Stylesheet
   Aufbau: 1 Schriften · 2 Design-Tokens · 3 Grundlagen · 4 Bausteine
           5 Kopfbereich · 6 Fußbereich · 7 Startseite · 8 Unterseiten
           9 Bewegung
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 Schriften (lokal, keine externen Dienste)
   Alle drei sind variable Schriften: eine Datei deckt alle Stärken ab,
   bei Archivo zusätzlich die Breite (125 % = "Expanded" für die Wortmarke).
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Archivo';
  src: url('/schriften/archivo-variabel.woff2') format('woff2');
  font-weight: 400 700;
  font-stretch: 62.5% 125%;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Instrument Sans';
  src: url('/schriften/instrument-sans-variabel.woff2') format('woff2');
  font-weight: 400 700;
  font-stretch: 75% 100%;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Spline Sans Mono';
  src: url('/schriften/spline-sans-mono-variabel.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* Nur der Kursiv-Schnitt – ausschließlich für einzelne hervorgehobene
   Wörter in großen Überschriften. */
@font-face {
  font-family: 'Instrument Serif';
  src: url('/schriften/instrument-serif-kursiv.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   2 Design-Tokens – verbindlich aus docs/briefing.md
   -------------------------------------------------------------------------- */

:root {
  /* Farben */
  --grundton: #f4f6f6;
  --tinte: #171d1c;
  --graphit: #12191b;
  --signal: #2557d6;
  --signal-hell: #7fa4ff;
  --linie: #dee3e3;

  /* Abgeleitete Töne (nur Mischungen der Grundfarben, keine neuen Farben) */
  --tinte-leise: #4a5453;
  --flaeche: #ffffff;
  --signal-dunkel: #1c46ad;

  /* Funktionale Zustandsfarbe für Formular-Fehler – bewusst außerhalb der
     Markenpalette, weil ein Fehler nicht wie ein Link aussehen darf.
     Kontrast auf Grundton und Weiß: über 6:1 (AA). */
  --fehler: #b3261e;

  /* Schriftfamilien */
  --schrift-display: 'Archivo', 'Segoe UI', system-ui, sans-serif;
  --schrift-text: 'Instrument Sans', 'Segoe UI', system-ui, sans-serif;
  --schrift-mono: 'Spline Sans Mono', ui-monospace, 'Consolas', monospace;
  --schrift-serif: 'Instrument Serif', Georgia, 'Times New Roman', serif;

  /* Schriftgrößen, mitwachsend.
     --gr-hero ist die Statement-Skala der Startseite: ab ca. 1100px Breite
     liegt sie über 96px und wird bei 120px gedeckelt (7.5rem). */
  --gr-hero: clamp(2.5rem, 0.6rem + 8vw, 7.5rem);
  --gr-h1: clamp(2.25rem, 1.35rem + 3.8vw, 4rem);
  --gr-h2: clamp(1.75rem, 1.3rem + 1.9vw, 2.5rem);
  --gr-h3: clamp(1.25rem, 1.1rem + 0.7vw, 1.5rem);
  --gr-gross: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  --gr-basis: 1rem;
  --gr-klein: 0.875rem;
  --gr-mini: 0.75rem;

  /* Abstände: 8px-Raster */
  --raum-1: 0.5rem;
  --raum-2: 1rem;
  --raum-3: 1.5rem;
  --raum-4: 2rem;
  --raum-5: 2.5rem;
  --raum-6: 3rem;
  --raum-8: 4rem;
  --raum-10: 5rem;
  --raum-12: 6rem;

  /* Sektionsabstand oben/unten: 64px auf schmalen, ca. 80–96px auf breiten
     Bildschirmen – großzügig, aber keine leeren Bildschirmhöhen. */
  --sektion: clamp(4rem, 2.75rem + 2.5vw, 6rem);

  /* Layout */
  --inhaltsbreite: 1140px;
  --seitenrand: clamp(1rem, 4vw, 2rem);

  /* Radien – spürbar weicher als früher, aber nirgends eine Pille.
     Die Editorial-Linien, das Graphit-Panel und die Typografie bleiben
     davon unberührt: Der Kontrast aus harter Typo und weicher Form ist
     gewollt. */
  --radius: 4px;
  --radius-gross: 8px;
  --radius-knopf: 12px;
  --radius-feld: 12px;
  --radius-menue: 14px;
  --radius-karte: 18px;

  /* Schatten, mehrstufig: eine enge Stufe zeichnet die Kante, eine mittlere
     löst die Fläche vom Grund, eine weite trägt sie. Beim Anheben wachsen
     Weite und Tiefe mit – die Fläche kommt der Hand entgegen. */
  --schatten-ruhe: 0 1px 2px rgba(18, 25, 27, 0.05),
    0 8px 20px rgba(18, 25, 27, 0.06), 0 20px 48px rgba(18, 25, 27, 0.05);
  --schatten-hoch: 0 1px 2px rgba(18, 25, 27, 0.06),
    0 14px 32px rgba(18, 25, 27, 0.1), 0 32px 72px rgba(18, 25, 27, 0.08);
  --schatten-menue: 0 1px 2px rgba(18, 25, 27, 0.06),
    0 16px 40px rgba(18, 25, 27, 0.14);
  --schatten-knopf: 0 1px 2px rgba(18, 25, 27, 0.06),
    0 6px 16px rgba(18, 25, 27, 0.08);
  --schatten-knopf-hoch: 0 2px 4px rgba(18, 25, 27, 0.08),
    0 12px 28px rgba(18, 25, 27, 0.14);

  /* Bewegung – eine einzige Bewegungssprache für die ganze Website.
     Es gibt genau zwei Zeitkurven und zwei Dauern; jede Transition und jede
     Animation greift auf sie zu. Keine ease-Standardkurve, kein linear.

     Faustregel, nach der hier alles gesetzt ist:
     – transform (Anheben, Nachgeben, Drehen, Schieben) läuft auf der
       Feder-Kurve: Sie schießt am Ziel minimal vorbei und fällt zurück.
       Dadurch wirken die Dinge, als hätten sie Masse.
     – alles andere (Farbe, Schatten, Deckkraft, Weichzeichner) läuft auf
       der Auslauf-Kurve. Ein Überschwingen wäre dort entweder unsichtbar
       (Deckkraft über 1 wird abgeschnitten) oder schmutzig (Farben, die
       kurz über ihren Zielwert hinausgehen).

     Die Feder darf nur auf kurze Wege: Bei 450 ms und 20 Pixeln wäre sie
     ein sichtbarer Hüpfer. Für das sanfte "Landen" der Scroll-Reveals gibt
     es deshalb eine dritte, sehr flache Kurve mit einem Hauch
     Überschwingen. */
  --kurve-feder: cubic-bezier(0.34, 1.56, 0.64, 1);
  --kurve-aus: cubic-bezier(0.22, 1, 0.36, 1);
  --kurve-landung: cubic-bezier(0.2, 0.9, 0.24, 1.04);
  --dauer-inter: 180ms;
  --dauer-einblenden: 450ms;

  /* Anhebehöhen. Größere Flächen heben weiter als kleine Zeilen – sonst
     wirkt der Hub an der Karte zaghaft und an der Zeile ruppig. */
  --hub-klein: -2px;
  --hub-gross: -4px;
  /* Wie weit Knöpfe und Karten beim Drücken nachgeben. */
  --druck: 0.985;
}

/* --------------------------------------------------------------------------
   3 Grundlagen
   -------------------------------------------------------------------------- */

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

/* Was per hidden-Attribut versteckt ist, bleibt versteckt – auch wenn eine
   eigene Regel dem Element sonst display: grid o.ä. geben würde (z.B. das
   Wunschzeit-Feld und das Formular nach dem Absenden). */
[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;
}

body {
  margin: 0;
  background: var(--grundton);
  color: var(--tinte);
  font-family: var(--schrift-text);
  font-size: var(--gr-basis);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1 0 auto;
}

h1,
h2,
h3,
h4 {
  font-family: var(--schrift-display);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin: 0 0 var(--raum-3);
  text-wrap: balance;
  /* Lange deutsche Wörter ("Suchmaschinenoptimierung",
     "Datenschutzerklärung") sind auf schmalen Handys breiter als der
     Bildschirm. Ohne diese Zeile schiebt so ein Wort die ganze Seite nach
     rechts und man kann seitwärts scrollen. Gebrochen wird nur, wenn es
     wirklich nicht anders passt – am Schreibtisch ändert sich nichts. */
  overflow-wrap: break-word;
}

/* Auf Handybreite darf zusätzlich mit Trennstrich getrennt werden. Das ist
   schöner als ein harter Bruch mitten im Wort und gilt nur hier. */
@media (max-width: 560px) {
  h1,
  h2,
  h3,
  h4 {
    hyphens: auto;
  }
}

h1 {
  font-size: var(--gr-h1);
}
h2 {
  font-size: var(--gr-h2);
}
h3 {
  font-size: var(--gr-h3);
  font-weight: 600;
}

p {
  margin: 0 0 var(--raum-3);
  max-width: 68ch;
}

a {
  color: var(--signal);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

a:hover {
  color: var(--signal-dunkel);
}

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

ul {
  margin: 0;
  padding: 0;
}

/* Sichtbarer Fokus – überall, nie entfernen.
   Der Fokusring folgt der eigenen Rundung des Elements. Früher stand hier
   zusätzlich "border-radius: 2px" – das setzte die Rundung des fokussierten
   Elements selbst auf 2 Pixel und hätte mit den jetzt deutlich weicheren
   Radien jeden Knopf beim Antabben eckig werden lassen. */
:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
}

/* Auf dunklen Flächen (Kopfbereich, Fußbereich) ist das kräftige
   Signalblau zu dunkel: Es hebt sich vom Graphit nur mit 2,9:1 ab,
   gefordert sind mindestens 3:1. Dort wird deshalb der aufgehellte Ton
   verwendet (7,3:1). */
.kopf__innen :focus-visible,
.fuss :focus-visible {
  outline-color: var(--signal-hell);
}

/* Nur für Screenreader sichtbar */
.nur-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   4 Bausteine
   -------------------------------------------------------------------------- */

.bereich {
  width: 100%;
  max-width: var(--inhaltsbreite);
  margin-inline: auto;
  padding-inline: var(--seitenrand);
}

.abschnitt {
  padding-block: var(--sektion);
}

.fliesstext {
  font-size: var(--gr-gross);
  color: var(--tinte-leise);
}

/* Kleines Label in Mono, gesperrt – für Kennzeichnungen innerhalb von
   Bauelementen (Feldbeschriftungen, Kennziffern, Platzhalter) und für die
   Standortzeile über der Hero-Überschrift. Nicht mehr für Etikettzeilen
   über Überschriften: Überschriften tragen sich selbst. */
.marke {
  font-family: var(--schrift-mono);
  font-size: var(--gr-mini);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--tinte-leise);
}

.platzhalter {
  font-family: var(--schrift-mono);
  font-size: var(--gr-klein);
  color: var(--tinte-leise);
  padding-block: var(--raum-12);
}

/* Sprungmarke: erst beim Tabben sichtbar */
.sprungmarke {
  position: absolute;
  top: var(--raum-1);
  left: var(--raum-1);
  z-index: 100;
  transform: translateY(-200%);
  background: var(--graphit);
  color: var(--grundton);
  padding: var(--raum-1) var(--raum-2);
  border-radius: var(--radius-knopf);
  font-size: var(--gr-klein);
  text-decoration: none;
  transition: transform var(--dauer-inter) var(--kurve-feder);
}

.sprungmarke:focus {
  transform: translateY(0);
  color: var(--grundton);
}

/* Knöpfe */
.knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--raum-1);
  padding: 0.75rem 1.25rem;
  /* 44 Pixel ist die kleinste Fläche, die man am Handy zuverlässig mit dem
     Daumen trifft. Die Knöpfe waren 43 hoch – eine Zeile, die das sicher
     stellt, ohne die Optik zu verändern. */
  min-height: 44px;
  border: 1px solid transparent;
  border-radius: var(--radius-knopf);
  font-family: var(--schrift-text);
  font-size: var(--gr-klein);
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  /* Der Weg federt, Farbe und Schatten laufen aus – die Regel gilt auf der
     ganzen Website. */
  transition: transform var(--dauer-inter) var(--kurve-feder),
    box-shadow var(--dauer-inter) var(--kurve-aus),
    background-color var(--dauer-inter) var(--kurve-aus),
    border-color var(--dauer-inter) var(--kurve-aus);
}

/* Anheben beim Überfahren, Nachgeben beim Drücken. Bewegt wird nur
   transform und box-shadow – nie eine Position im Layout, damit nichts
   umbricht und der Nachbar nicht mitrutscht. */
@media (hover: hover) and (pointer: fine) {
  .knopf:hover {
    transform: translateY(var(--hub-klein));
  }
}

.knopf:active {
  /* Beim Drücken gibt der Knopf nach und landet wieder auf der Grundlinie:
     Er hat Masse. Die Feder-Kurve holt ihn danach zurück. */
  transform: translateY(0) scale(var(--druck));
}

.knopf--primaer {
  background: var(--signal);
  color: #ffffff;
  box-shadow: var(--schatten-knopf);
}

.knopf--primaer:hover {
  background: var(--signal-dunkel);
  color: #ffffff;
  box-shadow: var(--schatten-knopf-hoch);
}

.knopf--sekundaer {
  background: transparent;
  border-color: var(--linie);
  color: var(--tinte);
}

.knopf--sekundaer:hover {
  border-color: var(--tinte);
  color: var(--tinte);
}

/* Umriss-Knopf für dunkle Flächen (Fußbereich): durchsichtig mit feiner
   heller Linie. Auf Graphit hat er über 7:1 Kontrast, der Rahmen über 3:1. */
.knopf--umriss {
  background: transparent;
  border-color: rgba(244, 246, 246, 0.45);
  color: var(--grundton);
}

.knopf--umriss:hover {
  border-color: var(--grundton);
  background: rgba(244, 246, 246, 0.08);
  color: var(--grundton);
}


/* Wortmarke */
.wortmarke {
  position: relative;
  /* Die Marke ist eine einzige Zeile: der Name mit seinem Punkt. Der Link
     ist nur so breit wie dieser Text, nicht so breit wie die Spalte –
     dadurch liegt die anklickbare Fläche nicht über leerem Raum daneben. */
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  color: inherit;
  line-height: 1;
  transition: transform var(--dauer-inter) var(--kurve-feder);
}

/* Nur ein Pixel: Die Wortmarke steht im mitscrollenden Kopf, ein größerer
   Hub würde dort wackeln statt zu antworten. */
@media (hover: hover) and (pointer: fine) {
  .wortmarke:hover {
    transform: translateY(-1px);
  }
}

.wortmarke:active {
  transform: translateY(0) scale(0.99);
}

/* Die Wortmarke ist als Link nur rund 25 Pixel hoch – eine einzige Zeile.
   Diese unsichtbare Fläche vergrößert den antippbaren Bereich auf 45 Pixel,
   ohne dass sich am Layout etwas verschiebt – sie liegt über nichts
   anderem. */
.wortmarke::after {
  content: '';
  position: absolute;
  inset: -10px 0;
}

/* Die Wortmarke ist keine gesperrte Versalienreihe mehr, sondern ein Wort:
   "Wenicker" in der Textschrift, Schnitt 700, normale Groß- und
   Kleinschreibung, eng gesetzt (-0.02em) – und direkt dahinter ein Punkt in
   Signalblau. Der Punkt ist das einzige farbige Zeichen der Marke; er setzt
   den Schlusspunkt und verbindet sie mit der Akzentfarbe der Website.
   25px: deutlich präsenter als der frühere 22px-Schnitt-600 und damit
   zweifelsfrei die kräftigste Stimme im Kopfbereich. */
.wortmarke__name {
  font-family: var(--schrift-text);
  font-weight: 700;
  font-size: 1.5625rem;
  letter-spacing: -0.02em;
  color: var(--tinte);
}

/* Der Punkt der Wortmarke. Auf Graphit eine Stufe heller, weil Signalblau
   dort zu dunkel stünde – beide Töne stehen schon oben in den Tokens. */
.wortmarke__punkt {
  color: var(--signal);
}

/* --------------------------------------------------------------------------
   5 Kopfbereich
   -------------------------------------------------------------------------- */

/* Der Kopfbereich ist die EINZIGE Stelle der Website mit backdrop-filter.
   Ein Weichzeichner kostet den Browser bei jedem Bild eine eigene Ebene –
   an einer einzelnen, schmalen, ohnehin dauerhaft eigenständigen Fläche
   (position: sticky) ist das bezahlbar, an Karten oder Panels wäre es das
   nicht. Deshalb: hier ja, sonst nirgends.

   Solange die Seite oben steht, ist der Kopf deckend im Grundton – man
   sieht keinen Unterschied zur Seite darunter. Sobald gescrollt wird, wird
   er zu einer milchigen Glasfläche: halbdurchsichtig, weichgezeichnet, mit
   feiner Linie und einem angedeuteten Schatten darunter.

   Fallback: Browser ohne backdrop-filter sehen den @supports-Rahmen gar
   nicht und behalten die deckende Fläche – derselbe Eindruck, nur ohne
   Durchblick. */
.kopf {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--grundton);
  border-bottom: 1px solid transparent;
  transition: background-color var(--dauer-einblenden) var(--kurve-aus),
    border-color var(--dauer-einblenden) var(--kurve-aus),
    box-shadow var(--dauer-einblenden) var(--kurve-aus),
    -webkit-backdrop-filter var(--dauer-einblenden) var(--kurve-aus),
    backdrop-filter var(--dauer-einblenden) var(--kurve-aus);
}

/* Kondensiert, sobald gescrollt wird */
.kopf[data-gescrollt='ja'] {
  border-bottom-color: var(--linie);
  box-shadow: 0 1px 0 rgba(18, 25, 27, 0.02), 0 8px 24px rgba(18, 25, 27, 0.06);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .kopf[data-gescrollt='ja'] {
    /* 72 % Deckkraft: genug Milch, dass die Wortmarke ohne Kontrastverlust
       darauf steht, und genug Durchblick, dass man den Inhalt darunter
       durchziehen sieht. */
    background: color-mix(in srgb, var(--grundton) 72%, transparent);
    -webkit-backdrop-filter: blur(18px) saturate(150%);
    backdrop-filter: blur(18px) saturate(150%);
  }

}

/* Das Kondensieren ändert die Höhe – eine Layout-Änderung. Sie wird bewusst
   NICHT animiert, sonst müsste der Browser 160 ms lang bei jedem Bild die
   ganze Seite neu umbrechen. */
.kopf__innen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--raum-3);
  padding-block: var(--raum-2);
}

.kopf[data-gescrollt='ja'] .kopf__innen {
  padding-block: var(--raum-1);
}

/* Menüschalter, nur auf schmalen Bildschirmen */
.kopf__schalter {
  display: none;
  position: relative;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--linie);
  border-radius: var(--radius-knopf);
  cursor: pointer;
  transition: transform var(--dauer-inter) var(--kurve-feder),
    border-color var(--dauer-inter) var(--kurve-aus);
}

.kopf__schalter:active {
  transform: scale(var(--druck));
}

.kopf__schalter-balken,
.kopf__schalter-balken::before,
.kopf__schalter-balken::after {
  position: absolute;
  left: 50%;
  width: 18px;
  height: 1.5px;
  margin-left: -9px;
  background: var(--tinte);
  transition: transform var(--dauer-inter) var(--kurve-feder),
    opacity var(--dauer-inter) var(--kurve-aus);
}

.kopf__schalter-balken {
  top: 50%;
  margin-top: -0.75px;
}

.kopf__schalter-balken::before,
.kopf__schalter-balken::after {
  content: '';
  left: 0;
  margin-left: 0;
}

.kopf__schalter-balken::before {
  top: -6px;
}
.kopf__schalter-balken::after {
  top: 6px;
}

.kopf__schalter[aria-expanded='true'] .kopf__schalter-balken {
  background: transparent;
}

.kopf__schalter[aria-expanded='true'] .kopf__schalter-balken::before {
  transform: translateY(6px) rotate(45deg);
}

.kopf__schalter[aria-expanded='true'] .kopf__schalter-balken::after {
  transform: translateY(-6px) rotate(-45deg);
}

/* Navigation */
.navigation {
  display: flex;
  align-items: center;
  gap: var(--raum-3);
}

.navigation__liste {
  display: flex;
  align-items: center;
  gap: var(--raum-1);
  list-style: none;
}

.navigation__punkt {
  position: relative;
}

.navigation__link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.5rem 0.75rem;
  border: 0;
  background: transparent;
  font-family: var(--schrift-text);
  font-size: var(--gr-klein);
  font-weight: 500;
  color: var(--tinte);
  text-decoration: none;
  border-radius: var(--radius-knopf);
  cursor: pointer;
  transition: transform var(--dauer-inter) var(--kurve-feder),
    color var(--dauer-inter) var(--kurve-aus),
    background-color var(--dauer-inter) var(--kurve-aus);
}

.navigation__link:hover {
  color: var(--signal);
  background: color-mix(in srgb, var(--signal) 7%, transparent);
}

@media (hover: hover) and (pointer: fine) {
  .navigation__link:hover {
    transform: translateY(var(--hub-klein));
  }
}

.navigation__link:active {
  transform: translateY(0) scale(var(--druck));
}

.navigation__link[aria-current='page'],
.navigation__schalter[data-aktiv='ja'] {
  color: var(--signal);
}

.navigation__pfeil {
  width: 10px;
  height: 6px;
  transition: transform var(--dauer-inter) var(--kurve-feder);
}

.navigation__schalter[aria-expanded='true'] .navigation__pfeil {
  transform: rotate(180deg);
}

/* Untermenü Leistungen */
.untermenue {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  min-width: 260px;
  padding: var(--raum-1);
  margin: 0;
  list-style: none;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius-menue);
  box-shadow: var(--schatten-menue);
}

.untermenue[hidden] {
  display: none;
}

.untermenue__link {
  display: block;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-knopf);
  font-size: var(--gr-klein);
  color: var(--tinte);
  text-decoration: none;
  transition: transform var(--dauer-inter) var(--kurve-feder),
    color var(--dauer-inter) var(--kurve-aus),
    background-color var(--dauer-inter) var(--kurve-aus);
}

.untermenue__link:hover,
.untermenue__link[aria-current='page'] {
  background: color-mix(in srgb, var(--signal) 7%, transparent);
  color: var(--signal);
}

@media (hover: hover) and (pointer: fine) {
  .untermenue__link:hover {
    transform: translateY(var(--hub-klein));
  }
}

.untermenue__link:active {
  transform: translateY(0) scale(var(--druck));
}

/* Schmale Bildschirme: Navigation einklappen */
@media (max-width: 900px) {
  .kopf__schalter {
    display: block;
  }

  /* Das aufgeklappte Menü ist eine eigene Fläche unter dem Kopf und bleibt
     bewusst deckend: Der Kopf darüber ist beim Scrollen milchiges Glas, das
     Menü darunter darf es nicht sein – sonst läse man den Seiteninhalt
     durch die Menüpunkte hindurch. */
  .navigation {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: var(--raum-2);
    padding: var(--raum-3) var(--seitenrand) var(--raum-4);
    background: var(--grundton);
    border-bottom: 1px solid var(--linie);
  }

  .navigation:not([data-offen='ja']) {
    display: none;
  }

  .navigation__liste {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .navigation__link {
    width: 100%;
    justify-content: space-between;
    padding: 0.75rem 0;
    font-size: var(--gr-gross);
    border-bottom: 1px solid var(--linie);
  }

  .navigation__link:hover {
    background: transparent;
  }

  .untermenue {
    position: static;
    min-width: 0;
    border: 0;
    box-shadow: none;
    background: transparent;
    padding: var(--raum-1) 0 var(--raum-1) var(--raum-2);
  }

  /* Die Untermenü-Einträge waren nur 38 Pixel hoch – zu klein für den
     Daumen. Sie bekommen dieselbe Mindesthöhe wie alles andere. */
  .untermenue__link {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  .kopf__knopf {
    width: 100%;
  }
}

/* --------------------------------------------------------------------------
   6 Fußbereich (Graphit)
   -------------------------------------------------------------------------- */

.fuss {
  background: var(--graphit);
  color: var(--grundton);
  padding-block: var(--raum-8) var(--raum-4);
}

/* Zwei Hälften: links die Marke mit Claim, Knöpfen und Direktkontakt,
   rechts drei Linkspalten. Beide Hälften beginnen oben auf derselben Höhe. */
.fuss__raster {
  display: grid;
  grid-template-columns: minmax(300px, 1fr) 1.1fr;
  align-items: start;
  gap: var(--raum-6) var(--raum-8);
  padding-bottom: var(--raum-8);
}

.fuss .wortmarke__name {
  color: var(--grundton);
}

/* Signalblau ist auf Graphit zu dunkel – dort steht der helle Signalton. */
.fuss .wortmarke__punkt {
  color: var(--signal-hell);
}

/* Der Claim steht direkt unter der Wortmarke – normaler Fließtext, damit
   die Wortmarke die kräftigste Stimme im Fußbereich bleibt. */
.fuss__claim {
  margin: var(--raum-3) 0 0;
  max-width: 34ch;
  color: rgba(244, 246, 246, 0.86);
}

.fuss__knoepfe {
  display: flex;
  flex-wrap: wrap;
  gap: var(--raum-2);
  margin-top: var(--raum-3);
}

/* E-Mail und Telefon in einer Zeile, klein und in Mono – dieselbe Rolle
   wie die übrigen technischen Kleinzeilen der Website. */
.fuss__direkt {
  margin: var(--raum-3) 0 0;
  font-family: var(--schrift-mono);
  font-size: var(--gr-mini);
  letter-spacing: 0.06em;
  color: rgba(244, 246, 246, 0.6);
}

.fuss__spalten {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--raum-4);
}

/* Spaltenüberschriften: fett in der Display-Schrift, in voller Helligkeit –
   sie sollen die Spalten anführen, nicht wie eine Kleinschrift zurücktreten. */
.fuss__titel {
  font-family: var(--schrift-display);
  font-size: var(--gr-basis);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.01em;
  color: var(--grundton);
  margin: 0 0 var(--raum-3);
}

.fuss__liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--raum-1);
}

.fuss__link {
  display: inline-block;
  font-size: var(--gr-klein);
  line-height: 1.6;
  color: rgba(244, 246, 246, 0.86);
  text-decoration: none;
  transition: transform var(--dauer-inter) var(--kurve-feder),
    color var(--dauer-inter) var(--kurve-aus);
}

.fuss__link:hover {
  color: var(--signal-hell);
  text-decoration: underline;
}

/* inline-block ist die Voraussetzung dafür, dass transform hier überhaupt
   greift – auf einem rein zeiligen (inline) Element bliebe es wirkungslos. */
@media (hover: hover) and (pointer: fine) {
  .fuss__link:hover {
    transform: translateY(var(--hub-klein));
  }
}

.fuss__link:active {
  transform: translateY(0);
}

/* Unterste Zeile: feine Linie über die volle Breite, darunter mittig die
   Urheberzeile. */
.fuss__unten {
  padding-top: var(--raum-4);
  border-top: 1px solid rgba(244, 246, 246, 0.12);
  text-align: center;
}

/* "margin-inline: auto" ist nötig, weil Absätze auf dieser Website
   grundsätzlich bei 68 Zeichen enden (Lesbarkeit). Dieser Absatz ist
   dadurch schmaler als die Leiste – ohne "auto" klebte er links, und
   text-align: center hätte ihn nur innerhalb seiner schmalen Box zentriert. */
.fuss__urheber {
  margin: 0 auto;
  font-family: var(--schrift-mono);
  font-size: var(--gr-mini);
  letter-spacing: 0.06em;
  color: rgba(244, 246, 246, 0.6);
}

/* Am Handy steht zuerst die linke Hälfte, darunter die Spalten. */
@media (max-width: 900px) {
  .fuss__raster {
    grid-template-columns: 1fr;
    gap: var(--raum-6);
    padding-bottom: var(--raum-6);
  }
}

/* Ganz schmal stapeln auch die drei Spalten untereinander; die Fuß-Links
   waren dort nur 22 Pixel hoch und lagen dicht beieinander – man trifft
   leicht den falschen. Sie bekommen eine Mindesthöhe von 44 Pixeln. */
@media (max-width: 620px) {
  .fuss__spalten {
    grid-template-columns: 1fr;
    gap: var(--raum-5);
  }

  .fuss__liste {
    gap: 0;
  }

  .fuss__link {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  .fuss__knoepfe .knopf {
    flex: 1 1 100%;
  }
}

/* Fuß-Freigabe: Der Fußbereich liegt optisch UNTER der Seite. Er klebt am
   unteren Fensterrand, der Inhalt darüber ist deckend und verdeckt ihn –
   bis man am Seitenende ankommt und der Inhalt darüber hinwegschiebt.
   Das erledigt allein der Browser: kein JavaScript, keine Messung, keine
   Animation. Bewegt wird nichts, es wird nur etwas frei.

   Nur am Schreibtisch und nur bei genug Fensterhöhe: Auf schmalen
   Bildschirmen stehen die Fuß-Spalten untereinander, der Fußbereich wird
   dort höher als das Fenster – und an seinen oberen Rand käme man dann
   nie heran. Und wer "Bewegung reduzieren" eingeschaltet hat, bekommt
   auch dieses Zusammenspiel nicht: Dann steht der Fußbereich schlicht am
   Ende der Seite. */
@media (min-width: 901px) and (min-height: 620px) and (prefers-reduced-motion: no-preference) {
  .fuss {
    position: sticky;
    bottom: 0;
  }

  /* Deckend und eine Ebene höher: Sonst schiene der Fußbereich durch den
     Inhalt hindurch. Der Kopfbereich liegt mit z-index 50 weiterhin über
     allem, die Sprungmarke mit 100 darüber. */
  main {
    position: relative;
    z-index: 1;
    background: var(--grundton);
  }
}

/* --------------------------------------------------------------------------
   7 Startseite
   -------------------------------------------------------------------------- */

/* 7.1 Hero – Statement, fast volle Fensterhöhe ---------------------------- */

.hero {
  display: flex;
  align-items: center;
  min-height: 84vh;
  min-height: min(84svh, 920px);
  padding-block: var(--raum-8) var(--raum-10);
}

.hero__eyebrow {
  margin: 0 0 var(--raum-3);
}

/* Die Statement-Überschrift der Startseite. Bewusst als h1.hero__titel
   geschrieben: So kann die allgemeine h1-Größe (max. 64px, für die
   Unterseiten gedacht) diese Zeile nie überstimmen.
   Skala laut Briefing: mobil klein, am Schreibtisch 96–120px.
   Die erste Zeile ist der Rückfall für Browser, die clamp() nicht kennen. */
h1.hero__titel {
  font-size: 8vw;
  font-size: var(--gr-hero);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.035em;
  margin: 0 0 var(--raum-4);
  max-width: 15ch;
  text-wrap: initial;
  /* Zeilen als eigene Spalte statt als Fließtext: Nur so kann jede Zeile
     eine eigene Maske bekommen, ohne dass sich die Zeilenabstände ändern
     (bei Flex-Kindern verschmelzen Außenabstände nicht miteinander). */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Die Maske einer Zeile: Sie schneidet ab, was über oder unter der Zeile
   steht. Damit im Ruhezustand nichts angeschnitten wird (Oberlängen, das
   kursive Serifenwort, das "g" in "Währung"), bekommt sie etwas
   Innenabstand – und exakt denselben Betrag als negativen Außenabstand
   wieder abgezogen. Unterm Strich steht die Überschrift damit auf den
   Pixel genau so wie vorher. */
.hero__zeile {
  display: block;
  overflow: hidden;
  padding-block: 0.16em 0.22em;
  margin-block: -0.16em -0.22em;
  /* Auch seitlich etwas Luft, nach demselben Muster: Das Akzentwort steht am
     Zeilenanfang und wird für den Farb-Sweep um 0.12em nach links verbreitert
     (siehe .hero__akzent). Ohne diesen Spielraum würde die Maske genau diese
     Verbreiterung abschneiden. Der negative Außenabstand nimmt den Zuwachs
     wieder zurück, die Zeile steht also unverändert an ihrem Platz. */
  padding-inline-start: 0.14em;
  margin-inline-start: -0.14em;
  padding-inline-end: 0.14em;
}

/* Das, was in der Maske hochfährt. */
.hero__zeile-innen {
  display: block;
}

/* Das hervorgehobene Wort: gleiche Größe, andere Stimme. */
.hero__akzent {
  font-family: var(--schrift-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--signal);
  letter-spacing: -0.01em;
  /* Die Serifenschrift wirkt bei gleicher Punktgröße etwas kleiner. */
  font-size: 1.06em;
  /* Der kursive Auslauf des letzten Buchstabens (das "t") ragt seitlich über
     die Textbox hinaus. Ein Hintergrund würde dort nicht mehr hinreichen –
     beim Farb-Sweep bliebe die Spitze farblos und flackerte. Deshalb wird die
     bemalbare Fläche links und rechts um 0.12em verbreitert und exakt derselbe
     Betrag als negativer Außenabstand wieder abgezogen: Das Layout bleibt auf
     den Pixel gleich, der Überhang liegt aber innerhalb der Fläche. */
  padding-inline: 0.12em;
  margin-inline: -0.12em;
}

.hero__text {
  font-size: var(--gr-gross);
  color: var(--tinte-leise);
  max-width: 56ch;
  margin-bottom: var(--raum-4);
}

/* Die Knöpfe sind das letzte Element des Heros – darunter kommt nichts
   mehr. Deshalb kein Abstand nach unten: Den Abschluss macht allein das
   padding-block der Sektion. */
.hero__knoepfe {
  display: flex;
  flex-wrap: wrap;
  gap: var(--raum-2);
  margin-bottom: 0;
}

/* Flache Bildschirme (kleine Notebooks): Abstände und Schrift etwas enger,
   damit der Hero bis zu den Knöpfen in den ersten Viewport passt.
   Zwei Stufen – je flacher das Fenster, desto kompakter. */
@media (max-height: 800px) and (min-width: 901px) {
  .hero {
    padding-block: var(--raum-5) var(--raum-6);
  }

  h1.hero__titel {
    font-size: clamp(2.5rem, 0.6rem + 6.4vw, 5.5rem);
  }

  .hero__text {
    margin-bottom: var(--raum-3);
  }
}

@media (max-height: 700px) and (min-width: 901px) {
  .hero {
    padding-block: var(--raum-4) var(--raum-5);
  }

  h1.hero__titel {
    font-size: clamp(2.25rem, 0.6rem + 4.6vw, 4rem);
    margin-bottom: var(--raum-3);
  }

  .hero__eyebrow {
    margin-bottom: var(--raum-2);
  }
}

/* Einstiegsanimation, genau einmal pro Seitenaufruf.
   Wichtig: Sie hängt an der Klasse .hero-los, die nur kurz gesetzt ist.
   Grundzustand des Heros ist "sichtbar" – die Animation kann ihn also nie
   dauerhaft verstecken. Fällt sie aus, steht sofort alles da.
   Animiert werden ausschließlich opacity, transform und – beim Farb-Sweep –
   die Position eines Farbverlaufs: kein Layout pro Bild, keine Last für den
   Renderer. Nichts davon wiederholt sich. */
@media (prefers-reduced-motion: no-preference) {
  /* a) Die drei Überschriftzeilen fahren nacheinander aus ihrer Maske auf.
        Versatz 120 ms, Dauer 700 ms – bewusst länger als das Einblende-Token:
        Die Zeilen legen eine volle Zeilenhöhe zurück, nicht 20 Pixel. Die
        Kurve ist dieselbe wie überall sonst bei langen Bewegungen. */
  .hero-los .hero__zeile-innen {
    animation: zeile-auf 700ms var(--kurve-aus) backwards;
    will-change: transform, opacity;
  }

  .hero-los .hero__zeile:nth-child(1) .hero__zeile-innen {
    animation-delay: 120ms;
  }
  .hero-los .hero__zeile:nth-child(2) .hero__zeile-innen {
    animation-delay: 240ms;
  }
  .hero-los .hero__zeile:nth-child(3) .hero__zeile-innen {
    animation-delay: 360ms;
  }

  /* b) Alles um die Überschrift herum blendet ein – nur zeitlich hinter den
        Zeilen, und mit derselben Landungs-Kurve wie die Scroll-Reveals:
        Der Inhalt setzt weich auf, statt einfach dazustehen. */
  .hero-los .hero__eyebrow,
  .hero-los .hero__text,
  .hero-los .hero__knoepfe {
    animation: einstieg var(--dauer-einblenden) var(--kurve-landung) backwards;
    will-change: opacity, transform;
  }

  .hero-los .hero__eyebrow {
    animation-delay: 0ms;
  }
  .hero-los .hero__text {
    animation-delay: 620ms;
  }
  .hero-los .hero__knoepfe {
    animation-delay: 700ms;
  }
}

@keyframes zeile-auf {
  from {
    opacity: 0;
    transform: translateY(105%);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes einstieg {
  from {
    opacity: 0;
    transform: translateY(0.35em);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* c) Farb-Sweep über das Serifenwort – genau einmal, direkt nachdem die
   letzte Zeile steht. Das Wort bekommt dafür kurz einen Farbverlauf als
   Füllung (background-clip: text); der hellere Streifen darin wandert
   einmal von links nach rechts. Danach fällt alles auf das normale
   Signalblau zurück, weil die ganze Regel an .hero-los hängt.

   Zwei Sicherungen:
   – Der @supports-Rahmen prüft, ob der Browser Text überhaupt mit einem
     Verlauf füllen kann UND color-mix beherrscht. Fehlt eines von beidem,
     sieht er die Regel gar nicht erst; sonst wäre das Wort unsichtbar.
   – Der Verlauf steht an beiden Enden der Bewegung auf reinem Signalblau,
     der helle Streifen liegt in der Mitte. Vor und nach der Animation ist
     das Wort also immer voll deckend eingefärbt.
   Der hellere Ton ist eine Mischung aus den beiden Signaltönen und hält auf
   dem Grundton noch 3,7:1 Kontrast – keine neue Farbe, AA für große
   Schrift erfüllt. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) and
  (color: color-mix(in srgb, red, blue)) {
  @media (prefers-reduced-motion: no-preference) {
    .hero-los .hero__akzent {
      /* Der Verlauf ist an beiden Enden auf reinem Signalblau festgeklemmt
         (0 % und 100 %). Alles außerhalb des schmalen Glanzbandes in der Mitte
         ist damit garantiert einfarbig – egal, welcher Ausschnitt gerade unter
         dem Wort liegt. */
      background-image: linear-gradient(
        100deg,
        var(--signal) 0%,
        var(--signal) 44%,
        color-mix(in srgb, var(--signal-hell) 45%, var(--signal)) 50%,
        var(--signal) 56%,
        var(--signal) 100%
      );
      /* Dreifache Breite: Auch am Anfang und am Ende der Bewegung liegt das
         ganze Wort samt Überhang sicher innerhalb des Verlaufs. */
      background-size: 300% 100%;
      /* Ohne das würde sich der Verlauf kacheln und am Wortende ein zweites
         Glanzband anschneiden. */
      background-repeat: no-repeat;
      -webkit-background-clip: text;
      background-clip: text;
      -webkit-text-fill-color: transparent;
      color: transparent;
      /* "both" = backwards + forwards: Vor dem Start (1060 ms Wartezeit) gilt
         der Anfangswert, nach dem Durchlauf bleibt der Endwert stehen. Beide
         sind einfarbiges Signalblau, es bleibt also kein Restverlauf stehen. */
      animation: akzent-sweep 800ms var(--kurve-aus) 1060ms both;
    }
  }
}

@keyframes akzent-sweep {
  from {
    background-position: 100% 0;
  }
  to {
    background-position: 0% 0;
  }
}

/* 7.2 Ihre neue Website (Hauptsektion) und Ausbaustufen -------------------- */

/* Das Hauptprodukt bekommt sichtbar mehr Raum als jede andere Sektion:
   mehr Abstand darum, eine große weiße Karte, Überschrift in H1-Größe. */
.hauptleistung {
  padding-block: calc(var(--sektion) * 1.3);
}

.hauptleistung__innen {
  position: relative;
  display: grid;
  grid-template-columns: 1.2fr 0.8fr;
  gap: clamp(var(--raum-5), 4vw, var(--raum-10));
  align-items: start;
  padding: clamp(var(--raum-5), 4vw, var(--raum-10));
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius-karte);
  box-shadow: var(--schatten-ruhe);
  overflow: hidden;
}

/* Feine Signal-Kante an der Oberkante: markiert die wichtigste Sektion,
   ohne eine neue Farbe einzuführen. */
.hauptleistung__innen::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  border-radius: var(--radius-karte) var(--radius-karte) 0 0;
  background: var(--signal);
}

.hauptleistung__titel {
  font-size: var(--gr-h1);
  line-height: 1.05;
  max-width: 17ch;
  /* Kein Abstand nach oben: Die Überschrift ist das Erste in der Karte und
     sitzt direkt auf deren Innenabstand. */
  margin: 0 0 var(--raum-4);
}

.hauptleistung__text {
  font-size: var(--gr-gross);
  color: var(--tinte-leise);
  max-width: 54ch;
  margin-bottom: var(--raum-5);
}

.hauptleistung__knoepfe {
  display: flex;
  flex-wrap: wrap;
  gap: var(--raum-2);
}

/* Editorial-Liste statt Kacheln: keine Flächen, keine Rahmen – nur Zeilen,
   die durch feine Linien getrennt sind. Gilt auf allen Bildschirmbreiten;
   am Schreibtisch kommt weiter unten nur die Fokus-Logik dazu. */
.hauptleistung__punkte {
  list-style: none;
  display: block;
  margin: 0;
  padding: 0;
}

.zeile {
  position: relative;
  padding: var(--raum-4) 0 var(--raum-4) var(--raum-3);
  border-top: 1px solid var(--linie);
}

/* Die letzte Zeile bekommt unten dieselbe Linie – so ist die Liste als
   Block abgeschlossen. */
.zeile:last-child {
  border-bottom: 1px solid var(--linie);
}

.zeile__titel {
  font-family: var(--schrift-display);
  font-weight: 600;
  font-size: clamp(1.5rem, 1.15rem + 1vw, 2rem);
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin: 0;
}

.zeile__text {
  margin: var(--raum-1) 0 0;
  font-family: var(--schrift-text);
  font-size: var(--gr-basis);
  color: var(--tinte-leise);
  max-width: 46ch;
}

/* Der Signal-Marker an der linken Kante. Er ist immer da, aber bis zum
   Fokuswechsel auf Höhe null zusammengeschoben – so wird nur er animiert
   und keine einzige Zeile verschiebt sich. Ohne Fokus-Logik (Handy, ohne
   Skript, "Bewegung reduzieren") bleibt er unsichtbar. */
.zeile__marker {
  position: absolute;
  left: 0;
  top: calc(var(--raum-4) + 0.15em);
  width: 2px;
  height: 1.4em;
  border-radius: 1px;
  background: var(--signal);
  transform: scaleY(0);
  transform-origin: top center;
  opacity: 0;
}

@media (max-width: 860px) {
  .hauptleistung__innen {
    grid-template-columns: 1fr;
  }

  .hauptleistung__titel {
    max-width: none;
  }
}

/* Scroll-Kapitel – nur am Schreibtisch ab 1024 px.
   Links bleibt der Text stehen, rechts steht die Liste von Anfang an
   vollständig an ihrem Platz. Beim Scrollen wechselt allein der Fokus:
   Die Zeile im mittleren Streifen des Fensters steht in voller Textfarbe
   und bekommt links ihren Signal-Marker, alle anderen sind zurückgenommen.
   Bewegt wird ausschließlich opacity und der Marker – nie eine Position.
   Die Scroll-Länge entsteht aus der Mindesthöhe der Zeilen.
   Auf schmalen Bildschirmen und bei "Bewegung reduzieren" gilt nichts
   davon – dort steht die Liste einfach vollständig sichtbar da. */
@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
  /* "overflow: hidden" wäre hier ein Käfig: Innerhalb einer solchen Karte
     kann nichts stehen bleiben. Die Signal-Kante oben bekommt ihre Rundung
     deshalb selbst, statt sie vom Kartenrand abgeschnitten zu bekommen. */
  .hauptleistung__innen {
    overflow: visible;
  }

  .hauptleistung__innen::before {
    border-radius: var(--radius-karte) var(--radius-karte) 0 0;
  }

  /* Die Karte selbst blendet hier nur noch ein, ohne sich zu verschieben:
     Ein verschobener Vorfahr würde das Stehenbleiben der linken Spalte
     aushebeln. */
  .js-bereit .hauptleistung__innen.reveal {
    transform: none;
  }

  .hauptleistung__spalte {
    position: sticky;
    top: clamp(6rem, 16vh, 9rem);
  }

  /* Jede Zeile füllt gut ein Fünftel Fensterhöhe: So ist fast immer genau
     eine Zeile "dran", und der Fokus wandert ruhig mit. Der Inhalt sitzt
     mittig in der Zeile, die Linie bleibt oben. */
  .zeile {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 22vh;
    padding-block: var(--raum-5);
  }

  .zeile__marker {
    top: 50%;
    height: 2.2em;
    transform: translateY(-50%) scaleY(0);
    transform-origin: center;
    transition: transform 420ms var(--kurve-aus), opacity 260ms var(--kurve-aus);
  }

  /* Ausgangszustand nur, wenn das Skript da ist – ohne Skript gäbe es
     keinen Fokuswechsel und die Liste bliebe für immer blass. */
  .js-bereit .hauptleistung__punkt {
    opacity: 0.35;
    transition: opacity 320ms var(--kurve-aus);
  }

  /* Die Zeile, die gerade "dran" ist: volle Deckkraft, voller Marker. */
  .js-bereit .hauptleistung__punkt[data-aktiv] {
    opacity: 1;
  }

  .js-bereit .hauptleistung__punkt[data-aktiv] .zeile__marker {
    opacity: 1;
    transform: translateY(-50%) scaleY(1);
  }
}

/* Ausbaustufen: halber Sektionsabstand, schmaleres Raster, flachere Karten –
   der Rangunterschied zur Hauptsektion soll ohne Lesen erkennbar sein. */
.ausbaustufen {
  padding-block: calc(var(--sektion) / 2);
}

.ausbaustufen__intro {
  margin-top: var(--raum-2);
  color: var(--tinte-leise);
  font-size: var(--gr-klein);
}

/* Ein zusammenhängendes Panel statt zweier Karten: eine durchgehende
   Graphit-Fläche, innen nur durch eine feine Linie geteilt. */
.ausbaustufen__panel {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  list-style: none;
  max-width: 820px;
  margin-top: var(--raum-4);
  padding: 0;
  background: var(--graphit);
  border-radius: var(--radius-karte);
  box-shadow: var(--schatten-ruhe);
  overflow: hidden;
}

/* Die Trennlinie gehört zur zweiten Hälfte – so gibt es sie genau einmal,
   egal wie viele Hälften es sind. */
.ausbaustufe + .ausbaustufe {
  border-left: 1px solid rgba(244, 246, 246, 0.18);
}

/* Der Link füllt die ganze Hälfte aus: Man trifft überall. */
.ausbaustufe__flaeche {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: clamp(var(--raum-4), 3vw, var(--raum-6));
  color: var(--grundton);
  text-decoration: none;
  transition: transform var(--dauer-inter) var(--kurve-feder);
}

.ausbaustufe__flaeche:hover {
  color: var(--grundton);
}

/* Die Hälfte ist durchsichtig – angehoben wird also nicht eine Fläche,
   sondern ihr Inhalt. Genau richtig: Das Panel bleibt eine durchgehende
   Graphit-Fläche mit einer Trennlinie, nur der Inhalt kommt entgegen.
   Eine echte Flächenverschiebung würde die Trennlinie aufreißen. */
@media (hover: hover) and (pointer: fine) {
  .ausbaustufe__flaeche:hover {
    transform: translateY(var(--hub-klein));
  }
}

.ausbaustufe__flaeche:active {
  transform: translateY(0) scale(var(--druck));
}

.ausbaustufe__marke {
  margin: 0 0 var(--raum-3);
  color: rgba(244, 246, 246, 0.6);
}

.ausbaustufe__titel {
  font-family: var(--schrift-display);
  font-size: var(--gr-h3);
  margin: 0 0 var(--raum-2);
}

.ausbaustufe__text {
  margin: 0 0 var(--raum-4);
  font-size: var(--gr-klein);
  color: rgba(244, 246, 246, 0.75);
}

/* Die kleine Preiszeile der Ausbaustufe: dieselbe Mono-Anmutung wie die
   Preiszeile im Pakete-Teaser, nur auf Graphit. Bewusst ohne Versalien –
   "Einrichtung 290 € · dann 79 €/Monat" ist eine Angabe zum Lesen, kein
   Etikett. Deshalb steht hier text-transform: none gegen .marke. */
.ausbaustufe__preis {
  margin: calc(var(--raum-4) * -1 + var(--raum-1)) 0 var(--raum-4);
  font-size: var(--gr-klein);
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--signal-hell);
}

/* Auf Graphit ist das kräftige Signalblau zu dunkel – hier gilt die helle
   Variante, wie überall auf dunklen Flächen. */
.ausbaustufe__pfeil {
  margin-top: auto;
  color: var(--signal-hell);
}

.ausbaustufe__pfeil svg {
  width: 20px;
  height: 12px;
  transition: transform var(--dauer-inter) var(--kurve-feder);
}

.ausbaustufe__flaeche:hover .ausbaustufe__pfeil svg {
  transform: translateX(4px);
}

/* Auf schmalen Bildschirmen wird aus der senkrechten Teilung eine
   waagerechte – das Panel bleibt eine Fläche. */
@media (max-width: 700px) {
  .ausbaustufen__panel {
    grid-template-columns: 1fr;
  }

  .ausbaustufe + .ausbaustufe {
    border-left: 0;
    border-top: 1px solid rgba(244, 246, 246, 0.18);
  }
}

/* Verweise auf die Ausbaustufen ("Was dazu passt" am Ende von /websites).
   Keine Karten mehr: geordnet wird allein durch feine waagerechte Linien,
   Titel links, Erklärsatz daneben, Pfeil rechts außen. */
.verweis-liste {
  list-style: none;
  margin: var(--raum-4) 0 0;
  padding: 0;
  border-top: 1px solid var(--linie);
}

.verweis-liste > li {
  border-bottom: 1px solid var(--linie);
}

.verweis {
  display: grid;
  grid-template-columns: minmax(0, 16rem) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--raum-1) var(--raum-4);
  padding: var(--raum-3) 0;
  color: inherit;
  text-decoration: none;
  transition: transform var(--dauer-inter) var(--kurve-feder);
}

/* Auch hier bewegt sich nur der Inhalt: Die feinen Linien sitzen am
   Listeneintrag, nicht am Link. Das Raster der Zeilen bleibt also
   millimetergenau stehen, während die Zeile antwortet. */
@media (hover: hover) and (pointer: fine) {
  .verweis:hover {
    transform: translateY(var(--hub-klein));
  }
}

.verweis:active {
  transform: translateY(0) scale(var(--druck));
}

.verweis__titel {
  margin: 0;
  font-size: var(--gr-gross);
  transition: color var(--dauer-inter) var(--kurve-aus);
}

.verweis:hover .verweis__titel,
.verweis:focus-visible .verweis__titel {
  color: var(--signal);
}

.verweis__text {
  margin: 0;
  color: var(--tinte-leise);
  font-size: var(--gr-klein);
}

.verweis__pfeil {
  align-self: center;
  color: var(--signal);
}

.verweis__pfeil svg {
  display: block;
  width: 20px;
  height: 12px;
  transition: transform var(--dauer-inter) var(--kurve-feder);
}

.verweis:hover .verweis__pfeil svg {
  transform: translateX(4px);
}

/* Am Handy steht der Erklärsatz unter dem Titel, der Pfeil bleibt rechts. */
@media (max-width: 720px) {
  .verweis {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
  }

  .verweis__titel {
    grid-column: 1;
  }

  .verweis__text {
    grid-column: 1;
  }

  .verweis__pfeil {
    grid-column: 2;
    grid-row: 1 / span 2;
  }
}

/* 7.3 Für wen ------------------------------------------------------------- */

.fuer-wen__innen {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--raum-6);
  align-items: start;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--raum-1);
  list-style: none;
}

.chip {
  padding: 0.5rem 0.875rem;
  border: 1px solid var(--linie);
  border-radius: 999px;
  background: var(--flaeche);
  font-size: var(--gr-klein);
  color: var(--tinte-leise);
}

@media (max-width: 860px) {
  .fuer-wen__innen {
    grid-template-columns: 1fr;
    gap: var(--raum-4);
  }
}

/* 7.4 FAQ ---------------------------------------------------------------- */

.faq__innen {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) 2fr;
  gap: var(--raum-6);
  align-items: start;
}

.faq__eintrag {
  border-top: 1px solid var(--linie);
}

.faq__eintrag:last-child {
  border-bottom: 1px solid var(--linie);
}

.faq__frage {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--raum-2);
  padding-block: var(--raum-2);
  font-family: var(--schrift-display);
  font-size: var(--gr-gross);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  transition: transform var(--dauer-inter) var(--kurve-feder),
    color var(--dauer-inter) var(--kurve-aus);
}

.faq__frage::-webkit-details-marker {
  display: none;
}

.faq__frage:hover {
  color: var(--signal);
}

@media (hover: hover) and (pointer: fine) {
  .faq__frage:hover {
    transform: translateY(var(--hub-klein));
  }
}

.faq__frage:active {
  transform: translateY(0) scale(var(--druck));
}

/* Plus, das beim Öffnen zum Minus wird */
.faq__zeichen {
  position: relative;
  flex: none;
  width: 14px;
  height: 14px;
}

.faq__zeichen::before,
.faq__zeichen::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 0;
  width: 14px;
  height: 1.5px;
  margin-top: -0.75px;
  background: currentColor;
  transition: transform var(--dauer-inter) var(--kurve-feder);
}

.faq__zeichen::after {
  transform: rotate(90deg);
}

.faq__eintrag[open] .faq__zeichen::after {
  transform: rotate(0deg);
}

.faq__antwort {
  padding-bottom: var(--raum-3);
}

/* Federnd weiches Auf- und Zuklappen.

   Ein <details> klappt von Haus aus hart um: Seine Höhe springt von 0 auf
   "so hoch wie der Inhalt", und nach "auto" ließ sich früher überhaupt
   nicht animieren. Beides kann der Browser inzwischen selbst –
   "interpolate-size: allow-keywords" erlaubt ihm, nach auto zu rechnen,
   und über ::details-content bekommt man den aufklappenden Teil als
   eigenes Ziel zu fassen. Der Übergang auf content-visibility mit
   "allow-discrete" hält den Inhalt beim Zuklappen so lange im Layout, bis
   die Bewegung durch ist – sonst verschwände er sofort und die Höhe
   spränge.

   Der @supports-Rahmen ist keine Höflichkeit, sondern Pflicht: Wo der
   Browser das nicht kann, sieht er die Regeln gar nicht erst und klappt
   wie bisher sofort um. Bedienbar ist das Akkordeon in jedem Fall.

   Bewusste Ausnahme von der Regel "keine Layout-Animationen": Das ist die
   Bewegung selbst, nicht ihre Verzierung – ein Akkordeon, das seine Höhe
   nicht ändert, klappt nicht auf. Betroffen ist nur der Inhalt EINER
   FAQ-Zeile, und nur solange geklappt wird. */
@supports (interpolate-size: allow-keywords) and (selector(::details-content)) {
  :root {
    interpolate-size: allow-keywords;
  }

  .faq__eintrag::details-content {
    block-size: 0;
    overflow: hidden;
    opacity: 0;
    transition: block-size var(--dauer-einblenden) var(--kurve-aus),
      opacity 260ms var(--kurve-aus),
      content-visibility var(--dauer-einblenden) allow-discrete;
  }

  .faq__eintrag[open]::details-content {
    block-size: auto;
    opacity: 1;
  }
}

.faq__antwort p {
  margin: 0;
  color: var(--tinte-leise);
}

@media (max-width: 860px) {
  .faq__innen {
    grid-template-columns: 1fr;
    gap: var(--raum-3);
  }
}

/* Auf der Startseite ist die FAQ die letzte Sektion vor dem dunklen
   Fußbereich. Die Liste schließt schon selbst mit einer feinen Linie ab;
   hier kommt nur etwas mehr Luft dazu, damit die letzte Antwort nicht
   unmittelbar an die Graphitfläche stößt. */
.faq--abschluss {
  padding-bottom: calc(var(--sektion) * 1.4);
}

/* 7.5 Großer Knopf ------------------------------------------------------- */

/* Die betonte Knopfgröße; sie steht am Kontaktformular. */
.knopf--gross {
  padding: 1rem 1.75rem;
  font-size: var(--gr-basis);
}

/* --------------------------------------------------------------------------
   8 Unterseiten
   Dieselben Muster wie auf der Startseite: großzügiger Weißraum, weiße
   Karten mit feiner Linie. Keine neuen Farben oder Schriften.
   -------------------------------------------------------------------------- */

/* 8.1 Seitenkopf: die einzige h1 der Seite und die Einleitung ------------- */

.seitenkopf {
  padding-block: var(--sektion) 0;
}

.seitenkopf__titel {
  max-width: 22ch;
}

.seitenkopf__intro {
  max-width: 60ch;
  margin-bottom: 0;
}

/* Aufeinanderfolgende Inhaltsblöcke einer Unterseite: halber Abstand,
   damit die Seite nicht in leere Bildschirmhöhen zerfällt. */
.abschnitt--kompakt {
  padding-block: calc(var(--sektion) / 2);
}

/* Anschluss-Satz direkt unter dem Seitenkopf einer Ausbaustufen-Seite.
   Der Seitenkopf bringt den Abstand nach oben schon mit, deshalb hier nur
   Abstand nach unten. */
.abschnitt--anschluss {
  padding-block: 0 calc(var(--sektion) / 2);
}

/* Ein Abschnitt, der inhaltlich direkt zum vorherigen gehört (etwa der
   Knopf unter einem Aussage-Band). Ohne Abstand nach oben rücken beide
   zusammen und lesen sich als ein Block, statt als zwei Sektionen. */
.abschnitt--fortsetzung {
  padding-top: 0;
}

.verweis-satz {
  margin: 0;
  max-width: 68ch;
  padding-left: var(--raum-3);
  border-left: 3px solid var(--signal);
}

/* Kleiner Abstand nach oben, wo ein Absatz auf eine Liste folgt */
.abstand-oben {
  margin-top: var(--raum-4);
}

/* 8.2 Checkliste: Punkte mit Plus-Marker ----------------------------------- */

.checkliste {
  list-style: none;
  display: grid;
  gap: var(--raum-2);
  max-width: 68ch;
  margin-top: var(--raum-4);
}

.checkliste li {
  position: relative;
  padding-left: 1.75rem;
  color: var(--tinte-leise);
}

.checkliste li::before {
  content: '+';
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--schrift-mono);
  font-weight: 500;
  color: var(--signal);
}

/* 8.3 Bänder statt Kästen ---------------------------------------------------
   Hervorgehoben wird nirgends mehr durch eine umrandete oder weiße Fläche,
   sondern über die volle Inhaltsbreite: feine Linie, darunter der Inhalt.
   Die einzigen umrandeten Flächen der Website sind die Preiskarten auf
   /pakete (vier Website-Pakete, zwei Sichtbarkeits-Bausteine) und das
   Formular auf /kontakt.

   .aussage        – ein einzelner betonter Satz (Klartext-Satz auf
                     /google-unternehmensprofil)
   .aussage--band  – dieselbe Zeile über die volle Inhaltsbreite, oben und
                     unten abgesetzt (Zusatzleistungen auf /pakete)
   .garantien-band – die drei Zusagen auf /websites, nebeneinander
   -------------------------------------------------------------------------- */

.aussage {
  max-width: 72ch;
  padding-top: var(--raum-4);
  border-top: 1px solid var(--linie);
}

.aussage__text {
  margin: 0;
  font-size: var(--gr-gross);
}

/* Bandvariante (Zusatzleistungen auf /pakete): Die feinen Linien laufen
   über die volle Inhaltsbreite und setzen die Zeile oben wie unten ab.
   Der Satz selbst behält seine ruhige Lesebreite. */
.aussage--band {
  max-width: none;
  padding-block: var(--raum-4);
  border-bottom: 1px solid var(--linie);
}

.aussage--band .aussage__text {
  max-width: 72ch;
}

/* Das Garantien-Band: volle Inhaltsbreite, feine Linie oben und unten. */
.garantien-band {
  padding-block: var(--raum-4);
  border-top: 1px solid var(--linie);
  border-bottom: 1px solid var(--linie);
}

.garantien-band__spalten {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--raum-3) var(--raum-5);
}

.garantie__titel {
  margin: 0 0 var(--raum-1);
  font-size: var(--gr-gross);
  font-weight: 700;
}

.garantie__text {
  margin: 0;
  font-size: var(--gr-klein);
  color: var(--tinte-leise);
}

/* Am Handy stehen die drei Zusagen untereinander, jede durch eine feine
   Linie von der vorigen getrennt. */
@media (max-width: 720px) {
  .garantien-band__spalten {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .garantie + .garantie {
    margin-top: var(--raum-3);
    padding-top: var(--raum-3);
    border-top: 1px solid var(--linie);
  }
}

/* 8.4 Pakete ---------------------------------------------------------------- */

.paket-gitter {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--raum-3);
  list-style: none;
  margin: var(--raum-2) 0 var(--raum-5);
}

/* Kein harter Rand mehr: Die Karte steht durch einen weichen, zweistufigen
   Schatten auf der Fläche – eine enge Stufe zeichnet die Kante, eine weite
   trägt die Karte. Innen eine Stufe mehr Luft als vorher. */
.paket {
  /* --paket-luft ist die Stellschraube für die Innenluft: Die Vier-Reihe
     (am Gitter) und die Baustein-Karte (an sich selbst) drehen sie
     herunter, das Badge folgt automatisch. Der Normalwert steht bewusst
     nur als Rückfallwert unten – eine Deklaration hier würde den vom
     Gitter geerbten Wert schlagen. */
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--paket-luft, var(--raum-5));
  background: var(--flaeche);
  border-radius: var(--radius-karte);
  box-shadow: var(--schatten-ruhe);
  /* Anheben und Schattenwachstum laufen auf denselben Tokens wie alles
     andere: der Weg federt, der Schatten läuft weich aus. */
  transition: transform var(--dauer-inter) var(--kurve-feder),
    box-shadow var(--dauer-inter) var(--kurve-aus);
}

@media (hover: hover) and (pointer: fine) {
  .paket:hover {
    transform: translateY(var(--hub-gross));
  }
}

/* Die meistgewählte Karte trägt eine 2px-Oberkante in Signalblau. Sie sitzt
   als eigene Ebene auf der Karte, damit sich nichts in der Größe verschiebt.

   Warum die Ebene so hoch ist wie der Eckradius und nicht nur 2 Pixel:
   Ein 2 Pixel flacher Kasten kann keine 18 Pixel Rundung tragen – der
   Browser staucht sie auf ein Pixel zusammen, und die Kante stünde als
   gerader Strich über die runden Ecken der Karte hinaus. Deshalb ist die
   Ebene 18 Pixel hoch (also genau so hoch wie die Rundung), trägt die
   Rundung damit sauber, und der Farbverlauf malt nur die obersten 2 Pixel
   aus. Die runden Ecken schneiden diese Kante beidseitig genau dort ab, wo
   auch die Karte aufhört. */
.paket--hervorgehoben::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--radius-karte);
  border-radius: var(--radius-karte) var(--radius-karte) 0 0;
  background: linear-gradient(var(--signal) 0 2px, transparent 2px);
}

.paket--hervorgehoben {
  box-shadow: var(--schatten-hoch);
}

.paket__badge {
  position: absolute;
  top: -0.75rem;
  left: var(--paket-luft, var(--raum-5));
  z-index: 1;
  padding: 0.25rem 0.625rem;
  border-radius: 999px;
  background: var(--signal);
  color: #ffffff;
  font-family: var(--schrift-mono);
  font-size: var(--gr-mini);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.paket__name {
  font-size: var(--gr-h3);
  font-weight: 700;
  margin-bottom: var(--raum-1);
}

.paket__preis {
  font-family: var(--schrift-mono);
  font-size: clamp(1.5rem, 1.3rem + 0.9vw, 2rem);
  font-weight: 500;
  margin-bottom: var(--raum-3);
}

.paket__liste {
  list-style: none;
  display: grid;
  gap: var(--raum-1);
  margin-bottom: var(--raum-4);
}

.paket__liste li {
  position: relative;
  padding-left: 1.5rem;
  font-size: var(--gr-klein);
  color: var(--tinte-leise);
}

.paket__liste li::before {
  content: '+';
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--schrift-mono);
  font-weight: 500;
  color: var(--signal);
}

.paket .knopf {
  margin-top: auto;
}

/* Reihe 1: die vier Website-Pakete nebeneinander. Vier Spalten passen bei
   1140px Inhaltsbreite gerade eben – deshalb steht hier eine feste
   Spaltenzahl statt auto-fit, das bei 260px Mindestbreite auf drei
   Spalten umbrechen würde. Darunter erst 2x2, am Handy gestapelt. */
.paket-gitter--vier {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  --paket-luft: var(--raum-4);
}

/* In vier Spalten ist für die große Preisstufe kein Platz: "auf Anfrage"
   liefe sonst aus der Karte. Eine Stufe kleiner, sonst unverändert. */
.paket-gitter--vier .paket__preis {
  font-size: clamp(1.25rem, 1rem + 0.8vw, 1.625rem);
}

@media (max-width: 1040px) {
  .paket-gitter--vier {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    --paket-luft: var(--raum-5);
  }

  .paket-gitter--vier .paket__preis {
    font-size: clamp(1.5rem, 1.3rem + 0.9vw, 2rem);
  }
}

@media (max-width: 620px) {
  .paket-gitter--vier {
    grid-template-columns: 1fr;
  }
}

/* Reihe 2: die beiden Sichtbarkeits-Bausteine. Gleiche Karte, eine Stufe
   kompakter – die Website bleibt sichtbar das Hauptprodukt. */
.paket-gitter--zwei {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-bottom: var(--raum-3);
}

@media (max-width: 720px) {
  .paket-gitter--zwei {
    grid-template-columns: 1fr;
  }
}

.paket--baustein {
  --paket-luft: var(--raum-4);
}

/* Die Preiszeile eines Bausteins ist ein Satz, keine einzelne Zahl:
   "Einrichtung 290 € · dann 79 €/Monat". In der großen Preisstufe wäre sie
   ein Balken quer durch die Karte. Also Mono in Fließtextgröße, mit
   Zeilenhöhe zum Umbrechen – der Rest der Karte bleibt, wie er ist. */
.paket--baustein .paket__preis {
  font-size: var(--gr-gross);
  line-height: 1.45;
  color: var(--signal);
}

.bausteine__intro {
  max-width: 68ch;
  margin-top: calc(var(--raum-3) * -1);
  margin-bottom: var(--raum-4);
}

/* Die Kombi-Zeile unter den Bausteinen: dezent hervorgehoben, aber keine
   weitere Karte – eine flache Tönung in Signalblau mit dem Plus-Marker der
   Leistungslisten davor. Sie soll auffallen, ohne mit den Karten darüber
   um Aufmerksamkeit zu streiten. */
.kombi-zeile {
  position: relative;
  max-width: none;
  margin: 0;
  padding: var(--raum-2) var(--raum-3) var(--raum-2) calc(var(--raum-3) + 1.5rem);
  border-radius: var(--radius-gross);
  background: color-mix(in srgb, var(--signal) 7%, transparent);
  font-size: var(--gr-klein);
  color: var(--tinte);
}

.kombi-zeile::before {
  content: '+';
  position: absolute;
  left: var(--raum-3);
  font-family: var(--schrift-mono);
  font-weight: 500;
  color: var(--signal);
}

/* Der Preisabschnitt am Ende von /google-unternehmensprofil und
   /automatisierung: dieselbe Mono-Preiszeile wie in den Baustein-Karten,
   aber offen im Satzspiegel über einer feinen Linie – auf diesen Seiten
   gibt es keine Karten. */
.preis-block {
  max-width: 68ch;
  padding-top: var(--raum-4);
  border-top: 1px solid var(--linie);
}

.preis-block__zeile {
  margin-bottom: var(--raum-2);
  font-family: var(--schrift-mono);
  font-size: var(--gr-gross);
  font-weight: 500;
  line-height: 1.45;
  color: var(--signal);
}

/* 8.5 Kontakt: Formular links, Kontaktwege rechts --------------------------- */

.kontakt__raster {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: var(--raum-6);
  align-items: start;
}

.formular {
  display: grid;
  gap: var(--raum-3);
}

.feld {
  display: grid;
  gap: 0.375rem;
}

.feld__label {
  font-size: var(--gr-klein);
  font-weight: 500;
}

.feld__hinweis {
  margin: 0;
  font-family: var(--schrift-mono);
  font-size: var(--gr-mini);
  letter-spacing: 0.04em;
  color: var(--tinte-leise);
}

.eingabe {
  width: 100%;
  padding: 0.7rem 0.875rem;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius-feld);
  font: inherit;
  color: var(--tinte);
  transition: border-color var(--dauer-inter) var(--kurve-aus),
    box-shadow var(--dauer-inter) var(--kurve-aus);
}

/* Ein Feld hebt sich nicht an – es liegt im Papier, es steht nicht darauf.
   Beim Überfahren wird nur seine Kante deutlicher. */
@media (hover: hover) and (pointer: fine) {
  .eingabe:hover {
    border-color: color-mix(in srgb, var(--tinte-leise) 45%, var(--linie));
  }
}

textarea.eingabe {
  resize: vertical;
  min-height: 8rem;
}

/* Ankreuzfelder: Kästchen und Beschriftung nebeneinander */
.feld--ankreuzen {
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--raum-1);
}

.feld--ankreuzen input[type='checkbox'] {
  width: 18px;
  height: 18px;
  margin: 0.15rem 0 0;
  accent-color: var(--signal);
}

.feld--ankreuzen .feld__label {
  font-weight: 400;
}

/* Am Handy: Kästchen etwas größer und die Beschriftung – die ebenfalls
   ankreuzt – auf 44 Pixel Höhe gebracht. So ist der Treffbereich groß
   genug, ohne dass das Formular anders aussieht. */
@media (max-width: 900px) {
  .feld--ankreuzen input[type='checkbox'] {
    width: 24px;
    height: 24px;
    margin-top: 0.6rem;
  }

  /* Bewusst display: block – die Datenschutz-Beschriftung enthält einen
     Link im Fließtext, der in einem Flex-Kasten in eine eigene Zeile
     rutschen würde. */
  .feld--ankreuzen .feld__label {
    display: block;
    min-height: 44px;
    padding-block: 0.55rem;
  }
}

/* Das unsichtbare Feld gegen Spam: weit außerhalb des Bildes, für
   Screenreader ausgeblendet, nicht per Tab erreichbar. */
.honigtopf {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.formular__senden {
  margin: 0;
}

/* Meldung direkt am Feld: unter der Eingabe, in der Fehlerfarbe. */
.feld__fehler {
  margin: 0;
  font-size: var(--gr-klein);
  font-weight: 500;
  color: var(--fehler);
}

/* Beim Ankreuzfeld steht die Meldung unter der Beschriftung, nicht unter
   dem Kästchen (zweite Rasterspalte). */
.feld--ankreuzen .feld__fehler {
  grid-column: 2;
}

/* Fehlerhafte Eingaben bekommen zusätzlich einen deutlichen Rand –
   Farbe allein reicht als Hinweis nicht. */
.eingabe[aria-invalid='true'] {
  border-color: var(--fehler);
  box-shadow: inset 0 0 0 1px var(--fehler);
}

/* Allgemeine Meldung (z.B. Verbindung weg) oberhalb des Sende-Knopfs:
   kein Kasten, sondern ein kräftiger Strich links am Text. */
.formular__fehler {
  margin: 0;
  padding-left: var(--raum-2);
  border-left: 3px solid var(--fehler);
  font-size: var(--gr-klein);
  font-weight: 500;
  color: var(--fehler);
}

/* Deutliche Erfolgsmeldung anstelle des abgeschickten Formulars – ebenfalls
   ohne Fläche, nur mit einer kräftigen Signal-Linie darüber. */
.formular__erfolg {
  padding-top: var(--raum-3);
  border-top: 2px solid var(--signal);
}

.formular__erfolg:focus {
  outline: none;
}

.formular__erfolg-titel {
  font-size: var(--gr-h3);
  margin-bottom: var(--raum-1);
}

/* Kein Kasten neben dem Formular, sondern eine offene Spalte: eine kräftige
   Kopflinie oben, darunter die Kontaktwege durch feine Linien getrennt. */
.kontaktwege {
  display: grid;
  gap: var(--raum-3);
  align-content: start;
  padding-top: var(--raum-3);
  border-top: 2px solid var(--tinte);
}

.kontaktwege__titel {
  font-size: var(--gr-h3);
  margin: 0;
}

.kontaktwege__liste {
  display: grid;
  gap: var(--raum-2);
  margin: 0;
}

.kontaktwege__liste > div + div {
  padding-top: var(--raum-2);
  border-top: 1px solid var(--linie);
}

.kontaktwege__wert {
  margin: 0;
}

.kontaktwege__wert .feld__hinweis {
  display: block;
  margin-top: 0.15rem;
}

.kontaktwege__check {
  margin: 0;
  padding-top: var(--raum-3);
  border-top: 1px solid var(--linie);
  font-size: var(--gr-klein);
  color: var(--tinte-leise);
}

@media (max-width: 860px) {
  .kontakt__raster {
    grid-template-columns: 1fr;
    gap: var(--raum-4);
  }
}

/* 8.6 Rechtstext (Impressum, Datenschutz) ----------------------------------- */

.rechtstext {
  max-width: 68ch;
  padding-bottom: var(--sektion);
}

.rechtstext h2 {
  font-size: var(--gr-h3);
  margin: var(--raum-5) 0 var(--raum-2);
}

.rechtstext p {
  color: var(--tinte-leise);
}

/* 8.7 /ueber-mich – eine reine Textseite ----------------------------------
   Kein Bild, keine Karten: Die Seite wird allein von der Typografie
   getragen. Eine große Überschrift, darunter eine einzige schmale
   Textspalte. Die Absätze stehen nicht in Kästen, sondern werden nur
   durch je eine feine Linie voneinander getrennt – dieselbe Linie wie
   überall sonst auf der Website.

   Die Spalte ist bewusst schmal (rund 60 Zeichen): Das ist die Breite,
   bei der das Auge am Zeilenende ohne Suchen in die nächste Zeile
   findet. */

.ueber-mich {
  max-width: 60ch;
}

.ueber-mich__titel {
  /* Auf breiten Bildschirmen bricht die Zeile dadurch früh um und die
     Überschrift steht als kompakter Block über dem Text. */
  max-width: 15ch;
  margin-bottom: var(--raum-6);
}

.ueber-mich__absatz {
  margin: 0;
  max-width: none;
  font-size: var(--gr-gross);
  color: var(--tinte-leise);
}

/* Der Auftakt: eine Stufe größer als der übrige Fließtext und im vollen
   Tintenton – er zieht den Blick in den Text hinein. */
.ueber-mich__absatz--auftakt {
  font-size: var(--gr-h3);
  line-height: 1.5;
  color: var(--tinte);
}

/* Die Trennung zwischen zwei Absätzen: gleich viel Luft ober- und
   unterhalb der Linie, damit sie ruhig in der Mitte sitzt. */
.ueber-mich__absatz + .ueber-mich__absatz {
  margin-top: var(--raum-5);
  padding-top: var(--raum-5);
  border-top: 1px solid var(--linie);
}

/* Der Schlusssatz bekommt mehr Luft als die Absätze untereinander: Er
   gehört schon zum Knopf, nicht mehr zum Text davor. */
.ueber-mich__abschluss {
  margin: var(--raum-8) 0 var(--raum-4);
  padding-top: var(--raum-8);
  border-top: 1px solid var(--linie);
  font-size: var(--gr-h3);
  font-weight: 600;
  line-height: 1.3;
  color: var(--tinte);
}

/* 8.8 Vorher/Nachher-Regler (nur auf /websites) -----------------------------
   Zwei Beispiel-Seiten liegen deckungsgleich übereinander. Der Regler ändert
   eine einzige Zahl – --pos. Daran hängen zwei Dinge:

   1. clip-path an der neuen Fassung: Sie wird links abgeschnitten. Ihre
      Breite bleibt dabei unverändert, es wird nur weniger von ihr gezeichnet.
      Deshalb bricht beim Ziehen nichts um und nichts springt.
   2. transform an der Hülle von Naht und Griff: beide wandern zusammen.

   Beide Ansichten liegen mit inset: 0 in derselben Bühne und sind dadurch
   zwangsläufig exakt gleich hoch. Die Bühne selbst hat eine feste Höhe.
   -------------------------------------------------------------------------- */

.vergleich__kopf {
  max-width: 68ch;
}

.vergleich__intro {
  max-width: 62ch;
  margin-bottom: 0;
}

/* Die Bühne ist zugleich Messlatte ("container"): Alles darin rechnet in
   cqw – also in Prozent IHRER Breite, nicht der Fensterbreite. Dadurch
   wachsen Schriften und Abstände der Beispiel-Seiten mit der Bühne mit,
   statt an Bildschirm-Haltepunkten zu springen. */
.vergleich__buehne {
  container-type: inline-size;
  margin-top: var(--raum-5);
}

.vergleich__bild {
  /* Die Reglerstellung. Nur diese Zahl ändert sich beim Ziehen. */
  --pos: 50%;

  /* Maßeinheit der beiden Beispiel-Seiten: ihre Grundschriftgröße. Sie
     wächst mit der Bühnenbreite mit, wird aber nie kleiner als 10,5 und nie
     größer als 15 Pixel. Jede Größe darin ist ein Vielfaches davon – so
     bleiben die Verhältnisse bei jeder Breite dieselben. */
  --e: clamp(10.5px, calc(5.9px + 0.8cqw), 15px);

  position: relative;
  height: clamp(350px, calc(203px + 23.8cqw), 475px);
  overflow: hidden;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius-gross);
  box-shadow: 0 1px 2px rgba(18, 25, 27, 0.05), 0 24px 60px rgba(18, 25, 27, 0.1);
  /* Senkrecht wischen soll die Seite weiterscrollen, waagerecht den Regler
     bewegen. Genau das erlaubt pan-y. */
  touch-action: pan-y;
  cursor: ew-resize;
  /* Beim Ziehen soll sich kein Text markieren. */
  user-select: none;
  -webkit-user-select: none;
}

.vergleich__seite {
  position: absolute;
  inset: 0;
  /* Jede Ansicht ist eine eigene Ebene für sich. Ohne das würde das Etikett
     mit seinem z-index aus der unteren Ansicht herausragen und auch dann
     noch über der neuen Fassung stehen, wenn die alte längst weggeschnitten
     ist. */
  isolation: isolate;
}

.vergleich__seite--neu {
  clip-path: inset(0 0 0 var(--pos));
}

/* Naht und Griff stecken in einer Hülle, die über die ganze Bühne reicht.
   Ein Prozentwert bei translate rechnet gegen die eigene Breite – und die
   ist genau die Bühnenbreite. So verschiebt EIN transform beides zugleich,
   ohne dass der Browser irgendetwas neu umbrechen muss. */
.vergleich__regler {
  position: absolute;
  inset: 0;
  transform: translate3d(var(--pos), 0, 0);
  /* Die Hülle liegt über der ganzen Bühne – Zeiger gehen durch sie hindurch,
     nur der Griff selbst nimmt sie an. */
  pointer-events: none;
}

.vergleich__naht {
  position: absolute;
  top: 0;
  bottom: 0;
  left: -1px;
  width: 2px;
  background: var(--signal);
  /* Haarfeine helle Linie an beiden Seiten: Damit steht die Naht sowohl auf
     dem Grau der alten als auch auf dem Anthrazit der neuen Fassung. */
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.72);
}

/* Der Glanz: ein schmaler heller Schimmer, der beidseits der Naht ausläuft.
   Er sitzt fest an der Naht und wandert im selben transform mit ihr mit –
   er kostet also keine eigene Bewegung. Beim Ziehen wird er kräftiger;
   verändert wird dabei ausschließlich opacity. */
.vergleich__naht::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 26px;
  margin-left: -13px;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.14) 40%,
    rgba(255, 255, 255, 0.58) 50%,
    rgba(255, 255, 255, 0.14) 60%,
    rgba(255, 255, 255, 0) 100%
  );
  opacity: 0.5;
  transition: opacity var(--dauer-inter) var(--kurve-aus);
  pointer-events: none;
}

.vergleich__bild[data-zieht="ja"] .vergleich__naht::before {
  opacity: 1;
}

.vergleich__griff {
  position: absolute;
  top: 50%;
  left: 0;
  /* 44 Pixel: die kleinste Fläche, die man am Handy sicher trifft. Gesetzt
     wird die Lage über margin, damit transform für das Wachsen beim
     Überfahren frei bleibt. */
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--signal);
  color: #ffffff;
  pointer-events: auto;
  cursor: grab;
  /* Auf dem Griff selbst darf auch senkrechtes Wischen ziehen, nicht
     scrollen – sonst rutscht man beim Greifen ab. */
  touch-action: none;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.92), 0 2px 6px rgba(18, 25, 27, 0.2),
    0 10px 24px rgba(18, 25, 27, 0.22);
  transition: transform var(--dauer-inter) var(--kurve-feder),
    background-color var(--dauer-inter) var(--kurve-aus);
}

.vergleich__griff:hover,
.vergleich__griff:focus-visible {
  transform: scale(1.08);
  background: var(--signal-dunkel);
}

/* Der Fokusring folgt jetzt der eigenen Rundung; hier bleibt nur der
   größere Abstand, damit der Ring den runden Griff nicht berührt. */
.vergleich__griff:focus-visible {
  outline-offset: 4px;
}

.vergleich__pfeile {
  width: 22px;
  height: 12px;
}

/* Solange gezogen wird: Griff etwas größer, Zeiger als geschlossene Hand,
   und der Browser bekommt den Hinweis, dass sich der Beschnitt gleich
   dauernd ändert – dann hält er die Fläche dafür bereit. */
.vergleich__bild[data-zieht='ja'] {
  cursor: grabbing;
}

.vergleich__bild[data-zieht='ja'] .vergleich__griff {
  transform: scale(1.12);
  cursor: grabbing;
  background: var(--signal-dunkel);
}

.vergleich__bild[data-zieht='ja'] .vergleich__seite--neu {
  will-change: clip-path;
}

/* Beim Ziehen wandert zusätzlich das Foto der neuen Fassung um wenige Pixel
   gegenläufig mit. Auch das ist nur ein transform – eine eigene Ebene, die
   der Browser verschieben kann, ohne irgendetwas neu zu zeichnen. */
.vergleich__bild[data-zieht="ja"] .wb__bild {
  will-change: transform;
}

/* Tastatur: Die Pfeiltasten springen in 5-Prozent-Schritten. Damit der
   Sprung nicht hart wirkt, gleitet der Regler dorthin – aber nur bei
   Tastatur-Bedienung. Beim Ziehen wäre jede Verzögerung störend, deshalb
   nimmt das Skript diese Markierung dort sofort wieder weg. */
.vergleich__bild[data-weich='ja'] .vergleich__seite--neu {
  transition: clip-path 160ms var(--kurve-aus);
}

.vergleich__bild[data-weich='ja'] .vergleich__regler,
.vergleich__bild[data-weich="ja"] .wb__bild {
  transition: transform 160ms var(--kurve-aus);
}

/* Die beiden Etiketten gehören zum Vergleichswerkzeug, nicht zu den
   abgebildeten Seiten – deshalb wachsen sie nicht mit, sondern behalten die
   Größe unserer Mono-Labels. Sie sitzen in den äußeren Ecken der
   Fensterleiste – dort verdecken sie in keiner der beiden Ansichten etwas.
   Jedes steckt dabei in seiner Ansicht: Zieht man den Regler ganz nach
   links, verschwindet "VORHER" zusammen mit der alten Fassung. */
.vergleich__etikett {
  position: absolute;
  top: calc(var(--e) * 1.25);
  transform: translateY(-50%);
  z-index: 2;
  padding: 4px 8px;
  border-radius: 2px;
  background: rgba(18, 25, 27, 0.82);
  color: var(--grundton);
  font-family: var(--schrift-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  line-height: 1;
  white-space: nowrap;
}

.vergleich__etikett--links {
  left: 12px;
}

.vergleich__etikett--rechts {
  right: 12px;
}

/* 8.8.1 Der Browser-Rahmen -------------------------------------------------
   Beide Ansichten stecken im selben Rahmen mit identischer Geometrie:
   gleiche Leistenhöhe, dieselbe Adresspille an derselben Stelle. Nur der Inhalt
   der Adresszeile unterscheidet sich – http mit Warnhinweis gegenüber https
   mit Schloss. Beim Ziehen wirkt es dadurch wie ein Fenster, in dem die
   Seite wechselt.
   -------------------------------------------------------------------------- */

.fenster {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--flaeche);
}

.fenster__leiste {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  height: calc(var(--e) * 2.5);
  /* Links und rechts bleibt Platz für die Etiketten. Weil die ihre Größe
     nicht mitwachsen lassen, ist auch dieser Rand ein fester Wert. Er ist in
     beiden Ansichten gleich groß, damit die Adresspille exakt an derselben
     Stelle steht – über der Naht darf keine Kante springen. */
  padding-inline: 92px;
  background: var(--grundton);
  border-bottom: 1px solid var(--linie);
}

/* Feste Breite statt mitwachsender: Beide Adressen sind unterschiedlich lang,
   die Pillen müssen aber deckungsgleich liegen. Die längere wird gekürzt. */
.fenster__adresse {
  display: flex;
  align-items: center;
  gap: calc(var(--e) * 0.35);
  flex: 0 0 auto;
  min-width: 0;
  width: min(calc(var(--e) * 26), 100%);
  height: calc(var(--e) * 1.55);
  padding-inline: calc(var(--e) * 0.65);
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: 999px;
  font-family: var(--schrift-mono);
  font-size: calc(var(--e) * 0.8);
  color: var(--tinte-leise);
}

.fenster__zeichen {
  flex: none;
  width: calc(var(--e) * 0.85);
  height: calc(var(--e) * 0.85);
}

/* "Nicht sicher" ist eine Zustandsmeldung, kein Markenelement – deshalb
   steht dafür dieselbe funktionale Warnfarbe wie bei Formularfehlern. Die
   Adresse selbst bleibt ruhig grau. */
/* Die unsichere Adresszeile bekommt zusätzlich einen leichten Warnton. An der
   Naht trifft dadurch nicht nur anderer Text, sondern eine sichtbar andere
   Fläche aufeinander – man sieht: zwei Browser, nicht ein zerrissener Text. */
.fenster__adresse--unsicher {
  background: color-mix(in srgb, var(--fehler) 5%, #ffffff);
  border-color: color-mix(in srgb, var(--fehler) 28%, var(--linie));
}

.fenster__adresse--unsicher .fenster__zeichen,
.fenster__adresse--unsicher .fenster__hinweis {
  color: var(--fehler);
}

.fenster__hinweis {
  flex: none;
  padding-right: calc(var(--e) * 0.3);
  border-right: 1px solid var(--linie);
  white-space: nowrap;
}

.fenster__url {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fenster__flaeche {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

/* 8.8.2 Die alte Fassung ---------------------------------------------------
   Nachgebaut, wie veraltete Betriebs-Websites tatsächlich aussehen: eine
   schmale weiße Spalte mittig auf grauem Grund, ein Farbverlauf als
   Kopfbalken, ein Schriftzug mit Schlagschatten, blau unterstrichene Links
   mit senkrechten Strichen dazwischen, ein Clipart neben dem Willkommenstext,
   die Öffnungszeiten in einem schief gesetzten Kasten und im Fuß ein
   Besucherzähler samt Browser-Hinweis.

   WICHTIG: Die Farben und Schriften in diesem Block gehören zur
   ABGEBILDETEN fremden Website, nicht zu unserem Design-System. Sie sind
   deshalb streng auf .alt* begrenzt und kommen nirgends sonst vor. Times,
   Arial und Courier sind auf jedem Rechner vorhanden – es wird keine Datei
   nachgeladen.
   -------------------------------------------------------------------------- */

.alt {
  --alt-blau: #0018a8;
  --alt-besucht: #551a8b;
  --alt-rand: #a9aeb2;

  height: 100%;
  padding: calc(var(--e) * 1) calc(var(--e) * 1.2);
  background: #e6e6e2;
  font-family: Arial, Helvetica, sans-serif;
  font-size: calc(var(--e) * 0.9);
  line-height: 1.3;
  color: #1a1a1a;
  overflow: hidden;
}

.alt__blatt {
  display: flex;
  flex-direction: column;
  width: 68%;
  height: 100%;
  margin-inline: auto;
  background: #ffffff;
  border: 1px solid var(--alt-rand);
}

.alt__banner {
  flex: none;
  padding: calc(var(--e) * 0.8) calc(var(--e) * 0.8);
  background: linear-gradient(180deg, #6a7a86 0%, #48565f 48%, #333e46 100%);
  border-bottom: 1px solid #262f36;
  color: #ffffff;
  text-align: center;
}

/* Der Schlagschatten am Schriftzug: das Erkennungszeichen der Banner, die
   damals in einem Bildprogramm zusammengesetzt wurden. */
.alt__banner-titel {
  display: block;
  font-family: 'Times New Roman', Times, serif;
  font-size: calc(var(--e) * 1.75);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.01em;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.55), 3px 3px 3px rgba(0, 0, 0, 0.35);
}

.alt__banner-zusatz {
  display: block;
  margin-top: 3px;
  font-family: 'Times New Roman', Times, serif;
  font-style: italic;
  font-size: calc(var(--e) * 0.92);
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.4);
}

.alt__navi {
  flex: none;
  padding: calc(var(--e) * 0.4) calc(var(--e) * 0.5);
  background: #dcdcd6;
  border-bottom: 1px solid var(--alt-rand);
  font-size: calc(var(--e) * 0.82);
  line-height: 1.5;
  text-align: center;
}

.alt__link {
  color: var(--alt-blau);
  text-decoration: underline;
}

/* Ein besuchter Link steht violett – das kleine Detail, an dem man alte
   Seiten sofort erkennt. */
.alt__link--besucht {
  color: var(--alt-besucht);
}

.alt__trenner {
  padding-inline: calc(var(--e) * 0.3);
  color: #777777;
}

.alt__inhalt {
  flex: 1;
  min-height: 0;
  padding: calc(var(--e) * 0.85) calc(var(--e) * 0.8);
  overflow: hidden;
}

.alt__titel {
  margin: 0 0 calc(var(--e) * 0.6);
  font-family: 'Times New Roman', Times, serif;
  font-size: calc(var(--e) * 1.3);
  font-weight: 700;
  line-height: 1.15;
  color: #333e46;
  text-align: center;
}

.alt__tabelle {
  display: grid;
  grid-template-columns: 1fr calc(var(--e) * 12.5);
  gap: calc(var(--e) * 0.9);
  align-items: start;
}

/* Das Clipart steht im Text – umflossen, mit dem winzigen Versatz, den
   niemand nachjustiert hat. */
.alt__clipart {
  float: left;
  width: calc(var(--e) * 2.7);
  height: calc(var(--e) * 2.7);
  margin: 1px calc(var(--e) * 0.5) calc(var(--e) * 0.1) 0;
}

.alt__absatz {
  margin: 0 0 calc(var(--e) * 0.5);
  text-align: justify;
  hyphens: auto;
}

.alt__absatz:last-child {
  margin-bottom: 0;
}

/* Der Öffnungszeiten-Kasten steht bewusst schief: ein Rahmen im Rahmen, der
   Rahmenstil "outset" von damals, und Zeilen, deren Zeiten nicht bündig
   untereinander stehen. */
.alt__kasten {
  padding: calc(var(--e) * 0.28);
  background: #f2f2ee;
  border: 2px outset #c8c8c2;
  font-size: calc(var(--e) * 0.82);
}

.alt__kasten-innen {
  padding: calc(var(--e) * 0.32) calc(var(--e) * 0.38);
  border: 1px solid #4a4a4a;
}

.alt__kasten-titel {
  margin: 0 0 calc(var(--e) * 0.32);
  padding-bottom: 2px;
  border-bottom: 1px solid #4a4a4a;
  font-weight: 700;
  text-align: center;
}

/* Kein space-between: Die Zeit beginnt direkt hinter dem Tag, also bei jeder
   Zeile woanders. Genau so sahen diese Kästen aus. */
.alt__zeit {
  display: flex;
  gap: calc(var(--e) * 0.4);
  padding-block: 1px;
}

.alt__zeit span {
  white-space: nowrap;
}

.alt__zeit--schief {
  padding-left: calc(var(--e) * 0.85);
  font-style: italic;
}

.alt__fuss {
  flex: none;
  padding: calc(var(--e) * 0.45) calc(var(--e) * 0.8) calc(var(--e) * 0.6);
  border-top: 1px solid var(--alt-rand);
  font-size: calc(var(--e) * 0.76);
  color: #555555;
  text-align: center;
}

/* Der Besucherzähler: grüne Ziffern auf schwarzen Kästchen, wie die
   Zählerbildchen, die man sich damals eingebunden hat. */
.alt__zaehler {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--e) * 0.35);
  margin: 0 0 calc(var(--e) * 0.3);
  font-size: calc(var(--e) * 0.72);
  color: #444444;
}

.alt__ziffern {
  display: inline-flex;
  gap: 1px;
}

.alt__ziffer {
  display: inline-block;
  min-width: calc(var(--e) * 0.6);
  padding: 1px 2px;
  background: #101010;
  border: 1px solid #6d6d6d;
  color: #33ff33;
  font-family: 'Courier New', Courier, monospace;
  font-size: calc(var(--e) * 0.68);
  line-height: 1.15;
  text-align: center;
}

.alt__fuss-zeile {
  margin: 0;
}

/* 8.8.3 Die neue Fassung – "Werkstatt Brandt" ------------------------------
   Der Auftritt eines fremden Betriebs, ausdrücklich KEIN Ableger dieser
   Website. Er teilt mit unserem Design-System nichts:

     Farbe    kühles Anthrazit bis Schwarzblau statt hellem Grundton,
              Bernstein statt Signalblau – und Bernstein nur als schmaler
              Akzent (Knopf, ein Wort, die Trennstriche), nie als Fläche.
     Form     durchweg kantig, kein einziger runder Radius, keine Karten.
     Schrift  schmal laufende Versalien (Archivo auf der schmalen Seite
              seiner Breitenachse, 87,5 %) statt unserer breiten Wortmarke
              mit 125 %; kein kursives Serifenwort als Akzent, kein Mono.
     Aufbau   ein formatfüllendes Foto über der oberen Hälfte, darauf
              Kopfzeile und Überschrift – statt einer zentrierten Textmitte.

   Gesucht ist "seriöse Meisterwerkstatt", ausdrücklich nicht
   "Tuning/Motorsport": kein Rennstreifen, kein Karbonmuster, keine
   Geschwindigkeits-Metaphorik, kein warmes Braunschwarz.

   Alle Werte sind streng auf .wb* begrenzt und kommen nirgends sonst vor.
   Kontraste auf dem Anthrazit: Bernstein 9,2:1, gedämpfter Text 7,1:1,
   dunkler Text auf dem Bernstein-Knopf 9,8:1.
   -------------------------------------------------------------------------- */

.wb {
  --wb-tief: #070a0e;
  --wb-nacht: #0d131b;
  --wb-kante: #1d2731;
  --wb-hell: #eef2f6;
  --wb-leise: #93a1b1;
  --wb-bernstein: #f0a92c;
  /* Spielraum links und rechts, damit der Parallax-Versatz des Fotos an
     keiner Seite eine Kante freilegt. */
  --wb-spiel: 24px;

  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--wb-tief);
  font-family: var(--schrift-text);
  font-size: calc(var(--e) * 0.95);
  line-height: 1.5;
  color: var(--wb-hell);
  overflow: hidden;
}

/* Die obere Hälfte: Foto, Schleier, Kopfzeile und Überschrift in einer
   einzigen Bühne. Kopfzeile oben, Überschrift unten. */
.wb__buehne {
  position: relative;
  /* Das Foto nimmt den größeren Teil der Höhe. Zwei Gründe: Darunter bleibt
     dadurch keine große leere schwarze Fläche mehr stehen, und der
     Reglergriff – er sitzt auf halber Höhe der ganzen Bühne – liegt sicher
     im Foto statt auf der Signalleiste darunter. */
  flex: 0 0 61%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  background: var(--wb-nacht);
}

/* Das Foto liegt in einem Kasten, der links und rechts über die Bühne
   hinausragt. Nur dieser Kasten wird beim Ziehen verschoben – ein einziges
   transform, sonst nichts. Ohne Skript steht er auf 0. */
.wb__bild {
  position: absolute;
  inset: 0 calc(var(--wb-spiel) * -1);
  transform: translate3d(var(--wb-versatz, 0px), 0, 0);
  /* Die Halle: dunkler Raum mit einem Lichtkegel über der Mitte. Sie liegt
     hinter dem Foto und ist im Normalfall unsichtbar – sie trägt die Fläche,
     solange das Foto noch lädt, und sie ist der Hintergrund der
     Ersatz-Silhouette, wenn gar keine Bilddatei vorliegt. */
  background: radial-gradient(
    120% 95% at 50% 30%,
    #26313e 0%,
    #131b24 44%,
    #070b10 100%
  );
}

/* cover statt contain und ohne repeat: Das Bild füllt die Fläche aus, wird
   dabei beschnitten, aber nie verzerrt und nie gekachelt. Der Bildausschnitt
   liegt deutlich oberhalb der Mitte: Dort steht das angehobene Fahrzeug über
   dem Monteur – das Bild erzählt damit die Werkstatt, nicht nur den Raum. */
/* Das Foto steckt in einem <picture>, damit der Browser zuerst die kleinere
   WebP-Fassung nehmen kann. Dieser Rahmen darf am Layout nichts ändern: Er
   übernimmt exakt die Maße, die vorher das Bild selbst hatte – sonst hätte
   das Bild darin keine Höhe mehr, an der sich "height: 100%" ausrichten
   kann, und die Fläche bliebe leer. */
.wb__rahmen {
  display: block;
  width: 100%;
  height: 100%;
}

.wb__foto {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 32%;
}

/* Die Ersatz-Silhouette ist gezeichnet, kein Bild: object-fit greift bei ihr
   nicht, das Verhältnis regelt preserveAspectRatio im SVG selbst. Sie steht
   mittig auf dem Hallenverlauf des Bildkastens. */
.wb__ersatz {
  display: block;
  width: 100%;
  height: 100%;
}

/* Der Schleier: oben kräftig, nach unten durchsichtig – so verlangt es die
   Kopfzeile. Weil die Überschrift am UNTEREN Rand des Fotos steht, kommt
   ein zweiter, schwächerer Verlauf von unten dazu; ohne ihn stünde die
   Headline auf ungeschütztem Bild. Ein drittes, sehr flaches Feld von links
   fängt helle Stellen hinter dem Fließtext ab. Alles in einem Element,
   also ein einziger Farbauftrag. */
.wb__schleier {
  position: absolute;
  inset: 0;
  background: linear-gradient(
      180deg,
      rgba(7, 10, 14, 0.94) 0%,
      rgba(7, 10, 14, 0.52) 28%,
      rgba(7, 10, 14, 0.1) 60%,
      rgba(7, 10, 14, 0) 82%
    ),
    linear-gradient(
      0deg,
      rgba(7, 10, 14, 0.9) 0%,
      rgba(7, 10, 14, 0.42) 26%,
      rgba(7, 10, 14, 0) 58%
    ),
    linear-gradient(90deg, rgba(7, 10, 14, 0.44) 0%, rgba(7, 10, 14, 0) 58%);
}

.wb__kopf {
  position: relative;
  display: flex;
  align-items: center;
  gap: calc(var(--e) * 1.2);
  flex: none;
  padding: calc(var(--e) * 0.85) calc(var(--e) * 1.35);
}

.wb__marke {
  font-family: var(--schrift-display);
  font-weight: 700;
  font-stretch: 87.5%;
  font-variation-settings: 'wdth' 87.5;
  font-size: calc(var(--e) * 0.95);
  letter-spacing: 0.17em;
  line-height: 1;
  color: #ffffff;
  white-space: nowrap;
}

.wb__navi {
  display: flex;
  gap: calc(var(--e) * 1.15);
  margin-left: auto;
  font-family: var(--schrift-display);
  font-weight: 500;
  font-stretch: 87.5%;
  font-variation-settings: 'wdth' 87.5;
  font-size: calc(var(--e) * 0.72);
  letter-spacing: 0.13em;
  line-height: 1;
  text-transform: uppercase;
  color: rgba(238, 242, 246, 0.86);
  white-space: nowrap;
}

/* Der einzige Bernstein-Fleck der Kopfzeile. Kantig, ohne Rundung. */
.wb__knopf {
  display: inline-flex;
  align-items: center;
  flex: none;
  padding: calc(var(--e) * 0.45) calc(var(--e) * 0.95);
  border-radius: 0;
  background: var(--wb-bernstein);
  color: var(--wb-tief);
  font-family: var(--schrift-display);
  font-weight: 700;
  font-stretch: 87.5%;
  font-variation-settings: 'wdth' 87.5;
  font-size: calc(var(--e) * 0.72);
  letter-spacing: 0.11em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

.wb__hero {
  position: relative;
  flex: none;
  padding: 0 calc(var(--e) * 1.35) calc(var(--e) * 1.15);
  max-width: calc(var(--e) * 33);
}

/* Die schwere Versal-Headline. Schmal laufend, eng gesetzt, ohne jede
   Schräge oder Verzerrung – der Text steht, er rast nicht. */
.wb__titel {
  margin: 0;
  font-family: var(--schrift-display);
  font-weight: 700;
  font-stretch: 87.5%;
  font-variation-settings: 'wdth' 87.5;
  font-size: calc(var(--e) * 2.25);
  line-height: 0.96;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  color: #ffffff;
  text-wrap: balance;
  text-shadow: 0 1px 20px rgba(7, 10, 14, 0.55);
}

.wb__text {
  margin: calc(var(--e) * 0.55) 0 0;
  max-width: calc(var(--e) * 28);
  font-size: calc(var(--e) * 0.87);
  line-height: 1.45;
  color: rgba(238, 242, 246, 0.9);
  text-shadow: 0 1px 12px rgba(7, 10, 14, 0.6);
}

.wb__knopf--gross {
  margin-top: calc(var(--e) * 0.85);
  padding: calc(var(--e) * 0.6) calc(var(--e) * 1.2);
  font-size: calc(var(--e) * 0.8);
}

/* Die schmale Signalleiste: drei Vertrauensangaben in Versalien, getrennt
   durch dünne senkrechte Bernstein-Striche. Die erste Angabe ist das eine
   hervorgehobene Wort der Ansicht. */
.wb__signale {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  /* Klarer Abstand nach oben und unten: Die Leiste steht unmittelbar unter
     dem Bildbereich und braucht Luft, damit sie dort nicht eingeklemmt
     wirkt und der Reglergriff sie nicht streift. */
  padding: calc(var(--e) * 0.95) calc(var(--e) * 1.1);
  background: var(--wb-tief);
  border-top: 1px solid var(--wb-kante);
  border-bottom: 1px solid var(--wb-kante);
  font-family: var(--schrift-display);
  font-weight: 600;
  font-stretch: 87.5%;
  font-variation-settings: 'wdth' 87.5;
  font-size: calc(var(--e) * 0.68);
  letter-spacing: 0.16em;
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--wb-leise);
  white-space: nowrap;
}

.wb__signal {
  padding-inline: calc(var(--e) * 1.05);
}

.wb__signal:first-child {
  padding-left: 0;
}

.wb__signal:last-child {
  padding-right: 0;
}

.wb__signal + .wb__signal {
  border-left: 1px solid rgba(240, 169, 44, 0.55);
}

.wb__signal--akzent {
  color: var(--wb-bernstein);
}

/* Drei Leistungen als sauberes Drei-Spalten-Raster – keine Kacheln, keine
   Rahmen, keine Preise.

   Die drei Spalten sind gleich breit und stehen nebeneinander; ihr Text
   ist linksbündig, der Block als Ganzes sitzt mittig auf der Fläche.
   Über jedem Titel steht ein kurzer Bernstein-Strich von höchstens 32
   Pixeln – ein Akzent, ausdrücklich keine durchgezogene Linie: Lange
   Striche quer durch die Fläche haben den Bereich vorher wie ein defektes
   Menü aussehen lassen.

   Dass das Raster über die volle Breite reicht, hat einen zweiten Grund:
   In der Ruhelage steht der Regler auf der Mitte. Weil die dritte Spalte
   in der rechten Hälfte liegt, trägt die untere Fläche auch dort noch
   Inhalt – man sieht nie eine leere schwarze Hälfte. */
.wb__leistungen {
  /* Nimmt die Höhe, die unter Foto und Signalleiste übrig bleibt, und
     stellt ihren Inhalt darin mittig – so entsteht weder oben noch unten
     eine tote Fläche. */
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: calc(var(--e) * 1.5);
  align-content: center;
  padding: calc(var(--e) * 1.1) calc(var(--e) * 1.35);
  background: var(--wb-tief);
}

.wb__leistung {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
}

/* Der Akzentstrich. 32 Pixel sind die Obergrenze; auf schmaler Bühne
   schrumpft er mit der Grundschriftgröße mit, damit er neben dem kleineren
   Titel nicht überproportional wirkt. */
.wb__leistung-strich {
  flex: none;
  width: min(32px, calc(var(--e) * 2.2));
  height: 2px;
  margin-bottom: calc(var(--e) * 0.62);
  background: var(--wb-bernstein);
}

.wb__leistung-titel {
  font-family: var(--schrift-display);
  font-weight: 700;
  font-stretch: 87.5%;
  font-variation-settings: 'wdth' 87.5;
  font-size: calc(var(--e) * 0.97);
  letter-spacing: 0.055em;
  line-height: 1.15;
  text-transform: uppercase;
  color: var(--wb-hell);
}

.wb__leistung-text {
  margin-top: calc(var(--e) * 0.42);
  font-size: calc(var(--e) * 0.83);
  line-height: 1.4;
  color: var(--wb-leise);
  text-wrap: pretty;
}

/* 8.8.4 Schmale Bühne ------------------------------------------------------
   Gefragt wird die Breite der BÜHNE, nicht die des Fensters – die Bühne ist
   die Messlatte. Dadurch stimmt die Umschaltung immer, egal wie breit die
   Seitenränder gerade sind. Auf dem Handy bekommt die Bühne mehr Höhe, die
   alte Spalte mehr Breite, und in der neuen Fassung weicht die Navigation;
   Foto, Headline, Signalleiste und die drei Leistungsspalten bleiben – sie
   tragen den Vergleich.
   -------------------------------------------------------------------------- */

@container (max-width: 619px) {
  .vergleich__bild {
    height: 400px;
  }

  .alt__blatt {
    width: 94%;
  }

  .alt__tabelle {
    grid-template-columns: 1fr;
    gap: calc(var(--e) * 0.6);
  }

  .alt__zaehler {
    margin-bottom: calc(var(--e) * 0.22);
  }

  .wb__navi {
    display: none;
  }

  /* Ohne die Navigation fehlt das Element, das den Knopf nach rechts
     schiebt – hier übernimmt das der Knopf selbst. */
  .wb__kopf .wb__knopf {
    margin-left: auto;
  }

  .wb__kopf,
  .wb__hero,
  .wb__leistungen {
    padding-inline: calc(var(--e) * 1);
  }

  .wb__kopf {
    padding-block: calc(var(--e) * 0.7);
  }

  .wb__marke {
    letter-spacing: 0.13em;
  }

  .wb__hero {
    padding-bottom: calc(var(--e) * 0.95);
    max-width: calc(var(--e) * 27);
  }

  .wb__titel {
    font-size: calc(var(--e) * 2);
  }

  .wb__text {
    margin-top: calc(var(--e) * 0.45);
    font-size: calc(var(--e) * 0.84);
  }

  .wb__knopf--gross {
    margin-top: calc(var(--e) * 0.65);
    padding: calc(var(--e) * 0.55) calc(var(--e) * 1);
  }

  .wb__signale {
    padding-block: calc(var(--e) * 0.75);
    font-size: calc(var(--e) * 0.62);
    letter-spacing: 0.12em;
  }

  .wb__signal {
    padding-inline: calc(var(--e) * 0.7);
  }

  /* Drei Spalten bleiben auch schmal drei Spalten – sie tragen den
     Eindruck einer fertigen Seite. Enger wird nur der Zwischenraum. */
  .wb__leistungen {
    gap: calc(var(--e) * 0.95);
    padding-block: calc(var(--e) * 0.85);
  }

  .wb__leistung-strich {
    margin-bottom: calc(var(--e) * 0.5);
  }

  .wb__leistung-titel {
    font-size: calc(var(--e) * 0.86);
    letter-spacing: 0.03em;
  }

  .wb__leistung-text {
    margin-top: calc(var(--e) * 0.35);
    font-size: calc(var(--e) * 0.78);
  }

  .vergleich__etikett {
    padding: 3px 6px;
    font-size: 0.625rem;
    letter-spacing: 0.1em;
  }

  .vergleich__etikett--links {
    left: 9px;
  }

  .vergleich__etikett--rechts {
    right: 9px;
  }

  .fenster__leiste {
    padding-inline: 74px;
  }
}

/* Ganz schmal braucht die ALTE Fassung am meisten Höhe: Ihre Navigation und
   ihr Fließtext brechen dort mehrfach um. Die Bühne gilt für beide Ansichten,
   also richtet sie sich nach der anspruchsvolleren. Die Signalleiste der
   neuen Fassung passt dann nicht mehr in eine Zeile – sie darf umbrechen,
   die Striche wandern mit. */
@container (max-width: 429px) {
  .vergleich__bild {
    height: 440px;
  }

  /* Ganz schmal wächst die Bühne allein wegen der ALTEN Fassung. Damit die
     neue dadurch unten keine leere Fläche bekommt, nimmt ihr Foto hier einen
     größeren Anteil der Höhe. */
  .wb__buehne {
    flex: 0 0 67%;
  }

  .wb__signale {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: calc(var(--e) * 0.2);
    white-space: normal;
  }

  .wb__signal:first-child,
  .wb__signal:last-child {
    padding-inline: calc(var(--e) * 0.7);
  }
}

/* 8.9 "Warum nicht einfach selbst bauen?" (nur auf /websites) --------------
   Keine Tabelle, keine Kontrast-Zeilen, kein Kasten, keine Fläche: Unter der
   Überschrift steht ein einzelner Absatz, eine Stufe größer als Fließtext und
   in voller Tintenfarbe – er trägt die Sektion allein. Darunter der
   Abschluss-Satz in der Displayschrift und der Knopf.
   -------------------------------------------------------------------------- */

.selbstbau__kopf {
  max-width: 68ch;
}

.selbstbau__text {
  max-width: 62ch;
  margin: var(--raum-4) 0 0;
  font-size: var(--gr-gross);
  line-height: 1.6;
  color: var(--tinte);
}

/* Der Abschluss-Satz ist die Pointe der Sektion und steht deshalb eine
   Stufe über dem Absatz darüber – so wie früher über den Kontrast-Zeilen. */
.selbstbau__fazit {
  max-width: 68ch;
  margin-top: var(--raum-6);
  margin-bottom: 0;
  font-family: var(--schrift-display);
  font-size: var(--gr-h3);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--tinte);
}

@media (max-width: 860px) {
  .selbstbau__fazit {
    margin-top: var(--raum-5);
  }
}

/* 8.10 Spotlight auf Karten -------------------------------------------------
   Ein weicher Lichtschein in Signalblau folgt dem Zeiger innerhalb einer
   Karte. Betroffen sind nur noch die Paketkarten auf /pakete (beide
   Reihen – Pakete wie Bausteine tragen dieselbe Klasse) und das
   Ausbaustufen-Panel der Startseite – die einzigen Kartenflächen, die es
   noch gibt. Die FAQ-Liste ist bewusst außen vor, sie ist keine Karte.

   Wie es arbeitet: Der Schein ist eine zusätzliche, nicht anklickbare Ebene
   über dem Kartenhintergrund und unter dem Text. Wo seine Mitte liegt,
   steht in zwei Variablen (--mx/--my), die das Skript setzt – der Browser
   malt daraufhin nur diese eine Ebene neu, es wird nichts umgebrochen.

   Nur an Geräten mit echtem Zeiger (Maus, Stift): Am Handy gibt es keinen
   Zeiger, dem etwas folgen könnte. Und nichts davon bei "Bewegung
   reduzieren".
   -------------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .paket,
  .ausbaustufe__flaeche {
    /* Startwert, bis der Zeiger das erste Mal gemeldet wurde. */
    --mx: 50%;
    --my: 50%;
    position: relative;
    /* Hält die Lichtebene innerhalb der Karte: Ohne das rutschte sie hinter
       den weißen Kartenhintergrund. */
    isolation: isolate;
  }

  .paket::after,
  .ausbaustufe__flaeche::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    pointer-events: none;
    opacity: 0;
    background: radial-gradient(
      260px circle at var(--mx) var(--my),
      color-mix(in srgb, var(--signal) 10%, transparent),
      transparent 72%
    );
    transition: opacity 220ms var(--kurve-aus);
  }

  /* Auf der dunklen Panelfläche geht ein 10-%-Schein unter. Hier leuchtet
     die helle Signalvariante etwas kräftiger – dieselbe Mechanik, nur
     sichtbar eingestellt. */
  .ausbaustufe__flaeche::after {
    background: radial-gradient(
      300px circle at var(--mx) var(--my),
      color-mix(in srgb, var(--signal-hell) 20%, transparent),
      transparent 72%
    );
  }

  .paket:hover::after,
  .ausbaustufe__flaeche:hover::after {
    opacity: 1;
  }

  /* Feiner Rand-Glanz in Signalblau, solange der Zeiger über der Karte
     steht – ein zusätzlicher Schatten mit 0 Weichzeichnung, also eine
     haarfeine Linie direkt am Rand. Bei den Paketkarten tritt er an die
     Stelle des früheren Rahmens; der weiche Schatten bleibt darunter. */
  .paket:hover {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--signal) 22%, transparent),
      var(--schatten-hoch);
  }

}

/* --------------------------------------------------------------------------
   9 Bewegung: auf Wunsch komplett aus
   -------------------------------------------------------------------------- */

/* Elemente, die beim Hereinscrollen einmalig einblenden.
   Ohne JavaScript (kein .js-bereit) sind sie von Anfang an sichtbar.

   Der Inhalt "landet", statt zu erscheinen: Er kommt von etwas weiter
   unten (20 statt 14 Pixel), braucht dafür etwas länger (450 ms) und
   schießt am Ziel einen Hauch darüber hinaus, bevor er sich setzt – das
   macht die Landungs-Kurve. Die Deckkraft läuft dabei auf der reinen
   Auslauf-Kurve: Ein Überschwingen über 1 wäre dort nur ein Stillstand.

   Ein Achtel Sekunde Nachlauf bei der Deckkraft (390 ms statt 450 ms):
   Das Element steht optisch schon voll da, während es die letzten zwei
   Pixel noch zurücklegt. Genau das lässt es weich aufsetzen. */
.js-bereit .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 390ms var(--kurve-aus),
    transform var(--dauer-einblenden) var(--kurve-landung);
}

.js-bereit .reveal.sichtbar {
  opacity: 1;
  transform: none;
}

/* Wer im Betriebssystem "Bewegung reduzieren" eingeschaltet hat, bekommt
   eine vollständig ruhige Seite. Das wird gezielt Regel für Regel gemacht.
   Früher stand hier eine pauschale Regel für *alle* Elemente mit
   "animation-duration: 0.01ms !important" – die hat jede Animation der Seite
   auf praktisch null gesetzt, unabhängig davon, was hier sonst steht. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  /* Nichts blendet ein, nichts läuft, nichts bewegt sich. */
  .js-bereit .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

  /* Keine Einstiegsanimation im Hero – weder Zeileneinlauf noch Farb-Sweep.
     Beide hängen ohnehin in einem "no-preference"-Rahmen und greifen hier
     gar nicht erst; diese Regel ist der Gurt zum Hosenträger. */
  .hero-los .hero__eyebrow,
  .hero-los .hero__zeile,
  .hero-los .hero__zeile-innen,
  .hero-los .hero__akzent,
  .hero-los .hero__text,
  .hero-los .hero__knoepfe {
    animation: none;
    opacity: 1;
    transform: none;
  }

  /* Das hervorgehobene Wort bleibt schlicht eingefärbt. */
  .hero-los .hero__akzent {
    background-image: none;
    color: var(--signal);
    -webkit-text-fill-color: currentColor;
  }

  /* Vorher/Nachher-Regler: kein Anteaser (den schaltet das Skript ab), kein
     Wachsen des Griffs, kein Gleiten bei Tastatur-Bedienung. Ziehen,
     Antippen und Pfeiltasten funktionieren unverändert – das ist keine
     Animation, sondern die Bedienung selbst. */
  .vergleich__griff {
    transition: none;
  }

  .vergleich__griff:hover,
  .vergleich__griff:focus-visible,
  .vergleich__bild[data-zieht='ja'] .vergleich__griff {
    transform: none;
  }

  .vergleich__bild[data-weich='ja'] .vergleich__seite--neu,
  .vergleich__bild[data-weich='ja'] .vergleich__regler,
  .vergleich__bild[data-weich='ja'] .wb__bild {
    transition: none;
  }

  /* Der Glanz bleibt, er wird nur nicht mehr heller und dunkler. Das Foto
     der neuen Fassung steht still – den Versatz setzt das Skript in diesem
     Modus gar nicht erst, die Regel hier sichert es zusätzlich ab. */
  .vergleich__naht::before {
    transition: none;
  }

  .wb__bild {
    transform: none;
  }

  /* Keine Mikrobewegungen beim Überfahren oder Drücken. Nichts hebt sich
     an, nichts gibt nach, nichts federt zurück – bedienbar bleibt alles
     unverändert, sichtbar ist der Zustandswechsel weiterhin über Farbe,
     Fläche und den Fokusring. */
  .knopf:hover,
  .knopf:active,
  .wortmarke:hover,
  .wortmarke:active,
  .kopf__schalter:active,
  .navigation__link:hover,
  .navigation__link:active,
  .untermenue__link:hover,
  .untermenue__link:active,
  .paket:hover,
  .ausbaustufe__flaeche:hover,
  .ausbaustufe__flaeche:active,
  .verweis:hover,
  .verweis:active,
  .verweis:hover .verweis__pfeil svg,
  .faq__frage:hover,
  .faq__frage:active,
  .fuss__link:hover,
  .fuss__link:active,
  .sprungmarke:focus {
    transform: none;
  }

  .verweis__titel,
  .verweis__pfeil svg,
  .verweis,
  .knopf,
  .wortmarke,
  .sprungmarke,
  .kopf,
  .kopf__schalter,
  .navigation__link,
  .navigation__pfeil,
  .untermenue__link,
  .paket,
  .eingabe,
  .ausbaustufe__flaeche,
  .ausbaustufe__pfeil svg,
  .faq__frage,
  .fuss__link,
  .faq__zeichen::before,
  .faq__zeichen::after,
  .kopf__schalter-balken,
  .kopf__schalter-balken::before,
  .kopf__schalter-balken::after {
    transition: none;
  }

  /* Das FAQ-Akkordeon klappt sofort um, statt weich aufzugehen. Der Inhalt
     steht dabei vollständig da – geklappt wird weiterhin, nur ohne Weg. */
  @supports (interpolate-size: allow-keywords) and (selector(::details-content)) {
    .faq__eintrag::details-content {
      transition: none;
    }

    .faq__eintrag[open]::details-content {
      opacity: 1;
    }
  }

  /* Der Kopfbereich wird beim Scrollen weiterhin zur Glasfläche – das ist
     ein Zustand, keine Bewegung. Nur der Übergang dorthin entfällt (siehe
     die transition: none oben für .kopf). */
}

/* --------------------------------------------------------------------------
   10 Seitenübergänge
   -------------------------------------------------------------------------- */

/* Beim Wechsel auf eine andere Seite blendet der Browser die alte Seite in
   die neue über, statt hart umzuschalten. Das macht er selbst – kein
   JavaScript, kein Nachbau. Browser, die das nicht können, überspringen die
   Regel und wechseln wie bisher: Es geht nichts verloren.
   Bei "Bewegung reduzieren" wird der Übergang gar nicht erst eingeschaltet. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

/* Der Kopfbereich bekommt einen eigenen Namen. Damit erkennt der Browser
   ihn auf beiden Seiten als dasselbe Element: Er blendet nicht mit über,
   sondern bleibt mitsamt Wortmarke optisch stehen, während darunter der
   Inhalt wechselt. Der Name darf pro Seite nur einmal vorkommen – deshalb
   nur der Kopfbereich, nicht die Wortmarke selbst (die steht auch im
   Fußbereich). */
.kopf {
  view-transition-name: kopf;
}
