/* =========================================================================
   Joel Sidler — Fundament
   Tokens · Reset · Typografie · Komponenten
   Diese Datei ist der Vertrag. Seiten-CSS liegt in css/pages/.
   ========================================================================= */

/* ---------- 1. Tokens ---------------------------------------------------- */

/* ---------- 0. Schriften — self-hosted, kein CDN -------------------------
   Jost fuer Ueberschriften und Schlagzeilen, Source Sans 3 fuer Lauftext.
   Beides so im FDP-Styleguide (S. 4) festgelegt: Jost ist die lizenzfreie
   Entsprechung zu Futura 100, Source Sans Pro der Lauftext auf Webseiten.
   ------------------------------------------------------------------------ */

@font-face {
  font-family: "Jost";
  src: url("../fonts/jost-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  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: "Jost";
  src: url("../fonts/jost-var-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  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: "Jost";
  src: url("../fonts/jost-var-italic.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
  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: "Jost";
  src: url("../fonts/jost-var-italic-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
  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: "Source Sans 3";
  src: url("../fonts/sourcesans3-var.woff2") format("woff2");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
  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: "Source Sans 3";
  src: url("../fonts/sourcesans3-var-ext.woff2") format("woff2");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
  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;
}

:root {
  /* Farben — die drei Werte des FDP-Farbklangs (Styleguide S. 3). Mehr wird
     von der Partei nicht uebernommen: keine Logos, keine Bildmarken.
     Die Seite selbst bleibt weiss. Die Farben kommen nicht als Flaeche,
     sondern punktuell: in Karten- und Navigations-Akzenten (Cyan, Dunkelblau),
     im Call-to-Action (Magenta) und in genau einem Band pro Seite.
     Schriftfarbe ist Schwarz oder Weiss, nie eine der drei Farben. */
  --cyan:       #00A0E2;
  --cyan-soft:  #E5F5FC;   /* aufgehelltes Cyan fuer ruhige Flaechen */
  --blue-deep:  #074EA1;
  --blue-hover: #05397A;
  /* Abgedunkeltes --blue-deep, ausschliesslich als Grund im Footer. Kein
     vierter Wert des Farbklangs: derselbe Blauton, nur so weit heruntergesetzt,
     dass er sich vom Schlussband (.band, --blue-deep) absetzt und Weiss darauf
     bei 14:1 steht. */
  --blue-night: #062A5A;
  --magenta:    #E6007D;
  --magenta-dark: #BE0067;
  --ink:        #000000;
  --ink-mute:   #55585C;
  --paper:      #FFFFFF;
  --paper-alt:  #F4F6F8;
  --white:      #FFFFFF;
  --line:       #D8DDE2;

  /* Glas — ausschliesslich fuer schwebende Ebenen: die Navigationsleiste im
     gescrollten Zustand, das Kampagnen-Band und das mobile Menue. Nur dort
     liegt Seiteninhalt darunter,
     der durchscheinen kann; auf ruhenden Flaechen (Footer, Karten im
     Textfluss) gibt es nichts, was das Glas zeigen wuerde — dort bleiben
     die deckenden Farben. Die Werte sind aus bestehenden Farben abgeleitet,
     keine neuen Farben. */
  --glas-blur: 18px;
  --glas-saettigung: 180%;
  --glas-hell: rgba(255, 255, 255, 0.68);
  --glas-dunkel: rgba(7, 78, 161, 0.72);   /* --blue-deep, durchscheinend */
  --glas-kante: rgba(255, 255, 255, 0.55); /* Lichtkante oben */

  /* Typo — Jost fuer Titel, Source Sans 3 fuer Lauftext */
  --font-sans: "Source Sans 3", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: "Jost", var(--font-sans);

  /* Fokusring — auf hellem und auf dunklem Grund */
  --focus: var(--blue-deep);
  --focus-on-dark: #FFFFFF;

  --step--1: clamp(0.875rem, 0.85rem + 0.15vw, 0.95rem);
  --step-0:  clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem);
  --step-1:  clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
  --step-2:  clamp(1.6rem, 1.4rem + 1vw, 2.25rem);
  --step-3:  clamp(2.1rem, 1.7rem + 2vw, 3.25rem);
  --step-4:  clamp(2.6rem, 1.9rem + 3.6vw, 4.5rem);

  /* Mass */
  --measure: 62ch;
  --wrap: 1180px;
  --gutter: clamp(1rem, 4vw, 2.5rem);
  --space-s:  0.75rem;
  --space-m:  1.5rem;
  --space-l:  clamp(2.5rem, 6vw, 5rem);
  --space-xl: clamp(4rem, 10vw, 8rem);

  /* Das FDP-Design ist hartkantig: Balken und Flaechen, keine Pillen.
     --radius bleibt als Token bestehen, steht aber auf null. */
  --radius: 0px;
  --nav-h: 64px;

  /* Die Neigung der kleinen Markierungen (Pill, Footer-Navpunkt, Funnel-Dash).
     Ein Wert, damit sie alle im selben Winkel stehen — rund zwei Grad.
     Schlagzeilen stehen gerade und tragen diesen Wert nicht. */
  --neigung: -2deg;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);          /* schneller Start, weiches Ausklingen */
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);   /* federt kurz nach */
}

@media (min-width: 980px) { :root { --nav-h: 72px; } }

/* ---------- 2. Reset ----------------------------------------------------- */

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

* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/* Lenis (js/scroll.js) übernimmt das Scrollen, sobald es läuft. Es setzt die
   Position jeden Frame selbst — mit scroll-behavior: smooth würde der Browser
   jeden dieser Schritte nochmal weichzeichnen, und das Ergebnis ruckelt.
   Ohne JavaScript bleibt die Regel oben stehen, die Ankerlinks gleiten also
   weiterhin. Die height-Regel verlangt Lenis selbst. */
html.lenis, html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto; }

body {
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

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

/* Jost traegt Ueberschriften. Der Styleguide setzt sie fett und eng —
   Jost laeuft von Haus aus weiter als Futura, darum negatives Tracking. */
h1, h2, h3 { font-family: var(--font-display); line-height: 1.05; letter-spacing: -0.015em; font-weight: 700; text-wrap: balance; }
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); }

p, li { text-wrap: pretty; }
p { max-width: var(--measure); }

a { color: var(--blue-deep); text-underline-offset: 0.2em; }

/* Zwei Kontrastregeln, die das ganze Farbsystem tragen:

   1. Cyan ist Flaechenfarbe, nicht Textfarbe. Auf Weiss kommt #00A0E2 nur auf
      rund 2,6:1 und faellt als Fliesstext durch. Kleiner Text auf hellem Grund
      laeuft deshalb ueber Dunkelblau.
   2. Weiss auf Cyan liegt bei 2,98:1. Fuer grosse Schlagzeilen reicht das
      (Schwelle 3:1, und die Balken sind 40px aufwaerts), fuer Fliesstext nicht.
      Flaechen, die kleinen Text tragen — das Schlussband, das Split-Panel, die
      Wortmarke in der Leiste — stehen darum auf Dunkelblau (8,1:1).
      Cyan bleibt den grossen Balken und den Kanten vorbehalten. */

ul[class] { list-style: none; padding: 0; }

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

/* Auf dunklen Flächen wäre der blaue Ring unsichtbar — dort weiss */
.band :focus-visible,
.split__body :focus-visible,
.campaign :focus-visible,
.hero :focus-visible,
.footer :focus-visible {
  outline-color: var(--focus-on-dark);
}

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

/* ---------- 3. Layout-Hilfen --------------------------------------------- */

