/* ============================================================
   Fonts (self-hosted, siehe /fonts)
   ============================================================ */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('../fonts/fraunces-variable.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('../fonts/inter-variable.woff2') format('woff2');
}

/* ============================================================
   Tokens
   ============================================================ */
:root {
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --color-bg: #faf8f5;
  --color-bg-alt: #f2eee7;
  --color-surface: rgba(255, 255, 255, 0.6);
  --color-surface-border: rgba(255, 255, 255, 0.5);
  --color-ink: #1c1b19;
  --color-ink-soft: #5b564f;
  --color-ink-faint: #8c867d;
  --color-line: rgba(28, 27, 25, 0.12);

  --color-accent: #5b45e0;
  --color-accent-soft: #ece8fb;
  --gradient-brand: linear-gradient(135deg, #5b45e0 0%, #c2497a 100%);
  --gradient-brand-soft: linear-gradient(135deg, #8d7bff 0%, #f0879f 50%, #ffc98a 100%);

  --gradient-theme: var(--gradient-brand);
  --gradient-theme-soft: var(--gradient-brand-soft);

  /* Lichtecke im CTA-Band, standardmaessig aus. */
  --cta-glow: transparent;

  /* Seitenidentitaet — Kleintitel, Navigationsstrich und CTA-Band.
     Diese drei werden hier bewusst NICHT als Alias auf das Theme
     gesetzt: :root ist <html>, das Theme sitzt aber auf <body>. Ein
     Alias wuerde hier zum neutralen Wert aufgeloest und diesen fertig
     nach unten vererben — Warm und Kuehl bekaemen den Markenverlauf.
     Stattdessen steht der Rueckfallwert am Verwendungsort, wo er im
     Kontext des jeweiligen Themes aufgeloest wird. */

  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-sm: 1.25rem;
  --space-md: 2rem;
  --space-lg: 3rem;
  --space-xl: 5rem;
  --space-2xl: 7.5rem;

  --radius-sm: 0.6rem;
  --radius-md: 1.25rem;
  --radius-lg: 2rem;
  --radius-pill: 999px;

  --blur-glass: 20px;
  --shadow-soft: 0 10px 30px -12px rgba(28, 27, 25, 0.18);
  --shadow-md: 0 24px 60px -20px rgba(28, 27, 25, 0.25);

  --container: 74rem;
  --container-narrow: 46rem;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Mindesthöhe einer Themenbox. Die großen Boxen auf "Für Unternehmen"
     rechnen damit, deshalb steht der Wert hier und nicht in der Regel. */
  --topic-card-min: 14rem;

  /* Kategoriefarben der Zeitleiste — abgeleitet aus den Themes der
     Zielgruppenseiten, damit die Zeitleiste die Zwei-Wege-Logik der
     Seite aufgreift. Sie stehen hier und nicht auf .timeline, weil
     die Filterleiste ein Geschwister-Element der Liste ist und die
     Token dort sonst nicht ankommen. */
  --kat-beruflich: #33465c;
  --kat-persoenlich: #85573a;
  --kat-ausbildung: #5b45e0;

  /* Zweiton-Verläufe für Linie und Punkte bei aktivem Filter.
     Hier steht kein Text darauf, deshalb darf das helle Ende hell sein. */
  --grad-beruflich: linear-gradient(180deg, #33465c 0%, #6b8299 100%);
  --grad-persoenlich: linear-gradient(180deg, #85573a 0%, #c49173 100%);
  --grad-ausbildung: linear-gradient(180deg, #5b45e0 0%, #a397f0 100%);

  /* Eigene Verläufe für die gefüllten Filterschalter: Sie laufen von
     einem dunkleren Ton zum Basiston, damit der hellste Punkt unter
     der weißen Schrift noch 4,5:1 Kontrast hält. Die Verläufe oben
     wären dafür am hellen Ende zu hell. */
  --grad-btn-beruflich: linear-gradient(135deg, #22303f 0%, #33465c 100%);
  --grad-btn-persoenlich: linear-gradient(135deg, #604735 0%, #85573a 100%);
  --grad-btn-ausbildung: linear-gradient(135deg, #4632c4 0%, #5b45e0 100%);
}

/* Warm-Theme: Für Einzelpersonen */
[data-theme='warm'] {
  --color-bg: #fbf3eb;
  --color-bg-alt: #f5e3d3;
  --color-accent: #85573a;
  --color-accent-soft: #f6e0d3;
  /* Dunkles Ende vertieft: Das CTA-Band laesst seinen Verlauf wandern,
     und die Bewegung wird erst durch einen groesseren Tonumfang
     sichtbar. Nach oben ist kein Platz — dort sitzt die Kontrast-
     grenze fuer den Absatz —, nach unten schon: 15 auf 21 Stufen. */
  --gradient-theme: linear-gradient(135deg, #543422 0%, #9a6b4c 100%);
  --gradient-theme-soft: linear-gradient(135deg, #e7a98c 0%, #f3c989 100%);

  /* Verlauf der Track-Karte auf der Startseite: läuft vom tiefen Akzent
     über den Theme-Verlauf bis in den weichen Ton, der auf der Zielseite
     den Hero prägt — dadurch der durchgehende rote Faden. */
  /* Farbtoene der Farbwolke (46°, 78°), auf Linienhelligkeit vertieft.
     Der weiche Verlauf selbst kaeme auf 1,8 bzw. 1,4:1 und waere auf
     einem 2px-Strich unsichtbar. */
  --gradient-linie: linear-gradient(135deg, #8f5032 0%, #966c1e 100%);

  --gradient-track: linear-gradient(
    28deg,
    #604735 0%,
    #8f6b51 34%,
    #c49173 70%,
    #e7a98c 100%
  );
  --track-glow: rgba(243, 201, 137, 0.6);
  /* Dieselbe Lichtquelle wie die Wegekarte, nun auch im CTA-Band. */
  --cta-glow: rgba(246, 214, 163, 0.82);
}

/* Cool-Theme: Für Unternehmen */
[data-theme='cool'] {
  --color-bg: #f2f4f5;
  --color-bg-alt: #e6eaed;
  --color-accent: #33465c;
  --color-accent-soft: #e2e7ec;
  --gradient-theme: linear-gradient(135deg, #202834 0%, #3e5a76 100%);
  --gradient-theme-soft: linear-gradient(135deg, #55708a 0%, #a9b8c6 100%);

  /* Farbtoene der Farbwolke (248°, 246°), auf Linienhelligkeit vertieft. */
  --gradient-linie: linear-gradient(135deg, #3f5b76 0%, #5c7890 100%);

  --gradient-track: linear-gradient(
    28deg,
    #171c22 0%,
    #33465c 36%,
    #55708a 72%,
    #93a8bb 100%
  );
  --track-glow: rgba(169, 184, 198, 0.5);
}

/* Vierte Wolkenfarbe: Salbei, nur auf "Über mich".
   Bewusst ein eigenes Attribut statt eines vierten data-theme — ein
   volles Theme würde auch Akzent, Buttons und die Zeitleistenlinie
   einfärben, und die gehört den drei Kategoriefarben. Hier wird
   ausschließlich der weiche Verlauf überschrieben. */
[data-wolke='natur'] {
  --gradient-theme-soft: linear-gradient(135deg, #95cfb4 0%, #c3dda5 52%, #f7db98 100%);

  /* Dieselben Farbtoene wie die Wolke (164°, 128°, 88°), nur deutlich
     dunkler: Der weiche Verlauf ist fuer eine grossflaechige, stark
     weichgezeichnete Wolke bei 52 % Deckkraft gemacht. Auf einer 2px
     hohen Linie kaeme er auf 1,3 bis 1,7:1 und waere unsichtbar.
     So bleibt der Charakter erhalten und der Strich wird gesehen. */
  --gradient-linie: linear-gradient(135deg, #2b7256 0%, #5e793a 52%, #947623 100%);
  --color-eyebrow: #256d4c;

  /* Dieselben Farbtoene wie die Wolke, auf Bandhelligkeit vertieft.
     Akzent und Themenverlauf bleiben bewusst unangetastet — beide
     speisen die Zeitleiste, die ihr Violett behalten soll. */
  --gradient-cta: linear-gradient(135deg, #024f37 0%, #496126 52%, #83681f 100%);
}

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

* {
  margin: 0;
}

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

body {
  min-height: 100svh;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  font-family: var(--font-body);
  background: var(--color-bg);
  color: var(--color-ink);
  transition: background 0.4s var(--ease);
}

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

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

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  list-style: none;
  padding: 0;
}

button {
  background: none;
  border: none;
  cursor: pointer;
}

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

/* ============================================================
   Typografie
   ============================================================ */
h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 560;
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: var(--color-ink);
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.6rem, 2rem + 3vw, 4.75rem);
  font-weight: 480;
}

h2 {
  font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.85rem);
}

h3 {
  font-size: clamp(1.2rem, 1.05rem + 0.5vw, 1.45rem);
  font-weight: 600;
}

p {
  color: var(--color-ink-soft);
  max-width: 60ch;
}

p.lead {
  font-size: clamp(1.05rem, 1rem + 0.4vw, 1.25rem);
  color: var(--color-ink-soft);
}

/* Silbentrennung: verhindert Löcher im Blocksatz und einen zerfransten
   Flattersatz-Rand. Die Limits vermeiden hässliche Kurz-Fragmente
   (Wort min. 7 Zeichen, min. 4 davor, min. 3 danach). */
p,
li {
  hyphens: auto;
  -webkit-hyphens: auto;
  hyphenate-limit-chars: 7 4 3;
}

/* Blocksatz nur bei ausreichender Zeilenlänge. In schmalen Spalten
   (Karten, Mobil) erzwingt Blocksatz sonst große Wortabstände. */
@media (min-width: 56rem) {
  .justify-text,
  .lead,
  .timeline-text,
  .legal p,
  .legal li,
  .legal-warning {
    text-align: justify;
    text-align-last: left;
  }
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-eyebrow, var(--color-accent));
}

.claim {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  color: var(--color-ink-soft);
  letter-spacing: 0.01em;
}

.text-center {
  text-align: center;
}

/* Für Textblöcke mit gesetzten Zeilenumbrüchen: kein Blocksatz und keine
   Silbentrennung. Blocksatz würde die Zeilen vor einem <br> auf volle
   Breite spreizen und die beabsichtigte Gliederung zerstören. */
p.text-lines {
  text-align: left;
  text-wrap: pretty;
  hyphens: none;
  -webkit-hyphens: none;
}

.measure {
  max-width: var(--container-narrow);
}

.measure-center {
  max-width: var(--container-narrow);
  margin-inline: auto;
}

/* ============================================================
   Layout-Hilfen
   ============================================================ */
.container {
  width: min(100% - 3rem, var(--container));
  margin-inline: auto;
}

.section {
  padding-block: var(--space-xl);
  position: relative;
}

.section-head {
  margin-bottom: var(--space-lg);
}

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

.hairline {
  border: none;
  border-top: 1px solid var(--color-line);
}

.divider {
  border: none;
  border-top: 1px solid var(--color-line);
  margin-block: var(--space-lg);
}

/* Weiche, verlaufende Gradient-Szene im Hintergrund */
/* Zwei weiche Farbwolken driften auf unterschiedlichen Bahnen umeinander.
   Start- und Endkeyframe sind identisch, dadurch läuft die Schleife
   endlos ohne sichtbaren Schnitt. Die Wege sind bewusst groß gewählt:
   bei 90px Weichzeichnung schluckt der Blur kleinere Bewegungen. */
@keyframes blob-drift-a {
  0% {
    transform: translate3d(0, 0, 0) scale(1);
    opacity: 0.52;
  }
  25% {
    transform: translate3d(18%, 10%, 0) scale(1.22);
    opacity: 0.70;
  }
  50% {
    transform: translate3d(8%, 26%, 0) scale(0.92);
    opacity: 0.56;
  }
  75% {
    transform: translate3d(-14%, 12%, 0) scale(1.14);
    opacity: 0.68;
  }
  100% {
    transform: translate3d(0, 0, 0) scale(1);
    opacity: 0.52;
  }
}

@keyframes blob-drift-b {
  0% {
    transform: translate3d(0, 0, 0) scale(1.06);
    opacity: 0.44;
  }
  30% {
    transform: translate3d(-20%, -14%, 0) scale(0.9);
    opacity: 0.62;
  }
  55% {
    transform: translate3d(-6%, -28%, 0) scale(1.24);
    opacity: 0.49;
  }
  80% {
    transform: translate3d(12%, -10%, 0) scale(1);
    opacity: 0.59;
  }
  100% {
    transform: translate3d(0, 0, 0) scale(1.06);
    opacity: 0.44;
  }
}

/* Verschiebt den Farbverlauf in sich, sodass die Farben ineinanderfließen */
@keyframes gradient-flow {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

.gradient-scene {
  position: relative;
  overflow: hidden;
}

.gradient-scene::before,
.gradient-scene::after {
  content: '';
  position: absolute;
  width: min(65vw, 680px);
  height: min(65vw, 680px);
  border-radius: 50%;
  filter: blur(90px);
  z-index: 0;
  pointer-events: none;
  background-size: 220% 220%;
}

.gradient-scene::before {
  background-image: var(--gradient-theme-soft);
  top: -18%;
  left: -12%;
  opacity: 0.52;
  animation: blob-drift-a 30s ease-in-out infinite,
    gradient-flow 24s ease-in-out infinite;
}

.gradient-scene::after {
  background-image: var(--gradient-brand-soft);
  bottom: -22%;
  right: -14%;
  opacity: 0.36;
  animation: blob-drift-b 38s ease-in-out infinite,
    gradient-flow 28s ease-in-out infinite;
  animation-delay: -9s, -5s;
}

.gradient-scene > * {
  position: relative;
  z-index: 1;
}

/* Zwei Geschwister, nicht Kind-Ebenen: mix-blend-mode braucht einen
   Hintergrund, gegen den es sich verrechnet. Steckt die blendende Ebene
   in einem Stapelkontext, ist dort nichts mehr — gemessen fiel das Korn
   damit auf den Wert ohne Korn zurueck. */
.koernung {
  position: absolute;
  inset: -300px;
  pointer-events: none;
}

/* Lichtpartikel: Die Turbulenz faerbt nicht, sie steuert nur die
   Deckkraft weisser Punkte (feColorMatrix setzt RGB auf Weiss und
   nimmt Alpha aus dem Rauschen). Der steile Alphaverlauf laesst nur
   die obere Haelfte der Verteilung durch — dadurch vereinzelte helle
   Punkte statt einer flaechigen Toenung. screen legt sie als Licht
   auf, ohne die Farben darunter zu truebn. */
.koernung--fein {
  mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='2.4' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='2.6' intercept='-1.05'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23p)'/%3E%3C/svg%3E");
  background-size: 120px 120px;
  animation: korn-fein 34s linear infinite,
    korn-atmen-hell 9s ease-in-out infinite;
}

/* Zweite Ebene, gegenlaeufig: gibt der Flaeche Struktur, damit die
   Partikel nicht im Leeren schweben. overlay statt screen, damit sie
   auch abdunkelt und Tiefe entsteht. */
.koernung--grob {
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='k'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.6' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='4.2' intercept='-1.45'/%3E%3CfeFuncG type='linear' slope='4.2' intercept='-1.45'/%3E%3CfeFuncB type='linear' slope='4.2' intercept='-1.45'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23k)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
  animation: korn-grob 63s linear infinite,
    korn-atmen-struktur 15s ease-in-out infinite;
  animation-delay: 0s, -5s;
}

/* Je genau eine Kachel — dadurch ist der Ruecksprung nahtlos. */
@keyframes korn-fein {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(120px, 120px, 0);
  }
}

@keyframes korn-grob {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-200px, 200px, 0);
  }
}

/* Das Atmen: die Dichte schwillt an und ab, in zwei verschiedenen
   Takten, damit kein gemeinsamer Puls entsteht. */
@keyframes korn-atmen-hell {
  0%,
  100% {
    opacity: 0.18;
  }
  50% {
    opacity: 0.37;
  }
}

@keyframes korn-atmen-struktur {
  0%,
  100% {
    opacity: 0.07;
  }
  50% {
    opacity: 0.15;
  }
}


/* ============================================================
   Glass / Liquid-Glass Oberflächen
   ============================================================ */
.glass-card {
  background: var(--color-surface);
  backdrop-filter: blur(var(--blur-glass)) saturate(160%);
  -webkit-backdrop-filter: blur(var(--blur-glass)) saturate(160%);
  border: 1px solid var(--color-surface-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-lg);
}

@supports not (backdrop-filter: blur(1px)) {
  .glass-card {
    background: rgba(255, 255, 255, 0.92);
  }
}


.card {
  background: var(--color-bg);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease), border-color 0.35s var(--ease);
}

.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-soft);
  border-color: transparent;
}

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.9rem 1.85rem;
  border-radius: var(--radius-pill);
  font-weight: 600;
  font-size: 0.98rem;
  white-space: nowrap;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease), background 0.35s var(--ease);
}

.btn-primary {
  background: var(--gradient-theme);
  color: #fff;
  box-shadow: var(--shadow-soft);
}

.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.btn-ghost {
  border: 1px solid var(--color-line);
  background: transparent;
  color: var(--color-ink);
}

.btn-ghost:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: center;
}

/* ============================================================
   Header / Navigation
   ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  padding-block: 1.1rem;
  background: rgba(250, 248, 245, 0.7);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.4s var(--ease), background 0.4s var(--ease);
}

[data-theme='warm'] .site-header {
  background: rgba(251, 243, 235, 0.7);
}

[data-theme='cool'] .site-header {
  background: rgba(242, 244, 245, 0.7);
}

.site-header.is-scrolled {
  border-bottom-color: var(--color-line);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
}

.wordmark {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* Optische Zentrierung der Kopfzeile.
   Die Flexbox zentriert die Zeilenboxen, nicht das sichtbare Schriftbild.
   Fraunces und Inter haben unterschiedliche Verhältnisse von Versal- zu
   x-Höhe (Fraunces x-Höhe 0,47em, Inter 0,55em), dadurch liegen die
   Mittellinien der beiden Schriften nicht automatisch auf einer Achse.
   Die Korrekturen legen die Mittellinien (x-Höhen-Achsen) exakt
   übereinander und halten das Schriftpaar zugleich mittig in der Leiste. */
.site-header .wordmark {
  transform: translateY(0.31px);
}

.site-nav ul {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  transform: translateY(0.68px);
}

.site-nav a {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--color-ink-soft);
  position: relative;
  padding-block: 0.25rem;
  transition: color 0.3s var(--ease);
}

.site-nav a:hover,
.site-nav a.is-active {
  color: var(--color-ink);
}

.site-nav a.is-active::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.15rem;
  height: 2px;
  background: var(--gradient-linie, var(--gradient-theme));
  border-radius: var(--radius-pill);
}

.site-nav a.nav-cta {
  padding: 0.55rem 1.25rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-line);
  color: var(--color-ink);
}

