@charset "utf-8";

/* ==========================================================================
   Felix Niemann — Transfer · Beratung · Lehre
   site.css

   Aufbau
     1  reset      Grundnormalisierung
     2  tokens     Farben, Typografie, Raster, Bewegung
     3  base       Grundtypografie und Fliesstext
     4  layout     Hülle, Rubriken, Raster
     5  components Kopf, Navigation, Einstieg, Akkordeon, Schritte, Reiter,
                   Person, Produktionen, Kontakt, Fuss
     6  motion     Ein- und Ausblendungen beim Scrollen
     7  utilities  Hilfsklassen
     8  print      Papierfassung

   Grundsätze
     · Ein einziges Stylesheet, keine Laufzeitabhängigkeiten, keine Inline-Styles
       (die Content-Security-Policy erlaubt weder style-Attribute noch <style>).
     · Alle Grössen fluid über clamp(): zwischen 320 px und 2560 px gibt es
       keinen Sprung, der Gestaltung kostet.
     · Kontraste durchgehend mindestens 4,5:1 für Text, 3:1 für Bedienelemente
       (WCAG 2.2 AA). Die Petrol-Werte des Entwurfs sind dafür für Textrollen
       aufgehellt; als Flächen- und Linienfarbe bleibt der Originalton.
   ========================================================================== */

@import url("fonts.css") layer(base);

@layer reset, tokens, base, layout, components, motion, utilities, print;

/* ==========================================================================
   1 · reset
   ========================================================================== */
@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-block-start: var(--header-h, 5rem);
    color-scheme: dark;
    -moz-tab-size: 4;
    tab-size: 4;
    /* clip statt hidden: verhindert seitliches Überlaufen, ohne
       position:sticky im Kopf zu zerstören. */
    overflow-x: clip;
  }

  body {
    margin: 0;
    min-height: 100svh;
  }

  h1,
  h2,
  h3,
  h4,
  h5,
  h6,
  p,
  figure,
  blockquote,
  dl,
  dd,
  ul,
  ol {
    margin: 0;
  }

  ul[role="list"],
  ol[role="list"] {
    list-style: none;
    padding: 0;
  }

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

  img,
  video {
    height: auto;
  }

  input,
  button,
  textarea,
  select {
    font: inherit;
    color: inherit;
    letter-spacing: inherit;
  }

  textarea {
    resize: vertical;
  }

  button {
    background: none;
    border: 0;
    padding: 0;
  }

  table {
    border-collapse: collapse;
    border-spacing: 0;
  }

  :where(a) {
    color: inherit;
  }

  ::selection {
    background: var(--c-accent-deep);
    color: var(--c-text-1);
  }
}

/* ==========================================================================
   2 · tokens
   ========================================================================== */
@layer tokens {
  :root {
    /* --- Flächen ----------------------------------------------------- */
    --c-ink: #1e2021; /* Grundfläche */
    --c-surface: #252728; /* abgesetzte Rubrik */
    --c-card: #2b2c2d; /* Karte, Feld */
    --c-card-hi: #333537; /* Karte im Hover */
    --c-footer: #1a1c1d;

    /* --- Schrift ------------------------------------------------------ */
    --c-text-1: #f1f1ef; /* Überschriften, Aussagen            ~16,5:1 */
    --c-text-2: #c7c9cb; /* Fliesstext                          ~10,0:1 */
    --c-text-3: #a9adb0; /* Sekundärtext                         ~7,3:1 */
    --c-text-4: #9da1a4; /* Etiketten, Bildunterschriften        ~6,3:1 */

    /* --- Akzent -------------------------------------------------------
       Petrol in zwei Rollen: aufgehellt, wo er Text ist; im Originalton,
       wo er Linie oder Fläche ist. */
    --c-accent: #529faf; /* Akzenttext, Links   ≥ 4,6:1 auf allen Flächen */
    --c-accent-line: #3a8190; /* Linien, Rahmen, Fortschritt  ≥ 3:1 */
    --c-accent-deep: #2a6470; /* gefüllte Fläche, Hover */

    /* --- Linien -------------------------------------------------------- */
    --c-hairline: rgb(241 241 239 / 0.12);
    --c-rule: rgb(241 241 239 / 0.24); /* nur Dekor — 1.4.11 gilt dafür nicht */
    --c-rule-strong: rgb(241 241 239 / 0.42);
    /* Grenzen von BEDIENELEMENTEN brauchen 3:1 (WCAG 1.4.11). --c-rule käme
       auf 2,07:1 und wäre auf einem Bürobildschirm schlicht nicht zu sehen —
       man fände die Eingabefelder nicht. Deshalb ein eigener Wert:
       3,57:1 auf --c-surface, 3,68:1 auf --c-ink. */
    --c-control-line: rgb(241 241 239 / 0.42);

    /* --- Status --------------------------------------------------------- */
    --c-ok: #7fb583;
    --c-warn: #d3ab6a;
    --c-error: #e08c8c;

    /* --- Schriftfamilien ------------------------------------------------ */
    --font-display: "Source Serif 4", "Iowan Old Style", "Palatino Linotype",
      Georgia, "Times New Roman", serif;
    --font-sans: "Manrope", ui-sans-serif, system-ui, -apple-system,
      "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo,
      Consolas, monospace;

    /* --- Typografische Skala (fluid, 320 → 1600 px) ---------------------- */
    --step--2: clamp(0.6875rem, 0.665rem + 0.11vw, 0.75rem); /* 11 → 12 */
    --step--1: clamp(0.8125rem, 0.79rem + 0.11vw, 0.875rem); /* 13 → 14 */
    --step-0: clamp(1rem, 0.964rem + 0.18vw, 1.125rem); /* 16 → 18 */
    --step-1: clamp(1.0625rem, 0.98rem + 0.42vw, 1.3125rem); /* 17 → 21 */
    --step-2: clamp(1.25rem, 1.107rem + 0.71vw, 1.625rem); /* 20 → 26 */
    --step-3: clamp(1.5rem, 1.25rem + 1.25vw, 2.125rem); /* 24 → 34 */
    --step-4: clamp(1.75rem, 1.32rem + 2.14vw, 2.875rem); /* 28 → 46 */
    --step-5: clamp(2.125rem, 1.42rem + 3.53vw, 3.875rem); /* 34 → 62 */

    --lh-tight: 1.08;
    --lh-snug: 1.22;
    --lh-text: 1.68;
    --track-caps: 0.18em;
    --track-tight: -0.015em;

    /* --- Raster und Abstände --------------------------------------------- */
    --shell: 75rem; /* 1200 px */
    --measure-text: 52rem; /* 832 px — dieselbe Zeilenlänge wie .u-lead
                              auf der Startseite (65ch bei --step-1) */
    --gutter: clamp(1.25rem, 0.9rem + 1.75vw, 2.5rem);
    --section-y: clamp(3.25rem, 2.1rem + 5.4vw, 5.5rem);
    --flow: clamp(1rem, 0.9rem + 0.5vw, 1.25rem);

    --space-2xs: 0.375rem;
    --space-xs: 0.625rem;
    --space-s: 0.875rem;
    --space-m: 1.375rem;
    --space-l: 2.125rem;
    --space-xl: 3.25rem;
    --space-2xl: clamp(2.75rem, 1.9rem + 4.2vw, 4.5rem);

    /* --- Bewegung --------------------------------------------------------- */
    /* Die Kurve der Überarbeitung: schneller Anlauf, langer Auslauf.
       Sie gibt jeder Bewegung Gewicht, ohne träge zu wirken. */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-in-out: cubic-bezier(0.65, 0.02, 0.28, 1);
    --dur-fast: 140ms;
    --dur: 260ms;
    --dur-slow: 620ms;

    --header-h: 4.25rem;
    --focus-ring: 2px solid var(--c-accent);
  }

  /* Etwas mehr Luft im Kopf, sobald die Zeile es hergibt. */
  @media (min-width: 48em) {
    :root {
      --header-h: 5rem;
    }
  }

  /* Sehr breite Bildschirme: das Raster darf atmen, die Zeile nicht reissen. */
  @media (min-width: 100em) {
    :root {
      --shell: 82.5rem;
    }
  }
}

