/* ==========================================================================
   Biebinger — Visitenkarte
   Eine Seite. Nur Typografie. Die Marke fuehrt keine Akzentfarbe.
   ========================================================================== */

/* ---------- Schriften (self-hosted) ---------- */

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

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

/* ---------- Marken-Token (Quelle: website/src/app/globals.css) ---------- */

:root {
  /* Der Browser zeichnet Scrollleisten und eigene Flaechen sonst hell auf eine
     dunkle Seite. */
  color-scheme: dark;

  --bg: #121415;
  --ink: #e7e0dd;
  --muted: #b7a8a5;
  --rule: #353132;
  --bright: #f4efec;

  --font-display: "Anton", "Arial Narrow", Impact, sans-serif;
  --font-mono: "Space Mono", ui-monospace, "Courier New", monospace;

  --s-xs: 8px;
  --s-sm: 16px;
  --s-md: 32px;
  --s-lg: 64px;
  --s-xl: 88px;

  --container: 1120px;
  --gutter: clamp(20px, 5vw, 48px);
  --measure: 56ch;

  /* Der Pfeil steht nicht als Zeichen im Text. U+2192 liegt ausserhalb der
     unicode-range, die Google fuer den latin-Schnitt von Space Mono deklariert
     — das Zeichen ist gar nicht in der Datei. Gemessen mit CDP: der Knopf
     zeichnete 16 Zeichen in Space Mono und eines in Courier New. Als Maske
     folgt der Pfeil currentColor und damit jedem Knopf.
     Die Punkte ersetzen den Pfeil, solange der Kalender laedt. */
  --pfeil: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 8h12.4M8.9 3.6 13.3 8l-4.4 4.4' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
  --punkte: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cg fill='%23000'%3E%3Ccircle cx='2.2' cy='8' r='1.5'/%3E%3Ccircle cx='8' cy='8' r='1.5'/%3E%3Ccircle cx='13.8' cy='8' r='1.5'/%3E%3C/g%3E%3C/svg%3E");
}

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

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

html {
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;
}

body {
  position: relative; /* Bezugsrahmen fuer das Korn */
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.9375rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---------- Korn ----------
   Aus Gradientool (applyGrain). Die Kachel entsteht mit `node tools/bauen.mjs`.

   Reines Schwarz auf einem Bildschirm ist tot. Das Korn gibt der Flaeche eine
   Oberflaeche, wie gedrucktes Papier. Es liegt ueber allem, faengt aber keine
   Klicks ab und steht still — auch bei reduzierter Bewegung.

   `overlay` ist Pflicht, nicht Geschmack. Gemessen an der Grundflaeche:

     reine Deckkraft 0,05   Mittel 18 -> 23,5   hellt auf
     soft-light 0,5         Mittel 18 -> 22,1   hellt auf, springt weit
     overlay                Mittel 18 -> 18,0   verschiebt nichts

   Nur overlay koernt symmetrisch: die Mitte der Kachel ist der neutrale Punkt,
   Werte darueber hellen auf, Werte darunter dunkeln ab. Der Hub waechst dabei
   mit der Helligkeit des Untergrunds. Deshalb traegt die helle Wortmarke
   sichtbar Textur und die dunkle Grundflaeche bleibt ruhig — so verhaelt sich
   Farbe auf Papier. */

/* Das Korn liegt im Traeger, nicht vor dem Bildschirm. Vorher stand hier
   position: fixed — dann bleibt das Korn stehen, waehrend der Inhalt darunter
   laeuft, und es liest sich als Linse. Papierkorn laeuft mit. Nebenbei faellt
   damit die vollflaechige Neuberechnung bei jedem Bildlauf weg, die eine feste
   Flaeche mit mix-blend-mode erzwingt. */

body::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: url("/assets/korn.png") repeat;
  mix-blend-mode: overlay;
  opacity: 0.18;
}

a {
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--bright);
  outline-offset: 3px;
}