.wrap { width: min(var(--wrap), 100% - var(--gutter) * 2); margin-inline: auto; }
.section { padding-block: var(--space-xl); }
.stack > * + * { margin-block-start: var(--space-m); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Sprunglink — bei Tastaturfokus sichtbar, sonst versteckt */
.skip-link {
  position: absolute; inset-block-start: -100%; inset-inline-start: var(--gutter);
  z-index: 100; padding: 0.8em 1.4em;
  background: var(--blue-deep); color: var(--white);
  text-decoration: none; font-weight: 600;
}
.skip-link:focus { inset-block-start: 0; }

/* Kicker über einer Überschrift.
   Stand bis 22.09.2026 in gesperrten Versalien (0.08em, uppercase). Das ist
   die verbreitetste Signatur generierter Gestaltung — ein getracktes
   ALL-CAPS-Label über jeder Überschrift jeder Sektion —, und diese Seite trug
   sie auf sieben Seiten durchgehend. Neu: Gemischtschreibung, kein Tracking,
   der Ton macht die Auszeichnung statt der Versalsatz.

   Die Versalien bleiben genau dort, wo sie eine Wortmarke sind und kein
   Label: .nav__brand und .footer__mark. Das ist der Unterschied zwischen
   einem Logo und einem Etikett. */
.eyebrow {
  display: inline-flex; align-items: center; gap: 0.6em;
  font-family: var(--font-display);
  font-size: var(--step--1); font-weight: 600;
  color: var(--blue-deep);
}

/* ---------- 4. Komponenten ----------------------------------------------- */

/* 4.1 Button */
.btn {
  display: inline-flex; align-items: center; gap: 0.6em;
  padding: 0.8em 1.4em;
  border: 2px solid transparent;
  font-family: var(--font-display);
  font-weight: 600; text-decoration: none; cursor: pointer;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease),
              border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
/* Kein transform beim Ueberfahren. Der Knopf wechselt ohnehin die Farbe;
   das Anheben um ein bis drei Pixel war dieselbe Geste, die auch .card und
   .tafel trugen — dreimal derselbe Standardeffekt. Er bleibt an genau einer
   Stelle, dort wo er etwas meint: .card hebt sich, weil sie eine Flaeche ist,
   die man aufnimmt. Ein Knopf wird gedrueckt, nicht angehoben. */
/* Magenta ist im Styleguide die Akzentfarbe fuer Call-to-Actions. Der
   Hauptbutton traegt sie darum allein — Cyan und Dunkelblau bleiben Flaeche. */
.btn--primary { background: var(--magenta); color: var(--white); }
.btn--primary:hover { background: var(--magenta-dark); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn--ghost:hover { border-color: var(--magenta); color: var(--magenta-dark); }
.btn--on-dark { background: var(--white); color: var(--ink); border-color: var(--white); }

/* Pfeilkreis im CTA — nur noch am Primaerknopf.
   Hing bis 22.09.2026 an jedem Knopf jeder Seite: Geisterknopf, Ghostknopf,
   Schlussband, Nav, dazu an den »Mehr erfahren«-Zeilen der Schwerpunkte.
   Ein angehaengter Pfeil an jedem Linktext ist eine der Signaturen
   generierter Gestaltung; neunmal auf einer Seite sagt er nichts mehr.
   Das Markup behaelt die <span> ueberall — welche davon erscheinen,
   entscheidet allein diese Regel. */
.btn__arrow { display: none; }
.btn--primary > .btn__arrow {
  display: grid; place-items: center;
  inline-size: 1.7em; block-size: 1.7em;
  background: var(--magenta); color: var(--white);
  font-size: 0.75em; flex: none;
}
.btn--primary .btn__arrow { background: var(--white); color: var(--magenta); }

/* 4.2 Pille (Label über Überschriften) */
.pill {
  display: inline-block; padding: 0.35em 0.8em;
  background: var(--magenta); color: var(--white);
  font-family: var(--font-display);
  font-size: var(--step--1); font-weight: 600; letter-spacing: 0.01em;
  rotate: var(--neigung);
}
.pill--soft { background: var(--blue-deep); color: var(--white); }

/* 4.3 Karte */
.card {
  display: flex; flex-direction: column; gap: var(--space-s);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--white); border: 1px solid var(--line);
  /* Die Karte traegt links den Cyan-Balken — dasselbe Element wie in der
     Schlagzeile, nur als Kante statt als Flaeche. */
  border-inline-start: 6px solid var(--cyan);
  transition: border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
a.card:hover { border-color: var(--line); border-inline-start-color: var(--magenta); transform: translateY(-2px); }
.card__fact { font-size: var(--step--1); color: var(--ink-mute); }
.card__fact strong { color: var(--blue-deep); }

/* 4.3b Nachweis — Beleg für eine Position, keine Schlagzeile in Zahlen.
   Joel: die Seite soll zeigen, wofür er steht, nicht was er erreicht hat —
   Erfahrungen, Stationen und Zahlen sind der Beleg dahinter, nicht die
   Botschaft selbst. Ersetzt die grosse Kennzahl (.tafel__zahl in home.css,
   .forderung__zahl-wert in themen.css): die Zahl steht hier klein, mit
   Label und Quelle, nicht als visuelles Hauptelement der Karte.
   Nicht mit .beleg/.belege verwechseln — das sind die Reportagefotos in
   css/pages/inhalt.css, eine andere Komponente. */
.nachweis {
  display: grid; gap: 0.3em;
  padding-inline-start: var(--space-s);
  /* 3px wie .belegzeilen li und die Bildlegenden in inhalt.css: der Cyansteg
     ist seitweit das Beleg-Signal, und dieselbe Aussage traegt dieselbe
     Strichstaerke. Stand bis 22.09.2026 auf 2px, ohne Grund. */
  border-inline-start: 3px solid var(--cyan);
}
.nachweis__label {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step--1);
  color: var(--ink-mute);
}
.nachweis__wert {
  font-family: var(--font-display); line-height: 1.1;
  font-size: var(--step-1); color: var(--blue-deep);
  font-variant-numeric: tabular-nums;
}
.nachweis__text { font-size: var(--step--1); color: var(--ink-mute); }
.nachweis__quelle { font-size: var(--step--1); color: var(--ink-mute); opacity: 0.75; }

/* 4.4 Testimonial-Karte — Person zuerst ------------------------------------
   Die Karte führt mit dem Gesicht: grosses Rundporträt, darunter Name und
   Funktion, erst dann das Zitat. Wer eine Stimme liest, soll in einer
   Sekunde sehen, WER da spricht — der Beleg steckt in Person und Funktion,
   nicht in der Länge des Zitats.

   Die Akzentfarbe steht als --akzent an der Karte und trägt Balken, Ring und
   Funktionszeile zugleich. Sie wechselt reihum durch Dunkelblau, Cyan und
   Magenta. Die Sektion legt die Karten auf --paper-alt, damit Weiss trägt.
   ------------------------------------------------------------------------ */
.quote {
  --akzent: var(--blue-deep);
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--space-s);
  padding: clamp(1.75rem, 3vw, 2.5rem) clamp(1.25rem, 3vw, 2.25rem) clamp(1.5rem, 3vw, 2.25rem);
  background: var(--white);
  border-block-start: 6px solid var(--akzent);
}
.quote:nth-child(3n + 2) { --akzent: var(--cyan); }
.quote:nth-child(3n + 3) { --akzent: var(--magenta); }