.site-nav a.nav-cta:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: var(--radius-sm);
}

.nav-toggle span,
.nav-toggle::before,
.nav-toggle::after {
  content: '';
  display: block;
  height: 2px;
  width: 1.4rem;
  margin-inline: auto;
  background: var(--color-ink);
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}

.nav-toggle[aria-expanded='true']::before {
  transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded='true'] span {
  opacity: 0;
}

.nav-toggle[aria-expanded='true']::after {
  transform: translateY(-7px) rotate(-45deg);
}

@media (max-width: 860px) {
  .nav-toggle {
    display: flex;
  }

  .site-nav {
    position: fixed;
    inset: 4.4rem 1rem auto 1rem;
    background: var(--color-bg);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    padding: var(--space-md);
    transform: translateY(-12px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), visibility 0.3s;
  }

  .site-nav.is-open {
    opacity: 1;
    transform: translateY(0);
    visibility: visible;
  }

  .site-nav ul {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-sm);
  }
}

/* ============================================================
   Hero
   ============================================================ */
/* Gemeinsame Mindesthöhe für alle Hero-Flächen: Die Größe der farbigen
   Fläche hängt sonst davon ab, ob die Überschrift ein- oder zweizeilig
   umbricht und ob ein Button im Hero steht. Der Inhalt wird vertikal
   zentriert, damit der zusätzliche Raum gleichmäßig verteilt wird.
   Auf der Startseite und im Mobilformat ist der Inhalt höher — dort
   greift die Mindesthöhe nicht und ändert nichts. */
