@import url("fonts.css");

/* ============================================================
   Ester Software — Tizian Ester

   Gestaltungsidee: Massarbeit.
   Die Seite ist nach einer technischen Zeichnung gebaut. Haarlinien,
   Teilstriche, Indexnummern am Rand, Masse im Monospace-Satz. Das ist
   kein Schmuck: Tizians Arbeit besteht darin, aus einer Messung das
   richtige Teil zu bestimmen (cat-zahnsystem.de) und aus einem
   Betrieb die richtige Seite.

   Rot ist die Anreisslinie — die Markierung, die ein Handwerker zieht,
   bevor er schneidet. Sie erscheint nur dort, wo etwas beginnt,
   gemessen oder entschieden wird. Nie dekorativ.
   ============================================================ */

/* --- Token ------------------------------------------------------
   Zwei Fassungen: dunkel (Standard, hier) und hell (weiter unten
   unter [data-thema="hell"]). Jede Farbe steht genau einmal je
   Fassung — wer etwas aendern will, aendert es hier.

   Die Rollen der Token bleiben in beiden Fassungen gleich:
   --karmin      Flaechen und Linien, nie Text in Lesegroesse
   --karmin-text Rot, das als Text lesbar ist (>= 4,5:1)
   --text-leise  leiseste Textfarbe, haelt aber 4,5:1 ein
   ---------------------------------------------------------------- */
:root {
  color-scheme: dark;

  /* Flaechen */
  --grund:        #131417;   /* Seitengrund */
  --grund-tief:   #0d0e10;   /* Fusszeile, Formularblock */
  --flaeche:      #1c1e22;   /* erhobene Karten */
  --flaeche-hoch: #262931;   /* Hover, Eingabefelder */
  --linie:        #34373e;   /* Haarlinien */
  --linie-still:  #23262b;   /* noch leisere Trennung */

  /* Anreisslinie */
  --karmin:       #b81d2c;   /* Flaechen und Linien */
  --karmin-text:  #f0616e;   /* Rot in Lesegroesse — 5,8:1 auf --grund */
  --karmin-tief:  #7a1220;   /* Verlaeufe, gedrueckter Zustand */

  /* Schrift */
  --text:         #f4f4f5;
  --text-still:   #a1a1a6;   /* 7,2:1 auf --grund */
  --text-leise:   #85878f;   /* leiseste Textfarbe — erreicht 5,4:1 */

  /* Glas, Schatten, Leuchten */
  --glas:         rgba(19, 20, 23, .60);   /* Kopfleiste */
  --glas-fest:    rgba(13, 14, 16, .88);   /* Kopfleiste nach dem Scrollen */
  --glas-marke:   rgba(13, 14, 16, .80);   /* Bildunterschrift im Portrait */
  --glas-marke-text: #f4f4f5;
  --schatten:       0 30px 60px -30px rgba(0, 0, 0, .9);
  --schatten-menue: 0 24px 40px -28px rgba(0, 0, 0, .95);
  --knopf-schatten: 0 12px 32px -14px rgba(184, 29, 44, .9);
  --karte-schatten: none;    /* im Dunkeln traegt die Flaeche, kein Schatten */
  --geflecht: 236 84 100;    /* Punkte und Linien im Hero, als RGB-Kanaele */
  --geflecht-kraft: 1;       /* Gesamtdeckkraft des Geflechts */

  /* Typografie */
  --display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --body:    "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:    "JetBrains Mono", ui-monospace, "Consolas", monospace;

  /* Raum */
  --raum-1: .5rem;
  --raum-2: 1rem;
  --raum-3: 1.5rem;
  --raum-4: 2.5rem;
  --raum-5: 4rem;
  --raum-6: 6rem;
  --raum-7: 9rem;

  --bahn: 76rem;             /* Inhaltsbreite */
  --bahn-eng: 46rem;         /* Lesebreite fuer Fliesstext */
  --rand: 1.5rem;

  --kante: 4px;
  --tempo: 200ms;
  --tempo-lang: 460ms;
  --kurve: cubic-bezier(.16, 1, .3, 1);

  --kopfhoehe: 4.5rem;
}

/* --- Helle Fassung ----------------------------------------------
   Kein umgedrehtes Dunkel, sondern ein eigener Gegenstand: warmes
   Papier statt Bildschirm. Der Grund ist cremefarben, nicht weiss —
   reines Weiss blendet und wirkt billig. Die Karten sind dafuer
   weiss und bekommen einen weichen Schatten: so liest sich eine
   Karte als aufgelegtes Blatt, nicht als hellerer Kasten.

   Karmin bleibt dasselbe Rot. Was sich dreht, sind die Rollen:
   --karmin-text wird dunkler statt heller, weil Text jetzt gegen
   Hell bestehen muss (7,8:1 auf --grund).

   Wird ueber data-thema am <html> gesetzt, siehe main.js.
   ---------------------------------------------------------------- */
:root[data-thema="hell"] {
  color-scheme: light;

  --grund:        #f4f1ec;   /* warmes Papier, nicht Weiss */
  --grund-tief:   #eae5dc;   /* abgesetzte Kapitel */
  --flaeche:      #ffffff;   /* aufgelegtes Blatt */
  --flaeche-hoch: #fbf9f6;
  --linie:        #cec6b8;
  --linie-still:  #e2dcd1;

  --karmin:       #b81d2c;   /* unveraendert: Weiss darauf ist 6,5:1 */
  --karmin-text:  #96101f;   /* 7,8:1 auf --grund */
  --karmin-tief:  #7a1220;

  --text:         #1a1815;   /* 15,4:1 */
  --text-still:   #5a544b;   /* 6,3:1 */
  --text-leise:   #665f54;   /* leiseste Textfarbe — erreicht 4,8:1 */

  --glas:         rgba(244, 241, 236, .72);
  --glas-fest:    rgba(250, 248, 245, .93);
  --glas-marke:   rgba(255, 255, 255, .88);
  --glas-marke-text: #1a1815;
  --schatten:       0 30px 60px -30px rgba(58, 48, 34, .35);
  --schatten-menue: 0 24px 40px -26px rgba(58, 48, 34, .38);
  --knopf-schatten: 0 10px 24px -12px rgba(184, 29, 44, .45);
  --karte-schatten: 0 1px 2px rgba(58, 48, 34, .05),
                    0 10px 28px -14px rgba(58, 48, 34, .14);
  --geflecht: 150 16 31;     /* auf Papier braucht Rot mehr Tiefe */
  --geflecht-kraft: .65;
}

@media (min-width: 60rem) {
  :root { --rand: 3rem; --kopfhoehe: 5.25rem; }
}

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

[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--kopfhoehe) + 1.5rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--grund);
  color: var(--text-still);
  font: 400 1.0625rem/1.65 var(--body);
  font-feature-settings: "cv05" 1, "ss03" 1;
  overflow-x: hidden;
  overflow-wrap: break-word;
}

/* Duennere Glaettung nur auf dunklem Grund. Helle Schrift auf Dunkel
   laeuft optisch zu, das gleicht antialiased aus. Auf hellem Grund
   macht dieselbe Einstellung den Text duenn und blass — dort bleibt
   es bei der Voreinstellung des Systems. */
:root:not([data-thema="hell"]) body { -webkit-font-smoothing: antialiased; }

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

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 500;
  color: var(--text);
  letter-spacing: -.02em;
  line-height: 1.08;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 var(--raum-3); }
p:last-child { margin-bottom: 0; }

strong { color: var(--text); font-weight: 600; }

a { color: var(--karmin-text); text-decoration-thickness: 1px; text-underline-offset: .22em; }
a:hover { color: var(--text); }

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

/* Fokus nimmt --text, nicht Rot. Im Dunkeln ist das der hellste Ton
   im Haus, im Hellen der dunkelste — so hebt sich der Rahmen in
   beiden Fassungen ab, auch auf den roten Flaechen. Wird nirgends
   entfernt. */