/* ==========================================================================
   3 · base
   ========================================================================== */
@layer base {
  body {
    background: var(--c-ink);
    color: var(--c-text-2);
    font-family: var(--font-sans);
    font-size: var(--step-0);
    font-weight: 400;
    line-height: var(--lh-text);
    font-synthesis-weight: none;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
  }

  /* Deutsche Fachsprache erzeugt lange Komposita. Ohne Trennung bricht das
     Layout auf schmalen Geräten; mit Trennung liest es sich sauber. */
  p,
  li,
  dd,
  figcaption,
  blockquote {
    hyphens: auto;
    hyphenate-limit-chars: 8 4 4;
    overflow-wrap: break-word;
    text-wrap: pretty;
  }

  h1,
  h2,
  h3 {
    font-family: var(--font-display);
    font-weight: 400;
    line-height: var(--lh-tight);
    letter-spacing: var(--track-tight);
    color: var(--c-text-1);
    text-wrap: balance;
    /* „anywhere“ und nicht „break-word“: nur „anywhere“ senkt auch die
       Mindestinhaltsbreite. Sonst wächst die Rasterspur auf die Breite des
       längsten Wortes — bei 200 % Grundschrift sprengt „Widerstand.“ so das
       Fenster (WCAG 1.4.4). Bei üblichen Grössen greift die Regel nie. */
    overflow-wrap: anywhere;
  }

  h1 {
    font-size: var(--step-5);
  }

  h2 {
    font-variation-settings: "opsz" 40;
  }

  /* Versal gesetzte Etiketten in der Schreibmaschinenschrift werden nie
     getrennt — eine Trennung mitten in „BERA-TUNG“ liest sich wie ein Fehler. */
  .eyebrow,
  .section__no,
  .section__label,
  .facts__title,
  .brief__title,
  .field__label,
  .production__kind,
  .portrait figcaption,
  .colophon__fine,
  .notfound__code,
  .brand__title,
  .brand__claim,
  .step__no,
  .timeline__row dt {
    hyphens: none;
    overflow-wrap: anywhere;
  }

  h2 {
    font-size: var(--step-4);
    line-height: var(--lh-snug);
  }

  h3 {
    font-size: var(--step-2);
    line-height: var(--lh-snug);
  }

  h4 {
    font-family: var(--font-sans);
    font-size: var(--step-1);
    font-weight: 600;
    line-height: var(--lh-snug);
    color: var(--c-text-1);
    margin: 0;
  }

  strong,
  b {
    font-weight: 600;
    color: var(--c-text-1);
  }

  a {
    color: var(--c-accent);
    text-decoration-line: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.22em;
    text-decoration-color: rgb(82 159 175 / 0.5);
    transition: color var(--dur-fast) var(--ease-out),
      text-decoration-color var(--dur-fast) var(--ease-out);
  }

  a:hover {
    color: var(--c-text-1);
    text-decoration-color: currentcolor;
  }

  :focus-visible {
    outline: var(--focus-ring);
    outline-offset: 3px;
    border-radius: 1px;
  }

  /* Für Elemente, die bündig an einer Kante sitzen, wandert der Ring nach innen. */
  .u-focus-inset:focus-visible {
    outline-offset: -3px;
  }

  ::placeholder {
    color: var(--c-text-4);
    opacity: 1;
  }
}

/* ==========================================================================
   4 · layout
   ========================================================================== */
@layer layout {
  .shell {
    inline-size: 100%;
    max-inline-size: var(--shell);
    margin-inline: auto;
    padding-inline: var(--gutter);
    /* Bezugsrahmen für die Rubrikschiene im linken Aussenraum. */
    position: relative;
  }

  /* Rechtstexte laufen in derselben Hülle wie die Startseite — gleiche
     Breite, gleicher linker Rand, gleiche Rubrikschiene. Begrenzt wird
     nur die Zeilenlänge des Fliesstextes, nicht die Hülle. Eine engere
     Hülle würde die Seite gegenüber der Startseite einrücken und die
     Lesespalte unter die Breite drücken, die Tabellen brauchen. */
  .shell--text > * {
    max-inline-size: var(--measure-text);
  }

  .section {
    border-block-start: 1px solid var(--c-hairline);
    padding-block: var(--section-y);
    position: relative;
  }

  .section--alt {
    background: var(--c-surface);
  }

  .section:first-of-type {
    border-block-start: 0;
  }

  /* Rubrikkennung: laufende Nummer + Name. Ab 84em wandert sie in den
     linken Aussenraum und wird zur Schiene — die Rubrik beginnt dann nicht
     mit einer Zeile über dem Text, sondern neben ihm. Das bricht die
     gestapelte Mitte, ohne die Lesespalte anzutasten. */
  .section__marker {
    display: flex;
    align-items: baseline;
    gap: var(--space-s);
    margin-block-end: var(--space-l);
  }

  @media (min-width: 84em) {
    .section > .shell {
      padding-inline-start: calc(var(--gutter) + 9.5rem);
    }

    .section__marker {
      position: absolute;
      inset-inline-start: var(--gutter);
      inset-block-start: 0.4rem;
      flex-direction: column;
      align-items: flex-start;
      gap: 0.55rem;
      margin: 0;
      inline-size: 8rem;
      /* Lange Rubriknamen sollen mit Trennstrich umbrechen statt mitten im
         Wort zu reissen — die Sperrung macht sie breiter, als sie aussehen. */
      hyphens: auto;
      overflow-wrap: break-word;
    }

    /* Feine Linie unter der Schiene — sie bindet die Kennung an die Rubrik,
       ohne einen Kasten zu bauen. */
    .section__marker::after {
      content: "";
      inline-size: 2.25rem;
      block-size: 1px;
      background: var(--c-accent-line);
      margin-block-start: 0.35rem;
    }
  }

  .section__no,
  .section__label {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
  }

  .section__no {
    color: var(--c-accent);
    letter-spacing: 0.06em;
  }

  .section__label {
    color: var(--c-text-4);
  }

  /* Zweispaltiges Editorial-Raster: Aussage links, Erläuterung rechts.
     Der Umbruch erfolgt über die Spaltenbreite, nicht über einen Breakpoint. */
  .duo {
    display: grid;
    gap: clamp(1.75rem, 1rem + 3.5vw, 4rem);
    align-items: start;
  }

  @media (min-width: 56em) {
    .duo {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    }

    .duo--lead {
      grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    }
  }

  /* Raster- und Flexkinder müssen unter ihre Mindestinhaltsbreite schrumpfen
     dürfen. Die Vorgabe min-width:auto lässt die Spur sonst auf das längste
     unteilbare Wort wachsen — bei vergrösserter Grundschrift läuft die Seite
     dadurch seitlich aus dem Fenster, und html { overflow-x: clip } schneidet
     das Ergebnis unerreichbar ab. */
  .hero__grid > *,
  .duo > *,
  .person > *,
  .contact > *,
  .steps > *,
  .form > *,
  .form__pair > *,
  .masthead__inner > *,
  .colophon__inner > *,
  .drawer__link,
  .brand__name,
  .objection__summary > *,
  .field > *,
  .facts__row > *,
  .channels__row > *,
  .timeline__row > * {
    min-inline-size: 0;
  }

  .flow > * + * {
    margin-block-start: var(--flow);
  }

  .measure {
    max-inline-size: 65ch;
  }

  .measure--tight {
    max-inline-size: 46ch;
  }

}

/* ==========================================================================
   5 · components
   ========================================================================== */