/* Oben ausgerichtet, nicht zentriert: Bei zentriertem Inhalt haengt die
   Hoehe der Ueberschrift daran, wie viel darunter steht. "Ueber mich" hat
   keine Button-Zeile und rutschte dadurch 66px tiefer als die uebrigen
   Seiten. Von oben verankert stehen alle Ueberschriften auf einer Linie. */
.hero {
  padding-block: var(--space-xl) var(--space-lg);
  min-height: 33rem;
  display: grid;
  align-content: start;
}

/* Textspalte etwas breiter und der Abstand knapper als zuvor, damit die
   Brückenzeile im Hero auf breiten Schirmen in eine Zeile passt. */
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  gap: var(--space-md);
  align-items: center;
}

.hero__signature {
  margin-top: var(--space-2xs);
  font-size: clamp(1.05rem, 1rem + 0.5vw, 1.35rem);
}

/* Einstiegsaussage: zwei parallel gebaute Sätze.
   Bewusst kein Blocksatz und keine Silbentrennung — die Zeilenumbrüche
   sind gesetzt und tragen die Wirkung des Gegensatzpaares. */
.hero__statement {
  margin-top: var(--space-md);
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.4rem);
  font-weight: 500;
  line-height: 1.4;
  color: var(--color-ink);
  max-width: 42ch;
  text-align: left;
  hyphens: none;
  -webkit-hyphens: none;
}