:focus-visible {
  outline: 3px solid var(--text);
  outline-offset: 3px;
  border-radius: 2px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Sprungmarke fuer die Tastatur */
.sprung {
  position: absolute; left: var(--rand); top: -6rem; z-index: 200;
  background: var(--karmin); color: #fff;
  padding: .75rem 1.25rem; border-radius: var(--kante);
  font: 600 .875rem var(--body); text-decoration: none;
  transition: top var(--tempo) var(--kurve);
}
.sprung:focus { top: 1rem; color: #fff; }

.bahn {
  width: 100%; max-width: var(--bahn);
  margin-inline: auto;
  padding-inline: var(--rand);
}

/* ============================================================
   Wiederkehrende Bausteine
   ============================================================ */

/* --- Label im Monospace-Satz ------------------------------- */
.label {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  font: 500 .6875rem/1.7 var(--mono);
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-still);
  margin: 0 0 var(--raum-3);
}
.label::before {
  content: ""; width: 1.75rem; height: 1px;
  background: var(--karmin); flex: none;
}
.label--ohne::before { display: none; }

/* --- Kapitelkopf ------------------------------------------- */
.abschnitt { padding-block: var(--raum-6); position: relative; }
.abschnitt--tief { background: var(--grund-tief); }
.abschnitt--eng { padding-block: var(--raum-5); }

@media (min-width: 60rem) {
  .abschnitt { padding-block: var(--raum-7); }
}

/* Teilstrich-Leiste: die Trennung zwischen zwei Kapiteln ist ein
   Massstab, kein Strich. */
.abschnitt + .abschnitt::before {
  content: ""; position: absolute; inset-inline: 0; top: 0; height: 9px;
  background:
    linear-gradient(to right, var(--linie) 1px, transparent 1px) 0 0 / 2.5rem 100%,
    linear-gradient(var(--linie-still), var(--linie-still)) 0 0 / 100% 1px;
  background-repeat: repeat-x, no-repeat;
  opacity: .85;
  pointer-events: none;
}

.kapitel {
  display: grid; gap: var(--raum-2);
  margin-bottom: var(--raum-5);
}
.kapitel h2 { font-size: clamp(1.875rem, 4.2vw, 2.75rem); }
.kapitel__text {
  max-width: 42rem; margin: 0;
  font-size: 1.0625rem;
}

@media (min-width: 60rem) {
  .kapitel {
    grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
    align-items: end; gap: var(--raum-4);
  }
  .kapitel__text { padding-bottom: .35rem; }
}

/* --- Schaltflaechen ---------------------------------------- */
.knopf {
  --knopf-grund: var(--karmin);
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center;
  gap: .65rem;
  min-height: 3rem; padding: .9rem 1.6rem;
  border: 1px solid transparent; border-radius: var(--kante);
  background: var(--knopf-grund); color: #fff;
  font: 600 .9375rem/1 var(--body); letter-spacing: -.005em;
  text-decoration: none; cursor: pointer;
  overflow: hidden;

  /* Drei Dinge greifen hier auf dieselbe Eigenschaft zu: der Magnet
     (folgt dem Zeiger), das Eindruecken beim Klick und der Anflug beim
     Scrollen. Frueher schrieb der Magnet `transform` direkt ins
     Element — eine Zeile im Stil-Attribut schlaegt jede Regel im
     Stylesheet, und `:active` kam damit nie zum Zug. Mit der Maus,
     also genau dann, wenn geklickt wird, sah man das Eindruecken nie.

     Jetzt schreibt jeder in seine eigene Eigenschaft, und die
     Transformation setzt sie zusammen. */
  --knopf-x: 0px;
  --knopf-y: 0px;
  --knopf-druck: 1;
  transform: translate(var(--knopf-x), var(--knopf-y)) scale(var(--knopf-druck));

  transition: transform 140ms var(--kurve), box-shadow 260ms var(--kurve);
  will-change: transform;
}
/* Die Flaeche wischt beim Zeigen durch — von links nach rechts,
   wie ein Strich, der gezogen wird. */
.knopf::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg, var(--karmin-tief), var(--karmin));
  transform: translateX(-101%);
  transition: transform var(--tempo-lang) var(--kurve);
}
.knopf:hover::before, .knopf:focus-visible::before { transform: translateX(0); }
/* Das Gluehen: zwei Schatten uebereinander. Der weiche traegt die
   Farbe weit nach aussen, der harte legt einen Haarrand um die Kante,
   damit der Knopf nicht ausfranst. Beim Druck ruecken beide enger — so
   wirkt er eingedrueckt statt nur kleiner. */
.knopf:hover, .knopf:focus-visible {
  color: #fff;
  box-shadow: 0 14px 40px -12px rgb(184 29 44 / .85),
              0 0 0 1px rgb(240 97 110 / .30);
}
.knopf:active {
  --knopf-druck: .97;
  box-shadow: 0 6px 16px -8px rgb(184 29 44 / .9),
              0 0 0 1px rgb(240 97 110 / .45);
}

/* Die Welle laeuft von der Stelle los, an der geklickt wurde — nicht
   aus der Mitte. Das ist der Unterschied zwischen „es hat reagiert"
   und „es hat auf *mich* reagiert". Die Stelle setzt main.js als
   --klick-x/--klick-y beim Druck. */
.knopf::after {
  content: ""; position: absolute; z-index: -1;
  left: var(--klick-x, 50%); top: var(--klick-y, 50%);
  width: 0; height: 0; border-radius: 50%;
  background: rgb(255 255 255 / .30);
  transform: translate(-50%, -50%);
  opacity: 0; pointer-events: none;
}
.knopf.ist-gedrueckt::after { animation: knopfwelle 620ms var(--kurve); }
@keyframes knopfwelle {
  from { width: 0; height: 0; opacity: .55; }
  to   { width: 280%; height: 680%; opacity: 0; }
}

/* Der Pfeil schiesst beim Klick kurz vor und faengt sich wieder. */
.knopf.ist-gedrueckt .knopf__pfeil { animation: pfeilstoss 440ms var(--kurve); }
@keyframes pfeilstoss {
  0%   { transform: translateX(3px); }
  35%  { transform: translateX(11px); }
  100% { transform: translateX(3px); }
}

.knopf__pfeil { transition: transform var(--tempo) var(--kurve); flex: none; }
/* Symbol vor der Beschriftung, z. B. der Hoerer vor der Rufnummer */
.knopf__symbol { width: 1.0625rem; height: 1.0625rem; flex: none; }
.knopf:hover .knopf__pfeil { transform: translateX(3px); }

.knopf--stil {
  --knopf-grund: transparent;
  border-color: var(--linie); color: var(--text);
}
.knopf--stil::before { background: var(--flaeche-hoch); }
.knopf--stil::after { background: rgb(240 97 110 / .18); }
/* Der Umrissknopf gluecht nicht, er nimmt Farbe an: Karmin am Rand
   statt Licht darum. Zwei leuchtende Knoepfe nebeneinander waeren
   zwei Hauptdarsteller. */
.knopf--stil:hover, .knopf--stil:focus-visible {
  border-color: var(--karmin); color: var(--text);
  box-shadow: 0 0 0 1px rgb(184 29 44 / .35);
}
.knopf--stil:active { box-shadow: 0 0 0 1px rgb(184 29 44 / .55); }

/* Textlink mit Anreisslinie, die beim Zeigen gezogen wird */
.strich-link {
  display: inline-flex; align-items: center; gap: .5rem;
  color: var(--text); text-decoration: none;
  font: 500 .9375rem/1 var(--body);
  padding-bottom: .4rem;
  background-image: linear-gradient(var(--karmin), var(--karmin));
  background-size: 0% 1px; background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size var(--tempo-lang) var(--kurve), color var(--tempo);
}
.strich-link:hover, .strich-link:focus-visible {
  color: var(--text); background-size: 100% 1px;
}
.strich-link svg { transition: transform var(--tempo) var(--kurve); }
.strich-link:hover svg { transform: translate(3px, -3px); }

/* ============================================================
   Kopfleiste
   ============================================================ */
.kopf {
  position: fixed; inset-inline: 0; top: 0; z-index: 100;
  height: var(--kopfhoehe);
  display: flex; align-items: center;
  background: var(--glas);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid transparent;
  transition: background var(--tempo) var(--kurve),
              border-color var(--tempo) var(--kurve),
              height var(--tempo) var(--kurve),
              transform 420ms var(--kurve);
}
.kopf.ist-gescrollt {
  background: var(--glas-fest);
  border-bottom-color: var(--linie-still);
}
@media (min-width: 60rem) {
  .kopf.ist-gescrollt { height: 4.25rem; }
}

.kopf__bahn {
  width: 100%; max-width: var(--bahn); margin-inline: auto;
  padding-inline: var(--rand);
  display: flex; align-items: center; justify-content: space-between; gap: var(--raum-3);
}

/* Wortmarke: der Punkt ist die Anreisslinie im Kleinformat */
.marke {
  display: inline-flex; align-items: baseline; gap: .5rem;
  text-decoration: none; color: var(--text);
  font: 600 1.0625rem/1 var(--display); letter-spacing: -.01em;
}
.marke__punkt {
  width: .4rem; height: .4rem; border-radius: 50%;
  background: var(--karmin); flex: none;
  transition: transform var(--tempo-lang) var(--kurve), background var(--tempo);
}
.marke:hover .marke__punkt { transform: scale(1.6); background: var(--karmin-text); }
.marke__zusatz { color: var(--text-leise); font: 400 .8125rem var(--body); }

/* Lesefortschritt: eine Anreisslinie, die mitwaechst */
.fortschritt {
  position: absolute; left: 0; bottom: -1px; height: 2px;
  width: 100%; transform: scaleX(0); transform-origin: 0 50%;
  background: linear-gradient(to right, var(--karmin-tief), var(--karmin));
  pointer-events: none;
}

/* --- Umschalter hell/dunkel -------------------------------- */
.thema-schalter {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; padding: 0; flex: none;
  background: none; border: 1px solid var(--linie); border-radius: var(--kante);
  color: var(--text-still); cursor: pointer;
  transition: color var(--tempo) var(--kurve),
              border-color var(--tempo) var(--kurve),
              background var(--tempo) var(--kurve);
}
.thema-schalter:hover {
  color: var(--text); border-color: var(--text-leise); background: var(--flaeche);
}
.thema-schalter svg {
  width: 1.125rem; height: 1.125rem;
  transition: transform var(--tempo-lang) var(--kurve);
}
.thema-schalter:hover svg { transform: rotate(35deg); }
.thema-schalter:hover { box-shadow: 0 0 0 1px rgb(184 29 44 / .3); }
/* Beim Umschalten dreht das Zeichen einmal ganz durch — der Wechsel
   zwischen hell und dunkel ist die groesste Aenderung, die ein Knopf
   auf dieser Seite ausloest, und darf sich so anfuehlen. */
.thema-schalter:active { transform: scale(.94); }
.thema-schalter.ist-gedreht svg { animation: themadrehung 520ms var(--kurve); }
@keyframes themadrehung {
  from { transform: rotate(35deg); }
  to   { transform: rotate(395deg); }
}

/* Gezeigt wird immer das Ziel, nicht der Zustand: im Dunkeln die
   Sonne (dorthin geht es), im Hellen der Mond. */
.ikon-mond { display: none; }
:root[data-thema="hell"] .ikon-sonne { display: none; }
:root[data-thema="hell"] .ikon-mond  { display: block; }