/* Das Porträt ist der grösste Gegenstand der Karte. Der doppelte Schatten
   malt einen weissen Spalt und darum den Ring in der Akzentfarbe — ohne
   border, das würde die Bildfläche selbst verkleinern. */
.quote__avatar {
  /* Kleiner als zuvor (war clamp(7.5rem, 15vw, 10rem)): vier Karten stehen
     jetzt nebeneinander auf einer Linie, dafür muss die Karte schlanker
     werden. */
  inline-size: clamp(5rem, 9vw, 6.5rem); block-size: clamp(5rem, 9vw, 6.5rem);
  border-radius: 50%; object-fit: cover; flex: none;
  box-shadow: 0 0 0 4px var(--white), 0 0 0 7px var(--akzent);
  margin-block-end: var(--space-s);
}
.quote__avatar[hidden] { display: none; }
.quote__person { display: grid; justify-items: center; gap: 0.15rem; }
.quote__name {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-1); line-height: 1.2; color: var(--ink);
}
/* Die Funktion ist der eigentliche Beleg — sie steht darum in der
   Akzentfarbe und gesperrt, nicht als graue Fussnote. */
.quote__role {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step--1); line-height: 1.35;
  color: var(--akzent);
  white-space: pre-line;
}
/* Das Zitat ist auf die Essenz gekürzt (data/stimmen.json). Es trägt die
   Karte nicht mehr allein und steht deshalb ruhiger als Name und Funktion. */
.quote__text {
  font-size: var(--step--1); line-height: 1.55; color: var(--ink-mute);
  max-inline-size: 34ch; margin-block-start: var(--space-s);
  padding-block-start: var(--space-s); border-block-start: 1px solid var(--line);
}
.quote__text::before { content: "«"; }
.quote__text::after  { content: "»"; }

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

.stimmen__intro { max-inline-size: var(--measure); margin-block-end: var(--space-l); }

.quotes-grid { display: grid; gap: var(--space-m); grid-template-columns: 1fr; }
.quotes-grid:empty { display: none; }
@media (min-width: 700px) {
  .quotes-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Die Trennlinie über dem Zitat soll in jeder Karte einer Reihe auf
     derselben Höhe liegen. Sie tut das nur, wenn der Block darüber —
     Porträt, Name, Funktion — in allen Karten gleich hoch ist; ein
     zweizeiliger Name oder eine lange Funktion schob sie sonst um bis zu
     30 px nach unten. Statt irgendwo eine Höhe zu raten, teilen sich die
     Karten zwei Zeilenspuren des Rasters (eine pro Kind: .quote__person und
     .quote__text) per Subgrid — dieselbe Technik wie bei den Schwerpunkten
     auf der Startseite. Jede Zeile richtet sich an der höchsten ihrer
     Karten aus, die Linie liegt damit überall gleich. Der Slider unter
     700 px bleibt ausgenommen: dort laufen die Karten in EINER Zeilenspur,
     es gibt nichts auszurichten. */
  .quote {
    grid-row: span 2;
    display: grid;
    grid-template-rows: subgrid;
    justify-items: center;
    /* start statt des geerbten center aus der Flex-Grundform: in der Zeile
       zentriert, rutschte das Zitat samt Trennlinie von der Zeilenoberkante
       weg — genau die Verschiebung, die das Subgrid beseitigen soll.
       Porträt und Zitat setzen so an der Oberkante ihrer Zeile an, der
       Ausgleich fällt jeweils darunter. */
    align-items: start;
  }
}
@media (min-width: 1100px) {
  /* Vier Stimmen auf einer Linie — Joels Wunsch. */
  .quotes-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* Zwei Stimmen bleiben zwei Spalten, statt sich über vier zu strecken.
     Der Selektor zählt die Kinder: erstes Kind, das zugleich das zweite
     von hinten ist. */
  .quotes-grid:has(> .quote:first-child:nth-last-child(2)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Unter 700px ein echter horizontaler Slider statt eines gestapelten Grids.
   grid-auto-columns statt fester Prozente, dazu ein Edge-Peek: die nächste
   Karte schaut sichtbar hervor, das signalisiert "hier geht's weiter" ohne
   Pfeile oder Punkte — Joel bemängelt ausdrücklich Elemente, die klickbar
   aussehen und keine sind. scroll-padding-inline hält die erste/letzte Karte
   auf Höhe des .wrap-Innenabstands, die negative margin lässt den Slider bis
   an den Bildschirmrand laufen. */
@media (max-width: 699.98px) {
  .quotes-grid {
    grid-auto-flow: column;
    grid-auto-columns: minmax(78%, 20rem);
    grid-template-columns: none;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    padding-inline: var(--gutter);
    margin-inline: calc(var(--gutter) * -1);
    scrollbar-width: none;
  }
  .quotes-grid::-webkit-scrollbar { display: none; }
  .quote { scroll-snap-align: start; }
}

/* Einladung unter den Stimmen: »Du fehlst hier?« — der CTA der Sektion. */
.einladung { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-s); }
.quotes-grid:not(:empty) + .einladung { margin-block-start: var(--space-l); }
.einladung .eyebrow { color: var(--magenta-dark); }
.einladung h3 { font-size: var(--step-2); }

/* 4.5 Timeline */
.timeline { display: grid; gap: 0; border-inline-start: 2px solid var(--line); padding-inline-start: var(--space-m); }
.timeline__item { position: relative; padding-block: var(--space-m); }
.timeline__item::before {
  content: ""; position: absolute; inset-inline-start: calc(var(--space-m) * -1 - 6px);
  inset-block-start: calc(var(--space-m) + 0.5em);
  inline-size: 10px; block-size: 10px;
  background: var(--cyan); outline: 4px solid var(--paper);
}
.timeline__when { font-size: var(--step--1); color: var(--ink-mute); font-variant-numeric: tabular-nums; }
.timeline__what { font-family: var(--font-display); font-weight: 600; }

/* 4.6 Akkordeon */
.accordion { border-block-start: 1px solid var(--line); }
.accordion__item { border-block-end: 1px solid var(--line); }
.accordion__trigger {
  inline-size: 100%; display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-m); padding: 1.2em 0;
  background: none; border: 0; text-align: start; cursor: pointer;
  font-family: var(--font-display);
  font-size: var(--step-1); font-weight: 600; color: var(--blue-deep);
}
.accordion__trigger:hover { color: var(--magenta); }
.accordion__icon { flex: none; transition: transform 0.25s var(--ease); }
.accordion__trigger[aria-expanded="true"] .accordion__icon { transform: rotate(180deg); }
.accordion__panel { padding-block-end: 1.4em; }
/* Ohne JS bleibt alles offen — hidden wird erst per JS gesetzt */
.accordion__panel[hidden] { display: none; }

/* 4.7 Formular */
.field { display: flex; flex-direction: column; gap: 0.4em; }
.field label { font-size: var(--step--1); font-weight: 600; }
.field input, .field textarea {
  padding: 0.8em 1em; background: var(--white);
  border: 1px solid var(--line);
}
.field input:focus-visible, .field textarea:focus-visible { border-color: var(--cyan); }
.field-grid { display: grid; gap: var(--space-m); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

fieldset { border: 0; padding: 0; }
fieldset legend { font-weight: 700; margin-block-end: var(--space-s); padding: 0; }

.check {
  display: flex; align-items: flex-start; gap: 0.7em;
  padding: 0.7em 1em; border: 1px solid var(--line);
  background: var(--white); cursor: pointer;
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease);
}
.check:hover { border-color: var(--cyan); }
.check:has(input:checked) { border-color: var(--cyan); background: var(--cyan-soft); }
.check input { margin-block-start: 0.25em; accent-color: var(--cyan); flex: none; }
.check-list { display: grid; gap: 0.6rem; }
.check-list--2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