.hero__lead {
  margin-top: var(--space-sm);
  /* Verhindert, dass das letzte Wort allein auf einer Zeile landet —
     auf schmalen Schirmen sonst der Fall. */
  text-wrap: pretty;
}

/* Folgt ein zweiter Absatz direkt auf den ersten, reicht ein
   kleinerer Abstand — sonst zerfällt der Fließtext optisch. */
.hero__lead + .hero__lead {
  margin-top: var(--space-xs);
}

/* Die Brückenzeile ist auf eine Zeile angelegt. Kein Blocksatz:
   Sollte sie auf schmaleren Schirmen doch umbrechen, würde Blocksatz
   die erste Zeile auf volle Breite spreizen und ein einzelnes Wort
   auf der zweiten Zeile zurücklassen. Flattersatz bricht dort ruhiger. */
.hero__lead.hero__bridge {
  text-align: left;
  text-wrap: pretty;
}

.hero__actions {
  margin-top: var(--space-md);
}

/* Porträt im Glasrahmen: die schmale Passepartout-Kante greift die
   Glasflächen der Seite auf und vermittelt zwischen Foto und Verlauf. */
.hero__portrait {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-lg);
  padding: var(--space-sm);
  margin: 0;
}

.hero__portrait-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* etwas oberhalb der Mitte, damit das Gesicht im Anschnitt sitzt */
  object-position: center 42%;
  border-radius: var(--radius-md);
  /* Leicht zurückgenommene Sättigung — das Foto ist von Himmel und
     Wasser her sehr kühl und würde sonst gegen die warme Hero-Fläche
     anspringen. */
  filter: saturate(0.92);
}

/* Farbliche Einbindung: ein Hauch der Markenfarben legt sich über das
   Foto. soft-light verschiebt nur die Lichtstimmung, die Zeichnung des
   Bildes bleibt erhalten. */
.hero__portrait::after {
  content: '';
  position: absolute;
  inset: var(--space-sm);
  border-radius: var(--radius-md);
  background-image: var(--gradient-brand-soft);
  mix-blend-mode: soft-light;
  opacity: 0.4;
  pointer-events: none;
}

@media (max-width: 900px) {
  .hero__grid {
    grid-template-columns: 1fr;
  }

  /* Quadratisch statt breit: ein Querformat würde aus dem Hochformat
     nur einen schmalen Streifen um das Gesicht übrig lassen. */
  .hero__portrait {
    order: -1;
    aspect-ratio: 1 / 1;
    max-width: 26rem;
    margin-inline: auto;
  }
}

/* ============================================================
   Grids / Themen
   ============================================================ */
.grid {
  display: grid;
  gap: var(--space-md);
}

/* minmax(0, 1fr) statt 1fr: ein blankes 1fr lässt Spalten wachsen, wenn
   der Inhalt (lange deutsche Komposita) breiter ist — dann werden die
   Spalten unterschiedlich breit. minmax(0, …) erzwingt exakt gleiche
   Breiten. grid-auto-rows: 1fr gibt allen Zeilen dieselbe Höhe, sonst
   richtet sich jede Zeile nur nach ihrer eigenen längsten Karte. */
.grid-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: 1fr;
}

.grid-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: 1fr;
}

/* Spaltenzahl so gestaffelt, dass die Karten nie zu schmal werden —
   zu schmale Karten sind der Grund, warum Textboxen unterschiedlich
   hoch werden. */
@media (max-width: 1200px) {
  .grid-4 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 900px) {
  .grid-3,
  .grid-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 600px) {
  .grid-2,
  .grid-3,
  .grid-4 {
    grid-template-columns: 1fr;
  }
}