/* --- Navigation -------------------------------------------- */
.nav__schalter {
  display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 2.75rem; height: 2.75rem; padding: 0;
  background: none; border: 1px solid var(--linie); border-radius: var(--kante);
  cursor: pointer;
}
.nav__schalter span {
  display: block; width: 1.125rem; height: 1.5px; margin-inline: auto;
  background: var(--text);
  transition: transform var(--tempo) var(--kurve), opacity 120ms linear;
}
.nav__schalter[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav__schalter[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__schalter[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* Rechte Seite der Kopfzeile: Navigation, Anfrage-Knopf, Menuschalter.
   Der Knopf steht bewusst AUSSERHALB der Navigation — sonst verschwindet
   er auf dem Telefon im zugeklappten Menue, und das ist der eine Knopf,
   der immer erreichbar sein muss. */
.kopf__rechts { display: flex; align-items: center; gap: var(--raum-2); }

.nav { display: flex; align-items: center; gap: var(--raum-3); }

.nav__liste {
  display: flex; align-items: center; gap: .35rem;
  list-style: none; margin: 0; padding: 0;
}

.nav__link {
  position: relative;
  display: block; padding: .55rem .8rem;
  color: var(--text-still); text-decoration: none;
  font: 500 .875rem/1 var(--body);
  border-radius: var(--kante);
  transition: color var(--tempo) var(--kurve);
}
.nav__link::after {
  content: ""; position: absolute; left: .8rem; right: .8rem; bottom: .25rem;
  height: 1px; background: var(--karmin);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform var(--tempo-lang) var(--kurve);
}
.nav__link:hover { color: var(--text); }
.nav__link:hover::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { color: var(--text); }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

.kopf__knopf { padding: .7rem 1.1rem; min-height: 2.75rem; font-size: .875rem; white-space: nowrap; }

/* Zwei Beschriftungen, je nach Platz. Die jeweils andere wird ganz
   entfernt (display:none), nicht nur versteckt — so hoert ein
   Vorleseprogramm genau das, was auch dasteht. */
.nur-schmal { display: none; }

/* Ohne JavaScript bleibt die Navigation sichtbar. Erst main.js
   schaltet auf das Klappmenue um (Klasse am <html>). */
.js .nav__schalter { display: inline-flex; }
.nav__schalter { display: none; }

/* Der Umschalter zwischen heller und dunkler Fassung braucht JavaScript.
   Ohne es waere er ein Knopf, der nichts tut — dann lieber gar keiner.
   Die dunkle Fassung bleibt, sie ist der Standard. */
html:not(.js) .thema-schalter { display: none; }

@media (max-width: 59.99rem) {
  .js .nav {
    position: fixed; inset: var(--kopfhoehe) 0 auto;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: var(--raum-2) var(--rand) var(--raum-3);
    background: var(--grund-tief);
    border-bottom: 1px solid var(--linie-still);
    box-shadow: var(--schatten-menue);
    transform: translateY(-8px); opacity: 0; visibility: hidden;
    transition: opacity var(--tempo) var(--kurve),
                transform var(--tempo) var(--kurve),
                visibility 0s linear var(--tempo);
  }
  .js .nav.ist-offen {
    transform: none; opacity: 1; visibility: visible;
    transition-delay: 0s;
  }
  .nav__liste { flex-direction: column; align-items: stretch; gap: 0; }
  /* Fingerbreite Zeilen: 56 px hoch, damit niemand zielen muss. */
  .nav__link {
    padding: 1.1rem .25rem; font-size: 1.0625rem;
    border-bottom: 1px solid var(--linie-still);
  }
  .nav__liste li:last-child .nav__link { border-bottom: 0; }
  .nav__link::after { left: .25rem; right: auto; width: 1.5rem; bottom: .7rem; }

  /* Der Umschalter wandert ins Menue. Vier Dinge nebeneinander sprengen
     die Kopfzeile auf schmalen Geraeten — bei 320 px rutschte der
     Menueknopf aus dem Bild. Im Menue ist ohnehin Platz, und dort kann
     er zeigen, was er tut, statt nur ein Symbol zu sein. */
  .js .nav .thema-schalter {
    width: 100%; height: auto; justify-content: flex-start; gap: .85rem;
    border: 0; border-top: 1px solid var(--linie-still); border-radius: 0;
    padding: 1.1rem .25rem; margin-top: .25rem;
    font: 500 1.0625rem/1.4 var(--body); color: var(--text-still);
    text-align: left;
  }
  .js .nav .thema-schalter:hover { background: none; color: var(--text); }
  .js .nav .thema-schalter:hover svg { transform: none; }
  /* Die Beschriftung, die sonst nur Vorleseprogramme hoeren, wird hier
     sichtbar — im Menue erklaert sich ein blosses Symbol nicht. */
  .js .nav .thema-schalter .sr-only {
    position: static; width: auto; height: auto;
    margin: 0; overflow: visible; clip: auto; white-space: normal;
  }

  /* Auf dem Telefon steht „Anfragen“ — „Projekt“ frisst nur Platz. */
  .nur-breit  { display: none; }
  .nur-schmal { display: inline; }
  .kopf__knopf { padding: .7rem .95rem; }

  /* Ohne JavaScript gibt es kein Klappmenue — die Navigation steht offen.
     Dann passt sie aber nicht mehr neben Wortmarke und Anfrage-Knopf in
     eine Zeile fester Hoehe: Die Verweise legten sich ueber die Marke und
     der Anfrage-Knopf wurde am rechten Rand abgeschnitten. Die Kopfzeile
     laeuft deshalb ohne JavaScript im Fluss mit, waechst mit ihrem Inhalt
     und setzt die Navigation in eine eigene Zeile darunter. */
  html:not(.js) { --kopfhoehe: 0rem; }
  html:not(.js) .kopf {
    position: static; height: auto;
    padding-block: var(--raum-2);
    border-bottom: 1px solid var(--linie-still);
  }
  html:not(.js) .kopf__bahn { flex-wrap: wrap; row-gap: var(--raum-2); }
  /* display:contents loest die Zwischenschachtel auf, damit Marke, Knopf
     und Navigation in derselben Zeilenumbruch-Ebene liegen. Die Schachtel
     traegt keine Bedeutung, nur Abstand — es geht nichts verloren. */
  html:not(.js) .kopf__rechts { display: contents; }
  html:not(.js) .kopf__knopf { order: 2; }
  html:not(.js) .nav {
    order: 3; flex-basis: 100%;
    flex-direction: column; align-items: stretch; gap: 0;
    border-top: 1px solid var(--linie-still);
  }
}

@media (min-width: 60rem) {
  .nav__schalter, .js .nav__schalter { display: none; }
  .kopf__rechts { gap: var(--raum-3); }
}

/* ============================================================
   Geflecht — der lebende Grund hinter der ganzen Seite
   ============================================================ */

/* Ein Feld feiner Punkte, das sich um den Zeiger vernetzt. Gezeichnet
   wird in JavaScript (Abschnitt 7 in main.js); hier steht nur, wo die
   Flaeche liegt und wie sie erscheint.

   position: fixed, nicht absolute: das Feld soll beim Scrollen stehen
   bleiben statt mitzufahren, und die Zeichenflaeche bleibt so gross wie
   das Fenster — nicht so hoch wie das Dokument.

   z-index: -1 legt sie unter jeden Inhalt, aber ueber den Seitengrund:
   Der Hintergrund des <body> wird auf die Wurzelflaeche uebertragen und
   ganz zuunterst gezeichnet, auch unter negative Ebenen. Abschnitte mit
   eigenem Grund (Formularblock, Fusszeile, Karten) decken das Geflecht
   dagegen ab — dort scheint es nur in den Zwischenraeumen durch.

   Ohne JavaScript bleibt die Flaeche leer und unsichtbar. */
.geflecht {
  position: fixed; inset: 0; z-index: -1;
  display: block; width: 100%; height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 900ms ease-out;
}
.geflecht.ist-da { opacity: 1; }

/* ============================================================
   Hero
   ============================================================ */
.hero {
  position: relative; isolation: isolate;
  padding-top: calc(var(--kopfhoehe) + var(--raum-5));
  padding-bottom: var(--raum-6);
  overflow: hidden;
}

/* Kein max-width hier — sonst schlaegt es die Bahnbreite und der Hero
   steht enger als die Kopfzeile. Begrenzt wird jede Zeile einzeln. */
.hero__inhalt { position: relative; }

.hero h1 {
  max-width: 22ch;
  font-size: clamp(2.625rem, 7.4vw, 5.125rem);
  line-height: .98;
  letter-spacing: -.035em;
  margin-bottom: var(--raum-3);
}
/* Jede Hero-Zeile ist ein eigener Block — nur so laesst sie sich
   einzeln hinter ihrer Maske hochschieben. */
.hero h1 .steigt { display: block; }
.hero h1 em {
  font-style: normal;
  color: var(--karmin-text);
}

.hero__text {
  max-width: 38rem;
  font-size: clamp(1.0625rem, 1.6vw, 1.1875rem);
  color: var(--text-still);
  margin-bottom: var(--raum-4);
}

.hero__knoepfe {
  display: flex; flex-wrap: wrap; gap: var(--raum-2);
  align-items: center;
}
.hero .hero__knoepfe { margin-bottom: var(--raum-5); }

/* Dieselbe Reihe ausserhalb des Heros — eigener Name, damit niemand raten
   muss, warum unter dem Preisblock „hero" steht. */
.knopfreihe {
  display: flex; flex-wrap: wrap; gap: var(--raum-2);
  align-items: center;
}

/* Der Weg zum Preis: steht unter beiden Tafeln, gilt fuer beide. */
.preis__weg {
  max-width: 42rem; margin: var(--raum-4) 0 var(--raum-3);
  font-size: 1.0625rem; line-height: 1.65;
}
.preis__weg strong { color: var(--text); }

/* Die Massleiste unter dem Hero: waechst beim Laden von 0 auf voll */
.masslinie {
  position: relative; height: 10px; margin-bottom: var(--raum-4);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform 1400ms var(--kurve) 640ms;
}
.masslinie.ist-gezogen { transform: scaleX(1); }
.masslinie::before {
  content: ""; position: absolute; inset-inline: 0; top: 0; height: 1px;
  background: linear-gradient(to right, var(--karmin), var(--karmin-tief) 65%, transparent);
}
.masslinie::after {
  content: ""; position: absolute; inset-inline: 0; top: 0; height: 100%;
  background: linear-gradient(to right, var(--karmin) 1px, transparent 1px) 0 0 / 3rem 6px;
  background-repeat: repeat-x;
  opacity: .55;
}


/* ============================================================
   Seitenkopf der Unterseiten
   ============================================================ */
.seitenkopf {
  position: relative; isolation: isolate; overflow: hidden;
  padding-top: calc(var(--kopfhoehe) + var(--raum-5));
  padding-bottom: var(--raum-5);
}
.seitenkopf h1 {
  max-width: 20ch;
  font-size: clamp(2.25rem, 5.6vw, 3.75rem);
  line-height: 1.02; letter-spacing: -.032em;
  margin-bottom: var(--raum-3);
}
.seitenkopf__text { max-width: 40rem; font-size: clamp(1.0625rem, 1.5vw, 1.125rem); }

/* ============================================================
   Karten (Leistungen)
   ============================================================ */
.karten {
  display: grid; gap: var(--raum-3);
  grid-template-columns: repeat(auto-fit, minmax(17.5rem, 1fr));
  list-style: none; margin: 0; padding: 0;
}

.karte {
  position: relative; isolation: isolate;
  display: flex; flex-direction: column; gap: var(--raum-2);
  padding: var(--raum-4) var(--raum-3) var(--raum-4);
  background-color: var(--flaeche);
  border: 1px solid var(--linie-still);
  border-radius: var(--kante);
  box-shadow: var(--karte-schatten);

  /* Lichtsaum an der Oberkante, der beim Zeigen von der Mitte nach aussen
     aufzieht. Als Hintergrundbild statt als eigenes Element: ein zusaetzliches
     Kind haette die Zaehlung fuer das gestaffelte Aufblenden verschoben und
     waere selbst mit aufgeblendet worden. Deshalb steht oben auch
     background-color statt der Kurzform — die wuerde das Bild bei jedem
     Zustandswechsel mit loeschen. */
  background-image: linear-gradient(to right, transparent, var(--karmin), transparent);
  background-repeat: no-repeat;
  background-position: 50% 0;
  background-size: 0 2px;

  transition: background-color var(--tempo) var(--kurve),
              background-size var(--tempo-lang) var(--kurve),
              transform var(--tempo-lang) var(--kurve),
              border-color var(--tempo) var(--kurve);
}
/* Passermarken an den Ecken, wie auf einem Druckbogen */
.karte::before, .karte::after {
  content: ""; position: absolute; width: 10px; height: 10px;
  border: 1px solid var(--karmin);
  opacity: 0; transition: opacity var(--tempo) var(--kurve), transform var(--tempo-lang) var(--kurve);
}
.karte::before { top: -1px; left: -1px; border-width: 1px 0 0 1px; transform: translate(4px, 4px); }
.karte::after  { bottom: -1px; right: -1px; border-width: 0 1px 1px 0; transform: translate(-4px, -4px); }
.karte:hover, .karte:focus-within {
  background-color: var(--flaeche-hoch); border-color: var(--linie);
  background-size: 100% 2px;
}

/* Das Anheben braucht eine eigene, spezifischere Regel: Die Karten tragen
   .zeigt, und `.js .zeigt.ist-sichtbar { transform: none }` ist mit drei
   Klassen staerker als `.karte:hover` mit zweien. Ohne die zweite Zeile
   wird das Anheben verschluckt — es hat aus genau diesem Grund noch nie
   gewirkt, ohne dass es jemandem auffiel. */
.karte:hover, .karte:focus-within,
.js .karte.ist-sichtbar:hover,
.js .karte.ist-sichtbar:focus-within { transform: translateY(-4px); }
.karte:hover::before, .karte:hover::after { opacity: 1; transform: translate(0, 0); }
.karte:focus-within::before, .karte:focus-within::after { opacity: 1; transform: translate(0, 0); }

.karte__nr {
  font: 500 .6875rem/1 var(--mono); letter-spacing: .18em;
  color: var(--text-leise);
}
.karte h3 { font-size: 1.375rem; }
.karte p { font-size: .9375rem; margin-bottom: 0; }
.karte__liste {
  list-style: none; margin: auto 0 0; padding: var(--raum-2) 0 0;
  display: grid; gap: .5rem;
  font-size: .875rem;
  border-top: 1px solid var(--linie-still);
}
.karte__liste li { display: flex; gap: .6rem; align-items: flex-start; }
.karte__liste li::before {
  /* 2px statt 1px: eine Haarlinie faellt bei krummen Bildschirm-
     positionen der Kantenglaettung zum Opfer und wirkt dann grau
     statt rot. Auf hellem Grund faellt das sofort auf. */
  content: ""; flex: none; width: .9rem; height: 2px;
  background: var(--karmin); margin-top: .65rem;
}

/* Symbol in der Karte */
.karte__symbol {
  width: 2rem; height: 2rem; color: var(--karmin-text);
  transition: transform var(--tempo-lang) var(--kurve);
}
.karte:hover .karte__symbol, .karte:focus-within .karte__symbol {
  transform: translateY(-3px) rotate(-4deg) scale(1.06);
}

/* Beim Zeigen: die Kennziffer nimmt Farbe an und atmet auseinander,
   die Striche vor den Listenpunkten wachsen nacheinander nach. Der
   Versatz laeuft von oben nach unten durch — dieselbe Leserichtung
   wie beim Aufblenden. */
.karte__nr { transition: color var(--tempo) var(--kurve), letter-spacing var(--tempo-lang) var(--kurve); }
.karte:hover .karte__nr, .karte:focus-within .karte__nr {
  color: var(--karmin-text); letter-spacing: .26em;
}

.karte__liste li::before { transition: width var(--tempo-lang) var(--kurve), background var(--tempo) var(--kurve); }
.karte:hover .karte__liste li::before, .karte:focus-within .karte__liste li::before { width: 1.5rem; }
.karte:hover .karte__liste li:nth-child(1)::before { transition-delay:   0ms; }
.karte:hover .karte__liste li:nth-child(2)::before { transition-delay:  45ms; }
.karte:hover .karte__liste li:nth-child(3)::before { transition-delay:  90ms; }
.karte:hover .karte__liste li:nth-child(n+4)::before { transition-delay: 135ms; }

/* Der Text der Karte ruecht dabei ein Haar mit — ohne das wirkt die
   Karte beim Anheben, als bliebe ihr Inhalt zurueck. */
.karte h3 { transition: transform var(--tempo-lang) var(--kurve); }
.karte:hover h3, .karte:focus-within h3 { transform: translateX(3px); }

/* ============================================================
   Fallstudie
   ============================================================ */
.fall {
  display: grid; gap: var(--raum-4);
  align-items: start;
}
@media (min-width: 60rem) {
  .fall { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: var(--raum-5); }

  /* Auf der Referenzseite steht jedes Projekt untereinander: erst die
     Bildschirmansicht in voller Breite, darunter die Beschreibung. Nebeneinander
     wird das Vorschaubild so klein, dass man nichts mehr erkennt — und genau
     dafuer ist es da. */
  .fall--untereinander { grid-template-columns: minmax(0, 1fr); gap: var(--raum-4); }
}

.fall--untereinander .fall__bild { max-width: 58rem; }
.fall--untereinander .fall__text { max-width: var(--bahn-eng); }

.fall__bild {
  position: relative;
  border: 1px solid var(--linie-still); border-radius: var(--kante);
  overflow: hidden; background: var(--flaeche);
  box-shadow: var(--karte-schatten);
}
.fall__bild img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

.fall__schritte {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 0;
  counter-reset: schritt;
}
.fall__schritt {
  position: relative;
  display: grid; grid-template-columns: 3rem 1fr; gap: var(--raum-2);
  padding: var(--raum-3) 0;
  border-top: 1px solid var(--linie-still);
}
.fall__schritt:last-child { border-bottom: 1px solid var(--linie-still); }
.fall__schritt::before {
  counter-increment: schritt;
  content: counter(schritt, decimal-leading-zero);
  font: 500 .75rem/1.9 var(--mono); letter-spacing: .12em;
  color: var(--karmin-text);
}
.fall__schritt h3 { font-size: 1.125rem; margin-bottom: .35rem; font-family: var(--body); font-weight: 600; letter-spacing: 0; }
.fall__schritt p { font-size: .9375rem; margin: 0; }

/* Beim Zeigen: die Zeile rueckt ein, ein Balken faehrt links heraus,
   die Nummer wird heller. Diese Kaesten waren die einzigen auf der
   Startseite, die auf gar nichts reagiert haben — und man scrollt
   direkt an ihnen entlang. */
.fall__schritt {
  transition: background var(--tempo) var(--kurve), padding-left var(--tempo-lang) var(--kurve);
  border-radius: var(--kante);
}
.fall__schritt::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--karmin);
  transform: scaleY(0); transform-origin: 50% 0;
  transition: transform var(--tempo-lang) var(--kurve);
}
.fall__schritt:hover { background: var(--flaeche); padding-left: var(--raum-2); }
.fall__schritt:hover::after { transform: scaleY(1); }
.fall__schritt::before { transition: color var(--tempo) var(--kurve), transform var(--tempo-lang) var(--kurve); }
.fall__schritt:hover::before { transform: translateX(2px); }
.fall__schritt h3 { transition: transform var(--tempo-lang) var(--kurve); }
.fall__schritt:hover h3 { transform: translateX(3px); }

/* Das Zitat holt beim Zeigen Luft: der rote Balken wird breiter und
   der Satz rueckt mit. */
.zitat { transition: border-left-width var(--tempo-lang) var(--kurve), padding-left var(--tempo-lang) var(--kurve); }
.zitat:hover { border-left-width: 4px; padding-left: calc(var(--raum-3) + 4px); }

/* Bildschirmansichten, die nicht beschnitten werden duerfen.
   .fall__bild schneidet sonst auf 4:3 zu — bei einer dichten Oberflaeche
   traegt aber gerade der Rand Information (Randspalten, Fusszeile). */
.fall__bild--voll img { aspect-ratio: auto; object-fit: contain; }

/* Mehrere Ansichten desselben Projekts nebeneinander, jede mit Bildunterschrift.
   Ein Bild allein zeigt bei einem groesseren System zu wenig. */
.ansichten {
  display: grid; gap: var(--raum-3);
  grid-template-columns: minmax(0, 1fr);
  margin-top: var(--raum-4);
}
@media (min-width: 34rem) { .ansichten { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 56rem) { .ansichten { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.ansicht { margin: 0; }
.ansicht img {
  width: 100%; display: block; aspect-ratio: 62 / 40;
  border: 1px solid var(--linie-still); border-radius: var(--kante);
  background: var(--flaeche);
}
.ansicht figcaption {
  margin-top: .7rem; font-size: .8125rem; line-height: 1.55;
  color: var(--text-still);
}
.ansicht figcaption strong {
  display: block; color: var(--text); font-weight: 600;
  font-size: .875rem; margin-bottom: .2rem;
}

/* Uebersicht ueber mehrere Arbeiten: eine Zeile je Projekt, damit der Umfang
   ohne Scrollen erkennbar ist. Als Liste gebaut, nicht als Tabelle — es sind
   keine Messwerte, und auf dem Telefon bricht eine Tabelle schlecht um. */
.uebersicht {
  list-style: none; margin: var(--raum-4) 0 0; padding: 0;
  border-top: 1px solid var(--linie);
}
.uebersicht li {
  display: grid; gap: .25rem var(--raum-3);
  grid-template-columns: minmax(0, 1fr);
  padding: var(--raum-3) 0;
  border-bottom: 1px solid var(--linie-still);
}
@media (min-width: 48rem) {
  .uebersicht li { grid-template-columns: 9rem minmax(0, 1fr) minmax(0, 1fr); align-items: baseline; }
}
.uebersicht__fach {
  font: 500 .6875rem/1.6 var(--mono); letter-spacing: .16em; text-transform: uppercase;
  color: var(--karmin-text);
}
.uebersicht__was { font-size: .9375rem; color: var(--text); }
.uebersicht__kern { font-size: .9375rem; color: var(--text-still); }

/* Fussnote unter einem Abschnitt: sachliche Einordnung, kein Warnkasten. */
.fussnote {
  margin-top: var(--raum-3);
  font-size: .8125rem; line-height: 1.6; color: var(--text-leise);
  max-width: 42rem;
}

/* Ergebniszeile */
.ergebnis {
  display: grid; gap: var(--raum-3);
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  margin-top: var(--raum-4); padding-top: var(--raum-3);
  border-top: 1px solid var(--karmin);
  list-style: none; padding-inline: 0;
}
.ergebnis dt { font: 500 .6875rem/1 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--text-leise); margin-bottom: .5rem; }
.ergebnis dd { margin: 0; font-size: .9375rem; color: var(--text); }

/* ============================================================
   Preis
   ============================================================ */
.preis-schalter {
  position: relative; display: inline-flex; gap: 0;
  padding: 4px; margin-bottom: var(--raum-4);
  background: var(--flaeche); border: 1px solid var(--linie-still);
  border-radius: var(--kante);
}
.preis-schalter__marke {
  position: absolute; top: 4px; bottom: 4px; left: 4px;
  /* Die halbe Breite als Ausgangswert ist kein Schoenheitswert: die
     Beschriftung des gewaehlten Reiters ist weiss und braucht die rote
     Flaeche darunter. Ohne diesen Startwert waere sie weiss auf weiss,
     solange main.js noch nicht gerechnet hat — und ohne JavaScript
     dauerhaft. JS ueberschreibt die Breite sofort exakt. */
  width: calc(50% - 4px);
  border-radius: 2px; background: var(--karmin);
  transition: transform var(--tempo-lang) var(--kurve), width var(--tempo-lang) var(--kurve);
  pointer-events: none;
}
.preis-schalter button {
  position: relative; z-index: 1;
  min-height: 2.75rem; padding: .6rem 1.25rem;
  background: none; border: 0; border-radius: 2px;
  color: var(--text-still); cursor: pointer;
  font: 600 .875rem/1 var(--body);
  transition: color var(--tempo) var(--kurve);
}
.preis-schalter button[aria-selected="true"] { color: #fff; }
.preis-schalter button:hover { color: var(--text); }
/* Beim Druck sinkt die Beschriftung mit, sonst wirkt der Reiter tot,
   waehrend die Marke darunter schon losfaehrt. */
.preis-schalter button:active { transform: scale(.97); }

/* Die Marke gluecht wie der Hauptknopf — es ist dieselbe Farbe in
   derselben Rolle, also soll sie sich auch gleich verhalten. */
.preis-schalter__marke { box-shadow: 0 6px 20px -8px rgb(184 29 44 / .75); }

.preis-tafel {
  display: grid; gap: var(--raum-4);
  padding: var(--raum-4);
  background: var(--flaeche); border: 1px solid var(--linie-still);
  border-radius: var(--kante);
  box-shadow: var(--karte-schatten);
}
@media (min-width: 60rem) {
  .preis-tafel { grid-template-columns: minmax(0, 20rem) minmax(0, 1fr); gap: var(--raum-5); padding: var(--raum-5); }
}
.preis-tafel[hidden] { display: none; }

.preis__zahl {
  font: 500 clamp(2.5rem, 6vw, 3.75rem)/1 var(--display);
  color: var(--text); letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
  display: block; margin-bottom: .35rem;
}
.preis__ab { font: 500 .6875rem/1 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--karmin-text); display: block; margin-bottom: .75rem; }
.preis__dazu {
  margin-top: var(--raum-3); padding-top: var(--raum-3);
  border-top: 1px solid var(--linie);
  font-size: .9375rem;
}
.preis__dazu .betrag { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }

.leistungsliste {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .85rem;
  font-size: .9375rem;
}
.leistungsliste li { display: grid; grid-template-columns: 1.25rem 1fr; gap: .75rem; align-items: start; }
.leistungsliste svg { width: 1.25rem; height: 1.25rem; color: var(--karmin-text); margin-top: .15rem; }

/* Portrait */
.portrait {
  position: relative;
  border: 1px solid var(--linie-still); border-radius: var(--kante);
  overflow: hidden; background: var(--flaeche);
  box-shadow: var(--karte-schatten);
}
.portrait img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.portrait__marke {
  position: absolute; left: var(--raum-2); bottom: var(--raum-2);
  font: 500 .625rem/1 var(--mono); letter-spacing: .18em; text-transform: uppercase;
  color: var(--glas-marke-text); background: var(--glas-marke);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  padding: .5rem .7rem; border-radius: 2px;
  border-left: 2px solid var(--karmin);
}

/* Zitat */
.zitat {
  margin: 0; padding-left: var(--raum-3);
  border-left: 2px solid var(--karmin);
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.25rem, 2.6vw, 1.75rem); line-height: 1.35;
  color: var(--text); letter-spacing: -.02em;
}
.zitat footer { margin-top: var(--raum-2); font: 500 .6875rem/1 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--text-leise); }

/* ------------------------------------------------------------
   Einbettung mit Einwilligung (Zwei-Klick)

   Das Rezensions-Widget laedt von einem fremden Server und
   uebertraegt dabei die IP jedes Besuchers. Das braucht eine
   Einwilligung — aber kein Banner auf jeder Seite: Solange
   niemand hier klickt, wird nichts geladen, kein Cookie gesetzt
   und nichts uebertragen. Die Seite bleibt also das, was sie
   verspricht, bis jemand sich anders entscheidet.

   Der zweite Klick ist gleichzeitig die Einwilligung. Sie merkt
   sich der Browser in localStorage — kein Cookie noetig, und
   widerrufen laesst sie sich mit einem Klick darunter.
   ------------------------------------------------------------ */
/* Es gibt nur noch eine Fassung: das kleine Zeichen in der Fusszeile.
   Der grosse Kasten auf der Startseite ist raus — zwei Rezensions-
   anzeigen auf einer Seite waren eine zu viel. */
.einbettung { position: relative; }
.einbettung__frage { display: grid; gap: var(--raum-2); text-align: left; }
.einbettung__inhalt:empty { display: none; }

/* Kleine Fassung fuer die Fusszeile: kein Rahmen, kein Hintergrund — in
   einer Fusszeile waere ein Kasten ein Fremdkoerper. Nur Text, ein
   zurueckhaltender Knopf und die Feinschrift darunter. */
.einbettung--klein { max-width: 15rem; align-self: end; }
.einbettung--klein .einbettung__frage { gap: .6rem; }

.einbettung__klein-text {
  font: 500 .6875rem/1.6 var(--mono); letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-leise); margin: 0;
}
.einbettung__klein-knopf {
  justify-self: start;
  font: 500 .8125rem/1 var(--body);
  color: var(--text); background: none;
  border: 1px solid var(--linie); border-radius: var(--kante);
  padding: .55rem .9rem; cursor: pointer;
  transition: border-color var(--tempo) var(--kurve),
              background var(--tempo) var(--kurve),
              color var(--tempo) var(--kurve);
}
.einbettung__klein-knopf:hover {
  border-color: var(--karmin); background: var(--flaeche); color: var(--text);
}
.einbettung__klein-fein {
  font-size: .75rem; line-height: 1.5; color: var(--text-leise); margin: 0;
}
.einbettung__klein-fein a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.einbettung__klein-fein a:hover { color: var(--text-still); }