/* 4.8 Split-Panel: Bild links, Farbfläche rechts */
.split { display: grid; gap: 0; grid-template-columns: 1fr; }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; } }
.split__media { block-size: 100%; min-block-size: 320px; object-fit: cover; inline-size: 100%; }
.split__body {
  display: flex; flex-direction: column; gap: var(--space-m);
  justify-content: center; padding: clamp(2rem, 5vw, 4rem);
  background: var(--blue-deep); color: var(--white);
}
.split__body h2, .split__body a { color: var(--white); }
/* Helle Buttons behalten dunklen Text — sonst weiss auf weiss */
.split__body a.btn--on-dark, .band a.btn--on-dark, .campaign a.btn--on-dark { color: var(--ink); }

/* 4.9 Farbband über die volle Breite — bringt seinen Innenabstand selbst mit.
   --space-l statt --space-xl: das Band ist ein Schlusswort vor dem Footer,
   keine eigene Sektion, und stand mit bis zu 8rem Polster je Seite hoeher als
   sein Inhalt verlangt. */
.band {
  background: var(--blue-deep); color: var(--white); text-align: center;
  padding-block: var(--space-l);
}
.band.section { padding-block: var(--space-l); }  /* doppelte Klasse schadet nicht */
/* Aufruf-Band — das Band, das zu /unterstuetzen fuehrt (Start, Themen).
   War bis 2026-09-21 vollflaechig Magenta; das stach als Flaeche zu stark
   heraus. Jetzt Dunkelblau wie jedes Band — Magenta ist im Styleguide die
   CTA-Farbe, bleibt aber »sparsam« und sitzt darum nur noch im Pfeilkreis
   des weissen Knopfs. Die Klasse bleibt als Haken fuer das Aufruf-Band. */
.band--aufruf { background: var(--blue-deep); }
.band h2, .band p { color: var(--white); }
.band p { margin-inline: auto; }

/* 4.10 Navigation — weisse Leiste, im Fluss (sticky).
   Sie liegt bewusst nicht ueber dem Bild: so steht nie weisse Schrift auf einem
   Foto, und jeder Hero beginnt genau unter der Leiste. Aktive und ueberfahrene
   Seite tragen einen Balken auf der Unterkante — dasselbe Element wie in der
   Schlagzeile, nur als Strich. Kein backdrop-filter und kein transform auf
   .nav selbst: beides wuerde einen Containing Block erzeugen und das
   fixierte Mobile-Menue (.nav__drawer, position: fixed) an die Leiste binden
   statt an den Viewport. Das Glas im gescrollten Zustand (.nav--solid) liegt
   darum weiter unten auf einem eigenen Pseudoelement statt auf .nav — ein
   Pseudoelement ist kein Vorfahre des Menues und hat dieses Problem nicht.

   Bewegung: der Balken gleitet zwischen den Links, die Wortmarke richtet sich
   auf, die Leiste faehrt beim Runterscrollen weg und beim Hochscrollen zurueck,
   das Menue blendet gestaffelt ein und aus. Alles ist Zugabe — ohne JS und
   unter prefers-reduced-motion bleibt die Leiste stehen und funktioniert. */
.nav {
  position: sticky; inset-block-start: 0; z-index: 50;
  block-size: var(--nav-h);
  display: flex; align-items: center;
  background: var(--white);
  box-shadow: inset 0 -1px 0 var(--line);
  transition: box-shadow 0.3s var(--ease), inset-block-start 0.4s var(--ease-out);
}
.nav--solid { box-shadow: inset 0 -1px 0 var(--line), 0 10px 20px -16px rgba(0, 0, 0, 0.45); }
/* Glas nur im gescrollten Zustand, nur auf einem Pseudoelement (Begruendung
   im Kopfkommentar oben). Nur .nav--solid wird dafuer transparent, sonst
   deckt die weisse Flaeche das Glas dahinter zu — die Grundleiste (die
   ersten 40px, bevor .nav--solid greift) bleibt bewusst deckend weiss,
   sonst waere sie in diesem kurzen Fenster ganz durchsichtig und ohne
   Weichzeichnung. Ohne @supports bleibt alles einfach weiss — das ist der
   ganze Fallback. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav--solid { background: transparent; }
  .nav--solid::before {
    content: "";
    position: absolute; inset: 0; z-index: -1;
    background: var(--glas-hell);
    backdrop-filter: blur(var(--glas-blur)) saturate(var(--glas-saettigung));
    -webkit-backdrop-filter: blur(var(--glas-blur)) saturate(var(--glas-saettigung));
    box-shadow: inset 0 1px 0 var(--glas-kante);
  }
}
/* Weggefahren: die Leiste schiebt sich um ihre eigene Hoehe nach oben */
.nav--hidden { inset-block-start: calc(var(--nav-h) * -1); box-shadow: none; }
.nav__inner {
  display: flex; align-items: center; gap: var(--space-m);
  /* Links wie .wrap ausgerichtet (Marke bleibt auf der Fluchtlinie des
     Inhalts darunter); rechts nur der Gutter statt der Wrap-Mitte, damit
     Navigation und Button auf breiten Screens naeher an den Rand ruecken.
     .nav__inner ist selbst ein Flex-Kind von .nav (display:flex) — ohne
     explizite Breite schrumpft es auf den Inhalt statt die Marge rechts
     freizuhalten, darum die Breite hier direkt ausrechnen statt margin:auto
     zu ueberlassen. */
  inline-size: calc(100% - max(var(--gutter), (100% - var(--wrap)) / 2) - var(--gutter));
  margin-inline-start: max(var(--gutter), (100% - var(--wrap)) / 2);
}

/* Wortmarke — gerade gesetzt, ohne Balken und ohne Neigung. Sein Name steht
   als Schrift da: beide Woerter fett, Versalien, leicht gesperrt. Die gekippte
   Flaeche bleibt dem Inhalt vorbehalten (Schlagzeilen); die Marke selbst kommt
   ohne sie aus und bleibt auf jedem Grund lesbar.

   Voller Fettschnitt statt Vorname mager / Nachname fett: die Marke tritt in
   der Leiste sonst hinter den Navigationslinks zurueck, die denselben Schnitt
   tragen. Dieselbe Setzung traegt .footer__mark im Fuss — eine Marke, zwei
   Groessen. Das <span> um den Nachnamen bleibt als Haken im Markup stehen,
   auch wenn es keinen Schnittwechsel mehr traegt. */
.nav__brand {
  position: relative; display: block;
  font-family: var(--font-display);
  font-weight: 700; font-size: 1.25rem;
  /* Enger gesperrt als zuvor (0.14em): der Fettschnitt schliesst von sich aus
     dichter, die alte Sperrung liess den Namen auseinanderfallen. */
  text-transform: uppercase; letter-spacing: 0.09em;
  /* Die Sperrung haengt hinter dem letzten Buchstaben als Leerraum. Derselbe
     Betrag negativ nimmt ihn zurueck, sonst sitzt der Balken rechts zu weit. */
  margin-inline-end: -0.09em;
  color: var(--ink); text-decoration: none; white-space: nowrap;
  /* Zeilenhoehe = Leistenhoehe, wie bei den Links: die Marke sitzt mittig,
     ihr Balken liegt buendig auf der Unterkante. */
  line-height: var(--nav-h);
}
/* Derselbe Cyan-Balken wie an den Links, nur zieht er hier auf statt zu
   gleiten. Kein Farbwechsel der Schrift: Schwarz auf Weiss bleibt stehen. */