@layer components {
  /* ---------------------------------------------------------------- Sprung */
  .skip-link {
    position: fixed;
    inset-block-start: 0;
    inset-inline-start: 0;
    z-index: 200;
    transform: translateY(-110%);
    background: var(--c-text-1);
    color: var(--c-ink);
    font-size: var(--step--1);
    font-weight: 600;
    padding: 0.75rem 1.25rem;
    text-decoration: none;
    transition: transform var(--dur) var(--ease-out);
  }

  /* Bewusst :focus und nicht nur :focus-visible — eine Sprungmarke muss
     auch dann erscheinen, wenn der Fokus programmatisch dorthin gesetzt
     wurde, etwa von einer Hilfstechnologie. */
  .skip-link:focus,
  .skip-link:focus-visible {
    transform: translateY(0);
    outline-offset: -4px;
    /* Der Ring liegt hier nach innen auf der hellen Fläche der Sprungmarke.
       Der Akzentton käme dort auf 2,68:1; das Anthrazit auf 14,5:1. */
    outline-color: var(--c-ink);
  }

  /* --------------------------------------------------------- Lesefortschritt */
  .progress {
    position: fixed;
    inset-block-start: 0;
    inset-inline-start: 0;
    z-index: 90;
    block-size: 2px;
    inline-size: 100%;
    transform-origin: 0 50%;
    transform: scaleX(var(--progress, 0));
    background: var(--c-accent-line);
    pointer-events: none;
  }

  /* Wo der Browser scroll-getriebene Animationen kennt, läuft der Balken
     ohne JavaScript und ohne Scroll-Handler. */
  @supports (animation-timeline: scroll()) {
    .progress {
      animation: progress-grow linear both;
      animation-timeline: scroll(root block);
      transform: scaleX(0);
    }
  }

  @keyframes progress-grow {
    to {
      transform: scaleX(1);
    }
  }

  /* ------------------------------------------------------------------ Kopf */
  .masthead {
    position: sticky;
    inset-block-start: 0;
    z-index: 80;
    background: color-mix(in srgb, var(--c-ink) 92%, transparent);
    border-block-end: 1px solid var(--c-hairline);
    transition: background var(--dur) var(--ease-out),
      border-color var(--dur) var(--ease-out);
  }

  @supports (backdrop-filter: blur(1px)) {
    .masthead {
      backdrop-filter: saturate(1.4) blur(14px);
    }
  }

  /* Ohne Transparenzunterstützung oder bei entsprechender Systemeinstellung
     bleibt der Kopf deckend. */
  @media (prefers-reduced-transparency: reduce) {
    .masthead {
      background: var(--c-ink);
      backdrop-filter: none;
    }
  }

  .masthead[data-scrolled="true"] {
    border-block-end-color: var(--c-rule);
  }

  /* Umbruch erlaubt. Bei „sehr grosser“ Browser-Grundschrift (WCAG 1.4.4
     verlangt 200 %) passt die Kopfzeile sonst nicht mehr in 320 px, das
     Dokument wird breiter als das Fenster — und weil html auf
     overflow-x: clip steht, wäre der Überstand unerreichbar abgeschnitten. */
  .masthead__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-m);
    min-block-size: var(--header-h);
    padding-block: 0.5rem;
  }

  /* ------------------------------------------------------------- Wortmarke */
  .brand {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    text-decoration: none;
    color: var(--c-text-1);
    flex: 0 1 auto;
    min-inline-size: 0;
  }

  .brand:hover {
    color: var(--c-text-1);
  }

  .brand__mark {
    inline-size: 2.375rem;
    block-size: 2.375rem;
    flex: none;
  }

  .brand__name {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }

  .brand__title {
    font-size: clamp(0.875rem, 0.83rem + 0.22vw, 1rem);
    font-weight: 700;
    letter-spacing: 0.055em;
    line-height: 1.1;
    text-transform: uppercase;
    /* kein nowrap: bei sehr grosser Grundschrift muss der Name umbrechen
       dürfen, sonst sprengt er die Kopfzeile */
    overflow-wrap: break-word;
  }

  .brand__claim {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0 0.3em;
    font-size: clamp(0.4375rem, 0.41rem + 0.14vw, 0.5rem);
    font-weight: 500;
    letter-spacing: 0.055em;
    line-height: 1.2;
    text-transform: uppercase;
    color: var(--c-text-4);
  }

  .brand--footer .brand__mark {
    inline-size: 3rem;
    block-size: 3rem;
  }

  .brand--footer .brand__title {
    font-size: 1.25rem;
  }

  .brand--footer .brand__claim {
    font-size: 0.59rem;
    gap: 0.35rem;
  }

  /* ------------------------------------------------------------ Navigation */
  .nav {
    display: flex;
    align-items: center;
    gap: clamp(1rem, 0.3rem + 1.6vw, 1.75rem);
  }

  .nav__link {
    font-size: var(--step--1);
    color: var(--c-text-3);
    text-decoration: none;
    padding-block: 0.35rem;
    position: relative;
    white-space: nowrap;
  }

  .nav__link::after {
    content: "";
    position: absolute;
    inset-block-end: 0;
    inset-inline-start: 0;
    block-size: 1px;
    inline-size: 100%;
    background: currentcolor;
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform var(--dur) var(--ease-out);
  }

  .nav__link:hover,
  .nav__link[aria-current="true"] {
    color: var(--c-text-1);
  }

  .nav__link:hover::after,
  .nav__link[aria-current="true"]::after {
    transform: scaleX(1);
  }

  .nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--c-text-1);
    cursor: pointer;
    padding: 0.6rem 0.75rem;
    margin-inline-end: -0.75rem;
    border: 1px solid transparent;
    min-block-size: 2.75rem;
  }

  .nav-toggle:hover {
    border-color: var(--c-hairline);
  }

  .nav-toggle__bars {
    inline-size: 1.125rem;
    block-size: 0.75rem;
    position: relative;
    flex: none;
  }

  .nav-toggle__bars::before,
  .nav-toggle__bars::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    block-size: 1.5px;
    background: currentcolor;
    transition: transform var(--dur) var(--ease-in-out),
      inset-block-start var(--dur) var(--ease-in-out);
  }

  .nav-toggle__bars::before {
    inset-block-start: 0.0625rem;
  }

  .nav-toggle__bars::after {
    inset-block-start: 0.625rem;
  }

  /* Die Schaltfläche in der Schublade trägt kein aria-expanded — sie schliesst
     nur. Ihr Zeichen ist deshalb dauerhaft das Kreuz. */
  .nav-toggle[aria-expanded="true"] .nav-toggle__bars::before,
  .drawer__close .nav-toggle__bars::before {
    inset-block-start: 0.34rem;
    transform: rotate(45deg);
  }

  .nav-toggle[aria-expanded="true"] .nav-toggle__bars::after,
  .drawer__close .nav-toggle__bars::after {
    inset-block-start: 0.34rem;
    transform: rotate(-45deg);
  }

  /* Umschaltpunkt zwischen Kopfnavigation und Schublade. Der Wert ist am
     Platzbedarf der fünf Beschriftungen ermittelt, nicht an einer Gerätegrösse.
     Steht bewusst NACH den Grundregeln — sonst gewinnt bei gleicher
     Spezifität die spätere Deklaration. */
  @media (max-width: 61.99em) {
    .nav--primary {
      display: none;
    }
  }

  @media (min-width: 62em) {
    .nav-toggle {
      display: none;
    }
  }

  /* Ohne JavaScript kann die Schublade nicht aufgehen. Dann wird die
     Menütaste ausgeblendet und die Kopfnavigation bleibt stehen — sie
     bricht auf schmalen Geräten einfach um. Sonst stünde dort eine
     Schaltfläche, die nichts tut, und die Seite wäre ohne Fussleiste
     nicht navigierbar. */
  .no-js .nav-toggle {
    display: none;
  }

  .no-js .nav--primary {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.1rem;
  }

  /* --------------------------------------------------------- Navigations­lade */
  .drawer {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: var(--c-ink);
    display: flex;
    flex-direction: column;
    padding-block: var(--space-m) var(--space-xl);
    visibility: hidden;
    opacity: 0;
    transition: opacity var(--dur) var(--ease-out),
      visibility 0s linear var(--dur);
  }

  .drawer[data-open="true"] {
    visibility: visible;
    opacity: 1;
    transition-delay: 0s;
  }

  .drawer__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-m);
    min-block-size: var(--header-h);
    margin-block-end: var(--space-l);
  }

  .drawer__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    border-block-start: 1px solid var(--c-hairline);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .drawer__link {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    padding-block: clamp(0.75rem, 0.4rem + 1.2vw, 1.1rem);
    border-block-end: 1px solid var(--c-hairline);
    font-family: var(--font-display);
    font-size: var(--step-2);
    color: var(--c-text-1);
    text-decoration: none;
    transform: translateY(12px);
    opacity: 0;
    transition: transform 380ms var(--ease-out), opacity 380ms var(--ease-out),
      color var(--dur-fast) var(--ease-out);
  }

  .drawer[data-open="true"] .drawer__link {
    transform: none;
    opacity: 1;
    transition-delay: 60ms;
  }

  /* Gestaffelter Einlauf der Navigationspunkte — ohne JavaScript. */
  .drawer[data-open="true"] li:nth-child(2) .drawer__link {
    transition-delay: 102ms;
  }

  .drawer[data-open="true"] li:nth-child(3) .drawer__link {
    transition-delay: 144ms;
  }

  .drawer[data-open="true"] li:nth-child(4) .drawer__link {
    transition-delay: 186ms;
  }

  .drawer[data-open="true"] li:nth-child(5) .drawer__link {
    transition-delay: 228ms;
  }

  .drawer[data-open="true"] li:nth-child(6) .drawer__link {
    transition-delay: 270ms;
  }

  .drawer__link:hover {
    color: var(--c-accent);
  }

  .drawer__no {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    color: var(--c-accent);
    letter-spacing: 0.08em;
    flex: none;
    inline-size: 2.25rem;
  }

  .drawer__foot {
    margin-block-start: auto;
    padding-block-start: var(--space-l);
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    font-size: var(--step--1);
  }

  /* ----------------------------------------------------------- Schaltflächen */
  .btn {
    --btn-bg: transparent;
    --btn-fg: var(--c-text-1);
    --btn-bd: var(--c-control-line);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    min-block-size: 2.875rem;
    padding: 0.8rem 1.6rem;
    font-size: var(--step--1);
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    color: var(--btn-fg);
    background: var(--btn-bg);
    border: 1px solid var(--btn-bd);
    cursor: pointer;
    transition: background var(--dur) var(--ease-out),
      border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out),
      transform var(--dur-fast) var(--ease-out);
  }

  .btn:hover {
    --btn-bd: var(--c-text-1);
    color: var(--btn-fg);
  }

  .btn:active {
    transform: translateY(1px);
  }

  .btn--solid {
    --btn-bg: var(--c-text-1);
    --btn-fg: var(--c-ink);
    --btn-bd: var(--c-text-1);
  }

  .btn--solid:hover {
    --btn-bg: #ffffff;
    --btn-bd: #ffffff;
    --btn-fg: var(--c-ink);
  }

  .btn--accent {
    --btn-bd: var(--c-accent-line);
  }

  .btn--accent:hover {
    --btn-bg: var(--c-accent-deep);
    --btn-bd: var(--c-accent-deep);
    --btn-fg: var(--c-text-1);
  }

  .btn[aria-disabled="true"],
  .btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    transform: none;
  }

  .btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.875rem;
  }

  /* --------------------------------------------------------------- Einstieg */
  .hero {
    padding-block: clamp(3rem, 1.4rem + 8vw, 7rem) var(--section-y);
  }

  .hero__grid {
    display: grid;
    gap: clamp(2.25rem, 1rem + 5vw, 4.5rem);
    align-items: start;
  }

  /* Bruchraster statt Halbierung: 1,75 zu 1 lässt die Aussage laufen und
     hält die Datenspalte schmal. Die Randspalte sitzt bewusst tiefer als
     die Kopfzeile — der obere Rand ist damit nicht mehr eine gerade Linie
     über die volle Breite. */
  @media (min-width: 62em) {
    .hero__grid {
      grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr);
      column-gap: clamp(2.5rem, 1rem + 5vw, 6rem);
    }

    .hero__aside {
      margin-block-start: clamp(3rem, 1rem + 6vw, 7.5rem);
    }
  }

  .eyebrow {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    color: var(--c-accent);
    margin-block-end: var(--space-m);
  }

  .hero__title {
    margin-block-end: var(--space-m);
    letter-spacing: -0.032em;
    line-height: 0.99;
    /* Source Serif 4 ist eine variable Schrift mit optischer Achse. Bei
       Displaygrössen den Schnitt für grosse Grade wählen — feinere Serifen,
       engere Punzen. Das ist der Unterschied zwischen „gross gesetzt“ und
       „für gross gezeichnet“. */
    font-variation-settings: "opsz" 60;
  }

  /* Jeder Satz der Kopfzeile ist ein eigener Block. Damit gleicht der Browser
     die Zeilen jedes Satzes für sich aus, statt „an.“ allein stehen zu lassen —
     und auf breiten Bildschirmen steht jeder Satz auf einer Zeile. */
  .hero__title > span {
    display: block;
    text-wrap: balance;
  }

  .hero__lead {
    font-size: var(--step-1);
    color: var(--c-text-2);
    max-inline-size: 62ch;
  }

  .hero__cta {
    margin-block-start: var(--space-l);
  }

  /* ------------------------------------------------------------ Datenleiste */
  .facts {
    border-block-start: 1px solid var(--c-rule);
    padding-block-start: var(--space-s);
  }

  .facts__title {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    color: var(--c-text-4);
    margin-block-end: var(--space-s);
  }

  .facts__list {
    margin: 0;
  }

  .facts__row {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.25rem 1rem;
    padding-block: 0.8rem;
    border-block-end: 1px solid var(--c-hairline);
  }

  .facts__row dt {
    font-size: var(--step--1);
    color: var(--c-text-4);
  }

  .facts__row dd {
    margin: 0;
    font-size: var(--step--1);
    color: var(--c-text-1);
    text-align: end;
    margin-inline-start: auto;
  }

  /* --------------------------------------------------------------- Einwände */
  /* Die fünf Einwände standen als Kartenraster. Karten sind hier nichts
     wert: Sie tragen keine Erhebung, sie gruppieren nur — und sechs gleich
     grosse Kacheln sind die generischste Anordnung, die es gibt. Stattdessen
     eine gesetzte Liste: laufende Nummer im Aussenrand, Aussage in der
     Lesespalte, Haarlinie als einzige Trennung. */
  .objections {
    margin-block-start: var(--space-m);
    border-block-start: 1px solid var(--c-rule);
  }

  .objection {
    border-block-end: 1px solid var(--c-hairline);
    position: relative;
  }

  /* Lichtspur des Zeigers — sehr flach, nur eine Andeutung von Materie,
     und ausschliesslich dort, wo es einen echten Zeiger gibt. */
  .objection::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image: radial-gradient(
      20rem circle at var(--spot-x, 50%) var(--spot-y, 50%),
      rgb(241 241 239 / 0.05),
      transparent 62%
    );
    opacity: 0;
    transition: opacity var(--dur) var(--ease-out);
  }

  @media (hover: hover) and (pointer: fine) {
    .objection[data-spot]:hover::before {
      opacity: 1;
    }
  }

  .objection__summary {
    display: grid;
    /* max-content statt fester Breite: Die Schiene ist genau so breit wie
       die Nummer. Eine feste rem-Breite wächst mit der Grundschrift mit und
       nimmt bei 200 % der Aussage den Platz weg. */
    grid-template-columns: max-content minmax(0, 1fr) 1.5rem;
    align-items: baseline;
    gap: 0 clamp(0.75rem, 0.4rem + 1.4vw, 1.5rem);
    cursor: pointer;
    list-style: none;
    padding-block: clamp(1rem, 0.7rem + 1.2vw, 1.5rem);
    color: var(--c-text-1);
    min-block-size: 2.75rem;
    transition: color var(--dur) var(--ease-out);
  }

  .objection__no {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: 0.12em;
    color: var(--c-accent);
    font-variant-numeric: tabular-nums;
    hyphens: none;
    min-inline-size: 2.5ch;
  }

  .objection__text {
    font-family: var(--font-display);
    font-size: var(--step-2);
    line-height: 1.25;
    letter-spacing: -0.015em;
    text-wrap: balance;
    /* Notbremse für sehr schmale Spalten bei vergrösserter Grundschrift. */
    overflow-wrap: anywhere;
    hyphens: auto;
  }

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

  .objection__summary:hover {
    color: var(--c-accent);
  }

  /* Taktile Rückmeldung: ein kurzer Druck nach unten, kein Farbsprung. */
  .objection__summary:active .objection__text,
  .tabs__tab:active {
    transform: translateY(1px);
  }

  .objection__sign {
    font-family: var(--font-mono);
    font-size: 1.125rem;
    line-height: 1.4;
    color: var(--c-accent);
    inline-size: 1ch;
    text-align: center;
    justify-self: end;
    transition: transform var(--dur) var(--ease-out);
  }

  .objection[open] .objection__sign {
    transform: rotate(180deg);
  }

  .objection__sign::before {
    content: "+";
  }

  .objection[open] .objection__sign::before {
    content: "–";
  }

  /* Die Antwort steht in derselben Spalte wie die Frage — die Nummernschiene
     bleibt frei. Auf breiten Schirmen bricht sie in zwei Lesespalten um. */
  .objection__body {
    padding-block-end: clamp(1.25rem, 0.9rem + 1.4vw, 1.9rem);
    color: var(--c-text-3);
    font-size: var(--step--1);
    max-inline-size: 68ch;
  }

  @media (min-width: 46em) {
    .objection__body {
      margin-inline-start: calc(2.5ch + clamp(0.75rem, 0.4rem + 1.4vw, 1.5rem));
    }
  }

  @media (min-width: 72em) {
    .objection__body {
      columns: 2;
      column-gap: clamp(1.75rem, 1rem + 2.4vw, 3rem);
      max-inline-size: none;
    }
  }

  .objection__body > * + * {
    margin-block-start: 0.75rem;
  }

  /* Sanftes Aufklappen, wo der Browser interpolate-size beherrscht;
     sonst klappt es ohne Übergang auf — funktional identisch. */
  @supports (interpolate-size: allow-keywords) {
    :root {
      interpolate-size: allow-keywords;
    }

    .objection::details-content {
      block-size: 0;
      overflow: clip;
      opacity: 0;
      transition: content-visibility var(--dur-slow) allow-discrete,
        block-size var(--dur-slow) var(--ease-out),
        opacity 320ms var(--ease-out);
    }

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

  /* Abschluss der Einwandtafel — kein Kasten, sondern eine eingerückte
     Ansprache im Aussenraum der Liste. */
  .invite {
    display: grid;
    gap: 0.7rem;
    justify-items: start;
    padding-block-start: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
  }

  @media (min-width: 46em) {
    .invite {
      margin-inline-start: calc(2.5ch + clamp(0.75rem, 0.4rem + 1.4vw, 1.5rem));
    }
  }

  .invite__line {
    font-family: var(--font-display);
    font-size: var(--step-2);
    line-height: 1.3;
    letter-spacing: -0.015em;
    color: var(--c-text-1);
  }

  /* ---------------------------------------------------------------- Schritte
     Vier gleich breite Spalten sind die Standardantwort auf „vier Schritte“ —
     und sie zwingen jeden Text in dieselbe schmale Gasse. Hier stattdessen
     gesetzte Zeilen: Nummer im Aussenrand, Name in der zweiten Spalte,
     Erläuterung in der Lesespalte. Die Reihenfolge wird dadurch lesbar,
     nicht nur behauptet. */
  .steps {
    display: grid;
    gap: 0;
    border-block-start: 1px solid var(--c-rule);
  }

  .step {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 0.35rem clamp(0.75rem, 0.4rem + 1.4vw, 1.5rem);
    padding-block: clamp(1.35rem, 1rem + 1.4vw, 2rem);
    border-block-end: 1px solid var(--c-hairline);
    position: relative;
  }

  .step:last-child {
    border-block-end: 0;
  }

  .step::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image: radial-gradient(
      20rem circle at var(--spot-x, 50%) var(--spot-y, 50%),
      rgb(241 241 239 / 0.05),
      transparent 62%
    );
    opacity: 0;
    transition: opacity var(--dur) var(--ease-out);
  }

  @media (hover: hover) and (pointer: fine) {
    .step[data-spot]:hover::before {
      opacity: 1;
    }
  }

  /* Ab mittlerer Breite bekommt die Erläuterung eine eigene Spalte —
     asymmetrisch, nicht hälftig. */
  @media (min-width: 56em) {
    .step {
      grid-template-columns: max-content minmax(0, 0.55fr) minmax(0, 1.55fr);
      align-items: baseline;
      gap: 0 clamp(1.25rem, 0.6rem + 2.4vw, 3rem);
    }
  }

  .step__no {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: 0.12em;
    color: var(--c-accent);
    font-variant-numeric: tabular-nums;
    grid-row: 1;
    min-inline-size: 2.5ch;
    hyphens: none;
  }

  .step h3 {
    font-weight: 400;
    font-size: var(--step-2);
    letter-spacing: -0.015em;
    grid-row: 1;
  }

  .step p {
    grid-column: 2;
    font-size: var(--step--1);
    color: var(--c-text-3);
    max-inline-size: 60ch;
  }

  @media (min-width: 56em) {
    .step p {
      grid-column: 3;
      grid-row: 1;
    }
  }

  /* ----------------------------------------------------------------- Reiter */
  /* Schmale Geräte: die drei Beschriftungen sind zu lang für eine Zeile.
     Statt sie umbrechen zu lassen — das ergäbe drei Stummel mit je eigener
     Unterstreichung — stehen sie untereinander und werden links markiert. */
  .tabs__list {
    display: flex;
    flex-direction: column;
    border-block-start: 1px solid var(--c-rule);
    margin-block-end: var(--space-xl);
  }

  .tabs__tab {
    appearance: none;
    text-align: start;
    padding: 0.85rem 0.5rem 0.9rem 0.9rem;
    font-size: var(--step--1);
    color: var(--c-text-3);
    cursor: pointer;
    min-block-size: 2.75rem;
    border-inline-start: 2px solid transparent;
    border-block-end: 1px solid var(--c-hairline);
    transition: color var(--dur) var(--ease-out),
      border-color var(--dur) var(--ease-out);
  }

  .tabs__tab:hover {
    color: var(--c-text-1);
  }

  .tabs__tab[aria-selected="true"] {
    color: var(--c-text-1);
    border-inline-start-color: var(--c-accent-line);
  }

  /* Ab hier tragen die drei Beschriftungen nebeneinander. */
  @media (min-width: 56em) {
    .tabs__list {
      flex-direction: row;
      border-block-start: 0;
      border-block-end: 1px solid var(--c-rule);
      overflow-x: auto;
      overscroll-behavior-inline: contain;
      scrollbar-width: thin;
    }

    .tabs__tab {
      white-space: nowrap;
      padding: 0.9rem 1.25rem 0.95rem;
      border-inline-start: 0;
      border-block-end: 2px solid transparent;
      margin-block-end: -1px;
    }

    .tabs__tab:first-child {
      padding-inline-start: 0;
    }

    .tabs__tab[aria-selected="true"] {
      border-inline-start-color: transparent;
      border-block-end-color: var(--c-accent-line);
    }
  }

  .tabs__panel[hidden] {
    display: none;
  }

  .tabs__panel:focus-visible {
    outline-offset: 6px;
  }

  /* Ohne JavaScript sind alle Tafeln sichtbar und tragen ihre Überschrift —
     die Reiterleiste selbst wird dann nicht angezeigt. */
  .no-js .tabs__list {
    display: none;
  }

  .no-js .tabs__panel {
    display: block;
    margin-block-end: var(--space-2xl);
  }

  /* ------------------------------------------------------------- Auftragsliste */
  .brief {
    border-block-start: 1px solid var(--c-rule);
    padding-block-start: var(--space-s);
  }

  .brief__title {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    color: var(--c-text-4);
    margin-block-end: var(--space-xs);
  }

  .brief__list {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .brief__list li {
    font-size: var(--step--1);
    line-height: 1.55;
    color: var(--c-text-1);
    padding-block: 0.85rem;
    border-block-end: 1px solid var(--c-hairline);
  }

  /* ---------------------------------------------------------------- Person */
  .person {
    display: grid;
    gap: clamp(2rem, 1rem + 4.5vw, 4rem);
    align-items: start;
  }

  @media (min-width: 56em) {
    .person {
      grid-template-columns: minmax(15rem, 21.25rem) minmax(0, 1fr);
    }
  }

  .portrait {
    margin: 0;
  }

  .portrait img {
    inline-size: 100%;
    block-size: auto;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    object-position: 50% 30%;
    filter: grayscale(1) contrast(1.04);
    background: var(--c-card);
  }

  .portrait figcaption {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--c-text-4);
    margin-block-start: 0.75rem;
  }

  .timeline {
    border-block-start: 1px solid var(--c-rule);
    padding-block-start: var(--space-s);
    margin-block-start: var(--space-l);
  }

  .timeline__list {
    margin: 0;
  }

  .timeline__row {
    display: grid;
    gap: 0.25rem 1.25rem;
    padding-block: 0.85rem;
    border-block-end: 1px solid var(--c-hairline);
  }

  @media (min-width: 30em) {
    .timeline__row {
      grid-template-columns: 6rem minmax(0, 1fr);
    }
  }

  .timeline__row dt {
    font-family: var(--font-mono);
    font-size: var(--step--1);
    color: var(--c-accent);
    font-variant-numeric: tabular-nums;
  }

  .timeline__row dd {
    margin: 0;
    font-size: var(--step--1);
    line-height: 1.5;
    color: var(--c-text-1);
  }

  /* ----------------------------------------------------------- Produktionen */
  /* Drei gleich grosse Karten nebeneinander sind die Standardantwort auf
     „drei Dinge“. Stattdessen ein asymmetrisches Raster: die erste
     Produktion gross und links, die beiden anderen versetzt rechts. Unter
     56em fällt alles sauber in eine Spalte. */
  .productions {
    display: grid;
    gap: 0;
    border-block-start: 1px solid var(--c-rule);
  }

  @media (min-width: 56em) {
    .productions {
      grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
      column-gap: clamp(1.75rem, 1rem + 3vw, 4rem);
    }

    .production--lead {
      grid-row: span 2;
      border-inline-end: 1px solid var(--c-hairline);
      padding-inline-end: clamp(1.75rem, 1rem + 3vw, 4rem);
    }
  }

  .production {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    padding-block: clamp(1.5rem, 1.1rem + 1.6vw, 2.25rem);
    border-block-end: 1px solid var(--c-hairline);
    position: relative;
  }

  .production:last-child {
    border-block-end: 0;
  }

  .production::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image: radial-gradient(
      20rem circle at var(--spot-x, 50%) var(--spot-y, 50%),
      rgb(241 241 239 / 0.05),
      transparent 62%
    );
    opacity: 0;
    transition: opacity var(--dur) var(--ease-out);
  }

  @media (hover: hover) and (pointer: fine) {
    .production[data-spot]:hover::before {
      opacity: 1;
    }
  }

  .production__kind {
    display: flex;
    align-items: baseline;
    gap: 0.9rem;
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--c-text-4);
    hyphens: none;
  }

  .production__no {
    color: var(--c-accent);
    letter-spacing: 0.08em;
  }

  .production h3 {
    font-weight: 400;
    font-size: var(--step-3);
    letter-spacing: -0.02em;
  }

  .production--lead h3 {
    font-size: var(--step-4);
  }

  .production p {
    font-size: var(--step--1);
    color: var(--c-text-3);
    margin: 0;
    max-inline-size: 48ch;
  }

  .production--lead p {
    font-size: var(--step-0);
    color: var(--c-text-2);
  }

  /* ---------------------------------------------------------------- Kontakt */
  .contact {
    display: grid;
    gap: clamp(2.25rem, 1rem + 5vw, 5rem);
    align-items: start;
  }

  @media (min-width: 62em) {
    .contact {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    }
  }

  .channels {
    border-block-start: 1px solid var(--c-rule);
    padding-block-start: var(--space-s);
    margin-block-start: var(--space-l);
  }

  .channels__row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.25rem 1rem;
    padding-block: 0.85rem;
    border-block-end: 1px solid var(--c-hairline);
  }

  .channels__row dt {
    font-size: var(--step--1);
    color: var(--c-text-4);
  }

  .channels__row dd {
    margin: 0;
    font-size: var(--step--1);
    margin-inline-start: auto;
    text-align: end;
    overflow-wrap: anywhere;
  }

  /* ---------------------------------------------------------------- Formular */
  .form {
    background: var(--c-surface);
    border: 1px solid var(--c-hairline);
    padding: clamp(1.5rem, 1rem + 2.4vw, 2.25rem);
    display: flex;
    flex-direction: column;
    gap: var(--space-m);
  }

  .form__pair {
    display: grid;
    gap: var(--space-m);
    grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  }

  .field {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-inline-size: 0;
  }

  .field__label {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--c-text-3);
  }

  .field__req {
    color: var(--c-accent);
    margin-inline-start: 0.35em;
  }

  .field__hint {
    font-size: var(--step--1);
    color: var(--c-text-4);
  }

  .field__error {
    font-size: var(--step--1);
    color: var(--c-error);
    min-block-size: 0;
  }

  .field__error:empty {
    display: none;
  }

  .input,
  .textarea,
  .select {
    inline-size: 100%;
    background: transparent;
    color: var(--c-text-1);
    font-size: var(--step-0);
    border: 0;
    border-block-end: 1px solid var(--c-control-line);
    padding: 0.55rem 0;
    min-block-size: 2.75rem;
    border-radius: 0;
    transition: border-color var(--dur) var(--ease-out);
  }

  .textarea {
    border: 1px solid var(--c-control-line);
    padding: 0.75rem 0.875rem;
    line-height: 1.6;
    min-block-size: 9rem;
  }

  .select {
    appearance: none;
    background-color: var(--c-surface);
    padding-inline-end: 1.75rem;
    cursor: pointer;
  }

  /* Der Pfeil wird gezeichnet, nicht geladen — kein zusätzlicher Request. */
  .select-wrap {
    position: relative;
    display: block;
  }

  .select-wrap::after {
    content: "";
    position: absolute;
    inset-inline-end: 0.35rem;
    inset-block-start: 50%;
    inline-size: 0.5rem;
    block-size: 0.5rem;
    border-inline-end: 1px solid var(--c-text-3);
    border-block-end: 1px solid var(--c-text-3);
    transform: translateY(-70%) rotate(45deg);
    pointer-events: none;
  }

  .input:hover,
  .textarea:hover,
  .select:hover {
    border-color: var(--c-rule-strong);
  }

  .input:focus-visible,
  .textarea:focus-visible,
  .select:focus-visible {
    border-color: var(--c-accent);
    outline-offset: 4px;
  }

  .input[aria-invalid="true"],
  .textarea[aria-invalid="true"],
  .select[aria-invalid="true"] {
    border-color: var(--c-error);
  }

  .consent {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.75rem;
    align-items: start;
    font-size: var(--step--1);
    color: var(--c-text-3);
  }

  .consent input[type="checkbox"] {
    /* 24 px sind die Untergrenze aus WCAG 2.2, Erfolgskriterium 2.5.8
       (Zielgrösse, Minimum). Kleiner sieht ruhiger aus, ist aber unzulässig. */
    inline-size: 1.5rem;
    block-size: 1.5rem;
    margin: 0.14rem 0 0;
    accent-color: var(--c-accent-deep);
    flex: none;
  }

  .form__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-m);
  }

  .form__note {
    font-size: var(--step--1);
    color: var(--c-text-4);
    max-width: 40ch;
  }

  /* Honigtopf: für Menschen und Screenreader nicht vorhanden, für einfache
     Bots aber ausfüllbar. Deshalb nicht display:none — sonst füllen viele
     Bots es gar nicht erst aus. */
  .honeypot {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
    padding: 0;
    margin: -1px;
  }

  .honeypot input,
  .honeypot label {
    inline-size: 1px;
    min-inline-size: 0;
  }

  .form__status {
    font-size: var(--step--1);
    line-height: 1.6;
    border-block-start: 1px solid var(--c-hairline);
    padding-block-start: var(--space-s);
  }

  /* Nicht display:none — der Live-Bereich muss im Barrierefreiheitsbaum
     bestehen bleiben, damit spätere Meldungen angesagt werden. */
  .form__status:empty {
    border-block-start: 0;
    padding-block-start: 0;
  }

  .form__status[data-state="ok"] {
    color: var(--c-ok);
  }

  .form__status[data-state="error"] {
    color: var(--c-error);
  }

  .form__status[data-state="busy"] {
    color: var(--c-text-3);
  }

  /* ------------------------------------------------------------------- Fuss */
  .colophon {
    background: var(--c-footer);
    border-block-start: 1px solid var(--c-rule);
    padding-block: var(--space-2xl);
  }

  .colophon__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-l);
  }

  .colophon__links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.6rem;
    font-size: var(--step--1);
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .colophon__links a {
    color: var(--c-text-3);
    text-decoration: none;
  }

  .colophon__links a:hover {
    color: var(--c-text-1);
    text-decoration: underline;
    text-underline-offset: 0.22em;
  }

  .colophon__fine {
    inline-size: 100%;
    border-block-start: 1px solid var(--c-hairline);
    margin-block-start: var(--space-l);
    padding-block-start: var(--space-m);
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.5rem 1.5rem;
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: 0.08em;
    color: var(--c-text-4);
  }

  /* ------------------------------------------------------------- Hinweiskasten */
  .notice {
    border: 1px solid var(--c-rule);
    border-inline-start: 3px solid var(--c-rule-strong);
    background: var(--c-surface);
    padding: clamp(1.1rem, 0.9rem + 0.9vw, 1.5rem);
    margin-block-start: var(--space-l);
    font-size: var(--step--1);
  }

  .notice > * + * {
    margin-block-start: 0.7rem;
  }

  .notice--todo {
    border-inline-start-color: var(--c-warn);
  }

  .notice__title {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    color: var(--c-warn);
    hyphens: none;
  }

  /* Offene Stelle im Rechtstext. Bewusst laut: was hier steht, darf nicht
     online gehen. */
  .todo {
    background: transparent;
    color: var(--c-warn);
    font-family: var(--font-mono);
    font-size: 0.86em;
    line-height: 1.4;
    letter-spacing: 0.02em;
    border: 1px dashed currentcolor;
    padding: 0.1em 0.4em;
    hyphens: none;
    overflow-wrap: break-word;
    text-transform: none;
  }

  /* ------------------------------------------------------- Textseiten (Recht) */
  .legal {
    counter-reset: legal-section;
  }

  .legal > section {
    padding-block-start: var(--space-xl);
  }

  .legal > section > h2 {
    font-size: var(--step-3);
    counter-increment: legal-section;
    display: flex;
    gap: 0.75rem;
    align-items: baseline;
    border-block-start: 1px solid var(--c-hairline);
    padding-block-start: var(--space-m);
  }

  .legal > section > h2::before {
    content: counter(legal-section, decimal-leading-zero);
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: 0.08em;
    color: var(--c-accent);
    flex: none;
  }

  .legal h3 {
    font-family: var(--font-sans);
    font-size: var(--step-1);
    font-weight: 600;
    margin-block-start: var(--space-m);
  }

  .legal p,
  .legal li,
  .legal dd {
    color: var(--c-text-2);
  }

  /* Rechtstexte enthalten Verordnungsnamen wie
     „Dienstleistungs-Informationspflichten-Verordnung“ und lange Adressen.
     Ohne Trennung und Umbruch sprengen sie auf 320 px das Layout. */
  .legal :is(p, li, dd, dt, address, th, td, h2, h3) {
    hyphens: auto;
    overflow-wrap: break-word;
  }

  .legal > section > * + *,
  .legal > section > h2 + * {
    margin-block-start: var(--flow);
  }

  .legal ul,
  .legal ol {
    padding-inline-start: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }

  .legal li::marker {
    color: var(--c-text-4);
  }

  .legal address {
    font-style: normal;
    color: var(--c-text-1);
  }

  .legal dl {
    display: grid;
    gap: 0.35rem 1.25rem;
  }

  @media (min-width: 34em) {
    .legal dl {
      grid-template-columns: minmax(9rem, auto) minmax(0, 1fr);
    }
  }

  .legal dt {
    color: var(--c-text-4);
    font-size: var(--step--1);
  }

  .legal dd {
    margin: 0;
  }

  /* Feste Spaltenaufteilung. Bei automatischer Aufteilung bestimmt der
     längste Zeilenkopf die erste Spalte — die Zeilenköpfe hier sind ganze
     Sätze, die zweite Spalte fiel dadurch auf gut 100 px zusammen und der
     Text stand senkrecht. Unterhalb von 30rem scrollt der Kasten. */
  .legal table {
    inline-size: 100%;
    min-inline-size: 30rem;
    table-layout: fixed;
    font-size: var(--step--1);
    text-align: start;
  }

  .legal thead th:first-child {
    inline-size: 42%;
  }

  .legal th,
  .legal td {
    padding: 0.7rem 0.9rem 0.7rem 0;
    border-block-end: 1px solid var(--c-hairline);
    vertical-align: top;
  }

  .legal th {
    color: var(--c-text-4);
    font-weight: 600;
  }

  /* Nur die Spaltenüberschriften bleiben einzeilig. Zeilenköpfe sind hier
     ganze Sätze und müssen umbrechen dürfen. */
  @media (min-width: 40em) {
    .legal thead th {
      white-space: nowrap;
    }
  }

  /* Breite Tabellen dürfen scrollen, die Seite nicht.
     tabindex="0" und role="region" setzt der Seitenbau, damit der Bereich
     auch per Tastatur erreichbar ist (WCAG 2.1.1). */
  .table-scroll {
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    max-inline-size: 100%;
  }

  .table-scroll:focus-visible {
    outline-offset: 2px;
  }

  .table-scroll table {
    min-inline-size: 28rem;
  }

  /* ------------------------------------------------------------ Fehlerseite */
  .notfound {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-block-size: min(78svh, 46rem);
    padding-block: var(--section-y);
  }

  .notfound__code {
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    color: var(--c-accent);
    margin-block-end: var(--space-m);
  }
}