/* Da fuer den Vorleser, weg fuer das Auge. Der Sprunglink benutzt denselben
   Grundzustand und nimmt ihn beim Fokus zurueck. Frueher stand dort
   left: -9999px — das haengt an html { overflow-x: clip }. */

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

.skip-link {
  top: var(--s-xs);
  left: var(--gutter);
  background: var(--ink);
  color: var(--bg);
  font-size: 0.75rem;
  z-index: 10;
}

.skip-link:focus {
  width: auto;
  height: auto;
  margin: 0;
  padding: var(--s-xs) var(--s-sm);
  overflow: visible;
  clip-path: none;
}

/* container-type macht die Spalte messbar. Das Lockup rechnete vorher mit
   100vw — und 100vw schliesst eine klassische Scrollleiste ein, die
   Inhaltsbreite nicht. Auf Windows, Linux und macOS mit dauerhaft sichtbarer
   Scrollleiste war die Satzbreite dadurch rund 15 px zu gross, und
   overflow-x: clip schnitt die Wortmarke ab, statt es zu zeigen. */
.container {
  container-type: inline-size;
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

/* ---------- Label ---------- */

.label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  line-height: 1.4;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.label--strong {
  font-weight: 700;
  color: var(--ink);
}

/* ---------- Seitengeruest ---------- */

.page {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

/* ---------- Kopfstreifen ----------
   Der Descriptor steht ueber der Wortmarke. Das ist eine Markenregel. */

.topstrip {
  border-bottom: 1px solid var(--rule);
}

.topstrip .container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-xs) var(--s-md);
  justify-content: space-between;
  padding-block: var(--s-sm);
}

/* ---------- Hauptteil ---------- */

.main {
  flex: 1 0 auto;
  padding-block: clamp(44px, 7vw, var(--s-xl));
}

/* ---------- Lockup ----------
   Bildmarke in heller Platte, Wortmarke rechts daneben. Das Lockup fuellt die
   Satzbreite auf jeder Bildschirmbreite exakt aus.

   Die Konstruktion stammt aus Eriks Vorlage, ausgemessen:
     Plattenbreite   0,6422 × Plattenhoehe
     Abstand         0,3578 × Plattenhoehe   (beide zusammen = Plattenhoehe)
     Marke in Platte 0,7689 × Plattenhoehe, mittig, 11,56 % Luft ringsum
     Versalhoehe     entspricht der Markenhoehe

   Anton, gemessen: Tuschebreite 3,6362 × Schriftgroesse,
   Tuschehoehe 0,8750 × Schriftgroesse. Daraus:
     Schriftgroesse = Satzbreite / (1,2893 × 0,8750 + 3,6362) = Satzbreite / 4,7643
     Plattenhoehe   = Schriftgroesse × 0,8750 × 1,2893 = Schriftgroesse × 1,1281 */

.lockup {
  /* 100cqi ist die Inhaltsbreite von .container — gemessen, nicht geschaetzt.
     --gutter faellt damit aus der Rechnung heraus. */
  --satz: 100cqi;
  --wort: calc(var(--satz) / 4.7643);
  --platte: calc(var(--wort) * 1.1281);

  display: flex;
  align-items: center;
  gap: calc(var(--platte) * 0.3578);
}

/* Die Platte bleibt flach. Ein Raster darin wurde geprueft und verworfen —
   das Logo traegt keine Flaeche. */

.mark-plate {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--platte) * 0.6422);
  height: var(--platte);
  background: var(--ink);
}

.mark {
  display: block;
  height: calc(var(--platte) * 0.7689);
  width: auto;
  color: var(--bg);
}

/* ---------- Wortmarke ---------- */

.wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--wort);
  line-height: 0.875;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--ink);
  /* Anton traegt links 0,0381 em Seitenflaeche. Der Zug setzt die Tusche
     exakt an die Abstandskante. */
  margin: 0 0 0 -0.0381em;
}