.nav__brand::after {
  content: ""; position: absolute; inset-inline: 0; inset-block-end: 0;
  block-size: 4px; background: var(--cyan);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.3s var(--ease);
}
.nav__brand:hover::after,
.nav__brand:focus-visible::after { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .nav__brand::after { transition: none; }
}

/* Links: Zeilenhoehe = Leistenhoehe, so sitzt der Text mittig und der Balken
   liegt buendig auf der Unterkante. */
.nav__list { display: none; position: relative; gap: clamp(1rem, 2.2vw, 2rem); margin-inline-start: auto; }
@media (min-width: 980px) { .nav__list { display: flex; } }
.nav__link {
  position: relative; display: block;
  font-family: var(--font-display); font-weight: 600;
  line-height: var(--nav-h); color: var(--ink); text-decoration: none;
}
/* Ohne JS: jeder Link zieht seinen eigenen Balken auf */
.nav__link::after {
  content: ""; position: absolute; inset-inline: 0; inset-block-end: 0;
  block-size: 4px; background: var(--cyan);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.25s var(--ease);
}
.nav__link:hover::after,
.nav__link:focus-visible::after { transform: scaleX(1); }
.nav__link[aria-current="page"]::after { background: var(--magenta); transform: scaleX(1); }
.nav__link:focus-visible { outline-offset: -3px; }

/* Mit JS: ein einziger Balken, der zwischen den Links gleitet. Ruhelage ist die
   aktive Seite in Magenta, unterwegs ist er Cyan. Auf Seiten ohne aktiven Link
   blendet er nur beim Ueberfahren ein. Position und Breite setzt das JS. */
.nav__list--marker .nav__link::after { content: none; }
.nav__marker {
  position: absolute; inset-block-end: 0; inset-inline-start: 0;
  block-size: 4px; inline-size: var(--w, 0px);
  background: var(--cyan); opacity: 0; pointer-events: none;
  transform: translateX(var(--x, 0px));
  transition: transform 0.45s var(--ease-out), inline-size 0.45s var(--ease-out),
              background-color 0.2s var(--ease), opacity 0.2s var(--ease);
}
.nav__marker.is-on { opacity: 1; }
.nav__marker.is-active { background: var(--magenta); }
/* Erstes Erscheinen: an die Stelle springen, nur einblenden — nicht anfliegen */
.nav__marker.is-instant { transition: background-color 0.2s var(--ease), opacity 0.2s var(--ease); }

/* Rechts: Button, Menueknopf */
.nav__actions { display: flex; align-items: center; gap: var(--space-s); margin-inline-start: auto; }
@media (min-width: 980px) { .nav__actions { margin-inline-start: 0; } }

/* In der Leiste kompakter als im Inhalt. Unter 520px passt er nicht neben
   Wortmarke und Menueknopf — dort steht er im Menue. Der Pfeil rueckt beim
   Ueberfahren nach vorn. */
.nav__cta { display: none; padding: 0.6em 0.6em 0.6em 1.1em; }
@media (min-width: 520px) { .nav__cta { display: inline-flex; } }
.nav__cta .btn__arrow, .nav__drawer-cta .btn__arrow { transition: transform 0.3s var(--ease-spring); }
.nav__cta:hover .btn__arrow, .nav__drawer-cta:hover .btn__arrow { transform: translateX(3px); }

/* Mobiles Menue als <details> — funktioniert ohne JavaScript. Der Knopf ist
   aus CSS gezeichnet: drei Balken, geoeffnet ein Kreuz. */
.nav__menu { display: block; }
@media (min-width: 980px) { .nav__menu { display: none; } }
.nav__menu > summary {
  display: grid; place-items: center;
  inline-size: 2.75rem; block-size: 2.75rem;
  cursor: pointer; list-style: none;
  transition: background-color 0.2s var(--ease);
}
.nav__menu > summary::-webkit-details-marker { display: none; }
.nav__menu > summary:hover { background: var(--paper-alt); }

.nav__burger, .nav__burger::before, .nav__burger::after {
  display: block; inline-size: 1.5rem; block-size: 3px; background: var(--ink);
  transition: transform 0.35s var(--ease-spring), background-color 0.2s var(--ease);
}
.nav__burger { position: relative; }
.nav__burger::before, .nav__burger::after { content: ""; position: absolute; inset-inline-start: 0; }
.nav__burger::before { inset-block-start: -0.5rem; }
.nav__burger::after  { inset-block-start: 0.5rem; }
/* is-closing: das JS haelt das Menue fuer die Ausblendung noch offen —
   der Knopf soll aber schon zurueckfalten. */
.nav__menu[open]:not(.is-closing) .nav__burger { background: transparent; }
.nav__menu[open]:not(.is-closing) .nav__burger::before { transform: translateY(0.5rem) rotate(45deg); }
.nav__menu[open]:not(.is-closing) .nav__burger::after  { transform: translateY(-0.5rem) rotate(-45deg); }

/* Menue-Flaeche: Zeilen. Die aktive Zeile traegt den Cyan-Balken
   links wie die Karte. Die Flaeche blendet ein, die Zeilen laufen gestaffelt
   nach; beim Schliessen faehrt alles in einem Zug weg. */
.nav__drawer {
  position: fixed; inset: var(--nav-h) 0 0; z-index: 49;
  display: flex; flex-direction: column;
  padding: var(--space-s) var(--gutter) var(--space-l);
  background: var(--white); overflow-y: auto;
  animation: nav-drawer-in 0.3s var(--ease-out) backwards;
}
/* Glas direkt am Element: .nav__drawer hat selbst keine fixierten Kinder,
   ein backdrop-filter hier erzeugt keinen Containing-Block-Konflikt wie
   bei .nav. Ohne @supports bleibt die deckende weisse Flaeche stehen. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav__drawer {
    background: var(--glas-hell);
    backdrop-filter: blur(var(--glas-blur)) saturate(var(--glas-saettigung));
    -webkit-backdrop-filter: blur(var(--glas-blur)) saturate(var(--glas-saettigung));
    box-shadow: inset 0 1px 0 var(--glas-kante);
  }
}
.nav__menu.is-closing .nav__drawer { animation: nav-drawer-out 0.18s var(--ease) forwards; }
@keyframes nav-drawer-in  { from { opacity: 0; transform: translateY(-10px); } }
@keyframes nav-drawer-out { to   { opacity: 0; transform: translateY(-10px); } }

/* backwards, nicht both: nach dem Einlaufen darf die Animation keinen
   transform mehr halten, sonst greift der Hover-Versatz des Buttons nicht. */
.nav__drawer > * { animation: nav-item-in 0.45s var(--ease-out) backwards; }
.nav__drawer > :nth-child(1) { animation-delay: 0.05s; }
.nav__drawer > :nth-child(2) { animation-delay: 0.09s; }
.nav__drawer > :nth-child(3) { animation-delay: 0.13s; }
.nav__drawer > :nth-child(4) { animation-delay: 0.17s; }
.nav__drawer > :nth-child(5) { animation-delay: 0.21s; }
.nav__drawer > :nth-child(6) { animation-delay: 0.25s; }
@keyframes nav-item-in { from { opacity: 0; transform: translateX(-14px); } }