.einbettung__zurueck {
  display: block; margin-top: var(--raum-2);
  font-size: .8125rem; color: var(--text-leise);
  background: none; border: 0; padding: 0;
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer; font-family: inherit;
}
.einbettung__zurueck:hover { color: var(--text-still); }

/* ============================================================
   Formular
   ============================================================ */
.formblock { background: var(--grund-tief); }

/* Formular links, der direkte Weg rechts. Wer nicht tippen mag,
   soll nicht erst suchen muessen. */
.anfrage-satz { display: grid; gap: var(--raum-5); align-items: start; }
@media (min-width: 60rem) {
  .anfrage-satz { grid-template-columns: minmax(0, 1fr) minmax(0, 22rem); gap: var(--raum-5); }
}

.anfrage-seite {
  display: grid; gap: var(--raum-4);
  padding: var(--raum-4);
  background: var(--flaeche);
  border: 1px solid var(--linie-still);
  border-left: 2px solid var(--karmin);
  border-radius: var(--kante);
  box-shadow: var(--karte-schatten);
}
.anfrage-seite h3 { font-size: 1.125rem; font-family: var(--body); font-weight: 600; letter-spacing: 0; margin-bottom: var(--raum-2); }

.ablaufliste { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--raum-2); counter-reset: ablauf; }
.ablaufliste li { display: grid; grid-template-columns: 1.75rem 1fr; gap: .5rem; font-size: .875rem; }
.ablaufliste li::before {
  counter-increment: ablauf;
  content: counter(ablauf, decimal-leading-zero);
  font: 500 .6875rem/1.7 var(--mono); letter-spacing: .12em; color: var(--karmin-text);
}