/* ==========================================================================
   6 · motion — Ein- und Ausblendungen beim Scrollen
   --------------------------------------------------------------------------
   Zwei Wege zum selben Ergebnis:
   a) Browser mit scroll-getriebenen Animationen erledigen alles in CSS,
      ohne einen einzigen Scroll-Handler im Hauptthread.
   b) Alle übrigen bekommen dieselbe Choreografie über einen
      IntersectionObserver, der [data-reveal] die Klasse .is-in gibt und
      beim Verlassen nach oben .is-out setzt.
   Warum das Zurücktreten die Deckkraft NICHT antastet:
   Ein scrollgebundenes Ausblenden dimmt zwangsläufig Text, der noch im Bild
   steht — wer mitten in der Bewegung stehen bleibt, hat ihn dauerhaft vor
   sich. Nachgerechnet: Damit --c-text-1 auf --c-ink noch 4,5:1 hält, darf die
   Deckkraft nicht unter 0,50 fallen; der Akzentton --c-accent bräuchte sogar
   0,85. Ein Effekt in diesem Bereich ist nicht mehr wahrnehmbar. Also
   umgekehrt: Das Erscheinen blendet ein (dort wächst die Deckkraft, der
   Endzustand ist voll lesbar), das Verlassen gleitet nach oben weg — Bewegung
   statt Trübung. Beides ist scrollgebunden, beides kehrt beim Zurückscrollen
   um, und an keiner Halteposition steht Text unter seinem Grenzwert.
   ========================================================================== */
