/* =========================================================================
   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;
  /* v13: eine Stufe dichter (war 2.5–5rem / 4–8rem). Joel: die Seite darf
     luftig bleiben, man soll aber weniger scrollen müssen. */
  --space-l:  clamp(2rem, 4.5vw, 3.5rem);
  --space-xl: clamp(3rem, 7vw, 5.5rem);

  /* Das FDP-Design ist hartkantig: Balken und Flaechen, keine Pillen.
     --radius bleibt als Token bestehen, steht aber auf null. */
  --radius: 0px;
  --nav-h: 64px;
  /* Wahlhinweis-Leiste über der Navigation (v12). --kopf-h ist die ganze
     Kopfhöhe; alles, was unter dem Kopf klebt oder ihn abzieht, rechnet
     damit statt mit --nav-h. */
  --leiste-h: 2rem;
  --kopf-h: calc(var(--leiste-h) + var(--nav-h));


  --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; }

/* ---------- 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;
}
.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. Seit v12 eine Farbe für alle (Cyan), und die
   Karte trägt eine Haarlinie: die Sektion liegt jetzt auf Weiss.
   ------------------------------------------------------------------------ */
.quote {
  --akzent: var(--cyan);
  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: 1px solid var(--line);
  border-block-start: 6px solid var(--akzent);
}

/* 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: "»"; }

.stimmen__intro { max-inline-size: var(--measure); margin-block-end: var(--space-l); }
/* Desktop: der Titel steht auf einer Zeile. */
@media (min-width: 900px) {
  .stimmen__intro, .stimmen__intro h2 { max-inline-size: none; }
}

.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; }
}

/* 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.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); }
/* v16: auf allen Seiten gleich gesetzt (vorher nur auf der Startseite, in
   home.css). Der Claim hat keine Breitengrenze und steht auf dem Desktop auf
   einer Zeile, die Unterzeile läuft auf der normalen Satzbreite (46ch war
   Joel zu eng) und bricht in gleich lange Zeilen. */
.band .stack { display: flex; flex-direction: column; align-items: center; }
.band p { margin-inline: auto; max-inline-size: var(--measure); text-wrap: balance; }

/* 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. */
/* Feste Leiste mit dem Wahlhinweis. Sie klebt immer oben, auch wenn die
   Navigation darunter beim Scrollen wegfährt. Dunkelblau als Fläche,
   Magenta bleibt der Handlung vorbehalten. Seit v16 nur noch ein Satz,
   ohne Liste und Countdown (Joel). */
.leiste {
  position: sticky; inset-block-start: 0; z-index: 51;
  block-size: var(--leiste-h);
  display: flex; align-items: center; justify-content: center;
  max-inline-size: none; margin: 0;
  padding-inline: var(--gutter);
  background: var(--blue-deep); color: var(--white);
  font-family: var(--font-display); font-weight: 500;
  font-size: var(--step--1); line-height: 1;
  white-space: nowrap; overflow: hidden;
}
@media (max-width: 559px) {
  .leiste { font-size: 0.75rem; padding-inline: var(--space-s); }
}

.nav {
  position: sticky; inset-block-start: var(--leiste-h); 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(--leiste-h) - var(--nav-h)); 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(--kopf-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.
   Beim Überfahren erscheint ein kleiner Cyan-Balken vor der Zeile. */
.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%;
  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), FDP-Logo. */
/* 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); }
/* FDP-Logo statt Parteilinks (v12): weisse Fassung, verlinkt auf fdp.ch. */
.footer__gruppe a.footer__fdp { display: block; border: 0; opacity: 0.9; transition: opacity 0.2s var(--ease); }
.footer__gruppe a.footer__fdp:hover,
.footer__gruppe a.footer__fdp:focus-visible { opacity: 1; }
.footer__fdp img { display: block; block-size: 13px; inline-size: auto; }

/* 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(--kopf-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. Seit v16 ohne »Mehr erfahren« darunter. */
  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 h1           { order: 2; }

/* 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%;
  /* v16: Untergrenze 2.25rem statt 2.75rem — »SCHWERPUNKTE« lief bei
     320 px über den Rand. Ab 400 px greift ohnehin 11vw. */
  font-size: clamp(2.25rem, 11vw, 8rem);
  font-weight: 800;
  line-height: 0.86;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  text-wrap: balance;
  margin-inline-start: -0.045em;
}

/* Die Startseite trägt seit v13 einen ganzen Satz als Slogan statt drei
   Wörter: gemischt geschrieben statt Versalien und kleiner, sonst füllt er
   das Bild. */
.hero--start h1 {
  max-inline-size: 26ch;
  font-size: clamp(1.9rem, 1.1rem + 2.6vw, 3.25rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  text-transform: 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); }