.form { display: grid; gap: var(--raum-3); max-width: 42rem; }

.feld { display: grid; gap: .5rem; }
.feld > label, .feld__legende {
  font: 500 .8125rem/1.4 var(--body);
  color: var(--text); letter-spacing: .01em;
}
.feld__hinweis { font-size: .8125rem; color: var(--text-leise); margin: 0; }

.form input[type="text"],
.form input[type="email"],
.form input[type="tel"],
.form select,
.form textarea {
  width: 100%; min-height: 3rem;
  padding: .8rem .9rem;
  background: var(--flaeche); color: var(--text);
  border: 1px solid var(--linie); border-radius: var(--kante);
  font: 400 1rem/1.5 var(--body);
  transition: border-color var(--tempo) var(--kurve), background var(--tempo) var(--kurve);
}
.form textarea { min-height: 8.5rem; resize: vertical; }
.form select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-still) 50%),
                    linear-gradient(135deg, var(--text-still) 50%, transparent 50%);
  background-position: calc(100% - 1.15rem) 1.35rem, calc(100% - .8rem) 1.35rem;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 2.5rem;
}
.form input:hover, .form textarea:hover, .form select:hover { background: var(--flaeche-hoch); }
.form input:focus, .form textarea:focus, .form select:focus { border-color: var(--karmin); }