/* Einheitliche Mindesthöhe, damit die Boxen auch seitenübergreifend
   (Start / Einzelpersonen / Unternehmen) gleich groß sind. */
.topic-card {
  min-height: var(--topic-card-min);
}

/* Drei Karten in der Höhe zweier gestapelter: zweimal die Mindesthöhe
   plus die Lücke, die sonst zwischen den beiden Reihen läge. */
.grid-doppelt .topic-card {
  min-height: calc(var(--topic-card-min) * 2 + var(--space-md));
}

/* Bei den kurzen Texten der Standardkarten sitzt die Überschrift direkt
   über dem Absatz. Hier folgen mehrere Sätze, da braucht sie Abstand. */
.grid-doppelt .topic-card h3 {
  margin-bottom: var(--space-xs);
}

/* Nebeneinander stehende Karten: Zwei Überschriften laufen über zwei
   Zeilen, eine über eine. Ohne reservierte Höhe startet der Text der
   einzeiligen Karte weiter oben und die Reihe wirkt schief. Zwei Zeilen
   sind eine Untergrenze — längere Überschriften wachsen weiterhin. */
@media (min-width: 901px) {
  .grid-doppelt .topic-card h3 {
    min-height: 2.24em; /* 2 Zeilen × line-height 1.12 */
  }
}

/* Stichpunkte innerhalb der großen Karten */
.topic-card__punkte {
  margin-top: var(--space-sm);
  display: grid;
  gap: var(--space-xs);
}

.topic-card__punkte li {
  position: relative;
  padding-left: 1.15rem;
  color: var(--color-ink-soft);
  font-size: 0.95rem;
  line-height: 1.45;
}

.topic-card__punkte li::before {
  content: '—';
  position: absolute;
  left: 0;
  color: var(--color-accent);
}

/* Drei hohe Karten in zwei Spalten ergäben ein Waisenkind in der
   zweiten Reihe. Einspaltig und auf Inhaltshöhe ist ruhiger. */
@media (max-width: 900px) {
  .grid-doppelt {
    grid-template-columns: 1fr;
  }

  .grid-doppelt .topic-card {
    min-height: 0;
  }
}

/* Lange deutsche Komposita wie "Veränderungsprozesse" sind breiter als
   eine schmale Karte. Überschriften erben die globale Silbentrennung
   nicht (die gilt nur für p und li) und ragten deshalb aus der Box.
   hyphens trennt sauber mit Trennstrich; break-word greift zusätzlich,
   falls für ein Wort kein Trennmuster gefunden wird. */
.topic-card h3 {
  hyphens: auto;
  -webkit-hyphens: auto;
  overflow-wrap: break-word;
}

/* Einspaltig (Mobil) hugged die Karte ihren Inhalt — sonst entstünden
   dort große leere Flächen. */
@media (max-width: 600px) {
  .topic-card {
    min-height: 0;
  }
}

.topic-card .eyebrow {
  margin-bottom: var(--space-xs);
}


/* ============================================================
   Prozess-Schritte
   ============================================================ */
.process {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-md);
  counter-reset: step;
}

.process-step {
  position: relative;
  padding-top: var(--space-md);
}

/* In den schmalen Spalten der Ablaufschritte landet sonst leicht ein
   einzelnes Wort auf der letzten Zeile. */
.process-step p {
  text-wrap: pretty;
}


.process-step::before {
  counter-increment: step;
  content: counter(step);
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--gradient-theme);
  color: #fff;
  margin-bottom: var(--space-sm);
}

@media (max-width: 780px) {
  .process {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   Zwei-Wege / Track-Karten (Startseite)
   ============================================================ */
.tracks {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: var(--space-md);
}

.track-card {
  padding: var(--space-lg);
  border-radius: var(--radius-lg);
  color: #fff;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  min-height: 20rem;
  justify-content: flex-end;
  position: relative;
  overflow: hidden;
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}

/* Beide Karten teilen sich über subgrid dieselben Zeilenhöhen. Dadurch
   liegen Überschrift, Text und Button auf einer Linie, auch wenn ein
   Text einzeilig und der andere zweizeilig umbricht. Zeile 1 ist ein
   Platzhalter, der den Inhalt wie bisher nach unten drückt.
   Unter 781px stehen die Karten untereinander — dort ist eine
   Ausrichtung zueinander gegenstandslos. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 781px) {
    .tracks {
      grid-template-rows: 1fr auto auto auto;
    }

    .track-card {
      display: grid;
      grid-row: span 4;
      grid-template-rows: subgrid;
      row-gap: var(--space-sm);
    }

    .track-card h3 {
      grid-row: 2;
    }

    .track-card p {
      grid-row: 3;
    }

    .track-card .btn {
      grid-row: 4;
      justify-self: start;
    }
  }
}

.track-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
}

.track-card--warm,
.track-card--cool {
  background-image: var(--gradient-track);
  /* 160% statt 200%: der Verlauf wandert sanfter, dadurch bleiben die
     Farben hinter dem Text über den ganzen Zyklus gleichmäßiger. */
  background-size: 160% 160%;
  animation: gradient-flow 18s ease-in-out infinite;
}

.track-card--cool {
  animation-duration: 22s;
}

/* Statische Ebene über dem animierten Verlauf:
   oben rechts ein Lichtschein im weichen Farbton der Zielseite,
   unten ein zarter Schleier, damit der weiße Text auf den helleren
   Verlaufstönen jederzeit lesbar bleibt. */
.track-card::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(
      120% 95% at 88% 4%,
      var(--track-glow) 0%,
      rgba(255, 255, 255, 0) 58%
    ),
    linear-gradient(
      to top,
      rgba(12, 10, 9, 0.46) 0%,
      rgba(12, 10, 9, 0.28) 42%,
      rgba(12, 10, 9, 0.1) 62%,
      rgba(12, 10, 9, 0) 80%
    );
}

.track-card > * {
  position: relative;
  z-index: 1;
}

.track-card h3 {
  color: #fff;
  font-size: clamp(1.5rem, 1.3rem + 1vw, 2rem);
}

.track-card p {
  color: rgba(255, 255, 255, 0.82);
}

.track-card .btn-ghost {
  align-self: flex-start;
  border-color: rgba(255, 255, 255, 0.4);
  color: #fff;
}

.track-card .btn-ghost:hover {
  border-color: #fff;
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
}