@layer motion {
  [data-reveal] {
    --reveal-y: 1.5rem;
  }

  /* --- (b) Klassenbasiert, überall lauffähig -------------------------- */
  .js [data-reveal] {
    opacity: 0;
    transform: translate3d(0, var(--reveal-y), 0);
    transition: opacity var(--dur-slow) var(--ease-out),
      transform var(--dur-slow) var(--ease-out);
    will-change: opacity, transform;
  }

  .js [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }

  .js [data-reveal].is-out {
    transform: translate3d(0, -1.5rem, 0);
  }

  /* Sobald die Animation gelaufen ist, wird der Kompositor entlastet. */
  .js [data-reveal].is-settled {
    will-change: auto;
  }

  /* --- (a) Scroll-getrieben, wo verfügbar ------------------------------ */
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .js [data-reveal] {
        opacity: 1;
        transform: none;
        transition: none;
        will-change: auto;

        /* Zwei Läufe auf derselben Zeitachse: einer für das Erscheinen von
           unten, einer für das Zurücktreten nach oben.

           Entscheidend ist die Füllart. Der zweite Lauf steht später in der
           Liste und gewinnt deshalb bei gleichzeitiger Wirkung. Bekäme er
           „both“, hielte er schon vor seinem Bereich seinen Anfangswert
           (Deckkraft 1) und würde damit das Einblenden vollständig
           aufheben — die Seite hätte gar keinen Einblendeffekt mehr.
           Mit „forwards“ wirkt er erst ab seinem Bereich. */
        animation: reveal-in linear both, reveal-out linear forwards;
        animation-timeline: view(block), view(block);
        animation-range: entry 0% cover 15%, exit 0% exit 100%;
        animation-delay: 0s, 0s;
      }

      /* Die Klassen aus (b) dürfen die CSS-Fassung nicht überschreiben. */
      .js [data-reveal].is-in,
      .js [data-reveal].is-out {
        opacity: revert-layer;
        transform: revert-layer;
      }
    }
  }

  @keyframes reveal-in {
    from {
      opacity: 0;
      transform: translate3d(0, 1.5rem, 0);
    }

    to {
      opacity: 1;
      transform: none;
    }
  }

  /* Nur Weg, keine Deckkraft — siehe die Begründung oben. */
  @keyframes reveal-out {
    from {
      transform: none;
    }

    to {
      transform: translate3d(0, -1.5rem, 0);
    }
  }

  /* --- Systemeinstellung „weniger Bewegung“ ---------------------------- */
  @media (prefers-reduced-motion: reduce) {
    html {
      scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }

    .js [data-reveal],
    .js [data-reveal].is-in,
    .js [data-reveal].is-out {
      opacity: 1;
      transform: none;
      animation: none;
    }

    .drawer__link {
      opacity: 1;
      transform: none;
    }
  }
}