/* text-wrap: pretty verteilt die letzten Zeilen neu. Ohne das stand die Lede
   bei 1440 px mit 531 / 583 / 541 / 52 px — die letzte Zeile ein einzelnes
   Wort gegen ein Satzmass von 583 px. */

.lede {
  max-width: var(--measure);
  margin: clamp(24px, 3.5vw, 44px) 0 0;
  font-size: clamp(0.9375rem, 1.5vw, 1.0625rem);
  line-height: 1.75;
  color: var(--ink);
  text-wrap: pretty;
}

/* ---------- Leistungen ----------
   Eine echte Reihenfolge: von der ersten Skizze bis zum Marktstart.
   Deshalb Ziffern. */

.services {
  margin-top: clamp(44px, 6vw, var(--s-xl));
}

.services-list {
  list-style: none;
  margin: var(--s-sm) 0 0;
  padding: 0;
  border-top: 1px solid var(--rule);
  counter-reset: leistung;
}

.services-list li {
  counter-increment: leistung;
  display: grid;
  grid-template-columns: 3ch minmax(0, 1fr);
  /* Die Ziffer ist 11 px gross, der Name waechst von 14 auf 18 px. Frueher
     glich ein line-height von 1.9 das aus — das stimmte bei genau einer
     Fensterbreite, sonst schwebte die Ziffer wie eine Fussnote ueber der
     Grundlinie. baseline gleicht bei jeder Groesse exakt aus. */
  align-items: baseline;
  column-gap: var(--s-sm);
  row-gap: var(--s-xs);
  padding-block: clamp(20px, 2.6vw, 28px);
  border-bottom: 1px solid var(--rule);
}

.services-list li::before {
  content: counter(leistung, upper-roman);
  grid-column: 1;
  grid-row: 1;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  color: var(--muted);
}

.service-name {
  grid-column: 2;
  grid-row: 1;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(0.875rem, 2vw, 1.125rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}

.service-desc {
  grid-column: 2;
  grid-row: 2;
  max-width: var(--measure);
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--muted);
  text-wrap: pretty;
}

/* ---------- Arbeit ----------
   Ein Register, keine Achse. Die vier Eintraege sind keine saubere Folge — drei
   ueberschneiden sich, zwei beginnen im selben Jahr. Eine massstabsgetreue
   Zeitachse waere also gelogen.

   Wahr ist: jeder Eintrag hat eine Jahresspanne, und sie laufen ohne Luecke von
   2021 bis heute. Deshalb steht die Spanne in einer eigenen Spalte an einer
   durchgehenden Haarlinie. Aus Fliesstext wird etwas, das man ueberfliegen kann.

   Der Griff ist derselbe wie in .services-list: ein Raster mit fester erster
   Spalte. Der Abstand entsteht aus Innenabstand, nicht aus Aussenabstand —
   sonst bricht die Linie zwischen den Eintraegen. */

.work {
  margin-top: clamp(44px, 6vw, var(--s-xl));
}

.work-list {
  /* Die Spur der Jahresspalte, gerechnet aus den Massen des Labels — nicht aus
     denen der Liste. Frueher stand hier 9ch, und ch rechnet mit der
     Schriftgroesse der Liste (15 px). Das Jahr steht aber im .label (11 px).
     Gemessen: Tinte 70,50 px in einer 82,61 px breiten Spur, also 28,11 px bis
     zur Linie gegen 16,00 px auf der anderen Seite.

     Vorschub von Space Mono 0,612 em, mit canvas.measureText gemessen. Die
     Spur ist die sichtbare Tinte breit: 9 Vorschuebe und 8 Sperrungen. Die
     neunte Sperrung steht hinter dem letzten Zeichen, laeuft unsichtbar in den
     Abstand und traegt deshalb nicht zur Spur bei. Wer die Schrift wechselt,
     misst neu — wie beim Lockup. */
  --jahr: calc(0.6875rem * (9 * 0.612 + 8 * 0.1));

  list-style: none;
  margin: var(--s-md) 0 0;
  padding: 0;
}