.feld--fehler input, .feld--fehler textarea, .feld--fehler select { border-color: var(--karmin-text); }
.fehler {
  margin: 0; font-size: .8125rem; color: var(--karmin-text);
  display: flex; gap: .4rem; align-items: baseline;
}
.fehler::before { content: "\2715"; font-size: .7em; }

.feld-reihe { display: grid; gap: var(--raum-3); }
@media (min-width: 40rem) { .feld-reihe { grid-template-columns: 1fr 1fr; } }

fieldset { margin: 0; padding: 0; border: 0; }

/* Auswahlkacheln statt nackter Radios */
.wahl { display: grid; gap: .75rem; margin-top: .75rem; }
@media (min-width: 40rem) { .wahl { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); } }

/* Die Karte ist ein <label>, das Optionsfeld liegt unsichtbar darueber.
   Beides zusammen: Der Klick trifft ueberall auf der Karte, und der
   Screenreader bekommt den Namen, den ein blosses <span> ihm nicht
   geben konnte. Das Aussehen ist unveraendert — ein label ohne eigene
   Regeln zeichnet sich wie ein span. */
.wahl__feld { position: relative; }
.wahl__feld input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; margin: 0; cursor: pointer;
}
.wahl__feld label {
  display: flex; align-items: center; gap: .7rem;
  min-height: 3rem; padding: .8rem 1rem;
  background: var(--flaeche); border: 1px solid var(--linie);
  border-radius: var(--kante); color: var(--text-still);
  font-size: .9375rem;
  transition: border-color var(--tempo) var(--kurve),
              color var(--tempo) var(--kurve),
              background var(--tempo) var(--kurve);
}
.wahl__feld label::before {
  content: ""; flex: none; width: .75rem; height: .75rem;
  border: 1px solid var(--linie); border-radius: 50%;
  transition: border-color var(--tempo), box-shadow var(--tempo);
}
.wahl__feld input:checked + label {
  border-color: var(--karmin); color: var(--text); background: var(--flaeche-hoch);
}
.wahl__feld input:checked + label::before {
  border-color: var(--karmin); box-shadow: inset 0 0 0 3px var(--karmin);
}
.wahl__feld label, .wahl__feld label::before { transition-duration: var(--tempo); }
.wahl__feld input:hover + label {
  border-color: var(--karmin); color: var(--text); background: var(--flaeche-hoch);
}
/* Der Punkt waechst schon beim Zeigen ein Stueck — man sieht, wohin
   der Klick fuehrt, bevor man ihn macht. */
.wahl__feld input:hover + label::before { border-color: var(--karmin); box-shadow: inset 0 0 0 2px rgb(184 29 44 / .45); }
.wahl__feld input:active + label { transform: scale(.985); }
/* Beim Waehlen faehrt der Punkt einmal auf und faengt sich. */
.wahl__feld input:checked + label::before { animation: wahlpunkt 420ms var(--kurve); }
@keyframes wahlpunkt {
  0%   { box-shadow: inset 0 0 0 0 var(--karmin); }
  55%  { box-shadow: inset 0 0 0 5px var(--karmin); }
  100% { box-shadow: inset 0 0 0 3px var(--karmin); }
}
.wahl__feld input:focus-visible + label { outline: 3px solid var(--text); outline-offset: 3px; }

/* Einwilligung */
.einwilligung { display: grid; grid-template-columns: auto 1fr; gap: .85rem; align-items: start; }
.einwilligung input {
  appearance: none; flex: none;
  /* 24 px ist das Mindestmaß fuer Bedienziele (WCAG 2.5.8). */
  width: 1.5rem; height: 1.5rem; margin: .1rem 0 0;
  background: var(--flaeche); border: 1px solid var(--linie);
  border-radius: 3px; cursor: pointer;
  transition: background var(--tempo), border-color var(--tempo);
}
.einwilligung input:checked {
  background: var(--karmin) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.2 3.2L13 5'/%3E%3C/svg%3E") center / 12px no-repeat;
  border-color: var(--karmin);
}
.einwilligung label { font-size: .875rem; color: var(--text-still); }

/* Rueckmeldung */
.meldung {
  padding: var(--raum-3); border-radius: var(--kante);
  border: 1px solid var(--linie); border-left-width: 3px;
  background: var(--flaeche);
  font-size: .9375rem;
}
.meldung p { margin: 0; }
.meldung--ok { border-left-color: #3f9e5c; color: var(--text); }
.meldung--fehler { border-left-color: var(--karmin); color: var(--text); }

/* Kontaktkarten neben dem Formular */
.kontaktliste { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--raum-3); }
.kontaktzeile { display: grid; grid-template-columns: 1.5rem 1fr; gap: var(--raum-2); align-items: start; }
.kontaktzeile svg { width: 1.25rem; height: 1.25rem; color: var(--karmin-text); margin-top: .2rem; }
.kontaktzeile dt { font: 500 .6875rem/1 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--text-leise); margin-bottom: .35rem; }
.kontaktzeile dd { margin: 0; }
.kontaktzeile a {
  color: var(--text); text-decoration: none;
  border-bottom: 1px solid var(--linie); padding-bottom: 1px;
  overflow-wrap: anywhere;
}
.kontaktzeile a:hover { border-bottom-color: var(--karmin); }

/* ============================================================
   Hinweisblock (Vorschau, offene Angaben)
   ============================================================ */
.hinweis {
  border: 1px dashed var(--karmin);
  background: rgba(184, 29, 44, .07);
  border-radius: var(--kante);
  padding: var(--raum-3);
  font-size: .875rem;
}
.hinweis strong { color: var(--karmin-text); }
.hinweis p:last-child { margin-bottom: 0; }

/* Platzhalterflaeche fuer noch fehlende Bilder */
.platzhalter {
  display: grid; place-items: center; gap: .5rem;
  background:
    repeating-linear-gradient(135deg, var(--flaeche) 0 12px, var(--linie-still) 12px 24px);
  color: var(--text-leise); text-align: center;
  font: 500 .6875rem/1.6 var(--mono); letter-spacing: .16em; text-transform: uppercase;
  padding: var(--raum-3);
}
.platzhalter--4-3 { aspect-ratio: 4 / 3; }
.platzhalter--4-5 { aspect-ratio: 4 / 5; }
.platzhalter--16-10 { aspect-ratio: 16 / 10; }

/* ============================================================
   Rechtstexte
   ============================================================ */