/* Gestapelt greift subgrid nicht mehr (die Karten liegen in getrennten
   Rasterzeilen). Bei gleicher Kartenhöhe und unten verankertem Inhalt
   schiebt der kürzere Text seine Überschrift nach unten — die zweite
   Überschrift säße dann tiefer als die erste. Deshalb folgen die Karten
   hier ihrer Inhaltshöhe: Beide Überschriften sitzen im selben Abstand
   zur Kartenoberkante, und der tote Raum darüber entfällt. */
@media (max-width: 780px) {
  .tracks {
    grid-template-columns: 1fr;
    grid-auto-rows: auto;
  }

  .track-card {
    min-height: 0;
  }
}

/* ============================================================
   Timeline (Über mich)
   ============================================================ */
.timeline {
  position: relative;
  padding-left: 2.25rem;
  max-width: 58rem;
}

/* Ruhende Linie */
.timeline::before {
  content: '';
  position: absolute;
  left: 0.34rem;
  top: 0.4rem;
  bottom: 0.4rem;
  width: 1px;
  background: var(--color-line);
}

/* Farbige Linie darüber. Grundzustand ist die volle Linie — so bleibt
   der Verlauf auch dort sichtbar, wo Scroll-Animationen nicht laufen
   (ältere Browser, reduzierte Bewegung). Nur wo beides gegeben ist,
   füllt sie sich beim Scrollen von oben nach unten. */
.timeline::after {
  content: '';
  position: absolute;
  left: 0.34rem;
  top: 0.4rem;
  bottom: 0.4rem;
  width: 1px;
  background-image: var(--gradient-theme);
  transform: scaleY(1);
  transform-origin: top;
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .timeline::after {
      animation: timeline-fill linear both;
      animation-timeline: view();
      animation-range: cover 12% cover 78%;
    }
  }
}

@keyframes timeline-fill {
  from {
    transform: scaleY(0);
  }
  to {
    transform: scaleY(1);
  }
}

/* Ist ein Filter gesetzt, nehmen Linie und Punkte die Farbe der
   Kategorie an. js/main.js setzt dafür data-aktiv auf die Liste.
   Ohne Filter bleibt alles im Markenverlauf. */
.timeline[data-aktiv='beruflich']::after,
.timeline[data-aktiv='beruflich'] .timeline-item::before {
  background-image: var(--grad-beruflich);
}

.timeline[data-aktiv='persoenlich']::after,
.timeline[data-aktiv='persoenlich'] .timeline-item::before {
  background-image: var(--grad-persoenlich);
}

.timeline[data-aktiv='ausbildung']::after,
.timeline[data-aktiv='ausbildung'] .timeline-item::before {
  background-image: var(--grad-ausbildung);
}

/* Zweispaltig: links Jahr und Kategorie, rechts der Inhalt.
   Unter 900px stapeln sich beide Spalten. */
.timeline-item {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr);
  gap: var(--space-md);
  padding-bottom: var(--space-lg);
  border-top: 1px solid var(--color-line);
  padding-top: var(--space-md);
}

/* Die oberste Station bekommt keine Trennlinie. Beim Filtern ist das
   erste sichtbare Element aber nicht mehr das erste im Dokument —
   ausgeblendete Geschwister zählen für :first-child weiterhin mit.
   js/main.js markiert deshalb das jeweils erste sichtbare Element.
   :first-child bleibt für den Fall ohne JavaScript bestehen. */
.timeline-item:first-child,
.timeline-item--erste {
  border-top: none;
  padding-top: 0;
}

.timeline-item:last-child {
  padding-bottom: 0;
}

/* Punkt auf der Linie */
.timeline-item::before {
  content: '';
  position: absolute;
  left: -2.25rem;
  top: var(--space-md);
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: var(--gradient-theme);
  box-shadow: 0 0 0 5px var(--color-bg);
}

.timeline-item:first-child::before,
.timeline-item--erste::before {
  top: 0.3rem;
}

.timeline-item--current::before {
  width: 0.9rem;
  height: 0.9rem;
  left: -2.35rem;
}

.timeline-meta {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  align-items: flex-start;
}

.timeline-year {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--color-ink);
  font-size: 1.05rem;
  letter-spacing: 0.02em;
}

/* Kategorie in der vorhandenen Eyebrow-Typografie, Farbe je Kategorie */
.timeline-tag {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--kat-farbe, var(--color-ink-faint));
  border: 1px solid currentColor;
  border-radius: var(--radius-pill);
  padding: 0.15rem 0.6rem;
  white-space: nowrap;
}

.timeline-tag[data-tag='beruflich'] {
  --kat-farbe: var(--kat-beruflich);
}

.timeline-tag[data-tag='persoenlich'] {
  --kat-farbe: var(--kat-persoenlich);
}

.timeline-tag[data-tag='ausbildung'] {
  --kat-farbe: var(--kat-ausbildung);
}

.timeline-title {
  margin-top: 0;
}

.timeline-text {
  margin-top: 0.5rem;
}

/* Reflexionszeile: kursive Fraunces wie die Claim-Zeile, mit farbigem
   Balken. Hebt sich damit sichtbar vom beschreibenden Text ab. */
.timeline-takeaway {
  margin-top: var(--space-sm);
  padding-left: var(--space-sm);
  border-left: 2px solid var(--color-line);
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1rem;
  line-height: 1.55;
  color: var(--color-ink-soft);
  hyphens: none;
  -webkit-hyphens: none;
}

.timeline-item[data-kategorie='beruflich'] .timeline-takeaway {
  border-left-color: var(--kat-beruflich);
}

.timeline-item[data-kategorie='persoenlich'] .timeline-takeaway {
  border-left-color: var(--kat-persoenlich);
}

.timeline-item[data-kategorie='ausbildung'] .timeline-takeaway {
  border-left-color: var(--kat-ausbildung);
}

/* Die aktuelle Station als einzige auf einer Glasfläche */
.timeline-item--current .timeline-body {
  padding: var(--space-md);
  border-radius: var(--radius-md);
}

@media (max-width: 900px) {
  .timeline-item {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2xs);
  }

  .timeline-meta {
    flex-direction: row;
    align-items: center;
    gap: var(--space-2xs);
    flex-wrap: wrap;
  }
}

/* ============================================================
   Filter der Zeitleiste
   ============================================================ */
.timeline-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
  margin-bottom: var(--space-lg);
}

.timeline-filter:empty {
  display: none;
}

.timeline-filter__btn {
  padding: 0.45rem 1.1rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-line);
  background: transparent;
  color: var(--color-ink-soft);
  font-size: 0.88rem;
  font-weight: 500;
  cursor: pointer;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease),
    background 0.25s var(--ease);
}