/* Schmal: Jahr und Feld stehen in einer Zeile, und eine Haarlinie trennt die
   Eintraege. Der Leistungsblock direkt darueber arbeitet genauso. Vorher trug
   der Arbeit-Block hier nur Weissraum und las sich als Wand. */

.work-list li + li {
  margin-top: clamp(var(--s-md), 4vw, 40px);
  padding-top: clamp(var(--s-md), 4vw, 40px);
  border-top: 1px solid var(--rule);
}

.work-jahr,
.work-feld {
  display: inline;
}

/* Eine Jahresspanne bricht nie um. Das ist eine Satzregel, und sie macht die
   Spur oben unabhaengig davon, wie der Browser den letzten Bruchteil rundet. */
.work-jahr {
  white-space: nowrap;
}

.work-jahr::after {
  content: " · ";
}

@media (min-width: 640px) {
  .work-jahr,
  .work-feld {
    display: block;
  }

  .work-jahr::after {
    content: none;
  }

  /* Die Haarlinie liegt auf der Liste, nicht auf den Eintraegen. So zieht sie
     durch, egal wieviele Zeilen ein Eintrag hat. Ab hier traegt sie die
     Gliederung — die waagerechten Linien von oben fallen weg. */
  .work-list {
    background: linear-gradient(var(--rule), var(--rule)) no-repeat;
    background-size: 1px 100%;
    background-position: calc(var(--jahr) + var(--s-sm)) 0;
  }

  .work-list li {
    display: grid;
    grid-template-columns: var(--jahr) 1px minmax(0, 1fr);
    align-items: baseline;
    column-gap: var(--s-sm);
    padding-block: clamp(18px, 2.4vw, 26px);
  }

  .work-list li + li {
    margin-top: 0;
    padding-top: clamp(18px, 2.4vw, 26px);
    border-top: 0;
  }

  .work-list li:first-child {
    padding-top: 0;
  }

  .work-list li:last-child {
    padding-bottom: 0;
  }

  .work-jahr {
    grid-column: 1;
    grid-row: 1;
    font-variant-numeric: tabular-nums;
  }

  .work-feld,
  .work-name,
  .work-arc {
    grid-column: 3;
  }

  .work-feld {
    grid-row: 1;
  }
}

.work-name {
  margin: var(--s-xs) 0 0;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(0.9375rem, 2.2vw, 1.25rem);
  line-height: 1.35;
  letter-spacing: 0.02em;
  color: var(--ink);
}

.work-arc {
  margin: var(--s-xs) 0 0;
  max-width: var(--measure);
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--muted);
  text-wrap: pretty;
}

/* Der Agenturblock steht innerhalb von „Arbeit". Er hatte 72 + 32 = 104 px
   Luft, waehrend eine ganze Sektion 86,4 px bekommt — ein Unterblock atmete
   also weiter als die Gliederung darueber. Jetzt 48 + 32 = 80 px. */
.work-agency {
  margin-top: clamp(var(--s-md), 4vw, 48px);
  padding-top: var(--s-md);
  border-top: 1px solid var(--rule);
}

.work-agency-names {
  margin: var(--s-xs) 0 0;
  max-width: var(--measure);
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--ink);
  text-wrap: pretty;
}

/* ---------- Kontakt ---------- */

.contact {
  margin-top: clamp(44px, 6vw, var(--s-xl));
}

/* Zwei Korrekturen an einem Element.

   Erstens die Sperrung. Sie stand auf -0.01em. Eine dicktengleiche Schrift
   wird nie enger gesetzt — das Raster ist der Zweck der Schrift. Das @ und das
   b halten gemessen 3,51 px Luft, es gibt also keine Kollision; die Sperrung
   war trotzdem falsch und ist jetzt neutral.

   Zweitens der Unterstrich. Er war ein border-bottom in --rule und hielt gegen
   --bg nur 1,44:1. Er ist das einzige Zeichen dafuer, dass die Adresse ein Link
   ist — WCAG 1.4.11 verlangt dafuer 3:1. --muted haelt 8,06:1. Echtes
   text-decoration folgt ausserdem dem Text, wenn er umbricht; ein
   border-bottom unterstreicht nur den Kasten. */