.rechtstext { max-width: var(--bahn-eng); }
.rechtstext h2 {
  font-size: 1.5rem; margin-top: var(--raum-5); margin-bottom: var(--raum-2);
  padding-top: var(--raum-3); border-top: 1px solid var(--linie-still);
}
.rechtstext h2:first-of-type { margin-top: 0; border-top: 0; padding-top: 0; }
.rechtstext h3 {
  font-family: var(--body); font-weight: 600; letter-spacing: 0;
  font-size: 1.0625rem; margin-top: var(--raum-3); margin-bottom: .5rem;
}
.rechtstext p, .rechtstext li { font-size: .9375rem; }
.rechtstext ul { padding-left: 1.1rem; display: grid; gap: .5rem; margin: 0 0 var(--raum-3); }
.rechtstext dl { display: grid; gap: .35rem var(--raum-3); margin: 0 0 var(--raum-3); font-size: .9375rem; }
@media (min-width: 34rem) { .rechtstext dl { grid-template-columns: 12rem 1fr; } }
.rechtstext dt { color: var(--text-leise); }
.rechtstext dd { margin: 0; color: var(--text); }

/* Noch auszufuellende Stelle — im Browser nicht zu uebersehen. */
.offen {
  background: rgba(184, 29, 44, .16);
  color: var(--karmin-text);
  border-bottom: 1px dashed var(--karmin);
  padding: 0 .25em; font-weight: 600;
}

/* ============================================================
   Fusszeile
   ============================================================ */
.fuss {
  background: var(--grund-tief);
  border-top: 1px solid var(--linie-still);
  padding-block: var(--raum-5) var(--raum-3);
}

/* Kopf der Fusszeile: links das Rezensionszeichen, rechts die Wortmarke.
   Die Wortmarke stand vorher links und fuellte die Zeile allein — jetzt
   traegt sie die rechte Haelfte und laesst links Platz. */
.fuss__kopf {
  display: grid; gap: var(--raum-4);
  align-items: end;
  margin-bottom: var(--raum-3);
}
@media (min-width: 52rem) {
  .fuss__kopf { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); }
  .fuss__kopf .fuss__marke { text-align: right; justify-self: end; }
}

.fuss__oben {
  display: grid; gap: var(--raum-4);
  padding-bottom: var(--raum-5);
}
@media (min-width: 48rem) {
  .fuss__oben { grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr)); gap: var(--raum-4); }
}

.fuss h2 { font-size: 1.0625rem; font-family: var(--body); font-weight: 600; letter-spacing: 0; margin-bottom: var(--raum-2); }
.fuss ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; font-size: .9375rem; }
.fuss a { color: var(--text-still); text-decoration: none; }
.fuss a:hover { color: var(--text); }
.fuss p.fuss__kontakt a { display: inline-flex; align-items: center; gap: .5rem; }
.fuss__symbol { width: 1rem; height: 1rem; flex: none; color: var(--karmin-text); }

/* Grosser Wortmarken-Schriftzug */
.fuss__marke {
  font-family: var(--display); font-weight: 500;
  font-size: clamp(2.5rem, 12vw, 8rem);
  line-height: .9; letter-spacing: -.045em;
  color: transparent;
  -webkit-text-stroke: 1px var(--linie);
  margin: 0;
  user-select: none;
  transition: -webkit-text-stroke-color var(--tempo-lang) var(--kurve);
}
.fuss__marke.ist-sichtbar { -webkit-text-stroke-color: var(--karmin-tief); }

.fuss__unten {
  display: flex; flex-wrap: wrap; gap: var(--raum-2) var(--raum-3);
  justify-content: space-between; align-items: center;
  padding-top: var(--raum-3);
  border-top: 1px solid var(--linie-still);
  font-size: .8125rem; color: var(--text-leise);
}
.fuss__unten ul { display: flex; flex-wrap: wrap; gap: var(--raum-3); font-size: .8125rem; }

/* ============================================================
   Staendige Bewegung

   Das Aufblenden weiter unten ist ein Ereignis: Es passiert einmal
   und ist vorbei. Was eine Seite lebendig wirken laesst, ist das,
   was *zwischen* den Ereignissen weiterlaeuft — sie antwortet dann
   auf jede Bewegung des Besuchers, statt beim Erscheinen einmal
   etwas vorzufuehren.

   Drei Dinge laufen deshalb durchgehend mit. Alle drei haengen an
   .js: ohne JavaScript gibt es sie nicht, und ohne sie fehlt nichts.
   ============================================================ */

/* --- Tiefe: Bilder wandern gegen den Scrollweg ---------------
   Bewusst `translate` statt `transform`: Dieselben Elemente tragen
   das Aufblenden, und das benutzt `transform`. Als eigenstaendige
   Eigenschaften wirken beide zusammen, statt sich gegenseitig
   aufzuheben — ein Fehler, der hier schon einmal passiert ist. */
.js .hat-tiefe { translate: 0 var(--sy, 0px); }

/* --- Die Kopfleiste weicht, wenn man nach unten liest --------
   Der Fortschrittsbalken sitzt an ihrer Unterkante. Faehrt die
   Leiste um genau ihre eigene Hoehe hoch, landet der Balken auf
   der Oberkante des Fensters und bleibt sichtbar — deshalb hier
   kein volles translateY(-100%). */
.kopf.ist-weg { transform: translateY(calc(-1 * var(--kopfhoehe))); }

/* ============================================================
   Scroll-Reveal
   ============================================================ */
/* Wichtig: nur mit .js am <html> verstecken. Ohne JavaScript gibt es
   niemanden, der wieder einblendet — dann muss alles sofort da sein. */
.js .zeigt {
  opacity: 0;
  transform: translateY(42px);
  filter: blur(6px);
  transition: opacity 1100ms var(--kurve),
              transform 1250ms var(--kurve),
              filter 1100ms var(--kurve);
  transition-delay: var(--rd, 0ms);
  will-change: opacity, transform, filter;
}
.js .zeigt.ist-sichtbar {
  opacity: 1; transform: none; filter: none;
  will-change: auto;
}

/* ------------------------------------------------------------
   Von links und rechts ins Bild

   Senkrecht aufsteigen ist die zurueckhaltende Loesung — und
   genau deshalb sieht man sie kaum. Waagerecht ist der Weg
   laenger und quer zur Leserichtung: Man bemerkt ihn.

   Welche Seite, entscheidet nicht der Zufall, sondern die
   Stelle: Was links im Raster steht, kommt von links; was
   rechts steht, von rechts. Die Bewegung faehrt damit an ihren
   eigenen Platz, statt querfeldein.

   Nur ab 60 rem. Auf dem Telefon steht ohnehin alles
   untereinander — dort waere jede Seite die falsche, und
   waagerechte Wege kosten auf schmalen Schirmen nur Platz.

   `.ist-sichtbar` wird hier ausdruecklich mit vier Klassen
   wiederholt. Mit dreien haette es dieselbe Spezifitaet wie
   `.fliegt-links` und haenge davon ab, was weiter unten in der
   Datei steht — das ist keine Grundlage.
   ------------------------------------------------------------ */
@media (min-width: 60rem) {
  .js .zeigt.fliegt-links  { transform: translateX(-84px); }
  .js .zeigt.fliegt-rechts { transform: translateX(84px); }

  .js .zeigt.fliegt-links.ist-sichtbar,
  .js .zeigt.fliegt-rechts.ist-sichtbar { transform: none; }

  /* Der Maskenwisch der Ueberschrift wird bei waagerechter
     Bewegung zur Unruhe: zwei Richtungen gleichzeitig. Wo etwas
     fliegt, faellt er weg. */
  .js .zeigt.fliegt-links h2,
  .js .zeigt.fliegt-rechts h2,
  .js .kapitel.zeigt h2 { clip-path: none; transform: none; transition: none; }

  /* --- Die Kapitelkoepfe, und das ist der eigentliche Punkt ---

     Ein Kapitelkopf ist zweispaltig: links Marke und Ueberschrift,
     rechts der Beitext. Als Ganzes nimmt er die volle Breite und
     haette deshalb keine Seite — man saehe wieder nichts.

     Also faellt die Bewegung eine Ebene tiefer: Die linke Haelfte
     kommt von links, die rechte von rechts, beide gleichzeitig.
     Der Block selbst blendet nur noch auf und wird scharf. */
  .js .kapitel.zeigt { transform: none; }
  .js .kapitel.zeigt > * {
    transition: transform 1250ms var(--kurve);
    transition-delay: var(--rd, 0ms);
  }
  .js .kapitel.zeigt > :first-child      { transform: translateX(-96px); }
  .js .kapitel.zeigt > .kapitel__text    { transform: translateX(96px); }
  .js .kapitel.zeigt.ist-sichtbar > *    { transform: none; }
}

/* Was von der Seite kommt, ragt waehrend der Bewegung ueber den
   Rand hinaus. Ohne diese Zeile waechst die Seite nach rechts und
   es entsteht ein waagerechter Rollbalken.

   `clip` statt `hidden`: `hidden` macht aus dem Element einen
   eigenen Rollbereich und setzt `overflow-y` heimlich auf `auto`
   — damit waere das Klebenbleiben der Kopfleiste und jedes
   Sprungziel betroffen. `clip` schneidet nur ab. */
.js main, .js .fuss { overflow-x: clip; }

/* Die Unschaerfe ist der Unterschied zwischen „etwas ist eingeblendet
   worden" und „etwas ist scharf geworden". Sie kostet nichts, weil sie
   nur waehrend der Bewegung besteht: `.ist-sichtbar` nimmt sie zurueck
   und gibt `will-change` wieder frei.

   Der Versatz zwischen Geschwistern steht in --rd und wird beim Start
   einmal gesetzt. Vorher lag er in Ketten aus :nth-child im Stylesheet
   und in setTimeout im Skript — an zwei Stellen dasselbe, und beides
   musste man von Hand nachziehen. */