.nav__drawer-link {
  display: block;
  padding: 0.6em 0 0.6em var(--space-s);
  border-block-end: 1px solid var(--line);
  border-inline-start: 6px solid transparent;
  font-family: var(--font-display); font-size: var(--step-2); font-weight: 700;
  color: var(--ink); text-decoration: none;
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease), padding-inline-start 0.3s var(--ease-out);
}
.nav__drawer-link:hover { border-inline-start-color: var(--magenta); background: var(--paper-alt); padding-inline-start: var(--space-m); }
.nav__drawer-link[aria-current="page"] { border-inline-start-color: var(--cyan); }
.nav__drawer-cta { justify-content: center; margin-block-start: var(--space-m); font-size: var(--step-1); }
@media (min-width: 520px) { .nav__drawer-cta { display: none; } }

/* 4.11 Kampagnen-Band am Seitenfuss */
.campaign {
  position: fixed; inset-inline: 0; inset-block-end: 0; z-index: 60;
  background: var(--blue-deep); color: var(--white);
  transform: translateY(100%); transition: transform 0.35s var(--ease);
}
/* Glas direkt am Element: .campaign ist selbst position: fixed und hat
   keine fixierten Kinder, ein backdrop-filter hier ist unproblematisch —
   anders als bei .nav (siehe dort). Der bestehende translateY vertraegt
   sich damit. Ohne @supports bleibt die deckende Flaeche stehen. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .campaign {
    background: var(--glas-dunkel);
    backdrop-filter: blur(var(--glas-blur)) saturate(var(--glas-saettigung));
    -webkit-backdrop-filter: blur(var(--glas-blur)) saturate(var(--glas-saettigung));
    box-shadow: inset 0 1px 0 var(--glas-kante);
  }
}
.campaign--visible { transform: translateY(0); }
.campaign[hidden] { display: none; }
.campaign__inner {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-s) var(--space-m);
  inline-size: min(var(--wrap), 100% - var(--gutter) * 2); margin-inline: auto;
  padding-block: 0.9rem;
}
.campaign__text { flex: 1 1 16rem; }
.campaign__text strong { display: block; }
.campaign__close {
  background: none; border: 0; color: inherit; cursor: pointer;
  inline-size: 2.75rem; block-size: 2.75rem; display: grid; place-items: center;
}
.campaign__close:hover { background: rgba(255, 255, 255, 0.15); }
.campaign__text strong { font-family: var(--font-display); }

/* 4.12 Footer — dunkle Schlussfläche ---------------------------------------
   Der Footer ist die einzige durchgehend dunkle Fläche der Seite und schliesst
   sie wie ein Plakatfuss ab. Er hat vier Bänder:

     1  Navigationsband — die fünf Hauptziele, gross und editorial gesetzt.
        Das dominante Element des Footers, ganz oben und links.
     2  Kontaktspalte — Kontakt, Direkt (Social) und Partei, ab 860px neben
        der Navigation, darunter unter ihr gestapelt.
     3  Wortmarke — unter den Spalten, nicht mehr darüber: der Footer beginnt
        ruhig (Navigation, Kontakt) und endet laut (die grosse Marke).
     4  Schlussband — Impressum, Datenschutz, Copyright, mittig.

   Das vierte Band steht mittig, alles darüber linksbündig. Genau dieser
   Wechsel macht den Schluss als Schluss lesbar.
   ------------------------------------------------------------------------ */
.footer {
  /* Eine Flaeche, kein Verlauf: der Fuss ist die ruhigste Zone der Seite und
     traegt mit der Navigation, der Kontaktspalte und der Wortmarke schon
     genug.

     Dunkelblau statt Schwarz. Auf »Ueber mich« steht direkt darueber das
     Schlussband .band in --blue-deep; damit die beiden Flaechen nicht
     ineinanderlaufen, ist --blue-night deutlich tiefer gesetzt. Der Sprung
     ist weicher als der zu Schwarz, aber sichtbar. Das gilt auch fuer das
     Aufruf-Band (.band--aufruf) auf Start und Themen.
     Weiss steht hier durchgehend bei 14:1. */
  background: var(--blue-night);
  color: var(--white);
  /* Eigener Wert statt --space-l: der Footer traegt seinen Abstand nach oben
     bereits im Schlussband der Seite (.band) und braucht das volle Polster
     einer Sektion hier nicht. */
  padding-block: clamp(2rem, 4vw, 3.25rem) 0;
  overflow: hidden;
}
.footer a { color: var(--white); }

/* Navigation und Kontaktspalte liegen nebeneinander ab 860px, darunter
   gestapelt. Die Wortmarke (dritter Punkt oben) spannt beide Spalten, sobald
   es welche gibt, und steht als eigene Zeile unter ihnen. */
.footer > .wrap {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-m) var(--space-l);
}
@media (min-width: 860px) {
  .footer > .wrap { grid-template-columns: 1.4fr 1fr; }
}

/* Label über jeder Gruppe — Navigation und jede Kontakt-Gruppe teilen sich
   dieselben Werte. */
.footer__nav > strong,
.footer__gruppe > strong {
  display: block;
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step--1);
  color: rgba(255, 255, 255, 0.6);
  margin-block-end: 0.25rem;
}

/* Navigationsband — das dominante Element des Footers. Fünf Ziele, gross und
   editorial gesetzt, jede Zeile durch eine Haarlinie vom Rest getrennt.
   Die Geste beim Überfahren ist dieselbe wie bei .merkpunkte im Funnel: ein
   kleiner gekippter Cyan-Balken — hier vor der Zeile statt vor dem Text. */
.footer__navlist {
  list-style: none; margin: 0; padding: 0;
  margin-block-start: 0.5rem;
  border-block-start: 1px solid rgba(255, 255, 255, 0.2);
}
.footer__navlist li { border-block-end: 1px solid rgba(255, 255, 255, 0.2); }
.footer__navlist a {
  position: relative; display: block;
  padding-block: 0.2em; padding-inline-start: 1.2em;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.95rem, 3.6vw, 2.75rem); line-height: 1.2;
  color: var(--white); text-decoration: none;
  transition: transform 0.25s var(--ease);
}
/* Der Balken liegt in einer reservierten Einrückung statt an einem
   negativen Versatz: so verschiebt sein Einblenden nichts, und er wird am
   Rand der .wrap nicht abgeschnitten (der Footer trägt overflow: hidden für
   den Verlauf der Fläche). */
.footer__navlist a::before {
  content: "";
  position: absolute; inset-inline-start: 0; inset-block-start: 50%;
  inline-size: 0.5em; block-size: 0.5em;
  translate: 0 -50%; rotate: var(--neigung);
  background: var(--cyan);
  opacity: 0; transition: opacity 0.2s var(--ease);
}
.footer__navlist a:hover,
.footer__navlist a:focus-visible { transform: translateX(0.2em); }
.footer__navlist a:hover::before,
.footer__navlist a:focus-visible::before,
.footer__navlist a[aria-current="page"]::before { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  /* Nur der Balken darf noch wechseln, kein Versatz der Zeile. */
  .footer__navlist a { transition: none; }
  .footer__navlist a:hover, .footer__navlist a:focus-visible { transform: none; }
}

/* Kontaktspalte — drei Gruppen: Kontakt, Direkt (Social), Partei. */
/* Eigener Abstand statt --space-l: das Token geht bis 5rem und riss die drei
   Gruppen auf dem Desktop weiter auseinander, als die Navigation daneben hoch
   ist. */