.contact-mail {
  display: inline-block;
  margin: var(--s-sm) 0 0;
  font-size: clamp(1.125rem, 3.4vw, 1.875rem);
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--muted);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.24em;
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}

.contact-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-sm) var(--s-md);
  margin-top: var(--s-md);
}

/* Nebeneinander brauchen die beiden Knoepfe 350,6 px. Ein Telefon mit 390 px
   Fensterbreite bietet 350 px. Statt am Innenabstand zu feilen, bis es gerade
   so passt, stehen sie schmal untereinander und fuellen die Spalte. Das haelt
   in jeder Sprache und bei jeder Ersatzschrift, und die Flaeche zum Tippen
   wird groesser. */
@media (max-width: 559px) {
  .contact-actions {
    display: grid;
    justify-items: stretch;
  }

  .contact-actions .btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .contact-actions .btn::after {
    margin-left: var(--s-sm);
  }
}

.btn {
  display: inline-block;
  padding: 14px 24px;
  border: 1px solid var(--ink);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.btn::after {
  content: "";
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-left: 0.9em;
  vertical-align: -0.05em;
  background: currentColor;
  -webkit-mask: var(--pfeil) center / contain no-repeat;
  mask: var(--pfeil) center / contain no-repeat;
}

/* Die Haupthandlung. Keine neue Farbe — nur der Tonwert wird getauscht. */
.btn--strong {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}

/* Der Kalender braucht rund zwei Sekunden. Ohne Zeichen sieht der Knopf in
   dieser Zeit kaputt aus. Drei Punkte statt Pfeil: gleicher Kasten, kein
   Sprung, keine Bewegung, kein Verlust an Kontrast. */
.btn[aria-busy="true"] {
  cursor: progress;
}

.btn[aria-busy="true"]::after {
  -webkit-mask-image: var(--punkte);
  mask-image: var(--punkte);
}

a.label {
  text-decoration: none;
  transition: color 0.2s ease;
}

/* Im Fuss steht der Link neben Text derselben Farbe. Ohne Unterstrich gibt es
   keinen Unterschied ausser der Farbe — und die stimmt ueberein. WCAG 1.4.1. */
.site-footer nav a.label {
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-underline-offset: 0.55em;
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}

/* Auf Touch bleibt :hover nach dem Tippen haengen. Deshalb nur dort, wo es
   einen Zeiger gibt. Fuer den Finger stehen die :active-Zustaende darunter. */
@media (hover: hover) {
  .btn:hover {
    background: var(--ink);
    color: var(--bg);
  }

  .btn--strong:hover {
    background: var(--bright);
    border-color: var(--bright);
  }

  .contact-mail:hover {
    color: var(--bright);
    text-decoration-color: var(--bright);
  }

  a.label:hover {
    color: var(--bright);
  }

  .site-footer nav a.label:hover {
    text-decoration-color: currentColor;
  }

  .legal-body a:hover {
    text-decoration-color: var(--ink);
  }
}

.btn:active {
  background: var(--bright);
  border-color: var(--bright);
  color: var(--bg);
}

.contact-mail:active,
a.label:active {
  color: var(--bright);
}

/* ---------- Fuss ---------- */

.site-footer {
  flex: 0 0 auto;
  border-top: 1px solid var(--rule);
}

.site-footer .container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-xs) var(--s-md);
  justify-content: space-between;
  padding-block: var(--s-sm);
}

.site-footer nav {
  display: flex;
  gap: var(--s-md);
}

/* ---------- Rechtsseiten ---------- */

/* Der Rücklink trug ein U+2190. Dasselbe Problem wie beim Pfeil auf den
   Knoepfen: das Zeichen fehlt im latin-Schnitt von Space Mono. Hier dieselbe
   Maske, um 180 Grad gedreht. Der Pfeil ist ein Hinweis, der keine Farbe ist —
   deshalb braucht dieser Link keinen Unterstrich. */