@media (prefers-reduced-motion: no-preference) {
  /* Ueberschriften steigen hinter einer Maske hervor statt zu schweben.
     Bei einer Seite, die ihre Wirkung aus der Typografie zieht, ist das
     die Bewegung, die zur Schrift passt. Der Versatz kommt nach dem der
     Gruppe, damit die Zeile nach ihrem Kasten kommt. */
  .js .zeigt h2 {
    clip-path: inset(-6% -8% 105% -8%);
    transform: translateY(20px);
    transition: clip-path 1150ms var(--kurve) calc(var(--rd, 0ms) + 80ms),
                transform 1150ms var(--kurve) calc(var(--rd, 0ms) + 80ms);
  }
  .js .zeigt.ist-sichtbar h2 { clip-path: inset(-6% -8% -12% -8%); transform: none; }

  /* Bildschirmansichten fahren langsam heran. Ein Bild, das sich beim
     Erscheinen noch bewegt, wirkt aufgenommen statt eingeklebt. */
  .js .fall__bild.zeigt img,
  .js .ansichten.zeigt img {
    transform: scale(1.06);
    transition: transform 1600ms var(--kurve) var(--rd, 0ms);
  }
  .js .fall__bild.zeigt.ist-sichtbar img,
  .js .ansichten.zeigt.ist-sichtbar img { transform: none; }
}

/* ============================================================
   Kleine Schirme

   Alles unter 48rem (768 px) ist Telefongebiet. Hier gelten drei
   Regeln, die am Rechner nicht noetig sind:

   1. Weniger Luft. Am 27-Zoll-Schirm traegt grosszuegiger Abstand
      die Wirkung. Auf dem Telefon wird daraus Scrollarbeit.
   2. Groessere Bedienziele. Ein Finger ist kein Mauszeiger — alles,
      was angetippt wird, ist mindestens 44 px hoch.
   3. Nichts, was Schweben braucht. Wird ueber (hover: hover)
      geregelt, nicht ueber die Fensterbreite — ein Notebook mit
      Touchscreen kann beides.
   ============================================================ */
@media (max-width: 47.99rem) {
  :root {
    --raum-5: 3rem;
    --raum-6: 3.75rem;
    --raum-7: 4.5rem;
  }

  /* --- Luft rausnehmen ------------------------------------- */
  .hero { padding-bottom: var(--raum-4); }
  .hero .hero__knoepfe { margin-bottom: var(--raum-4); }
  .seitenkopf { padding-bottom: var(--raum-4); }
  .kapitel { margin-bottom: var(--raum-4); }
  .fall { gap: var(--raum-3); }
  .karte { padding: var(--raum-3); }
  .arbeit__link { padding-block: var(--raum-3); }
  .preis-tafel, .anfrage-seite { padding: var(--raum-3); }
  .anfrage-satz { gap: var(--raum-4); }
  .abschnitt + .abschnitt::before { height: 7px; background-size: 2rem 100%, 100% 1px; }

  /* --- Bewegung: kuerzer, schneller, weniger Unschaerfe ------
     Dieselbe Bewegung wie am Rechner, nur auf den kurzen
     Bildschirm gerechnet.

     Weg und Dauer: 42 px in 1,25 s sind auf 844 px Hoehe zu
     langsam. Wer wischt, hat den Abschnitt halb wieder aus dem
     Bild geschoben, bevor er angekommen ist — die Bewegung
     erreicht ihr Ziel dann nie sichtbar. 26 px in 0,72 s sind
     innerhalb eines Wischs fertig.

     Unschaerfe: von 6 auf 3 px, und zwar aus optischen Gruenden.

     Zuerst stand hier die Begruendung, sie sei der teuerste Teil
     der Animation. Nachgemessen stimmt das nicht: mit gedrosselter
     CPU (Faktor 6) ueber die ganze Startseite liegen 3 px, 6 px,
     12 px und gar keine Unschaerfe alle bei 16,7 ms Median und
     keinem einzigen Bild ueber 33 ms. Der Unterschied liegt im
     Rauschen. Gemessen wurde allerdings am Rechner mit gedrosselter
     CPU — die Grafikeinheit laesst sich so nicht drosseln, auf
     einem schwachen Telefon kann es anders liegen.

     Der Grund ist also ein anderer: Unschaerfe muss zum Weg passen.
     6 px auf 42 px Weg lesen sich als „kommt von weit her und wird
     scharf". Dieselben 6 px auf 26 px Weg lesen sich als „ist
     verschmiert" — die Strecke ist zu kurz, um das aufzuloesen. Bei
     der Haelfte stimmt das Verhaeltnis wieder.

     Der Maskenwisch der Ueberschriften folgt mit. */
  .js .zeigt {
    transform: translateY(26px);
    filter: blur(3px);
    transition: opacity 620ms var(--kurve),
                transform 720ms var(--kurve),
                filter 620ms var(--kurve);
  }


  /* --- Schrift ---------------------------------------------- */
  .hero h1 { font-size: clamp(2.375rem, 10.5vw, 3rem); letter-spacing: -.03em; }
  .seitenkopf h1 { font-size: clamp(2.125rem, 9.5vw, 2.75rem); }
  .kapitel h2, .abschnitt h2 { font-size: clamp(1.75rem, 7.4vw, 2.25rem); }
  .zitat { font-size: 1.1875rem; padding-left: var(--raum-2); }
  .kapitel__text, .seitenkopf__text { font-size: 1rem; }

  /* Preisumschalter ueber die volle Breite — zwei fette Ziele
     statt zwei schmaler. */
  .preis-schalter { display: flex; width: 100%; }
  .preis-schalter button { flex: 1; min-height: 3rem; padding-inline: .5rem; }

  /* Ergebniszeilen zu zweit statt gequetscht nebeneinander */
  .ergebnis { grid-template-columns: 1fr 1fr; gap: var(--raum-2) var(--raum-3); }
}

/* ------------------------------------------------------------
   Bedienziele fuer Finger

   Zwei Ausloeser, mit Absicht:

   - (hover: none) / (pointer: coarse) — es wird mit dem Finger
     bedient. Ein Tablet im Hochformat ist 768 px breit und faellt
     sonst durch jedes Breitenraster.
   - (max-width: 47.99rem) — schmales Fenster. Groessere Ziele
     schaden hier auch mit Maus nicht, und diese Bedingung laesst
     sich am Rechner nachmessen.

   Alles Antippbare wird 44 px hoch.
   ------------------------------------------------------------ */
@media (hover: none), (pointer: coarse), (max-width: 47.99rem) {
  .marke { padding-block: .8rem; }

  .strich-link {
    min-height: 2.75rem; padding-block: .75rem .6rem;
    background-position: 0 calc(100% - .6rem);
  }

  /* Auch die Mail- und Telefonzeile in der Fusszeile — gerade die
     werden unterwegs angetippt. */
  .fuss ul a,
  .fuss__unten ul a,
  .fuss p a,
  .rechtstext dd a,
  .kontaktzeile a {
    display: inline-block;
    min-height: 2.75rem;
    padding-block: .7rem;
    line-height: 1.5;
  }
  /* Die Kontaktzeilen der Fusszeile bleiben trotzdem eine Reihe: Das
     Sinnbild gehoert neben den Text, nicht darueber. Das grosse
     Antippziel von oben bleibt dabei erhalten. */
  .fuss p.fuss__kontakt a { display: inline-flex; }
  .fuss ul { gap: 0; }
  .fuss__unten ul { gap: var(--raum-3); }

  .wahl__feld label { min-height: 3.25rem; }
  .nav__link { padding-block: 1.1rem; }
  .preis-schalter button { min-height: 3rem; }
}

@media (max-width: 47.99rem) and (prefers-reduced-motion: no-preference) {
  .js .zeigt h2 {
    transition: clip-path 700ms var(--kurve) calc(var(--rd, 0ms) + 50ms),
                transform 700ms var(--kurve) calc(var(--rd, 0ms) + 50ms);
  }
  .js .fall__bild.zeigt img,
  .js .ansichten.zeigt img {
    transform: scale(1.035);
    transition: transform 900ms var(--kurve) var(--rd, 0ms);
  }
}

/* Sehr schmale Geraete (unter 360 px, z. B. iPhone SE quer im
   geteilten Fenster): noch einmal eine Stufe zurueck. */
@media (max-width: 22.5rem) {
  :root { --rand: 1.125rem; }
  .hero h1 { font-size: 2.125rem; }
  .ergebnis { grid-template-columns: 1fr; }
  .kopf__knopf { padding: .7rem .8rem; font-size: .8125rem; }
}

/* ============================================================
   Bewegung aus
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

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

  /* Alles Versteckte sofort zeigen — niemand darf auf eine
     Animation warten muessen, die nie kommt. */
  .js .zeigt, .js .blendet {
    opacity: 1 !important; transform: none !important;
    filter: none !important; transition-delay: 0s !important;
  }
  .js .zeigt h2 { clip-path: none !important; }
  .js .fall__bild.zeigt img, .js .ansichten.zeigt img { transform: none !important; }
  .js .steigt > * { transform: none !important; }
  .js .zeigt.fliegt-links, .js .zeigt.fliegt-rechts { transform: none !important; }
  .js .kapitel.zeigt > * { transform: none !important; }
  .knopf:active, .preis-schalter button:active,
  .wahl__feld input:active + label, .thema-schalter:active { transform: none !important; }
  .knopf.ist-gedrueckt::after, .knopf.ist-gedrueckt .knopf__pfeil,
  .wahl__feld input:checked + label::before,
  .thema-schalter.ist-gedreht svg { animation: none !important; }
  .js .hat-tiefe { translate: none !important; }
  .kopf.ist-weg { transform: none !important; }
  .karte:hover, .karte:focus-within,
  .js .karte.ist-sichtbar:hover,
  .js .karte.ist-sichtbar:focus-within { transform: none !important; }
  .fall__schritt:hover { padding-left: 0 !important; }
  .fall__schritt:hover h3, .fall__schritt:hover::before { transform: none !important; }
  .fall__schritt::after { transform: scaleY(1) !important; opacity: .45; }
  .karte:hover h3, .karte:focus-within h3 { transform: none !important; }
  .masslinie { transform: scaleX(1) !important; }
}