.footer__kontakt { display: grid; gap: clamp(1.5rem, 2.6vw, 2.25rem); align-content: start; }
.footer__gruppe { display: grid; gap: 0.5rem; align-content: start; }
.footer__gruppe a {
  display: inline-flex; align-items: center; gap: 0.3em;
  text-decoration: none; color: var(--white);
  inline-size: fit-content;
  border-block-end: 1px solid transparent;
  transition: border-color 0.2s var(--ease);
}
.footer__gruppe a:hover,
.footer__gruppe a:focus-visible { border-block-end-color: var(--magenta); }
.footer__gruppe a span[aria-hidden] { color: var(--cyan); }
/* Die Mailadresse ist der wichtigste Kontaktweg und steht darum eine Stufe
   grösser als die übrigen Zeilen. */
.footer__kontakt a[href^="mailto:"] { font-size: var(--step-1); }

/* Wortmarke — der Abschluss der Seite, uebernommen von der Seismos-Seite.

   Sie steht nicht mehr im Satzspiegel ueber dem Schlussband, sondern liegt
   vollflaechig darunter und wird vom unteren Seitenrand angeschnitten: ein
   Versatz nach unten schiebt sie ueber die Kante, das overflow: hidden des
   Footers schneidet sie dort ab. Die Marke sitzt damit nicht auf der Seite,
   sie steigt aus ihrem Rand auf.

   Das Ausblenden nach unten machen zwei deckungsgleiche Lagen:
     1  scharf — oben voll deckend, bis 66 Prozent ausgelaufen
     2  weichgezeichnet — setzt bei 30 Prozent ein, laeuft zur Kante aus
   Die zweite uebernimmt genau dort, wo die erste verschwindet. Die Marke
   loest sich dadurch nach unten auf, statt bloss durchsichtig zu werden.

   Es bewegt sich nichts: der Verlauf liegt fest, beim Scrollen wird nichts
   zugeschaltet. Auf der Seismos-Seite ist es genauso geloest.

   Die Marke ist damit Flaeche, nicht Text — im Markup traegt sie aria-hidden.
   Der Name steht lesbar im Schlussband darueber und oben in der Leiste. */
.footer__mark {
  position: relative;
  margin-block-start: clamp(1.5rem, 4vw, 3rem);
  /* Deckung an einer Stelle, damit sie sich ohne Suche nachziehen laesst.
     Darunter verschwindet die Marke auf Schwarz, darueber nimmt sie dem
     Schlussband die Ruhe. */
  --mark-deckung: 0.18;
  /* Der Anschnitt. Mobil faellt er kleiner aus: dort ist die Marke im
     Verhaeltnis zur Fuellhoehe des Fusses ohnehin praesenter. */
  translate: 0 12%;
}
@media (min-width: 860px) { .footer__mark { translate: 0 18%; } }