/* Jeder Schalter trägt die Farbe seiner Kategorie — inaktiv als Rand
   und Schrift wie die Kennzeichnungen neben den Jahreszahlen, aktiv
   als gefüllte Fläche. „Alle" gehört zu keiner Kategorie und bleibt
   neutral bzw. nimmt aktiv den Markenverlauf. */
.timeline-filter__btn[data-wert='beruflich'] {
  --btn-farbe: var(--kat-beruflich);
  --btn-verlauf: var(--grad-btn-beruflich);
}

.timeline-filter__btn[data-wert='persoenlich'] {
  --btn-farbe: var(--kat-persoenlich);
  --btn-verlauf: var(--grad-btn-persoenlich);
}

.timeline-filter__btn[data-wert='ausbildung'] {
  --btn-farbe: var(--kat-ausbildung);
  --btn-verlauf: var(--grad-btn-ausbildung);
}

/* Der ausgeschlossene Zustand ist hier ausdrücklich mitgeschrieben:
   ohne :not([aria-pressed='true']) hätte diese Regel wegen höherer
   Spezifität die weiße Schrift des aktiven Schalters überschrieben. */
.timeline-filter__btn[data-wert]:not([data-wert='alle']):not([aria-pressed='true']) {
  color: var(--btn-farbe);
  border-color: var(--btn-farbe);
}

.timeline-filter__btn:not([aria-pressed='true']):hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.timeline-filter__btn[data-wert]:not([data-wert='alle']):not([aria-pressed='true']):hover {
  border-color: var(--btn-farbe);
  color: var(--btn-farbe);
  background-color: color-mix(in srgb, var(--btn-farbe) 10%, transparent);
}

.timeline-filter__btn[aria-pressed='true'] {
  background-image: var(--btn-verlauf, var(--gradient-theme));
  background-color: transparent;
  border-color: transparent;
  color: #fff;
}

.timeline-filter__btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Die Stationszahl wird nicht mehr angezeigt. Sie bleibt aber im
   Dokument und als Live-Region bestehen, damit Screenreader nach dem
   Filtern weiterhin melden, wie viele Stationen übrig sind — sonst
   wäre der Filtervorgang für sie ohne jede Rückmeldung.
   display:none würde die Ansage unterdrücken, deshalb nur optisch
   ausgeblendet. */
.timeline-count {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Ausgefilterte Stationen */
.timeline-item[hidden] {
  display: none;
}

/* ============================================================
   Platzhalter-Hinweise
   ============================================================ */
.placeholder-note {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: #a15b1f;
  background: #fdf1e2;
  border: 1px solid #f0d9b5;
  border-radius: var(--radius-sm);
  padding: 0.3rem 0.7rem;
  margin-bottom: var(--space-sm);
}

.legal-warning {
  background: #fdf1e2;
  border: 1px solid #f0d9b5;
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-lg);
}

.legal-warning strong {
  color: #a15b1f;
}


/* ============================================================
   Kontakt
   ============================================================ */
/* Kontaktseite: breites Formular links, Hinweisbox rechts.
   Die Überschrift läuft über beide Spalten. Dadurch beginnen
   Einleitungstext und Hinweisbox automatisch auf derselben
   Oberkante — ohne von der Höhe der Überschrift abzuhängen. */
.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  column-gap: var(--space-xl);
  row-gap: var(--space-md);
  align-items: start;
}

.contact-form__title {
  grid-column: 1 / -1;
}

.contact-form-wrap {
  grid-column: 1;
}

.contact-aside {
  grid-column: 2;
}

.contact-note {
  padding: var(--space-md);
}

.contact-note h3 {
  margin-top: var(--space-xs);
}

.contact-note p {
  margin-top: var(--space-xs);
  font-size: 0.95rem;
  /* Der schmale Kasten laesst sonst ein einzelnes Wort auf der
     letzten Zeile stehen. */
  text-wrap: pretty;
}

@media (max-width: 900px) {
  .contact-layout {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-lg);
  }

  .contact-form-wrap,
  .contact-aside {
    grid-column: 1;
  }
}

/* ============================================================
   Formular
   ============================================================ */
.contact-form__title {
  font-size: clamp(1.5rem, 1.3rem + 1vw, 2rem);
}

/* Kein margin-top: der Abstand zur Überschrift kommt aus dem row-gap
   des Grids, damit Einleitung und Hinweisbox exakt gleich hoch starten. */
.contact-form__intro {
  margin-top: 0;
  margin-bottom: var(--space-md);
}

.contact-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.form-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-sm);
}

@media (max-width: 600px) {
  .form-row {
    grid-template-columns: 1fr;
  }
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 0;
}

.form-field > label,
.form-fieldset legend {
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--color-ink);
}

/* E-Mail-Adressen nie mit Trennstrich umbrechen — der Bindestrich
   würde wie ein Teil der Adresse aussehen. */
a[href^='mailto:'] {
  hyphens: none;
  -webkit-hyphens: none;
  overflow-wrap: anywhere;
}

.form-optional {
  font-weight: 400;
  color: var(--color-ink-faint);
}

.req {
  color: var(--color-accent);
}

.form-field input[type='text'],
.form-field input[type='email'],
.form-field input[type='tel'],
.form-field select,
.form-field textarea {
  width: 100%;
  padding: 0.8rem 1rem;
  font-size: 1rem;
  color: var(--color-ink);
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease),
    background 0.25s var(--ease);
}

.form-field textarea {
  resize: vertical;
  min-height: 8rem;
  font-family: inherit;
  line-height: 1.6;
}

.form-field select {
  appearance: none;
  /* Pfeil als Inline-SVG, damit keine externe Datei nötig ist */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%235b564f' stroke-width='1.6' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.6rem;
  cursor: pointer;
}

.form-field input:focus-visible,
.form-field select:focus-visible,
.form-field textarea:focus-visible {
  outline: none;
  border-color: var(--color-accent);
  background: #fff;
  box-shadow: 0 0 0 3px var(--color-accent-soft);
}

.form-field input[aria-invalid='true'],
.form-field textarea[aria-invalid='true'] {
  border-color: #b3261e;
}

.form-error {
  font-size: 0.82rem;
  color: #b3261e;
  min-height: 0;
  margin: 0;
}

.form-error:empty {
  display: none;
}