/* ==========================================================================
   7 · utilities
   ========================================================================== */
@layer utilities {
  .u-visually-hidden {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  .u-mono {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
  }

  .u-lead {
    font-size: var(--step-1);
    color: var(--c-text-2);
  }

  .u-muted {
    color: var(--c-text-3);
  }

  .u-mt-l {
    margin-block-start: var(--space-l);
  }

  .u-mt-xl {
    margin-block-start: var(--space-xl);
  }

  .u-mb-xl {
    margin-block-end: var(--space-xl);
  }

  /* Sperrt den Hintergrund, während die Navigationslade offen ist.
     Die Klasse sitzt auf <html>, weil dort der Scrollcontainer liegt. */
  .u-scroll-lock {
    overflow: hidden;
    /* verhindert den Layoutsprung durch die verschwindende Scrollleiste */
    scrollbar-gutter: stable;
    padding-inline-end: var(--scrollbar-w, 0px);
  }

  /* Ohne !important. Bei wichtigen Deklarationen kehrt die Kaskade die
     Reihenfolge der Ebenen um: „utilities“ stünde dann VOR „print“ und
     die Papierfassung könnte nichts mehr aufklappen. Als normale
     Deklaration gewinnt die spätere Ebene — genau wie gewollt. */
  [hidden] {
    display: none;
  }

  /* Hoher Systemkontrast: eigene Farben treten zurück, Ränder bleiben. */
  @media (forced-colors: active) {
    .btn,
    .input,
    .textarea,
    .select,
    .form,
    .objection {
      border: 1px solid;
    }

    /* Kopfzeile und Schublade liegen über dem Inhalt. Ihre Fläche ist im
       Normalfall halbdurchsichtig (color-mix plus backdrop-filter) — im
       erzwungenen Kontrast bleibt davon nichts übrig, und der Text darunter
       scheint durch. Deshalb hier ausdrücklich die deckende Systemfläche
       und eine sichtbare Trennlinie. */
    .masthead,
    .drawer {
      background: Canvas;
      backdrop-filter: none;
    }

    .masthead {
      border-block-end: 1px solid;
    }

    .progress,
    .nav__link::after {
      forced-color-adjust: none;
      background: Highlight;
    }

    .tabs__tab[aria-selected="true"] {
      border-block-end-color: Highlight;
    }

    .portrait img {
      filter: none;
    }
  }
}

/* ==========================================================================
   8 · print — Papierfassung
   --------------------------------------------------------------------------
   Der Bildschirmauftritt ist dunkel; Papier ist es nicht. Für den Druck
   wechselt die Seite auf die hellen Werte des Gestaltungssystems.
   ========================================================================== */
@layer print {
  @media print {
    @page {
      margin: 18mm 16mm;
    }

    :root {
      --c-ink: #ffffff;
      --c-surface: #ffffff;
      --c-card: #ffffff;
      --c-card-hi: #ffffff;
      --c-footer: #ffffff;
      --c-text-1: #1a1c1d;
      --c-text-2: #2b2c2d;
      --c-text-3: #4d5052;
      --c-text-4: #5c6063;
      --c-accent: #1f4a52;
      --c-accent-line: #5c6063;
      --c-hairline: #d8dadb;
      --c-rule: #a9adb0;
      --c-rule-strong: #5c6063;
    }

    html {
      color-scheme: light;
    }

    body {
      background: #fff;
      color: #2b2c2d;
      font-size: 10.5pt;
      line-height: 1.5;
    }

    .skip-link,
    .progress,
    .nav-toggle,
    .drawer,
    .nav--primary,
    .form,
    .btn-row,
    .objection__sign {
      display: none;
    }

    .masthead {
      position: static;
      backdrop-filter: none;
    }

    .section {
      padding-block: 10mm;
      break-inside: auto;
    }

    h1,
    h2,
    h3 {
      break-after: avoid;
      color: #1a1c1d;
    }

    p,
    li,
    figure,
    .step,
    .production {
      break-inside: avoid;
    }

    .portrait img {
      filter: grayscale(1);
      max-block-size: 90mm;
      inline-size: auto;
    }

    /* Aufgeklappte Fassung: gedruckt gehört der ganze Text aufs Blatt.
       content-visibility deckt Browser ab, die ::details-content kennen;
       für alle übrigen klappt site.js vor dem Druck auf. */
    .objection::details-content {
      block-size: auto;
      opacity: 1;
      overflow: visible;
      content-visibility: visible;
    }

    .tabs__panel[hidden] {
      display: block;
    }

    .tabs__list {
      display: none;
    }

    /* Zieladressen sichtbar machen — auf Papier ist ein Link sonst wertlos. */
    a[href^="http"]::after,
    a[href^="mailto"]::after {
      content: " (" attr(href) ")";
      font-family: var(--font-mono);
      font-size: 8pt;
      color: #5c6063;
      word-break: break-all;
    }

    a[href^="#"]::after {
      content: "";
    }

    .js [data-reveal] {
      opacity: 1;
      transform: none;
      animation: none;
    }
  }
}