.footer__mark-lage {
  margin: 0;
  font-family: var(--font-display); font-weight: 700;
  /* Ueber die volle Breite gerechnet, nicht ueber die Satzbreite. Deutlich
     kleiner als die 25vw der Seismos-Marke, weil »JOEL SIDLER« elf Versalien
     hat und »SEISMOS« sieben — bei gleicher Zahl liefe die Zeile weit ueber
     den Bildschirm hinaus.

     Nachgemessen: die Zeile ist in Jost Bold 6.04em breit. 17.5vw stellen sie
     damit auf rund 106 Prozent der Fensterbreite — sie laeuft ueber beide
     Raender hinaus und wird dort angeschnitten, wie die Marke auf der
     Seismos-Seite. Das overflow: hidden des Footers faengt den Ueberstand
     ab; die Seite bekommt dadurch keine Querscrollleiste, auch nicht mit
     einer Ersatzschrift. Wer sie enger haben will, dreht an dieser einen
     Zahl: 16.5vw stellen sie randlos, 15.5vw mit Luft an beiden Seiten. */
  font-size: clamp(2.6rem, 17.5vw, 22rem);
  line-height: 0.78;
  text-transform: uppercase; letter-spacing: -0.03em;
  text-align: center; white-space: nowrap;
  /* Die globale p-Regel gibt jedem Absatz die Satzbreite --measure. Ohne
     diese Zeile braeche die Marke dort um. */
  max-inline-size: none;
  color: var(--white); opacity: var(--mark-deckung);
  user-select: none;
  mask-image: linear-gradient(to bottom, #000 0%, #000 36%, transparent 66%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 36%, transparent 66%);
}
/* Die weiche Lage liegt deckungsgleich ueber der scharfen. */
.footer__mark-lage--weich {
  position: absolute; inset: 0;
  /* In em statt px, damit die Weichzeichnung mit der Marke mitskaliert. */
  filter: blur(0.03em);
  mask-image: linear-gradient(to bottom, transparent 30%, #000 62%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 30%, #000 62%, transparent 100%);
}

/* Schlussband — mittig. Impressum, Datenschutz und Copyright stehen hier
   zentriert, damit die Pflichtangaben als eigene Ebene lesbar sind und nicht
   als vierte Spalte missverstanden werden. */
.footer__schluss {
  /* Ohne Haarlinie nach oben: die Spalten darueber tragen ihre eigenen
     Linien (Navigationsband), eine weitere haette den Fuss in drei
     sichtbare Kaesten zerlegt. Den Abstand macht jetzt allein das Polster.
     Nicht --space-l: das Token geht bis 5rem und haette den Fuss wieder so
     weit aufgezogen, wie er vor dem Verkleinern war. */
  padding-block: clamp(3rem, 5.5vw, 4.5rem) var(--space-m);
  text-align: center;
}
.footer__legal {
  display: flex; justify-content: center; align-items: center;
  gap: 0.4rem 2rem; flex-wrap: wrap;
  font-size: var(--step--1);
  /* Die globale Regel gibt jedem p die Satzbreite --measure. Ohne diese
     Zeile zentriert justify-content nur innerhalb dieser 62 Zeichen — die
     Zeile selbst stünde links. */
  max-inline-size: none;
}
.footer__legal a { color: rgba(255, 255, 255, 0.85); text-decoration: none; }
.footer__legal a:hover { color: var(--white); text-decoration: underline; }
/* Der Mittelpunkt zwischen Impressum und Datenschutz ist weg: zwei Glieder
   sind keine Kette, und mit Punkt verbundene Metazeilen sind eine der
   Signaturen generierter Gestaltung. Die Trennung macht der Abstand. */
.footer__legal span[aria-hidden] { display: none; }
.footer__copy {
  font-size: var(--step--1); color: rgba(255, 255, 255, 0.6);
  max-inline-size: none; margin-block-start: 0.5rem;
}

/* 4.13 Hero — auf jeder Seite derselbe Bau ---------------------------------
   Ein Bild über die ganze Fläche, darüber der Balkentitel. Der Hero nimmt
   immer den ganzen Bildschirm ein: 100svh abzüglich der Navigationsleiste,
   die im Fluss darüber steht und keine Fläche überdeckt. svh statt vh, sonst
   schneidet die Browserleiste auf iOS den unteren Rand ab.

   Zwei Bildfassungen je Seite, gewählt über <picture>:
     hero-<seite>-quer.jpg  2000×1125  ab 700 px Viewportbreite
     hero-<seite>-hoch.jpg  1000×1500  darunter
   Eine einzige Querfassung würde auf dem Telefon zu einem senkrechten
   Streifen aus der Bildmitte zusammenschneiden — der Kopf fiele heraus.
   ------------------------------------------------------------------------ */
.hero {
  position: relative;
  min-block-size: calc(100svh - var(--nav-h));
  display: grid; align-content: end;
  /* Der Textblock sitzt seit 2026-09-22 so tief wie möglich: er ist mit der
     breiten Schlagzeile hoch geworden, und auf hero-start-quer.jpg beginnt
     genau darüber Joels Gesicht. Jedes Pixel Fusspolster schiebt die erste
     Zeile in sein Kinn. Der Hinweis nach unten steht darum rechts aussen und
     nicht mehr mittig unter dem Block — sonst müsste hier wieder Platz für
     ihn frei bleiben. */
  padding-block: var(--space-l);
  background: var(--blue-deep); color: var(--white);
  overflow: hidden; isolation: isolate;
}
/* <picture> ist ein Inline-Element und würde als leere Zeile Höhe im Hero
   erzeugen. display: contents nimmt es aus dem Layout; das <img> darin
   positioniert sich weiterhin an .hero. */
.hero > picture { display: contents; }
.hero__media {
  position: absolute; inset: 0; z-index: -2;
  inline-size: 100%; block-size: 100%;
  object-fit: cover; object-position: var(--bildpunkt, 50% 30%);
}
/* Ein einziger Fuss trägt den Kontrast. Der Text steht seit 2026-09-22 als
   breiter Block ganz unten über die volle Spaltenbreite, nicht mehr in einer
   schmalen Säule links — darum fällt der frühere Verlauf von links weg und
   der untere wird kräftiger. Schwarz trägt die Lesbarkeit, Dunkelblau legt
   den Farbklang darüber, ohne das Bild grau zu machen.
   Auf hero-start-quer.jpg bleibt Joel vom Brustbild aufwärts frei; dass die
   Schlagzeile ihn auf Hüfthöhe schneidet, ist die Geste, nicht ein Unfall. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(to top, rgba(0, 0, 0, 0.88) 0%, rgba(0, 0, 0, 0.66) 24%, rgba(0, 0, 0, 0.26) 52%, rgba(0, 0, 0, 0) 80%),
    linear-gradient(to top, rgba(7, 78, 161, 0.42) 0%, rgba(7, 78, 161, 0) 62%);
}

/* Die Ordnung im Hero ist seit 2026-09-22 umgedreht: der Kicker steht über
   dem Titel, der Titel schliesst den Block nach unten ab. Gemacht mit order,
   nicht im Markup — so bleibt die Lesereihenfolge für Screenreader bei h1
   zuerst, und alle sieben Seiten tragen weiter dieselbe Komponente ohne
   eigene Auszeichnung. */
.hero__inner {
  position: relative;
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--space-s);
}
.hero__inner .pill { order: -1; }
.hero h1           { order: 2; }
.hero__actions     { order: 3; }

/* Versalien, gross, dicht: der Hero trägt seit 2026-09-22 nur noch den
   Seitentitel, keinen Claim und keinen Vorspann mehr. Ein Wort pro Seite,
   satzbreit gesetzt — die Aussage steht im Inhalt darunter, hier steht, wo
   man ist. text-transform statt Versalien im Markup: Screenreader und
   <title> lesen weiter die normale Schreibweise.
   Der negative Anfangsrand ist optischer Ausgleich — die Glyphe bringt ihre
   Seitenlagerung mit, ohne ihn stünde die Buchstabenkante sichtbar innerhalb
   der Spaltenkante, und bei dieser Grösse sieht man das. */
.hero h1 {
  color: var(--white);
  max-inline-size: 100%;
  font-size: clamp(2.75rem, 11vw, 8rem);
  font-weight: 800;
  line-height: 0.86;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  text-wrap: balance;
  margin-inline-start: -0.045em;
}

.hero__actions {
  display: flex; flex-wrap: wrap; gap: var(--space-s); align-items: center;
  margin-block-start: var(--space-s);
}
/* Die Startseite macht als einzige nicht den Seitentitel gross, sondern den
   Claim: sie hat keinen Namen zu nennen, sie hat etwas zu sagen. Also zurück
   zu Gross-/Kleinschreibung, kleinerem Grad und ausgefranstem rechtem Rand —
   balance mittelt die Zeilen sonst zu einem ruhigen Block aus und nimmt genau
   die Wirkung weg, um die es hier geht.

   Der Grad ist seit 2026-09-22 rein an die Fensterbreite gebunden (vw statt
   clamp mit rem-Untergrenze), damit der Claim auf jeder Breite auf genau zwei
   Zeilen steht: die Spalte wächst mit vw, also bleibt bei festem vw-Grad die
   Zeichenzahl pro Zeile konstant — und mit ihr die Zeilenzahl. 5.8vw ist
   gemessen, nicht geschätzt: der Satz ist 27.15em lang, bei mehr Grad bricht
   er auf 320 px in die dritte Zeile. Wer den Claim ändert, muss die Zahl neu
   messen. Die Obergrenze hält ihn ab 1280 px an der Rasterbreite fest.
   Preis dieser Regel: auf dem Telefon steht der Claim bei rund 21 px — wer
   ihn dort gross will, muss ihn kürzen. */
.hero--start h1 {
  text-transform: none;
  font-size: min(5.8vw, 4.9rem);
  line-height: 0.92;
  letter-spacing: -0.035em;
  text-wrap: wrap;
}

/* Nur die Startseite steht so tief: ihr Block trägt zusätzlich Kicker und
   zwei Schaltflächen und wird dadurch so hoch, dass jedes Fusspolster die
   erste Zeile in Joels Kinn schiebt. Die Unterseiten haben den Platz. */
.hero--start { padding-block-end: calc(var(--space-m) * 1.25); }

/* Ein Bildschirm voll Bild braucht das Signal, dass darunter etwas kommt.
   Der Hinweis ist dekorativ und für Hilfsmittel ausgeblendet. */
/* .hero__weiter ist seit 2026-09-21 ein <a> mit Sprungziel, kein
   <p aria-hidden> mehr: das Element sah wie ein Link aus, war aber keiner —
   genau das kritisierte Joel im Mobile-Feedback. */
.hero__weiter {
  position: absolute; inset-block-end: var(--space-m);
  inset-inline: auto var(--gutter);
  display: grid; justify-content: end; justify-items: end; gap: 0.35rem;
  font-family: var(--font-display); font-size: 0.8rem;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
  text-decoration: none;
  transition: color 0.2s var(--ease);
}
.hero__weiter:hover,
.hero__weiter:focus-visible { color: var(--white); }
.hero__weiter::after {
  content: ""; inline-size: 1px; block-size: 2rem;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0));
  animation: weiter 2.4s var(--ease) infinite;
  transform-origin: top;
}
@keyframes weiter {
  0%, 100% { transform: scaleY(0.35); opacity: 0.3; }
  50%      { transform: scaleY(1);    opacity: 1;   }
}

/* Schmale Viewports: der Hinweis steht rechts aussen am selben Platz wie die
   Schaltflächen und drängte sich dort neben sie. Er rutscht darum unter den
   Block in den Fluss — er bleibt ein echter Link mit Sprungziel, nur ohne
   eigene Ebene. */
@media (max-width: 699px) {
  .hero__weiter {
    position: static;
    justify-self: end;
    margin-block-start: var(--space-m); margin-inline-end: var(--gutter);
  }
}

/* Auf niedrigen, breiten Fenstern (Laptop im Querformat, Telefon gedreht)
   würde der volle Bildschirm den Text an den Hinweis drücken. Dort fällt er
   weg und der Hero atmet weniger. */
@media (max-height: 560px) {
  .hero { padding-block: var(--space-l); }
  .hero__weiter { display: none; }
}

/* Nur auf farbigem Grund ist der Geisterbutton mit schwarzem Rand unleserlich. */
.band .btn--ghost,
.hero .btn--ghost { color: var(--white); border-color: var(--white); }
.band .btn--ghost:hover,
.hero .btn--ghost:hover { background: var(--white); color: var(--ink); border-color: var(--white); }