.back::before {
  content: "";
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-right: 0.7em;
  vertical-align: -0.05em;
  rotate: 180deg;
  background: currentColor;
  -webkit-mask: var(--pfeil) center / contain no-repeat;
  mask: var(--pfeil) center / contain no-repeat;
}

.legal {
  padding-block: clamp(var(--s-lg), 8vw, var(--s-xl));
}

.legal h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.25rem, 7vw, 4.5rem);
  line-height: 0.95;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  margin: 0;
}

.legal-stand {
  display: block;
  margin-top: var(--s-sm);
}

.legal-body {
  max-width: 68ch;
  margin-top: clamp(var(--s-md), 5vw, var(--s-lg));
}

.legal-body h2 {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: var(--s-lg) 0 var(--s-sm);
}

.legal-body p {
  margin: 0 0 var(--s-sm);
  font-size: 0.875rem;
  line-height: 1.8;
}

.legal-body address {
  font-style: normal;
  font-size: 0.875rem;
  line-height: 1.8;
}

.legal-body a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--rule);
  transition: text-decoration-color 0.2s ease;
}

/* ---------- Bewegung ----------
   Ein einziger Einblendvorgang beim Laden. Sonst nichts.

   Der verborgene Zustand steht im Keyframe, nicht in der Grundregel. Vorher
   trug .rise selbst opacity: 0. Laeuft die Animation dann nicht — ein
   Nutzerstylesheet, ein Hilfsmittel, ein alter Browser — ist der Inhalt fuer
   immer weg. Mit `both` als Fuellmodus haelt der Anfangszustand nur waehrend
   der Verzoegerung; ohne Animation steht der Inhalt einfach da.

   Die Verzoegerung haengt an :nth-child, zaehlt also alle Geschwister. Wer in
   .main .container ein Element einschiebt, verschiebt die Treppe. */

@media (prefers-reduced-motion: no-preference) {
  .js .rise {
    animation: rise 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
  }

  .js .rise:nth-child(1) { animation-delay: 0.05s; }
  .js .rise:nth-child(2) { animation-delay: 0.13s; }
  .js .rise:nth-child(3) { animation-delay: 0.21s; }
  .js .rise:nth-child(4) { animation-delay: 0.29s; }
  .js .rise:nth-child(5) { animation-delay: 0.37s; }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ---------- Druck ----------
   Die Token werden getauscht, nicht einzelne Regeln. Vorher stand hier nur
   `body { color:#000 }` — geerbt hat das fast nichts, weil jedes Element seine
   Farbe selbst setzt. Gemessen druckten Wortmarke, Lede, Leistungs- und
   Arbeitsnamen und die Adresse in --ink (#e7e0dd) auf Weiss: unsichtbar. Der
   Rest lag bei 2,29:1.

   Die Platte kippt durch den Tausch von selbst richtig: dunkle Flaeche, helle
   Marke. Das ist die richtige Umkehrung fuer Papier. */

@media print {
  :root {
    --bg: #fff;
    --ink: #16130f;
    --muted: #4a4542;
    --rule: #bdb7b3;
    --bright: #000;
  }

  body {
    background: var(--bg);
    color: var(--ink);
  }

  body::after,
  .skip-link,
  .btn {
    display: none;
  }

  /* Beim Wechsel auf die Druckmedien liefen sonst die Farbuebergaenge an, und
     das Blatt fing den alten, hellen Wert. Gemessen: die Adresse druckte noch
     in #e7e0dd, waehrend --ink schon auf #16130f stand. */
  .contact-mail,
  a.label,
  .legal-body a {
    transition: none;
  }

  /* Wer waehrend des Ladens druckt, soll den Inhalt sehen, nicht den
     Anfangszustand der Einblendung. */
  .js .rise {
    animation: none;
    opacity: 1;
    transform: none;
  }

  @page {
    margin: 16mm;
  }
}