/* Zeichenzaehler unter dem Nachrichtenfeld. Ohne JavaScript bleibt er leer
   und nimmt keinen Platz ein — begrenzt wird dann ueber maxlength und die
   Pruefung auf dem Server. Ziffern tabellarisch, damit die Zahl beim
   Tippen nicht springt. */
.form-zaehler {
  margin: var(--space-3xs) 0 0;
  font-size: 0.82rem;
  color: var(--color-ink-faint);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.form-zaehler:empty {
  display: none;
}

/* Dieselbe Farbe wie eine Fehlermeldung, sobald es eng wird */
.form-zaehler[data-knapp='true'] {
  color: #b3261e;
  font-weight: 600;
}

/* Fieldset optisch wie ein normales Feld */
.form-fieldset {
  border: none;
  padding: 0;
  margin: 0;
}

.form-fieldset legend {
  padding: 0;
  margin-bottom: 0.55rem;
}

.form-choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.form-field .form-choice,
.form-choice {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--color-ink-soft);
  cursor: pointer;
  line-height: 1.5;
}

.form-choice input {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.15rem;
  accent-color: var(--color-accent);
  cursor: pointer;
}

.form-choice input:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.form-consent {
  margin-top: var(--space-2xs);
}

.form-consent .form-choice span {
  max-width: 58ch;
}

.form-consent a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.form-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: var(--space-2xs);
}

.form-actions .btn[disabled] {
  opacity: 0.6;
  cursor: progress;
}

.form-status {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 500;
}

.form-status:empty {
  display: none;
}

.form-status[data-state='success'] {
  color: #1b6b3a;
}

.form-status[data-state='error'] {
  color: #b3261e;
}

.form-fallback {
  font-size: 0.88rem;
  color: var(--color-ink-faint);
  margin-top: var(--space-2xs);
}

.form-fallback a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Honeypot: für Menschen unsichtbar, für Bots ein Köder.
   Nicht display:none — das erkennen viele Bots. */
.form-honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Erfolgsmeldung, die das Formular ersetzt */
.form-success {
  padding: var(--space-md);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-line);
  background: rgba(255, 255, 255, 0.7);
}

.form-success h3 {
  margin-bottom: var(--space-xs);
}

.text-link {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.text-link:hover {
  text-decoration-thickness: 2px;
}

/* ============================================================
   Rechtstexte
   ============================================================ */
.legal h2 {
  margin-top: var(--space-lg);
  font-size: 1.35rem;
}

.legal p,
.legal li {
  max-width: none;
}

.legal ul {
  list-style: disc;
  padding-left: 1.4rem;
  margin-top: var(--space-2xs);
}

.legal li {
  margin-top: 0.3rem;
  color: var(--color-ink-soft);
}

/* ============================================================
   Footer
   ============================================================ */
.site-footer {
  padding-block: var(--space-lg);
  border-top: 1px solid var(--color-line);
}

.site-footer__inner {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: var(--space-md);
}

.site-footer__brand .wordmark {
  display: block;
}

.site-footer__brand .claim {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.95rem;
}

.site-footer__links {
  display: flex;
  gap: var(--space-md);
  flex-wrap: wrap;
}

.site-footer__links a {
  font-size: 0.9rem;
  color: var(--color-ink-soft);
}

.site-footer__links a:hover {
  color: var(--color-accent);
}

.site-footer__meta {
  margin-top: var(--space-md);
  font-size: 0.8rem;
  color: var(--color-ink-faint);
}

/* Nur für Vorlesehilfen: nimmt keinen Platz ein, bleibt aber im
   Zugänglichkeitsbaum. display:none wäre dort nicht mehr vorhanden. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   Scroll-Reveal
   ============================================================ */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* ============================================================
   Finale CTA-Bahn
   ============================================================ */
.cta-band {
  border-radius: var(--radius-lg);
  padding: var(--space-xl) var(--space-lg);
  text-align: center;
  color: #fff;
  background: var(--gradient-cta, var(--gradient-theme));
  background-size: 200% 200%;
  animation: gradient-flow 16s ease-in-out infinite;
  position: relative;
  overflow: hidden;
}

/* Lichtecke unten rechts. Bewusst unbewegt, waehrend der Verlauf
   darunter wandert: So kann die Ecke hell sein, ohne dass das Licht
   jemals unter den Text zieht. Der Mittelpunkt liegt unterhalb des
   Bandes, dadurch leuchtet nur die Ecke selbst. */
.cta-band::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Mittelpunkt ausserhalb des Bandes und bewusst knapper Radius: So
     bleibt das Licht unterhalb der Textzeilen. Gemessen reichte eine
     groessere Ellipse bis unter den Absatz und drueckte ihn auf 2,4:1.
     Der gestaffelte Abfall loest den Rand auf — ein einzelner Stopp
     auf transparent erzeugt eine sichtbare Kante, weil sRGB dabei
     durch Grau laeuft. */
  background-image: radial-gradient(
    65% 55% at 104% 118%,
    var(--cta-glow) 0%,
    color-mix(in srgb, var(--cta-glow) 45%, transparent) 34%,
    color-mix(in srgb, var(--cta-glow) 14%, transparent) 62%,
    transparent 86%
  );
}

.cta-band > * {
  position: relative;
  z-index: 1;
}

.cta-band h2 {
  color: #fff;
}

/* Keine Breitenbegrenzung: der Satz soll auf breiten Schirmen in eine
   Zeile passen. Zentriert bleibt er über text-align des Bandes, die
   Mittelachse ist damit dieselbe wie bei der Überschrift. Auf schmalen
   Schirmen bricht er weiterhin um — balance verteilt die Zeilen dann
   gleichmäßig, statt eine lange Zeile mit Rest zu erzeugen. */
/* Volles Weiss statt 85 %: Mit 85 % erreichte der Absatz am hellen
   Verlaufsende nur 3,8:1 — und weil der Verlauf wandert, zieht dieses
   Ende einmal je Zyklus unter ihm durch. Die Hierarchie zur Ueberschrift
   traegt ohnehin die Schriftgroesse. */
.cta-band p {
  color: #fff;
  margin-inline: auto;
  max-width: none;
  text-wrap: balance;
}

.cta-band .btn-row {
  justify-content: center;
  margin-top: var(--space-md);
}

.cta-band .btn-primary {
  background: #fff;
  color: var(--color-ink);
}

.cta-band .btn-ghost {
  border-color: rgba(255, 255, 255, 0.5);
  color: #fff;
}

.cta-band .btn-ghost:hover {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}
