/* ==========================================================================
   PERSPEKTIVBLICK – style.css · Design-System „Blick nach vorn“
   Mobile First · Hell/Dunkel-Modus · lokal gehostete Schriften
   --------------------------------------------------------------------------
   Farbwelt: Blau · Petrol · Türkis · warme Weißtöne
   Zielgruppen: Jugendliche = Himmelblau · Familien = Türkis · Fachkräfte = Petrol
   ========================================================================== */

/* 0. SCHRIFTEN ------------------------------------------------------------ */
@font-face {
  font-family: "Baloo 2";
  src: url("fonts/baloo2-latin.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Nunito";
  src: url("fonts/nunito-latin.woff2") format("woff2");
  font-weight: 200 1000;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Nunito";
  src: url("fonts/nunito-latin-italic.woff2") format("woff2");
  font-weight: 200 1000;
  font-style: italic;
  font-display: swap;
}

/* 1. DESIGN TOKENS -------------------------------------------------------- */
:root {
  /* Marke */
  --color-primary: #0A5578;
  --color-primary-dark: #063C56;
  --color-secondary: #2F89C4;
  /* Schriftfarbe fuer alles, was in Sekundaerblau geschrieben wird:
     Eyebrow, Kachel-Etikett, Funktionsbezeichnung, umrandete Knoepfe.
     Gleiche Begruendung wie bei --color-teal-ink: Der hellste Untergrund
     ist das Etikett auf color-mix(secondary 13%) ueber einer eingefaerbten
     Flaeche (~#D4E9EF). Frueher #1F6F9F -> nur 4,36:1. #1B6590 -> 5,04:1
     dort und 6,34:1 auf Weiss. */
  --color-secondary-dark: #1B6590;

  /* Unterstützung */
  --color-success: #2F9680;
  --color-success-dark: #247562;
  --color-teal: #42B7AD;
  /* Teal als SCHRIFTFARBE ("ink"). Eigener, dunklerer Wert, weil
     --color-teal auf hellem Grund zu wenig Kontrast fuer Text hat.
     WICHTIG (WCAG 1.4.3): Der Wert muss nicht nur auf Weiss reichen,
     sondern auch auf dem HELLSTEN Untergrund, auf dem er landet – das ist
     das Kachel-Etikett .tile-badge im ambulanten Bereich: dort liegt der
     Text auf color-mix(teal 13%) ueber --color-surface-teal, also auf
     etwa #D7EFEC. Der fruehere Wert #1F7B74 kam dort nur auf 4,21:1 und
     verfehlte die geforderten 4,5:1. #1B6E68 liefert 5,02:1 dort und
     6,04:1 auf Weiss. Im Dunkelmodus wird aufgehellt (Bloecke unten). */
  --color-teal-ink: #1B6E68;
  --color-highlight: #63B3ED;

  /* Flächen */
  --color-white: #FFFFFF;
  --color-bg: #FAFBFC;
  --color-surface: #FFFFFF;
  --color-surface-alt: #F3F7FA;
  --color-surface-warm: #F7F6F2;
  --color-surface-teal: #EDF7F5;
  --color-surface-muted: #EEF3F6;

  /* Text und Linien */
  --color-heading: #15344C;
  --color-text: #435261;
  /* --color-muted traegt einen GROSSEN Teil der Seite: .section-lead,
     Kacheltexte, FAQ-Antworten, Schrittbeschreibungen, Qualifikationen,
     Formularhinweise. Der fruehere Wert #697886 erreichte auf den hellen
     Flaechen nur 4,19–4,38:1 und verfehlte damit WCAG AA (4,5:1) auf
     nahezu jedem eingefaerbten Abschnitt. #5A6875 liefert 5,29:1 auf
     --color-surface-warm (schlechtester Fall) und 5,72:1 auf Weiss. */
  --color-muted: #5A6875;
  --color-link: #1B6590;
  --color-accent: #2F89C4;
  --color-border: #E4ECF2;
  --color-placeholder-bg: #EEF4F7;
  --color-placeholder-text: #5A6875;
  --color-on-dark-muted: #D8E8F0;
  /* Ueberschriften auf dunklem Grund (Fusszeile). --color-highlight
     (#63B3ED) kam auf --color-primary nur auf 3,56:1 – zu wenig fuer die
     0,85rem kleine Versalzeile. #A9D8F2 liefert 5,34:1. */
  --color-on-dark-heading: #A9D8F2;

  /* Zwei Radien, zwei Schatten */
  --radius-small: 12px;
  --radius-large: 22px;
  --shadow: 0 14px 40px rgba(10, 85, 120, 0.08);
  --shadow-hover: 0 20px 48px rgba(10, 85, 120, 0.15);

  /* Typografie und Layout */
  /* Die WOFF2-Dateien in fonts/ werden per @font-face oben geladen. Damit sie
     auch wirklich verwendet werden, zeigen die Variablen auf sie – Helvetica
     bleibt als Fallback, falls die Datei einmal fehlen sollte. */
  --font-display: "Baloo 2", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body: "Nunito", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --container: 1180px;
  --nav-height: 76px;
  --panel-gap: clamp(0.65rem, 1.8vw, 1.25rem);

  color-scheme: light;
}

:root[data-theme="dark"] {
  --color-bg: #0E1B24;
  --color-surface: #152732;
  --color-surface-alt: #19303D;
  --color-surface-warm: #202D33;
  --color-surface-teal: #183733;
  --color-surface-muted: #1B2F39;
  --color-heading: #F5FAFC;
  --color-text: #E2EDF2;
  --color-muted: #AFC0CA;
  --color-link: #8BC8E7;
  --color-teal-ink: #5FCBC1;
  /* Aufgehellt wie --color-link und --color-teal-ink: Das Marken-Blau
     #1F6F9F kommt auf dunklem Grund nur auf 2,8:1 – WCAG verlangt 4,5:1
     fuer Text. Betroffen waeren Eyebrows, Funktionsbezeichnungen,
     Kachel-Etiketten, umrandete Knoepfe und der aktive Menuepunkt.
     #8BC8E7 liefert 8,5:1. Im Hellmodus bleibt #1F6F9F unveraendert. */
  --color-secondary-dark: #8BC8E7;
  --color-accent: #63B3ED;
  --color-border: #2B4350;
  --color-placeholder-bg: #203540;
  --color-placeholder-text: #AFC0CA;
  --color-on-dark-muted: #D8E8F0;
  --shadow: 0 14px 40px rgba(0, 0, 0, 0.28);
  --shadow-hover: 0 20px 48px rgba(0, 0, 0, 0.42);
  color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg: #0E1B24;
    --color-surface: #152732;
    --color-surface-alt: #19303D;
    --color-surface-warm: #202D33;
    --color-surface-teal: #183733;
    --color-surface-muted: #1B2F39;
    --color-heading: #F5FAFC;
    --color-text: #E2EDF2;
    --color-muted: #AFC0CA;
    --color-link: #8BC8E7;
    --color-teal-ink: #5FCBC1;
    --color-secondary-dark: #8BC8E7;   /* Begruendung siehe Block darueber */
    --color-accent: #63B3ED;
    --color-border: #2B4350;
    --color-placeholder-bg: #203540;
    --color-placeholder-text: #AFC0CA;
    --color-on-dark-muted: #D8E8F0;
    --shadow: 0 14px 40px rgba(0, 0, 0, 0.28);
    --shadow-hover: 0 20px 48px rgba(0, 0, 0, 0.42);
    color-scheme: dark;
  }
}

/* --------------------------------------------------------------------------
   2. BASIS UND ZUGÄNGLICHKEIT
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--color-text);
  background: var(--color-bg);
  transition: background-color 0.3s ease, color 0.3s ease;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

h1, h2, h3, h4 {
  margin: 0 0 0.55em;
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.12;
  color: var(--color-heading);
  text-wrap: balance;
}

h1 { font-size: clamp(2.5rem, 6vw, 4.35rem); font-weight: 800; }
h2 { font-size: clamp(1.85rem, 4vw, 2.75rem); }
h3 { font-size: 1.35rem; }
h4 {
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--color-muted);
}

p { margin: 0 0 1em; }
ul { padding-inline-start: 1.2em; }
strong { color: var(--color-heading); }
address { margin: 0 0 0.75em; font-style: normal; color: var(--color-muted); }

a {
  color: var(--color-link);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  text-decoration-skip-ink: none;
}
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: 4px;
}

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

.skip-link {
  position: absolute;
  top: -100%;
  left: 1rem;
  z-index: 200;
  padding: 0.65rem 1rem;
  border-radius: var(--radius-small);
  background: var(--color-primary);
  color: var(--color-white);
}
.skip-link:focus { top: 0.5rem; }

/* --------------------------------------------------------------------------
   3. SIGNATUR, LAYOUT UND FLÄCHEN
   -------------------------------------------------------------------------- */
.hl {
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--color-teal) 45%, transparent);
  text-decoration-thickness: 8px;
  text-underline-offset: 2px;
  text-decoration-skip-ink: none;
  padding-inline: 0.03em;
}
.hl--secondary {
  text-decoration-color: color-mix(in srgb, var(--color-highlight) 55%, transparent);
}
.hero .hl { color: var(--color-secondary-dark); }
.page-hero .hl { color: var(--color-highlight); }
.doodle { position: absolute; pointer-events: none; user-select: none; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 2rem);
}
.narrow { max-width: 780px; }
.section { padding-block: clamp(3.5rem, 8vw, 6rem); }
/* Fuer den ersten Abschnitt direkt unter dem Seitenkopf.
   Der Hero bringt unten schon ein kraeftiges Polster UND die Welle mit;
   zusammen mit dem vollen padding-top entsteht sonst ein leerer Streifen,
   der wie ein Abschnittsende wirkt. Wichtig: kein Farbblock (also kein
   .section--muted o.ae.) verwenden, sonst kommen Rand und abgerundete
   Ecken zurueck und die Trennung ist wieder da. */
.section--flush-top { padding-top: clamp(1rem, 2.5vw, 2rem); }

.section--alt,
.section--surface,
.section--warm,
.section--teal,
.section--muted {
  margin: var(--panel-gap);
  border-radius: var(--radius-large);
  transition: background-color 0.3s ease;
}
.section--alt,
.section--surface { background: var(--color-surface-alt); }
.section--warm { background: var(--color-surface-warm); }
.section--teal { background: var(--color-surface-teal); }
.section--muted { background: var(--color-surface-muted); }

/* Abschnitte wechseln sich ab: eingefaerbter Block, dann Seitengrund, dann
   wieder ein Block. Der Farbwechsel allein markiert das neue Thema – zwei
   gleich eingefaerbte Abschnitte direkt hintereinander sind deshalb nicht
   vorgesehen und stehen auf keiner Seite. (Falls doch mal noetig: sie
   wuerden als zwei getrennte Karten mit einer Fuge dazwischen erscheinen
   und muessten dann bewusst zusammengefasst werden.) */

.section-head { max-width: 780px; margin-bottom: clamp(1.8rem, 5vw, 3.25rem); }
.section-lead { font-size: 1.15rem; color: var(--color-muted); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.9rem;
  padding: 0.3rem 0.85rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-secondary) 12%, transparent);
  color: var(--color-secondary-dark);
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.eyebrow::before {
  content: "";
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: currentColor;
}
.eyebrow--hero {
  background: color-mix(in srgb, var(--color-white) 62%, transparent);
  color: var(--color-primary);
  border: 1px solid color-mix(in srgb, var(--color-primary) 14%, transparent);
}
.eyebrow--success {
  background: color-mix(in srgb, var(--color-success) 13%, transparent);
  color: var(--color-success-dark);
}
/* --color-success-dark hat keinen eigenen Dunkelmodus-Wert, weil es an
   anderer Stelle (.card-tag--success) als DECKENDER Hintergrund fuer
   weisse Schrift dient – dort waere ein aufgehellter Wert falsch (weisse
   Schrift auf hellem Mint waere selbst das Kontrastproblem). Hier als
   Textfarbe auf fast durchsichtigem Grund braucht es aber einen eigenen,
   dunkelmodus-sicheren Wert: Im Dunkelmodus kommt das dunkle Gruen sonst
   nur auf ca. 2,8:1. --color-teal-ink ist schon dunkelmodus-sicher und
   farblich naeher an Gruen als etwa Blau – deshalb hier statt einer
   weiteren neuen Farbe wiederverwendet. */
:root[data-theme="dark"] .eyebrow--success { color: var(--color-teal-ink); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .eyebrow--success { color: var(--color-teal-ink); }
}

/* Ergaenzung zu .eyebrow--success: Auf der Startseite stand unter der
   gruenen Eyebrow "Unser Ansatz" ein normaler .btn--secondary – der greift
   auf die globalen Tokens zurueck und ist deshalb Blau. Zwei Akzentfarben
   in einem einzigen, in sich geschlossenen Textblock. Diese Klasse zieht
   den Knopf auf dieselbe gruene Akzentfarbe wie die Eyebrow – direkt auf
   dem <a>-Element gesetzt, nicht auf dem umgebenden Block, damit sie sich
   bei Bedarf gezielt auf ein einzelnes Element anwenden laesst. */
.accent--success {
  --color-secondary: var(--color-success);
  --color-secondary-dark: var(--color-success-dark);
  --color-accent: var(--color-success-dark);
}
/* Dieselbe Umschaltung auf --color-teal-ink wie bei .eyebrow--success
   weiter oben: --color-success-dark bleibt im Dunkelmodus bewusst
   unveraendert (siehe Begruendung dort), hier auf Textfarbe/Fokusring
   gebraucht braucht es denselben dunkelmodus-sicheren Ersatzwert. */
:root[data-theme="dark"] .accent--success {
  --color-secondary-dark: var(--color-teal-ink);
  --color-accent: var(--color-teal-ink);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .accent--success {
    --color-secondary-dark: var(--color-teal-ink);
    --color-accent: var(--color-teal-ink);
  }
}

.eyebrow--highlight {
  background: color-mix(in srgb, var(--color-highlight) 17%, transparent);
  color: var(--color-secondary-dark);
}

.grid { display: grid; gap: 1.5rem; }
.grid--spacious { gap: 2rem; }

/* --------------------------------------------------------------------------
   TRENNLINIE ZWISCHEN KARTEN  (standorte.html)
   --------------------------------------------------------------------------
   Bewusst ein echtes hr-Element und keine Randlinie an der Karte: Die Karten
   haben overflow: hidden und abgerundete Ecken – eine Linie AN der Karte
   saesse deshalb innerhalb des Kastens statt zwischen zwei Kaesten. Als
   eigenes Element im Raster bekommt die Linie ihre eigene Zeile, und der
   Abstand des Rasters wirkt dadurch oben UND unten. Aus 2rem Abstand werden
   so gut 4rem plus Linie – genau der ruhige Zwischenraum, um den es geht.

   Kurz und mittig statt ueber die volle Breite: Sie soll die Standorte
   gliedern, nicht wie eine Wand zwischen ihnen stehen. Farbe aus
   --color-secondary, damit sie sich in Bereiche mit eigener Farbe von selbst
   einfuegt (siehe Abschnitt BEREICHSFARBEN). */
.card-divider {
  width: min(120px, 35%);
  height: 3px;
  margin: 0 auto;
  border: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-secondary) 38%, transparent);
}

/* Bewusste Abstände statt verstreuter Inline-Styles */
.flow-offset-sm { margin-top: 1rem; }
.flow-offset-md { margin-top: 1.5rem; }
.flow-offset-lg { margin-top: 2rem; }
.flow-offset-xl { margin-top: 2.5rem; }
.address-inline { display: inline; margin: 0; color: inherit; }
.split {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; }
  .split--media-right > .split-media { order: 2; }
}

.picture-frame { position: relative; margin: 0; isolation: isolate; }
.picture-frame img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-large);
  box-shadow: var(--shadow);
}
.picture-frame::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -14px auto auto -14px;
  width: 34%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-highlight) 34%, transparent);
}
.picture-frame::after {
  content: "";
  position: absolute;
  right: -10px;
  bottom: 6%;
  width: 18%;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 3px dashed color-mix(in srgb, var(--color-secondary) 45%, transparent);
}
.picture-frame--soft img { border-radius: var(--radius-large); }
.picture-frame--success::before { background: color-mix(in srgb, var(--color-teal) 35%, transparent); }
.picture-frame--primary::before { background: color-mix(in srgb, var(--color-primary) 25%, transparent); }

/* --------------------------------------------------------------------------
   4. NAVIGATION
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   KOPFZEILE: oben deckend, beim Scrollen milchig
   --------------------------------------------------------------------------
   Der Glaseffekt kommt erst ab dem ersten Stueck Scrollen. Die Klasse
   is-scrolled setzt script.js (Abschnitt 1).

   Warum nicht durchgehend milchig, wie es urspruenglich war: Eine
   durchscheinende Kopfzeile nimmt die Farbe dessen an, was gerade darunter
   durchlaeuft – weisse Karten, eingefaerbte Abschnitte. Die Browser-
   Titelleiste auf Mobilgeraeten steht dagegen fest auf --color-bg (siehe
   applyBrowserBarColor in script.js). Oben, wo beide direkt aneinander-
   grenzen, entstand dadurch ein sichtbarer Farbsprung.

   Das fiel nur im Hellmodus auf: Der Abstand zwischen Seitengrund
   (#FAFBFC) und den weissen Karten (#FFFFFF) ist zwar klein, direkt neben
   einer fast weissen Titelleiste sieht man ihn aber sofort. Im Dunkelmodus
   liegt derselbe Sprung zwischen #0E1B24 und #152732 – nahe Schwarz loest
   das Auge Helligkeitsunterschiede deutlich schlechter auf.

   Die Aufteilung loest beides: Am Seitenanfang, wo Titelleiste und
   Kopfzeile aneinanderstossen, ist sie deckend und damit exakt deren
   Farbe. Sobald gescrollt wird, grenzt dort nichts mehr aneinander – und
   der Glaseffekt darf wirken.

   -webkit- zusaetzlich wegen Safari, das backdrop-filter bis heute nur
   mit Praefix kennt. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-bg);
  border-bottom: 1px solid color-mix(in srgb, var(--color-border) 82%, transparent);
  transition: background-color 0.25s ease;
}
.site-header.is-scrolled {
  background: color-mix(in srgb, var(--color-bg) 82%, transparent);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}
/* Ohne Glaseffekt-Unterstuetzung waere die Kopfzeile schlicht
   durchsichtig und der Text liefe ueber den Inhalt darunter. Dann lieber
   deckend bleiben. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-header.is-scrolled { background: var(--color-bg); }
}

.nav {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: var(--nav-height);
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1rem, 3vw, 2rem);
}
.brand { display: inline-flex; align-items: center; margin-right: auto; text-decoration: none; }
.brand-logo { display: block; width: auto; height: 48px; }
.brand-logo--dark { display: none; }
:root[data-theme="dark"] .brand-logo--light { display: none; }
:root[data-theme="dark"] .brand-logo--dark { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand-logo--light { display: none; }
  :root:not([data-theme="light"]) .brand-logo--dark { display: block; }
}

.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 10px;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.nav-toggle-bar {
  width: 100%;
  height: 2.5px;
  border-radius: 3px;
  background: var(--color-heading);
  transition: transform 0.25s ease, opacity 0.25s ease;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.nav-menu {
  position: absolute;
  inset: var(--nav-height) 0 auto;
  display: none;
  margin: 0;
  padding: 0.75rem 1.25rem 1.25rem;
  list-style: none;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow);
}
.nav-menu.is-open { display: block; }

@media (max-width: 991px) {
  body.nav-open { overflow: hidden; }
}
body.dialog-open { overflow: hidden; }

.nav-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  width: 100%;
  padding: 0.85rem 0.25rem;
  border: 0;
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-heading);
  font: inherit;
  font-weight: 750;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.nav-link:hover,
.nav-link[aria-current="page"] { color: var(--color-secondary-dark); }

.chevron { flex-shrink: 0; transition: transform 0.25s ease; }
.chevron--nav { display: none; }
.submenu-toggle[aria-expanded="true"] .chevron { transform: rotate(180deg); }

.has-submenu { display: flex; flex-wrap: wrap; align-items: stretch; }
.has-submenu > .nav-link { flex: 1 1 auto; width: auto; }
.has-submenu > .submenu-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-heading);
  cursor: pointer;
}
.has-submenu > .submenu-toggle:hover { color: var(--color-accent); }

.submenu {
  display: none;
  flex-basis: 100%;
  margin: 0;
  padding: 0.25rem 0 0.25rem 1rem;
  list-style: none;
}
.has-submenu.is-open > .submenu { display: block; }
.submenu a {
  display: block;
  padding: 0.6rem 0.25rem;
  color: var(--color-text);
  font-weight: 650;
  text-decoration: none;
}
.submenu a:hover { color: var(--color-accent); }

.nav-social {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  color: var(--color-heading);
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.nav-social:hover,
.nav-social:focus-visible {
  color: var(--color-secondary-dark);
  background: color-mix(in srgb, var(--color-secondary) 12%, transparent);
}
.nav-social-icon {
  display: block;
  width: 22px;
  height: 22px;
  background-color: currentColor;
  -webkit-mask: url("photos/corporateidentity/instagram.png") center / contain no-repeat;
  mask: url("photos/corporateidentity/instagram.png") center / contain no-repeat;
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border: 1px solid color-mix(in srgb, var(--color-white) 35%, transparent);
  border-radius: 999px;
  background: transparent;
  color: var(--color-on-dark-muted);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
}
.theme-toggle:hover { color: var(--color-white); border-color: var(--color-white); }
.icon-sun { display: none; }
:root[data-theme="dark"] .icon-moon { display: none; }
:root[data-theme="dark"] .icon-sun { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .icon-moon { display: none; }
  :root:not([data-theme="light"]) .icon-sun { display: block; }
}

@media (min-width: 992px) {
  .nav-toggle { display: none; }
  .nav-menu {
    position: static;
    display: flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
  }
  .nav-link {
    width: auto;
    padding: 0.55rem 0.8rem;
    border: 0;
    border-radius: 999px;
    font-size: 0.95rem;
  }
  /* --color-primary stand hier vorher fest, ohne Dunkelmodus-Wert. Beim
     Hover ueber einen NICHT aktiven Menuepunkt (aria-current greift dann
     nicht) blieb dieses dunkle Marken-Navy die einzige Farbangabe – auf
     dem dunklen Kopfzeilenhintergrund im Dunkelmodus kam das nur auf
     ca. 2:1 Kontrast, der Menuepunkt war beim Hover kaum noch lesbar.
     --color-secondary-dark ist bereits dunkelmodus-sicher (siehe :root)
     und deckt sich mit dem Hover auf Mobilgeraeten weiter oben. */
  .nav-link:hover,
  .nav-link[aria-current="page"],
  .nav-link--active {
    background: color-mix(in srgb, var(--color-secondary) 11%, transparent);
    color: var(--color-secondary-dark);
  }
  .has-submenu { position: relative; flex-wrap: nowrap; align-items: center; }
  .has-submenu > .submenu-toggle { display: none; }
  .chevron--nav { display: inline-block; }
  .has-submenu:hover .chevron--nav,
  .has-submenu:focus-within .chevron--nav,
  .has-submenu.is-open .chevron--nav { transform: rotate(180deg); }
  .submenu {
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    min-width: 240px;
    padding: 0.5rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-small);
    box-shadow: var(--shadow-hover);
  }
  .submenu::before {
    content: "";
    position: absolute;
    top: -12px;
    left: 0;
    right: 0;
    height: 12px;
  }
  .has-submenu:hover > .submenu,
  .has-submenu:focus-within > .submenu,
  .has-submenu.is-open > .submenu { display: block; }
  .submenu a { padding: 0.6rem 0.8rem; border-radius: var(--radius-small); }
  .submenu a:hover { background: color-mix(in srgb, var(--color-secondary) 10%, transparent); }
}

/* --------------------------------------------------------------------------
   5. HERO – STARTSEITE
   --------------------------------------------------------------------------
   Es stehen DREI Varianten bereit. Umgeschaltet wird ausschliesslich ueber
   die Klasse an der Section in index.html – am uebrigen HTML aendert sich
   nichts:

     <section class="hero" ...>                  A · "Glas"     (Standard)
     <section class="hero hero--split" ...>      B · "Split"
     <section class="hero hero--immersive" ...>  C · "Immersiv"

   Motivhinweis: Auf dem Foto (Kletterpark) sind die Personen RECHTS OBEN.
   Deshalb steht der Bildfokus auf 68 % und der Text links.

   Alle Verlaeufe rechnen mit color-mix(... var(--color-bg) ...) bzw.
   var(--color-primary-dark). Dadurch passen sie sich automatisch an Hell-
   und Dunkelmodus an; separate Farbangaben je Farbschema sind nicht mehr
   noetig (frueher gab es dafuer vier zusaetzliche Regelbloecke).
   -------------------------------------------------------------------------- */
.hero {
  /* Das Motiv lag als PNG mit 3,0 MB vor – als Hintergrundbild des ersten
     Bildschirms war es damit der langsamste Baustein der ganzen Website
     (PNG ist fuer Fotos das falsche Format: es komprimiert verlustfrei und
     kann Fotorauschen nicht zusammenfassen). Als JPEG sind es 0,34 MB bei
     praktisch gleichem Aussehen – 88 % weniger Daten.

     Das Original photos/design/headeryouth.png bleibt liegen und kann geloescht
     werden; es wird von der Website nicht mehr gebraucht.

     Mobil wird weiter unten auf headeryouth_mobil.jpg (0,13 MB, 900 px)
     umgeschaltet – dort ist das Bild nur ein schmales Band, die grosse
     Fassung waere reine Verschwendung. */
  --hero-image: url("photos/headeryouth_web.jpg");
  --hero-focus: 68% center;

  position: relative;
  display: flex;
  align-items: center;
  min-height: clamp(480px, calc(100vh - var(--nav-height)), 680px);
  overflow: hidden;
  padding-block: clamp(2.5rem, 4vw, 4rem) clamp(4rem, 6vw, 5.5rem);

  /* Deutlich zurueckhaltender als vorher (dort deckte der Verlauf links zu
     98 % ab und das Foto war praktisch unsichtbar). Fuer die Lesbarkeit des
     Textes sorgt jetzt die Glaskarte .hero-content. */
  background:
    linear-gradient(100deg,
      color-mix(in srgb, var(--color-bg) 58%, transparent) 0%,
      color-mix(in srgb, var(--color-bg) 40%, transparent) 32%,
      color-mix(in srgb, var(--color-bg) 12%, transparent) 60%,
      color-mix(in srgb, var(--color-bg) 0%, transparent) 84%),
    var(--hero-image) var(--hero-focus) / cover no-repeat;
}
.hero-inner { position: relative; z-index: 1; width: 100%; }
/* Deckkraft der Glaskarte: 80 %, nicht 68 %.
   Begruendung (WCAG 1.4.3): Hinter der Karte liegt ein FOTO, dessen
   Helligkeit nicht vorhersehbar ist. Bei 68 % Weiss ueber einer dunklen
   Bildpartie (~#303030) sinkt der Kontrast des Fliesstextes #435261 auf
   4,27:1 – unter die geforderten 4,5:1. Bei 80 % sind es 5,6:1, auch
   ueber einer nahezu schwarzen Stelle noch 5,5:1. Das Foto bleibt durch
   den blur deutlich sichtbar; die 12 Prozentpunkte kosten optisch kaum
   etwas, sichern aber die Lesbarkeit unabhaengig vom Bildmotiv.
   Wer das Hintergrundfoto tauscht, muss hier nichts nachrechnen. */
.hero-content {
  max-width: 700px;
  padding: clamp(1.6rem, 4vw, 2.75rem);
  border: 1px solid color-mix(in srgb, var(--color-white) 78%, transparent);
  border-radius: var(--radius-large);
  background: color-mix(in srgb, var(--color-white) 80%, transparent);
  box-shadow: var(--shadow-hover);
  backdrop-filter: blur(20px) saturate(115%);
  -webkit-backdrop-filter: blur(20px) saturate(115%);
}
.hero h1 {
  margin-bottom: 0.35em;
  color: var(--color-heading);
  /* Etwas kleiner als zuvor (3.6rem), damit die laengere, keywordstarke
     Ueberschrift auf dem Desktop in drei statt vier Zeilen passt. */
  font-size: clamp(2.3rem, 3.5vw, 3.25rem);
}
.hero-lead {
  max-width: 52ch;
  margin-bottom: 1.8rem;
  color: var(--color-text);
  font-size: clamp(1.05rem, 2vw, 1.2rem);
  line-height: 1.72;
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-bottom: 1.65rem; }
.hero-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.hero-facts li {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.52rem 0.85rem;
  border: 1px solid color-mix(in srgb, var(--color-primary) 12%, transparent);
  border-radius: 999px;
  /* 80 % wie die Glaskarte darueber – gleiche Begruendung. */
  background: color-mix(in srgb, var(--color-white) 80%, transparent);
  color: var(--color-heading);
  font-size: 0.9rem;
  font-weight: 750;
}
.hero-facts li::before {
  content: "";
  width: 0.48em;
  height: 0.48em;
  border-radius: 50%;
  background: var(--color-teal);
}
.hero-wave,
.page-hero-wave {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  width: 100%;
  height: clamp(34px, 6vw, 80px);
  pointer-events: none;
}
.hero-wave path,
.page-hero-wave path { fill: var(--color-bg); }

.hero-lines { display: none; }

/* --------------------------------------------------------------------------
   VARIANTE B · "SPLIT" – Text und Foto als zwei gleichberechtigte Spalten
   --------------------------------------------------------------------------
   Kein Verlauf, kein Filter: das Foto ist zu 100 % sichtbar, der Text steht
   auf ruhigem Seitengrund (bester Kontrast). Auf Mobil wird daraus
   automatisch ein Bildband oben und Text darunter.
   Das Foto ist ::after von .hero-inner – so bleibt das HTML unveraendert.
   -------------------------------------------------------------------------- */
.hero--split {
  display: block;
  min-height: 0;
  overflow: visible;
  padding-block: clamp(1.75rem, 4vw, 3.25rem) clamp(4rem, 7vw, 6rem);
  background: none;
}
.hero--split .hero-inner {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}
.hero--split .hero-inner::after {
  content: "";
  order: 1;                        /* Mobil: Bild oben */
  min-height: clamp(230px, 52vw, 470px);
  border-radius: var(--radius-large);
  background: var(--hero-image) var(--hero-focus) / cover no-repeat;
  box-shadow: var(--shadow-hover);
}
.hero--split .hero-content {
  order: 2;
  max-width: none;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
/* Auf ruhigem Grund brauchen Eyebrow und Ghost-Button normale Kontraste */
.hero--split .eyebrow--hero {
  border-color: transparent;
  background: color-mix(in srgb, var(--color-secondary) 12%, transparent);
  color: var(--color-secondary-dark);
}
.hero.hero--split .btn--ghost {
  border-color: color-mix(in srgb, var(--color-secondary) 68%, var(--color-border));
  background: transparent;
  color: var(--color-secondary-dark);
}
.hero.hero--split .btn--ghost:hover {
  background: color-mix(in srgb, var(--color-secondary) 11%, transparent);
}
@media (min-width: 900px) {
  .hero--split .hero-inner { grid-template-columns: 1.02fr 0.98fr; }
  .hero--split .hero-content { order: 1; }
  .hero--split .hero-inner::after {
    order: 2;
    align-self: stretch;
    min-height: clamp(340px, 34vw, 520px);
  }
}

/* --------------------------------------------------------------------------
   VARIANTE C · "IMMERSIV" – grossflaechiges Foto, helle Schrift
   --------------------------------------------------------------------------
   Der Verlauf laeuft von unten nach oben ins Foto. Oben bleibt das Motiv
   vollstaendig frei, der Text sitzt unten auf dunklem Grund.
   -------------------------------------------------------------------------- */
.hero--immersive {
  align-items: flex-end;
  min-height: clamp(560px, calc(100vh - var(--nav-height)), 780px);
  background:
    radial-gradient(ellipse 72% 58% at 16% 94%,
      color-mix(in srgb, var(--color-primary-dark) 52%, transparent), transparent 70%),
    linear-gradient(to top,
      color-mix(in srgb, var(--color-primary-dark) 94%, transparent) 0%,
      color-mix(in srgb, var(--color-primary-dark) 72%, transparent) 26%,
      color-mix(in srgb, var(--color-primary-dark) 32%, transparent) 55%,
      color-mix(in srgb, var(--color-primary-dark) 6%, transparent) 84%,
      color-mix(in srgb, var(--color-primary-dark) 0%, transparent) 100%),
    var(--hero-image) var(--hero-focus) / cover no-repeat;
}
.hero--immersive .hero-content {
  max-width: 700px;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.hero--immersive h1 {
  color: var(--color-white);
  text-shadow: 0 2px 20px rgba(3, 20, 33, 0.5);
}
.hero--immersive .hl { color: var(--color-highlight); }
.hero--immersive .hero-lead { color: var(--color-on-dark-muted); }
.hero--immersive .eyebrow--hero {
  border-color: rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.14);
  color: var(--color-white);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.hero--immersive .hero-facts li {
  border-color: rgba(255, 255, 255, 0.26);
  background: rgba(255, 255, 255, 0.14);
  color: var(--color-white);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.hero.hero--immersive .btn--ghost {
  border-color: rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.12);
  color: var(--color-white);
}
.hero.hero--immersive .btn--ghost:hover { background: rgba(255, 255, 255, 0.24); }

/* --------------------------------------------------------------------------
   HERO – TABLET
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  .hero {
    min-height: min(94vh, 660px);
    background:
      linear-gradient(105deg,
        color-mix(in srgb, var(--color-bg) 64%, transparent) 0%,
        color-mix(in srgb, var(--color-bg) 44%, transparent) 46%,
        color-mix(in srgb, var(--color-bg) 8%, transparent) 88%),
      var(--hero-image) 66% center / cover no-repeat;
  }
  .hero-content { max-width: 100%; }
  .hero--split { background: none; }
}

/* --------------------------------------------------------------------------
   HERO – MOBIL
   --------------------------------------------------------------------------
   Behebt "auf Mobilgeraeten sieht man gar nichts vom Bild": Das Foto steht
   jetzt als klar erkennbares Band ueber dem Text und laeuft nach unten in
   den Seitengrund aus. Der Text sitzt vollstaendig auf ruhigem Grund und ist
   damit unabhaengig von der Bildhelligkeit lesbar.
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {
  .hero {
    --hero-band: clamp(215px, 52vw, 330px);
    /* Kleinere Bilddatei fuer kleine Bildschirme: 900 px statt 1600 px,
       0,13 MB statt 0,34 MB. Auf einem Handy im Mobilfunknetz ist das der
       spuerbarste Unterschied der ganzen Seite. */
    --hero-image: url("photos/headeryouth_mobil.jpg");
    display: block;
    min-height: 0;
    padding-block: 0 3.25rem;
    background: var(--color-bg);
  }
  /* Das Bildband ist ein echtes Element (::before) und kein Hintergrund-Trick.
     Vorteil: "cover" haelt das Seitenverhaeltnis, Verlauf und Bild liegen
     zwangslaeufig deckungsgleich, und der Text fliesst einfach darunter –
     ohne Berechnung von padding-top. */
  .hero::before {
    content: "";
    display: block;
    height: var(--hero-band);
    margin-bottom: 1.35rem;
    background:
      linear-gradient(to bottom,
        color-mix(in srgb, var(--color-bg) 0%, transparent) 0%,
        color-mix(in srgb, var(--color-bg) 0%, transparent) 56%,
        color-mix(in srgb, var(--color-bg) 50%, transparent) 84%,
        var(--color-bg) 100%),
      var(--hero-image) 62% 26% / cover no-repeat;
  }
  .hero-inner { padding-top: 0; }
  .hero-content {
    max-width: 100%;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .hero h1 { font-size: clamp(1.85rem, 6.5vw, 2.65rem); }
  /* Frueher: display: none. Das hat auf Mobilgeraeten – wo der groesste
     Teil der Besucher ankommt – genau die drei Vertrauensangaben
     entfernt, die den Traeger einordnen (Standorte, Angebotsarten,
     Rufbereitschaft). Inhaltsgleichheit zwischen Mobil und Desktop ist
     wichtiger als eine kurze Startseite. Sie bleiben also stehen, nur
     kompakter gesetzt; auf dem ruhigen Seitengrund (die Glaskarte
     entfaellt mobil) reicht eine schlichte Pille. */
  .hero-facts {
    gap: 0.4rem;
    margin-top: 1.25rem;
  }
  .hero-facts li {
    padding: 0.4rem 0.7rem;
    background: var(--color-surface);
    border-color: var(--color-border);
    font-size: 0.83rem;
  }

  /* Split bringt sein Bild schon selbst mit (Grid einspaltig, Bild oben) */
  .hero--split { background: none; }
  .hero--split::before { display: none; }
  .hero--split .hero-inner { padding-top: 0; }

  /* Immersiv bleibt auch mobil grossflaechig */
  .hero--immersive::before { display: none; }
  .hero--immersive {
    display: flex;
    align-items: flex-end;
    min-height: min(90vh, 620px);
    padding-block: 3rem 3rem;
    background:
      linear-gradient(to top,
        color-mix(in srgb, var(--color-primary-dark) 95%, transparent) 0%,
        color-mix(in srgb, var(--color-primary-dark) 74%, transparent) 30%,
        color-mix(in srgb, var(--color-primary-dark) 24%, transparent) 62%,
        color-mix(in srgb, var(--color-primary-dark) 0%, transparent) 100%),
      var(--hero-image) 62% 30% / cover no-repeat;
  }
  .hero--immersive .hero-inner { padding-top: 0; }
}

/* --------------------------------------------------------------------------
   HERO – DUNKELMODUS
   Die Hintergrundverlaeufe passen sich automatisch an (color-mix mit
   --color-bg). Nur Glaskarte, Chips und Ghost-Button brauchen eigene Werte.
   -------------------------------------------------------------------------- */
:root[data-theme="dark"] .hero-content {
  border-color: rgba(255, 255, 255, 0.12);
  background: rgba(21, 39, 50, 0.72);
}
:root[data-theme="dark"] .hero .hl { color: var(--color-highlight); }
:root[data-theme="dark"] .hero-facts li {
  border-color: rgba(255, 255, 255, 0.12);
  background: rgba(21, 39, 50, 0.72);
}
:root[data-theme="dark"] .hero .btn--ghost {
  border-color: rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.12);
  color: var(--color-white);
}
:root[data-theme="dark"] .hero .btn--ghost:hover { background: rgba(255, 255, 255, 0.22); }
:root[data-theme="dark"] .hero--split .eyebrow--hero {
  background: color-mix(in srgb, var(--color-highlight) 20%, transparent);
  color: var(--color-highlight);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hero-content {
    border-color: rgba(255, 255, 255, 0.12);
    background: rgba(21, 39, 50, 0.72);
  }
  :root:not([data-theme="light"]) .hero .hl { color: var(--color-highlight); }
  :root:not([data-theme="light"]) .hero-facts li {
    border-color: rgba(255, 255, 255, 0.12);
    background: rgba(21, 39, 50, 0.72);
  }
  :root:not([data-theme="light"]) .hero .btn--ghost {
    border-color: rgba(255, 255, 255, 0.55);
    background: rgba(255, 255, 255, 0.12);
    color: var(--color-white);
  }
  :root:not([data-theme="light"]) .hero .btn--ghost:hover { background: rgba(255, 255, 255, 0.22); }
  :root:not([data-theme="light"]) .hero--split .eyebrow--hero {
    background: color-mix(in srgb, var(--color-highlight) 20%, transparent);
    color: var(--color-highlight);
  }
}

/* Mobil gibt es KEINE Glaskarte – auch nicht im Dunkelmodus.
   Der Abschnitt "HERO – MOBIL" schaltet sie mit padding: 0 und
   background: none ab. Die beiden Dunkelmodus-Bloecke darueber sind
   spezifischer (:root[...] .hero-content) und haben die Flaeche danach
   wieder eingeschaltet – aber eben NUR die Flaeche, nicht das padding.
   Ergebnis auf dem Handy: ein dunkler Kasten, in dem die Ueberschrift
   direkt an der Kante klebte. Deshalb hier das letzte Wort. */
@media (max-width: 640px) {
  .hero-content,
  :root[data-theme="dark"] .hero-content,
  :root:not([data-theme="light"]) .hero-content {
    border-color: transparent;
    background: none;
    box-shadow: none;
  }
}

/* --------------------------------------------------------------------------
   6. BUTTONS
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 48px;
  padding: 0.75rem 1.45rem;
  border: 2px solid transparent;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 750;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.btn:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.btn:active { transform: translateY(0); }
.btn--primary { background: var(--color-primary); color: var(--color-white); }
.btn--primary:hover { background: var(--color-primary-dark); color: var(--color-white); }
.btn--secondary {
  border-color: color-mix(in srgb, var(--color-secondary) 68%, var(--color-border));
  background: transparent;
  color: var(--color-secondary-dark);
}
.btn--secondary:hover { background: color-mix(in srgb, var(--color-secondary) 11%, transparent); }
.btn--success { background: var(--color-success); color: var(--color-white); }
.btn--success:hover { background: var(--color-success-dark); color: var(--color-white); }
.btn--ghost {
  border-color: rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.08);
  color: var(--color-white);
}
.btn--ghost:hover { background: rgba(255, 255, 255, 0.18); }
.hero .btn--ghost {
  border-color: color-mix(in srgb, var(--color-primary) 32%, transparent);
  background: color-mix(in srgb, var(--color-white) 42%, transparent);
  color: var(--color-primary);
}
.hero .btn--ghost:hover { background: color-mix(in srgb, var(--color-white) 76%, transparent); }
.cta-band .btn--primary { background: var(--color-highlight); color: var(--color-primary-dark); }
.cta-band .btn--primary:hover { background: var(--color-white); color: var(--color-primary-dark); }

/* --------------------------------------------------------------------------
   7. KARTEN
   -------------------------------------------------------------------------- */
.card {
  /* Akzentfarbe der Karte. Steuert die Einfaerbung und den Rahmen beim
     Anfahren – und, wo vorhanden, die farbige Oberkante. Karten mit
     eigener Farbe ueberschreiben sie (siehe .card--audience, .card--job,
     .service-block). Innerhalb von .area--ambulant ist --color-secondary
     bereits Teal, dort wird die Karte also von selbst teal. */
  --card-accent: var(--color-secondary);

  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-large);
  background: var(--color-surface);
  box-shadow: var(--shadow);
  transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease, background-color 0.3s ease;
}

/* --------------------------------------------------------------------------
   HOVER: ANHEBEN NUR, WO DIE GANZE KARTE ANKLICKBAR IST
   --------------------------------------------------------------------------
   GRUNDSATZ
     Das Anheben ist ein Versprechen: "Hier kannst du hinklicken." Wo nur
     ein Knopf in der Karte anklickbar ist, ist dieses Versprechen falsch –
     und es schadet zusaetzlich der Bedienbarkeit, weil sich das Ziel unter
     dem Mauszeiger wegbewegt.

     Der schlimmste Fall war die Teamliste: Beim Anfahren einer
     Personenkarte rutschte die E-Mail-Adresse 5 px nach oben. Wer den
     Link ansteuert, verfolgt also ein Ziel, das ausweicht – bei einer
     einzeiligen Adresse ist das rund ein Drittel der Zeilenhoehe. Fuer
     Menschen mit Tremor oder mit einem Trackpad ist das ein echtes
     Hindernis, fuer alle anderen laestig.

   WAS SICH VERAENDERT (Farbe, Rahmen, Schatten) GILT WEITER FUER ALLE
   KARTEN – das ist eine reine Rueckmeldung "du bist hier" und verschiebt
   nichts.

   ANGEHOBEN WIRD NUR NOCH
     a.card         die Teaser-Karten auf der Startseite. Sie sind selbst
                    ein Link, die gesamte Flaeche ist anklickbar.
     .tile--link    die Angebots-Kacheln (Toepfern, Jugendcafe ...). Sie
                    sind zwar <article>, aber .tile-more::after legt eine
                    unsichtbare Flaeche ueber die GANZE Kachel – auch hier
                    trifft jeder Klick. Eigene Regel in Abschnitt 19.

   NICHT MEHR ANGEHOBEN
     .card--person    Teamliste, enthaelt einen Mailto-Link
     .card--audience  "Fuer junge Menschen" usw., enthaelt einen Knopf
     .card--wide      Standorte, enthalten "Route planen"
     .card--job       Stellenangebote
     die Karten der Wohnungsgalerie und des Videorundgangs

   In allen diesen Faellen hebt sich stattdessen der Knopf selbst an,
   sobald man IHN anfaehrt (.btn:hover, Abschnitt 6). Genau dort gehoert
   die Rueckmeldung auch hin.

   >>> BEIM ANLEGEN EINER NEUEN KARTE: Ist die ganze Karte ein Link, dann
   >>> <a class="card ..."> schreiben – das Anheben kommt automatisch.
   >>> Steht nur ein Knopf darin, <article> oder <div> nehmen.

   DIE EINFAERBUNG NIMMT DIE FARBE DER JEWEILIGEN BOX
   Sie rechnet mit --card-accent, nicht mit dem globalen Sekundaerblau.
   Eine teal umrandete Karte wird also teal angefahren, eine mit heller
   Oberkante hell. Karten ohne eigene Farbe bleiben blau.
   -------------------------------------------------------------------------- */
.card:hover,
.service-block:hover {
  border-color: color-mix(in srgb, var(--card-accent) 26%, var(--color-border));
  box-shadow: var(--shadow-hover);
  /* Leichte Einfaerbung als Ersatz fuer das entfallene Anheben. Bewusst
     schwach (5 %): Sie soll die Box hervorheben, nicht den Text
     schlechter lesbar machen. Ueber color-mix passt sie sich dem
     Dunkelmodus von selbst an. */
  background-color: color-mix(in srgb, var(--card-accent) 5%, var(--color-surface));
}
/* Die farbige Oberkante behaelt beim Anfahren ihre volle Farbe.
   Ohne diese Zeile wuerde sie vom border-color oben mit ueberschrieben
   und auf 26 % verblassen – die Karte verloere beim Anfahren genau das
   Merkmal, das sie kennzeichnet. */
.card--audience:hover,
.card--job:hover,
.service-block:hover { border-top-color: var(--card-accent); }

a.card:hover,
a.card:focus-visible {
  transform: translateY(-5px);
}
.card-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1.55rem 1.6rem 1.7rem;
}
.card-body .btn { align-self: flex-start; margin-top: auto; }
.card-media { position: relative; aspect-ratio: 16 / 9; overflow: hidden; }
.card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.45s ease;
}
/* Der Bildzoom bleibt an den Link gebunden: Er ist Teil desselben
   Versprechens wie das Anheben. .card-media kommt ohnehin nur in den
   Teaser-Karten vor. */
a.card:hover .card-media img,
a.card:focus-visible .card-media img { transform: scale(1.04); }

.placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: repeating-linear-gradient(45deg, transparent 0 12px, rgba(47, 137, 196, 0.06) 12px 24px), var(--color-placeholder-bg);
  color: var(--color-placeholder-text);
  font-size: 0.9rem;
  font-weight: 650;
}
.check-list { margin: 0 0 1em; padding: 0; list-style: none; }
.check-list li { position: relative; margin-bottom: 0.45em; padding-inline-start: 1.7em; }
/* inset-inline-start statt left: damit der Haken bei arabischer
   Schreibrichtung (dir="rtl") auf der richtigen Seite steht.

   Farbe kommt aus --color-secondary/-dark statt fest aus --color-teal:
   Vorher war der Haken IMMER teal, auch in blauen Abschnitten (Betreutes
   Wohnen, jobs.html, impressum.html, datenschutz.html) – dort passte er
   zu nichts anderem auf der Seite. Ueber das Token faerbt er sich jetzt
   automatisch mit dem Bereich: teal innerhalb von .area--ambulant (das
   Token wird dort umgeschaltet, siehe Abschnitt BEREICHSFARBEN), sonst
   Blau – genau wie Etikett, "Mehr erfahren" und die Funktionsbezeichnungen
   schon funktionieren. */
.check-list li::before {
  content: "";
  position: absolute;
  top: 0.28em;
  inset-inline-start: 0;
  width: 1.05em;
  height: 1.05em;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-secondary) 18%, transparent);
}
.check-list li::after {
  content: "";
  position: absolute;
  top: 0.53em;
  inset-inline-start: 0.28em;
  width: 0.5em;
  height: 0.28em;
  border-bottom: 2.5px solid var(--color-secondary-dark);
  border-left: 2.5px solid var(--color-secondary-dark);
  transform: rotate(-45deg);
}
.hours { color: var(--color-muted); font-size: 0.95rem; }
.map-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 110px;
  margin-bottom: 1rem;
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-small);
  color: var(--color-placeholder-text);
  font-size: 0.9rem;
}
.card--person { text-align: center; }
.card--person .card-body { align-items: center; }
.avatar {
  position: relative;
  flex-shrink: 0;
  width: 122px;
  height: 122px;
  margin: 1.6rem auto 0;
  overflow: hidden;
  border: 3px solid var(--color-surface);
  border-radius: 50%;
  outline: 1px solid var(--color-border);
  background: var(--color-placeholder-bg);
  box-shadow: var(--shadow);
}
.avatar img { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.avatar-fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--color-placeholder-text);
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 750;
}
.team-photo { position: relative; margin: 0 0 clamp(2rem, 5vw, 3rem); }
.team-photo img {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-large);
  object-fit: cover;
  box-shadow: var(--shadow);
}
/* Funktion und Qualifikation auf der Personenkarte.
   Frueher stand hier nur ein kurzes Bereichslabel ("LEITUNG"), deshalb
   Grossbuchstaben und gesperrte Schrift. Inzwischen stehen dort echte
   Bezeichnungen wie "Stellv. Bereichsleitung Betreutes Wohnen" – die
   waeren in Versalien eine Mauer. Darum normale Schreibung. */
.person-role {
  margin-bottom: 0.15em;
  color: var(--color-secondary-dark);
  font-size: 0.9rem;
  font-weight: 750;
  line-height: 1.35;
  text-wrap: balance;
}
.person-qualification {
  margin-bottom: 0;
  color: var(--color-muted);
  font-size: 0.82rem;
  line-height: 1.35;
  text-wrap: balance;
}
/* Der Abstand zur E-Mail haengt an der E-Mail selbst. So sitzt sie
   gleich weit unten, egal ob die Karte eine oder zwei Zeilen hat. */
.person-mail { max-width: 100%; margin: 0.55em 0 0; overflow-wrap: break-word; font-size: 0.85rem; }
.person-mail a { color: var(--color-muted); text-decoration: none; }
.person-mail a:hover,
.person-mail a:focus-visible { color: var(--color-accent); text-decoration: underline; }
.card--job {
  --card-accent: var(--color-highlight);
  border-top: 4px solid var(--card-accent);
}
.job-tag {
  align-self: flex-start;
  margin-bottom: 0.75rem;
  padding: 0.25rem 0.8rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-highlight) 20%, transparent);
  color: var(--color-secondary-dark);
  font-size: 0.82rem;
  font-weight: 800;
}
.jobs-note { margin-top: 2rem; color: var(--color-muted); }
/* Bewerbungsadresse im Stellen-Popup. Stand vorher dreimal als
   style="..." direkt im HTML von jobs.html – dadurch war die Angabe an drei
   Stellen zu pflegen und liess sich per Content-Security-Policy nicht
   erlauben. Die globale address-Regel setzt --color-muted; hier soll die
   Adresse aber wie normaler Text lesbar sein. */
.application-address {
  margin: 0;
  color: var(--color-text);
  font-style: normal;
  line-height: 1.8;
}

/* --------------------------------------------------------------------------
   8. FAQ
   -------------------------------------------------------------------------- */
.faq-list { display: grid; gap: 0.8rem; }

.faq-item {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-small);
  margin-bottom: 0;
  box-shadow: var(--shadow);
  transition: border-color 0.2s ease;
}
.faq-item[open] { border-color: color-mix(in srgb, var(--color-secondary) 45%, transparent); }
/* Flex statt absoluter Positionierung.
   Vorher hing das Plus-Zeichen mit position:absolute und top:50% in der
   Mitte der GESAMTEN Zeile. Auf dem Desktop passt jede Frage in eine Zeile,
   da faellt das nicht auf. Mobil brechen die langen Fragen aber auf zwei
   bis drei Zeilen um – dann schwebte das Plus mittig neben dem Textblock
   statt neben der ersten Zeile, und das feste padding-right: 3.2rem riss
   zusaetzlich eine Luecke in jede Zeile.

   Als Flex-Element sitzt es jetzt neben der ersten Zeile (align-items:
   flex-start) und der Platz dafuer entsteht automatisch – kein
   Reserve-Polster mehr, das bei einzeiligen Fragen ins Leere geht. */
.faq-item summary {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  padding: 1.05rem 1.35rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--color-heading);
  cursor: pointer;
  list-style: none;
  /* Sonst blitzt beim Antippen auf Android ein grauer Kasten ueber die
     ganze Zeile – der eigentliche "sieht komisch aus"-Effekt beim Tippen. */
  -webkit-tap-highlight-color: transparent;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  flex-shrink: 0;
  margin-inline-start: auto;
  display: grid;
  place-items: center;
  width: 1.8rem;
  height: 1.8rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-highlight) 22%, transparent);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--color-secondary-dark);
  transition: transform 0.2s ease, background-color 0.2s ease;
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item p { padding: 0 1.35rem 1.15rem; margin: 0; color: var(--color-muted); }
/* Eine Antwort darf auch eine Aufzaehlung enthalten (z. B. moegliche Ziele
   der Hilfe auf "Infos fuer junge Menschen"). Die Liste bekommt denselben
   seitlichen Innenabstand wie die Antworttexte; padding-inline statt
   padding-left, damit sie im Arabischen mitwandert. */
.faq-item .check-list {
  padding-inline: 1.35rem;
  margin-bottom: 1.15rem;
  color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   9. FOOTER
   -------------------------------------------------------------------------- */
.site-footer {
  background: linear-gradient(180deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
  color: #C9DAE6;
  padding-block: 3.5rem 1.5rem;
  border-radius: var(--radius-large) var(--radius-large) 0 0;
  margin-top: var(--panel-gap);
}
.site-footer a { color: #B8DDF0; }
.site-footer a:hover { color: #8FD8D1; }

.footer-grid { display: grid; gap: 2rem; }

.footer-brand { margin-bottom: 0.75rem; }
.footer-logo { display: block; height: 52px; width: auto; }

.footer-heading {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--color-on-dark-heading);
  margin-bottom: 0.8rem;
}

.footer-list { list-style: none; margin: 0; padding: 0; }
.footer-list li { margin-bottom: 0.5rem; }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  font-size: 0.9rem;
}
.footer-bottom p { margin: 0; }

.footer-col { min-width: 0; }
.theme-toggle-label { white-space: nowrap; }
.to-top {
  color: var(--color-on-dark-muted);
  font-weight: 700;
  text-decoration: none;
}
.to-top:hover { color: var(--color-white); text-decoration: underline; }


/* --------------------------------------------------------------------------
   10. SCROLL-REVEAL-ANIMATION
   --------------------------------------------------------------------------
   WARUM eine @keyframes-Animation und nicht einfach ein transition auf
   .reveal?

   Fast alle Reveal-Elemente sind Karten, und .card:hover hebt die Karte per
   "transform" an. Die fruehere Loesung setzte im sichtbaren Zustand
   ".js .reveal.is-visible { transform: none }" – drei Klassen, also
   SPEZIFISCHER als ".card:hover" (zwei Selektorteile). Damit war der
   Hover-Effekt auf jeder Karte mit .reveal still ausgeschaltet: Auf der
   404-Seite (Karten ohne .reveal) hob sich die Karte, auf der Startseite
   nicht. Zusaetzlich hat das transition-Kurzschreiben von .reveal die
   Uebergaenge der Karte (box-shadow, border-color) ersetzt, sodass diese
   ohne Weichzeichnung umsprangen.

   Die Animation nutzt deshalb die Einzel-Eigenschaft "translate" statt
   "transform" und laesst transition + transform der Komponenten voellig
   unberuehrt. Beide Effekte koennen sich so nicht mehr in die Quere kommen.
   -------------------------------------------------------------------------- */
.js .reveal { opacity: 0; }
.js .reveal.is-visible { animation: reveal-rise 0.6s ease both; }

@keyframes reveal-rise {
  from { opacity: 0; translate: 0 24px; }
  to   { opacity: 1; translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  .js .reveal { opacity: 1; }
  .js .reveal.is-visible { animation: none; }
}

section[id],
article[id] { scroll-margin-top: calc(var(--nav-height) + 16px); }

/* --------------------------------------------------------------------------
   11. RESPONSIVE: TABLET (ab 640px)
   -------------------------------------------------------------------------- */
@media (min-width: 640px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
}

/* --------------------------------------------------------------------------
   12. RESPONSIVE: DESKTOP (ab 992px)
   -------------------------------------------------------------------------- */
@media (min-width: 992px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
}

/* --------------------------------------------------------------------------
   13. RESPONSIVE: GROSSE BILDSCHIRME (ab 1400px)
   -------------------------------------------------------------------------- */
@media (min-width: 1400px) {
  :root { --container: 1280px; }
  body { font-size: 1.125rem; }
}

@media (min-width: 640px) {
  .footer-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 992px) {
  .footer-grid { grid-template-columns: 2fr 1fr 1fr 1fr; }
}

/* ==========================================================================
   14. ERGÄNZUNGEN FÜR DIE MEHRSEITIGE VERSION
   ========================================================================== */
.nav-link[aria-current="page"],
.nav-link--active,
.submenu a[aria-current="page"] {
  color: var(--color-link);
}
@media (min-width: 992px) {
  .nav-link[aria-current="page"],
  .nav-link--active {
    background: color-mix(in srgb, var(--color-highlight) 15%, transparent);
    color: var(--color-heading);
  }
}

/* Unterseiten-Kopf: ein System, pro Seitentyp fein akzentuiert */
.page-hero {
  --page-hero-start: var(--color-primary);
  --page-hero-end: var(--color-primary-dark);
  --page-hero-glow-primary: var(--color-teal);
  --page-hero-glow-secondary: var(--color-secondary);
  --page-hero-orbit-inner: #8FD8D1;
  --page-hero-orbit-outer: var(--color-highlight);
  position: relative;
  overflow: hidden;
  color: var(--color-white);
  background:
    radial-gradient(ellipse 55% 60% at 88% 8%, color-mix(in srgb, var(--page-hero-glow-primary) 25%, transparent), transparent 62%),
    radial-gradient(ellipse 80% 80% at 8% 100%, color-mix(in srgb, var(--page-hero-glow-secondary) 34%, transparent), transparent 60%),
    linear-gradient(160deg, var(--page-hero-start) 0%, var(--page-hero-end) 100%);
  padding-block: clamp(3rem, 7vw, 4.75rem) clamp(4.25rem, 9vw, 6.5rem);
}
.page-hero--services {
  --page-hero-glow-primary: var(--color-teal);
  --page-hero-glow-secondary: var(--color-highlight);
}
.page-hero--youth {
  --page-hero-glow-primary: var(--color-highlight);
  --page-hero-glow-secondary: var(--color-teal);
  --page-hero-orbit-inner: #B9E4F7;
  --page-hero-orbit-outer: var(--color-teal);
}
.page-hero--locations {
  --page-hero-glow-primary: var(--color-success);
  --page-hero-glow-secondary: var(--color-secondary);
  --page-hero-orbit-outer: var(--color-success);
}
.page-hero--about {
  --page-hero-glow-primary: var(--color-teal);
  --page-hero-glow-secondary: var(--color-success);
  --page-hero-orbit-outer: var(--color-teal);
}
.page-hero--jobs {
  --page-hero-glow-primary: var(--color-highlight);
  --page-hero-glow-secondary: var(--color-secondary);
  --page-hero-orbit-inner: #B9E4F7;
}
.page-hero--legal {
  --page-hero-glow-primary: var(--color-secondary);
  --page-hero-glow-secondary: var(--color-teal);
  --page-hero-orbit-inner: #C8E7F3;
  --page-hero-orbit-outer: var(--color-secondary);
}
.page-hero h1 { color: var(--color-white); margin-bottom: 0.3em; }
.page-hero .page-lead { color: var(--color-on-dark-muted); max-width: 62ch; font-size: 1.15rem; margin: 0; }
.page-hero .container { position: relative; z-index: 1; }

.page-hero-orbit {
  position: absolute;
  top: clamp(-70px, -6vw, -30px);
  right: clamp(-70px, -4vw, 40px);
  width: clamp(140px, 22vw, 260px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--page-hero-orbit-inner), var(--page-hero-orbit-outer) 70%);
  opacity: 0.48;
  pointer-events: none;
}
.page-hero-orbit::after {
  content: "";
  position: absolute;
  inset: -22%;
  border-radius: 50%;
  border: 3px dashed color-mix(in srgb, var(--page-hero-orbit-inner) 42%, transparent);
}

.breadcrumb { margin: 0 0 1.25rem; font-size: 0.9rem; }
.breadcrumb ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
}
.breadcrumb li + li::before {
  content: "›";
  margin-right: 0.4rem;
  color: #9FD1EF;
}
.breadcrumb a { color: #B8DDF0; }
.breadcrumb [aria-current="page"] { color: #8FD8D1; }

.card--teaser { text-decoration: none; color: inherit; position: relative; }
.card--teaser:focus-visible { outline-offset: 5px; }
.card--teaser .teaser-more {
  margin-top: auto;
  padding-top: 0.5rem;
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--color-link);
  transition: gap 0.2s ease;
}
.card--teaser:hover .teaser-more { text-decoration: underline; text-underline-offset: 4px; }

/* --------------------------------------------------------------------------
   ETIKETT AUF EINEM FOTO
   --------------------------------------------------------------------------
   Grundsatz: Dieses Etikett liegt auf einem FOTO, nicht auf dem
   Seitenhintergrund. Fotos aendern sich beim Umschalten zwischen Hell- und
   Dunkelmodus nicht – also darf sich das Etikett auch nicht aendern. Es
   verwendet deshalb bewusst nur Tokens OHNE Dunkelmodus-Wert
   (--color-primary, --color-secondary, --color-success) und niemals die
   "-dark"-Varianten, die im Dunkelmodus aufgehellt werden.

   Vorher war das anders und dadurch kaputt: --color-secondary-dark ist
   inzwischen dunkelmodus-abhaengig, weil es als Schriftfarbe auf hellem
   Grund gebraucht wird. Im Dunkelmodus wurde daraus ein HELLES Blau – und
   damit lag weisse Schrift auf hellblauem Grund, ein Kontrast von rund
   1,8:1 statt der geforderten 4,5:1. Das Etikett "Ambulant & stationaer"
   war praktisch unlesbar.

   Zweite Aenderung: Die Farbe ist nicht mehr fast deckend, sondern nur noch
   ein Hauch Farbe auf dunklem Glas. Kraeftige Vollfarben wirken auf einem
   Foto wie ein aufgeklebter Zettel; das dunkle Glas dagegen gehoert optisch
   zum Bild. Die drei Varianten bleiben unterscheidbar, ohne zu schreien.

   Der Hintergrund ist bewusst in ZWEI Schritten aufgebaut, damit man an
   einer Schraube drehen kann, ohne die andere zu treffen:

     --card-tag-ink     der fertige Farbton (Farbe + dunkler Glasgrund)
     --card-tag-opacity  wie durchsichtig das Ganze ist  <- hier stellen

   Der dunkle Grund ist als fester rgb-Wert notiert und nicht als Token: Er
   muss auf JEDEM Foto funktionieren, hell wie dunkel, und darf sich deshalb
   an keinem Farbschema orientieren.

   ACHTUNG BEIM WEITEREN AUFHELLEN: 0.72 ist die Untergrenze. Massgeblich
   ist der schlimmste Fall – eine ausgebrannte, rein weisse Stelle im Foto
   direkt hinter dem Etikett. Dort liegt die weisse Schrift bei rund 4,9:1,
   also knapp ueber den 4,5:1, die WCAG AA verlangt. Schon 0.68 rutscht auf
   4,4:1 und faellt durch. Soll es unbedingt heller werden, muesste die
   Schrift dunkel statt weiss werden – das ist dann aber ein anderes
   Gestaltungskonzept. */
.card-tag {
  --card-tag-tint: var(--color-primary);
  --card-tag-ink: color-mix(in srgb, var(--card-tag-tint) 34%, rgb(6, 22, 35));
  --card-tag-opacity: 72%;
  position: absolute;
  top: 0.9rem;
  left: 0.9rem;
  z-index: 1;
  padding: 0.24rem 0.8rem;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 700;
  background: color-mix(in srgb, var(--card-tag-ink) var(--card-tag-opacity), transparent);
  border: 1px solid color-mix(in srgb, var(--color-white) 26%, transparent);
  color: var(--color-white);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--shadow);
}
/* Ohne Glaseffekt-Unterstuetzung faellt der Blur weg – dann fehlt die
   Beruhigung des Bildes darunter und die Schrift braucht mehr Deckkraft. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .card-tag { --card-tag-opacity: 86%; }
}

.steps {
  list-style: none;
  counter-reset: step;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
}
.steps li {
  counter-increment: step;
  position: relative;
  padding: 1.35rem 1.35rem 1.35rem 4.4rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-small);
  box-shadow: var(--shadow);
}
.steps li::before {
  content: counter(step);
  position: absolute;
  left: 1.25rem;
  top: 1.3rem;
  width: 2.2rem;
  height: 2.2rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--color-highlight);
  color: var(--color-primary-dark);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.05rem;
}
.steps h3 { font-size: 1.1rem; margin-bottom: 0.25em; }
.steps p { margin: 0; color: var(--color-muted); }
@media (min-width: 992px) {
  .steps--row { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 768px) {
  .card--wide { flex-direction: row; }
  .card--wide .card-media {
    width: 38%;
    flex-shrink: 0;
    aspect-ratio: auto;
    min-height: 100%;
  }
}

.info-list {
  list-style: none;
  margin: 0 0 1em;
  padding: 0;
  display: grid;
  gap: 0.4rem;
  font-size: 0.97rem;
}
.info-list strong { color: var(--color-heading); }

.cta-band {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse 50% 80% at 90% 110%, rgba(168, 224, 216, 0.28), transparent 60%),
    radial-gradient(ellipse 70% 100% at 8% 0%, rgba(47, 137, 196, 0.35), transparent 60%),
    var(--color-primary);
  color: var(--color-white);
  text-align: center;
  padding-block: clamp(3.25rem, 7vw, 5rem);
  border-radius: var(--radius-large);
  margin-inline: var(--panel-gap);
  margin-block: var(--panel-gap);
}
.cta-band h2 { color: var(--color-white); }
.cta-band p { color: var(--color-on-dark-muted); max-width: 60ch; margin-inline: auto; }
.cta-band .btn--primary { margin-top: 1rem; }
.cta-band .container { position: relative; z-index: 1; }

.cta-contacts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem 2rem;
  margin: 1.4rem 0 0.4rem;
  padding: 0;
  list-style: none;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2.6vw, 1.4rem);
  font-weight: 700;
}
.cta-contacts a { color: #8FD8D1; text-decoration: none; }
.cta-contacts a:hover { text-decoration: underline; text-underline-offset: 5px; }

/* Die Wohnungs-Galerie (infos-fuer-jugendliche.html) nutzt jetzt dieselbe
   .slideshow-Komponente wie standorte.html – siehe Abschnitt 17
   BILDER-SLIDESHOW weiter unten. Das fruehere eigene Raster
   (.photo-gallery / .photo-grid-item / .gallery-hint) ist damit
   entfallen.

   Sie braucht aber eine Breitenbegrenzung, die es auf standorte.html
   nicht braucht: Dort steht die Diashow in einer .card--wide neben dem
   Textblock und nimmt dadurch nur 38 % der Breite ein. Hier steht sie
   allein im Abschnitt und lief deshalb ueber die volle Containerbreite –
   bei 3:2 sind das an die 790 px Hoehe, das Bild fuellte den kompletten
   Bildschirm. Auf Handys aendert sich nichts: Dort ist der Container
   ohnehin schmaler als die 720 px. */
/* --------------------------------------------------------------------------
   GALERIE + VIDEORUNDGANG NEBENEINANDER (infos-fuer-jugendliche.html)
   --------------------------------------------------------------------------
   Links die Diashow im Querformat, rechts das Hochkantvideo.

   Das Spaltenverhaeltnis ist 8fr : 3fr und nicht das naheliegende 2fr : 1fr –
   Grund ist die Rechnung dahinter: Die Diashow ist 3:2 quer, das Video 9:16
   hoch. Damit beide Kaesten GLEICH HOCH werden, muss gelten

       Breite_Bild * 2/3  =  Breite_Video * 16/9

   also Breite_Bild = Breite_Video * 8/3. Genau das ist 8fr : 3fr. Bei 2fr : 1fr
   waere das Video rund 120 px hoeher als die Diashow und die Zeile wirkte
   schief. Wird eines der beiden Seitenverhaeltnisse geaendert, muss diese
   Rechnung mit angepasst werden.

   align-items: start statt des Grid-Standards stretch: Sonst zoege die
   hoehere Karte die andere auf ihre Hoehe, und unter der Diashow entstuende
   ein leerer weisser Streifen (ihre Hoehe ist durch aspect-ratio fest).

   Unter 900 px stehen beide untereinander. Der Umbruch liegt bewusst nicht
   bei 768 px wie anderswo: Die schmale Spalte waere dort nur noch rund
   190 px breit – zu wenig, um im Video etwas zu erkennen. */
.media-duo {
  display: grid;
  gap: 1.5rem;
  /* Einspaltig: nicht ueber die volle Breite laufen lassen, sonst wird die
     Diashow auf Tablets ueber 800 px breit und damit sehr hoch. */
  max-width: 720px;
  margin-inline: auto;
}
@media (min-width: 900px) {
  .media-duo {
    grid-template-columns: 8fr 3fr;
    align-items: start;
    max-width: none;
  }
}

/* Mit dem Handy hochkant gefilmt.

   aspect-ratio haelt den Platz schon frei, BEVOR das Video geladen ist –
   sonst springt das Layout, sobald die Abmessungen bekannt werden. 9:16 ist
   das uebliche Hochkantformat vom Handy.

   object-fit: contain statt cover, weil das genaue Seitenverhaeltnis der
   Datei nicht feststeht: Passt es nicht exakt, entstehen schmale Balken –
   das ist deutlich besser, als dem Video oben und unten etwas abzuschneiden.
   Die Balken bekommen die Platzhalterfarbe, damit sie wie Teil der
   Gestaltung wirken und nicht wie ein Fehler. */
.video-card {
  /* Einspaltig schmal halten, sonst wird das Hochkantvideo riesig.
     Nebeneinander gibt die Grid-Spalte die Breite vor.

     Die mittlere Grenze rechnet mit der BILDSCHIRMHOEHE: 340 px Breite
     ergeben bei 9:16 rund 600 px Hoehe – auf einem Handy mehr als eine
     Bildschirmseite. Das Video ragte dadurch unten aus dem Sichtfeld und
     wirkte wie ein Fehler im Layout. 34vh Breite entsprechen gut 60 % der
     Hoehe; das Video ist damit immer am Stueck zu sehen.

     Die Untergrenze von 200 px ist fuer das quer gehaltene Handy: dort
     sind 34vh nur gut 120 px – da waere nichts mehr zu erkennen. */
  max-width: clamp(200px, 34vh, 340px);
  margin-inline: auto;
}
@media (min-width: 900px) {
  .video-card { max-width: none; }
}
/* Bildunterschrift: sagt, was das Video ueberhaupt zeigt. Ohne sie folgte
   unter der Foto-Diashow uebergangslos ein Gesicht im Badezimmer. */
.video-caption {
  margin: 0;
  padding: 0.8rem 1.05rem 0.95rem;
  color: var(--color-muted);
  font-size: 0.9rem;
  line-height: 1.5;
}
.video-portrait {
  display: block;
  width: 100%;
  aspect-ratio: 9 / 16;
  object-fit: contain;
  background: var(--color-placeholder-bg);
}

/* --------------------------------------------------------------------------
   GROSSE ABSPIELFLAECHE
   --------------------------------------------------------------------------
   Die Klasse .video-stage und die Schaltflaeche darin baut script.js
   (Abschnitt 8) auf. Ohne JavaScript entsteht beides nicht – dann bleibt es
   bei den normalen Bedienelementen des Browsers.

   Die Schaltflaeche liegt ueber dem gesamten Vorschaubild, ist aber selbst
   durchsichtig: Zu sehen ist nur der runde Knopf in der Mitte. Ein Tipp an
   BELIEBIGER Stelle startet trotzdem das Video. */
.video-stage { position: relative; }
.video-play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  width: 100%;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--color-white);
  cursor: pointer;
}
.video-play-icon {
  display: grid;
  place-items: center;
  width: 78px;
  height: 78px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-primary-dark) 72%, transparent);
  box-shadow: 0 6px 24px rgba(5, 27, 43, 0.45);
  /* Das Dreieck sitzt geometrisch links von der Mitte, wenn man es exakt
     zentriert – optisch wirkt der Knopf dadurch schief. Die Verschiebung
     gleicht das aus. */
  padding-inline-start: 5px;
  transition: transform 0.2s ease, background-color 0.2s ease;
}
.video-play:hover .video-play-icon,
.video-play:focus-visible .video-play-icon {
  transform: scale(1.08);
  background: var(--color-primary-dark);
}
.video-play:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: -3px;
}
@media (prefers-reduced-motion: reduce) {
  .video-play-icon { transition: none; }
  .video-play:hover .video-play-icon,
  .video-play:focus-visible .video-play-icon { transform: none; }
}
/* Nur sichtbar, wenn der Browser das video-Element gar nicht kennt. */
.video-fallback { margin: 0; padding: 1rem; }

.tile-grid { display: grid; gap: 1rem; }
.tile {
  padding: 1.35rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-inline-start: 5px solid var(--color-secondary);
  border-radius: var(--radius-small);
  box-shadow: var(--shadow);
}
/* h4 gilt fuer Kacheln im Stundenplan: dort ist der Wochentag die
   uebergeordnete h3, die Angebote stehen eine Ebene darunter. */
.tile h3,
.tile h4 { font-size: 1.08rem; margin-top: 0; margin-bottom: 0.25em; }
/* Die globale h4-Regel setzt Grossbuchstaben und gesperrte Schrift (dort ist
   h4 eine Zwischenueberschrift). In einer Kachel ist h4 aber der Titel und
   muss genauso aussehen wie ein h3 – deshalb hier zurueckgesetzt. */
.tile h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: normal;
  text-transform: none;
  color: var(--color-heading);
}
.tile p { margin: 0; font-size: 0.95rem; color: var(--color-muted); }
@media (min-width: 640px) { .tile-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 992px) { .tile-grid { grid-template-columns: repeat(3, 1fr); } }

/* --------------------------------------------------------------------------
   STUNDENPLAN DER ANGEBOTE
   --------------------------------------------------------------------------
   Die Angebote stehen nicht mehr als lange Kachelwand untereinander, sondern
   wie in einem Stundenplan nach Wochentagen nebeneinander. Innerhalb einer
   Tagesspalte sind sie chronologisch sortiert (morgens -> nachmittags).

   Jede Tagesspalte liegt in einem eigenen Blauton. Die Toene entstehen per
   color-mix aus --color-secondary und --color-surface und passen sich
   dadurch automatisch an Hell- und Dunkelmodus an. Wer die Abstufung
   aendern moechte, dreht ausschliesslich an --tint (Spalte) und
   --tint-head (Kopfzeile) der sechs Modifier-Klassen weiter unten.

   Vor jeder color-mix-Angabe steht eine einfache Farbe als Rueckfallebene
   fuer aeltere Browser.

   >>> PFLEGE: Ein neues Angebot ist eine <article class="tile tile--link">
   >>> in der passenden Tagesspalte – an die richtige Stelle der Uhrzeit
   >>> einsortieren. Angebote ohne festen Wochentag kommen in das Band
   >>> "Alle zwei Wochen" darunter.
   -------------------------------------------------------------------------- */
.schedule { display: grid; gap: 1rem; }

.schedule-week {
  display: grid;
  gap: 0.85rem;
  align-items: start;
}
/* Sechs Tage, sechs Spalten. Bis 1180px stehen sie in zwei Reihen zu drei
   Spalten – das teilt die Woche sauber und laesst den Kacheln genug Breite.
   Erst darueber steht die ganze Woche nebeneinander. */
@media (min-width: 620px)  { .schedule-week { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .schedule-week { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1180px) { .schedule-week { grid-template-columns: repeat(6, 1fr); } }

.schedule-day {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-small);
  overflow: hidden;
  background: var(--color-surface-alt);
  background: color-mix(in srgb, var(--color-secondary) var(--tint, 8%), var(--color-surface));
}

.schedule-day-head {
  margin: 0;
  padding: 0.65rem 0.95rem;
  font-size: 1rem;
  line-height: 1.2;
  color: var(--color-heading);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface-muted);
  background: color-mix(in srgb, var(--color-secondary) var(--tint-head, 18%), var(--color-surface));
}

.schedule-day-list {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 0.7rem;
}

/* Sechs Abstufungen von hell nach kraeftig – Montag bis Samstag. */
.schedule-day--mo { --tint:  4%; --tint-head: 12%; }
.schedule-day--di { --tint:  7%; --tint-head: 18%; }
.schedule-day--mi { --tint: 10%; --tint-head: 24%; }
.schedule-day--do { --tint: 13%; --tint-head: 30%; }
.schedule-day--fr { --tint: 16%; --tint-head: 36%; }
.schedule-day--sa { --tint: 19%; --tint-head: 42%; }

/* Baender fuer Angebote ohne feste Spalte: taeglich bzw. alle zwei Wochen. */
.schedule-band {
  padding: 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-small);
  background: var(--color-surface-alt);
  background: color-mix(in srgb, var(--color-secondary) 6%, var(--color-surface));
}
.schedule-band-head {
  margin: 0 0 0.7rem;
  font-size: 1rem;
  line-height: 1.2;
  color: var(--color-heading);
}
.schedule-band-list { display: grid; gap: 0.7rem; }
@media (min-width: 620px) { .schedule-band-list { grid-template-columns: repeat(2, 1fr); } }

/* Kacheln im Stundenplan etwas kompakter als im uebrigen Kachelraster. */
.schedule .tile { padding: 0.9rem 1rem; }
.schedule .tile h4 { font-size: 1.02rem; }
.schedule .tile p { font-size: 0.9rem; }
.schedule .tile-badge { margin-bottom: 0.15rem; }

/* --------------------------------------------------------------------------
   SPRACHUMSCHALTER  (nur "Infos fuer junge Menschen", Logik: sprachen.js)
   --------------------------------------------------------------------------
   Die Leiste steht im HTML mit dem Attribut "hidden". Erst sprachen.js
   nimmt es weg – ohne JavaScript waeren die Knoepfe wirkungslos.

   Bei Arabisch setzt sprachen.js dir="rtl" auf <main>. Die Leiste selbst
   dreht dadurch automatisch mit, weil sie mit Flexbox und logischen
   Eigenschaften gebaut ist.
   -------------------------------------------------------------------------- */
.lang-bar {
  padding: 0.9rem 0;
  background: var(--color-surface-alt);
  border-bottom: 1px solid var(--color-border);
}
.lang-bar[hidden] { display: none; }

.lang-bar-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem 1rem;
}
.lang-bar-label {
  margin: 0;
  font-weight: 650;
  color: var(--color-heading);
}
.lang-buttons { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.lang-btn {
  padding: 0.35rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-link);
  font: inherit;
  font-size: 0.92rem;
  line-height: 1.4;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.lang-btn:hover { border-color: var(--color-accent); }
.lang-btn:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 2px; }
.lang-btn.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-white);
}

/* Eigene Zeile: der Hinweis gehoert unter die Knoepfe, nicht daneben. */
.lang-note {
  flex-basis: 100%;
  margin: 0;
  font-size: 0.85rem;
  color: var(--color-muted);
}

/* --------------------------------------------------------------------------
   BEREICHSFARBEN:  ambulant = Teal,  stationaer/Betreutes Wohnen = Blau
   --------------------------------------------------------------------------
   Nicht jede Regel einzeln umfaerben, sondern die Farb-Tokens fuer den
   ganzen Abschnitt neu belegen. Alles, was im Standard in Sekundaerblau
   erscheint, wird dadurch von selbst teal – Etikett, Kachelrand,
   "Mehr erfahren", die umrandeten Knoepfe und der Fokusrahmen. Vorher war
   nur der Rand und das Etikett teal, der Link darunter blieb blau.

   Die Ueberschriften bleiben bewusst im Navy von --color-heading: sie sind
   die neutrale Textfarbe der ganzen Seite, keine Akzentfarbe. Sollen sie
   im ambulanten Bereich ebenfalls teal werden, hier zusaetzlich
   --color-heading: var(--color-teal-ink); setzen.

   Der stationaere Bereich braucht keine eigene Regel: Sekundaerblau ist
   schon der Standard aus :root. Frueher standen hier .area--stationaer
   .tile und .tile-badge – die haben nur die Standardwerte wiederholt. */
.area--ambulant {
  --color-secondary: var(--color-teal);
  --color-secondary-dark: var(--color-teal-ink);
  --color-link: var(--color-teal-ink);
  /* Bewusst das dunkle Teal, nicht das helle: --color-accent zeichnet den
     Fokusrahmen fuer die Tastaturbedienung. Das helle #42B7AD kaeme auf
     weissem Grund nur auf 2,4:1 – zu wenig, der Rahmen waere fuer manche
     kaum zu sehen. WCAG verlangt 3:1, #1F7B74 liefert 5,1:1. */
  --color-accent: var(--color-teal-ink);
}

/* --------------------------------------------------------------------------
   HINWEISE ZU GELADENEN INHALTEN  (inhalte.js)
   --------------------------------------------------------------------------
   Wird verwendet fuer den Ladezustand der Teamtabelle, fuer Pflegehinweise
   ("Bereich vertippt") und fuer Fehlermeldungen ("Datei nicht erreichbar").
   Bewusst KEINE reine Farbcodierung: jede Variante ist auch am Text
   erkennbar (WCAG 1.4.1 – Information darf nicht allein ueber Farbe
   vermittelt werden). Die farbige Kante ist eine Zusatzinformation.
   -------------------------------------------------------------------------- */
.data-notice {
  margin: 0 0 1.25rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--color-border);
  border-inline-start: 4px solid var(--color-secondary);
  border-radius: var(--radius-small);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 0.95rem;
}
.data-notice[hidden] { display: none; }
.data-notice > :last-child { margin-bottom: 0; }
.data-notice--warn { border-inline-start-color: #B4791C; }
.data-notice--error { border-inline-start-color: #A6362B; }
/* Im Raster (leerer Bereich) soll der Hinweis die volle Breite nutzen und
   nicht als schmale Spalte neben nichts stehen. */
.grid > .data-notice { grid-column: 1 / -1; margin-bottom: 0; }

.legal {
  padding: clamp(1.5rem, 4vw, 2.75rem);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-large);
  background: var(--color-surface);
  box-shadow: var(--shadow);
  overflow-wrap: anywhere;
}
.legal h2 {
  margin-top: 2em;
  padding-top: 1.4em;
  border-top: 1px solid var(--color-border);
  font-size: 1.35rem;
}
.legal h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.legal > :last-child { margin-bottom: 0; }


/* --------------------------------------------------------------------------
   SEMANTISCHE FARBVARIANTEN
   -------------------------------------------------------------------------- */
/* Nur der Farbton wird gewechselt – Deckkraft, Glas und Rahmen kommen aus
   .card-tag. Bewusst die Grundfarben und NICHT die "-dark"-Varianten:
   siehe die Begruendung bei .card-tag. */
.card-tag--primary   { --card-tag-tint: var(--color-primary); }
.card-tag--secondary { --card-tag-tint: var(--color-secondary); }
.card-tag--success   { --card-tag-tint: var(--color-success); }

/* ==========================================================================
   16. FLOATING PLATZANZEIGE + KONTAKT-DIALOG
   ========================================================================== */
.vacancy-fab {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 90;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.75rem 1.3rem;
  border: none;
  border-radius: 999px;
  background: var(--color-primary);
  color: var(--color-white);
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(5, 42, 68, 0.4);
  /* visibility 0s = beim EINBLENDEN sofort sichtbar schalten, damit die
     Überblendung von Anfang an zu sehen ist. Beim Ausblenden wird sie unten
     verzögert, damit die Überblendung dort nicht abgeschnitten wird. */
  transition: transform 0.22s ease, box-shadow 0.15s ease, opacity 0.22s ease,
              visibility 0s;
}
.vacancy-fab:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(5, 42, 68, 0.5);
}

/* Zwei Zustaende, in denen der Button nicht sichtbar sein soll:
     is-tucked  – im Footer weggeklappt, damit "Nach oben" frei liegt
     is-pending – noch keine Platzdaten vorhanden (erster Besuch)
   Beide werden von script.js gesetzt (Abschnitt 4a). Die Regel muss NACH
   der :hover-Regel stehen, weil sie gleich stark gewichtet sind. */
.vacancy-fab.is-tucked,
.vacancy-fab.is-pending {
  opacity: 0;
  visibility: hidden;
  transform: translateY(150%);
  pointer-events: none;
  transition: transform 0.22s ease, opacity 0.22s ease, visibility 0s linear 0.22s;
}
@media (prefers-reduced-motion: reduce) {
  .vacancy-fab.is-tucked,
  .vacancy-fab.is-pending { transform: none; }
}
.vacancy-fab .vacancy-count {
  display: grid;
  place-items: center;
  min-width: 1.7rem;
  height: 1.7rem;
  padding-inline: 0.3rem;
  border-radius: 999px;
  background: var(--color-highlight);
  color: var(--color-primary-dark);
  font-weight: 800;
  animation: vacancy-pulse 2.4s ease-in-out infinite;
}
/* Zahl wird ausgeblendet, solange die Freiplatz-API noch keine Daten
   geliefert hat bzw. wenn keine Plätze frei sind (siehe script.js, 4a).
   Notwendig, weil die Regel oben "display: grid" setzt und damit das
   HTML-Attribut [hidden] überschreiben würde. */
.vacancy-fab .vacancy-count[hidden] { display: none; }
@keyframes vacancy-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(99, 179, 237, 0.45); }
  50%      { box-shadow: 0 0 0 7px rgba(99, 179, 237, 0); }
}

/* --------------------------------------------------------------------------
   DIALOGE – Groesse und Scrollverhalten
   --------------------------------------------------------------------------
   Die Hoehe steht zweimal da: Die erste Zeile ist der Rueckfallwert fuer
   aeltere Browser, die zweite gilt ueberall sonst.

   WARUM svh UND NICHT dvh – das war ein echter Fehler:
   Auf Mobilgeraeten aendert sich die sichtbare Fensterhoehe staendig, weil
   die Adressleiste beim Scrollen ein- und ausblendet. Dafuer gibt es drei
   Einheiten:

     lvh  "large"   – Hoehe OHNE Adressleiste (der groesste Wert)
     svh  "small"   – Hoehe MIT Adressleiste  (der kleinste Wert)
     dvh  "dynamic" – der aktuelle Wert, aendert sich also laufend
     vh   entspricht auf den meisten Mobilbrowsern lvh

   Mit dvh trat folgendes auf: Man scrollt, die Adressleiste verschwindet,
   dvh ist jetzt gross. Beim Oeffnen des Dialogs wird seine Hoehe aus diesem
   grossen Wert berechnet. Gleichzeitig sperrt body.dialog-open das
   Scrollen – woraufhin der Browser die Adressleiste wieder einblendet. Das
   sichtbare Fenster schrumpft, der Dialog behaelt aber seine eben
   berechnete Hoehe. Er ist damit hoeher als der Platz, wird oben an den
   Rand gedrueckt und unten abgeschnitten.

   svh rechnet immer mit dem KLEINSTEN Fenster, also so, als waere die
   Adressleiste sichtbar. Der Dialog passt dadurch in jedem Zustand – bei
   ausgeblendeter Leiste bleibt unten etwas Luft, was deutlich besser ist
   als ein abgeschnittener Dialog.

   Aus demselben Grund ist der Rueckfallwert von 88vh auf 80vh gesenkt: vh
   ist auf Mobilgeraeten der GROSSE Wert und hatte dasselbe Problem.

   Gescrollt wird nicht der Dialog selbst, sondern der innere Bereich
   .dialog-scroll (wird von script.js eingezogen). Nur so bleibt der
   Schliessen-Knopf beim Scrollen an seinem Platz.
   -------------------------------------------------------------------------- */
.site-dialog {
  position: relative;
  width: min(92vw, 500px);
  max-height: min(80vh, 860px);
  max-height: min(86svh, 860px);
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-large);
  padding: 0;
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow);
}
/* Nur im geoeffneten Zustand – sonst wuerde display:flex das display:none
   des Browsers fuer geschlossene Dialoge aushebeln. */
.site-dialog[open],
.info-modal[open] {
  display: flex;
  flex-direction: column;
}
.dialog-scroll {
  overflow: auto;
  overscroll-behavior: contain;
}
.site-dialog .dialog-scroll { padding: 1.75rem; }
.site-dialog::backdrop {
  background: rgba(5, 27, 43, 0.6);
  backdrop-filter: blur(2px);
}
.site-dialog h2 { padding-right: 2.5rem; font-size: 1.4rem; }
.site-dialog[open] { animation: modal-in 0.22s ease; }

.site-dialog-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--color-muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.site-dialog-close:hover { background: color-mix(in srgb, var(--color-secondary) 12%, transparent); color: var(--color-heading); }

/* --------------------------------------------------------------------------
   FREIPLATZ-AUSWAHL
   --------------------------------------------------------------------------
   Die Liste war frueher reine Anzeige, jetzt ist jeder Eintrag eine
   auswaehlbare Option (Radiogruppe, aufgebaut in script.js).
   Das fieldset bringt von Haus aus Rahmen und Innenabstand mit – beides
   weg, das Aussehen macht weiterhin das li. min-width: 0 verhindert, dass
   ein fieldset im Grid seine Spalte aufsprengt (alter Browserklassiker). */
.vacancy-choice {
  margin: 0 0 0.35rem;
  padding: 0;
  border: 0;
  min-width: 0;
}
.vacancy-choice[hidden] { display: none; }

.vacancy-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.4rem;
}
.vacancy-list li {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-small);
  font-size: 0.97rem;
  transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
}
/* li label statt nur label: schlaegt die allgemeine Regel .site-form label
   (display: grid), die sonst Text und Anzahl untereinander setzen wuerde.

   Das Polster sitzt hier und nicht am li, damit das Label die komplette
   Zeile ausfuellt – ohne Kreis zum Zielen muss jeder Punkt der Zeile
   klickbar sein, auch die Raender. */
.vacancy-list li label {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.72rem 0.95rem;
  font-size: inherit;
  font-weight: 700;
  color: var(--color-heading);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* KEIN Auswahlkreis – die ganze Zeile IST der Schalter und zeigt die
   Auswahl selbst an: farbiger Rahmen, eingefaerbter Grund und ein weicher
   Schein ringsum.

   Das Radio wird dafuer nur optisch entfernt, NICHT per display:none oder
   visibility:hidden. Beides wuerde es aus der Tastatur-Reihenfolge und aus
   der Screenreader-Ausgabe nehmen; die Gruppe waere dann gar nicht mehr
   bedienbar. Mit position:absolute + clip-path bleibt es ein vollwertiges
   Radio: Pfeiltasten wechseln weiterhin zwischen den Optionen, der
   Screenreader sagt "ausgewaehlt" an, das Formular liest den Wert aus.

   Eingepackt in @supports, weil die Anzeige der Auswahl komplett an
   :has() haengt. Kennt ein Browser :has() nicht, greift die Regel nicht –
   dann bleibt das native Radio als Anzeige sichtbar. Lieber ein
   schlichter Kreis als eine Auswahl, die man ueberhaupt nicht sieht. */
@supports selector(:has(*)) {
  .vacancy-list input[type="radio"] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
.vacancy-list .count {
  margin-inline-start: auto;
  font-weight: 800;
  color: var(--color-link);
  white-space: nowrap;
}
/* Ruecksicht auf die Maus: Beim Ueberfahren zeigt der Rahmen an, dass die
   ganze Zeile anklickbar ist – ohne Kreis fehlt sonst jeder Hinweis
   darauf, dass hier ueberhaupt etwas zu waehlen ist. */
.vacancy-list li:hover {
  border-color: color-mix(in srgb, var(--color-accent) 45%, var(--color-border));
}
/* Der "Leucht"-Zustand: kraeftiger Ring direkt am Rand plus ein weicher,
   farbiger Schein daruntergelegt. box-shadow statt dickerem Rahmen, damit
   die Zeile beim Auswaehlen nicht um zwei Pixel springt. */
.vacancy-list li:has(input:checked) {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-secondary) 10%, var(--color-surface-alt));
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--color-accent) 55%, transparent),
    0 6px 20px color-mix(in srgb, var(--color-accent) 22%, transparent);
}
.vacancy-list li:has(input:focus-visible) {
  outline: 3px solid var(--color-accent);
  outline-offset: 3px;
}

.site-form { display: grid; gap: 0.9rem; }
.site-form label {
  display: grid;
  gap: 0.3rem;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--color-heading);
}
.site-form input,
.site-form select,
.site-form textarea {
  font: inherit;
  padding: 0.65rem 0.9rem;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-small);
  background: var(--color-bg);
  color: var(--color-text);
}
.site-form textarea { resize: vertical; min-height: 90px; }
.site-form input:focus-visible,
.site-form select:focus-visible,
.site-form textarea:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 1px;
}
.form-hint { font-size: 0.85rem; color: var(--color-muted); margin: 0; }

/* --------------------------------------------------------------------------
   Dialoge auf dem Desktop breiter und zweispaltig
   --------------------------------------------------------------------------
   Ziel: Kontakt- und Platzanfrage-Formular passen ohne Scrollen in den
   Dialog. Ab 900 px Fensterbreite wird der Dialog breiter und die kurzen
   Felder stehen paarweise nebeneinander – das halbiert die Höhe.
   Auf kleineren Bildschirmen bleibt alles wie bisher einspaltig.
   -------------------------------------------------------------------------- */
@media (min-width: 900px) {
  /* 720px -> 840px: Bei zwei Spalten blieben fuer "Ihre Nachricht" nur rund
     300px netto – lange Anfragen liefen dort auf viele kurze Zeilen und man
     tippte wie durch ein Guckloch. 840px ist der Punkt, an dem das
     Textfeld ueber die volle Breite gut lesbar wird, ohne dass der Dialog
     auf 1280px-Notebooks den Bildschirm dominiert. */
  .site-dialog { width: min(92vw, 840px); }
  .site-dialog .dialog-scroll { padding: 2rem 2.25rem; }

  .site-dialog .site-form {
    grid-template-columns: 1fr 1fr;
    column-gap: 1.1rem;
  }

  /* Volle Breite: Name, Nachricht, Absende-Button und Hinweistexte
     (die Klasse "field--wide" wird in script.js gesetzt). */
  .site-dialog .site-form > .field--wide,
  .site-dialog .site-form > button,
  .site-dialog .site-form > .form-hint {
    grid-column: 1 / -1;
  }

  .site-dialog .site-form > button { justify-self: start; }
  /* Mit der groesseren Dialogbreite ist auch mehr Hoehe sinnvoll: Sonst
     steht ein sehr breites, sehr flaches Feld da, in dem man beim Tippen
     staendig scrollen muss. */
  .site-dialog .site-form textarea { min-height: 132px; }
}

/* Sehr flache Fenster (z. B. Notebooks im Querformat): Dialog darf scrollen,
   aber der Inhalt wird kompakter gesetzt. */
@media (min-width: 900px) and (max-height: 700px) {
  .site-dialog .dialog-scroll { padding: 1.5rem 2rem; }
  .site-dialog .site-form { gap: 0.7rem; }
  .site-dialog .site-form textarea { min-height: 80px; }
}

/* ==========================================================================
   17. BILDER-SLIDESHOW
   ========================================================================== */
.slideshow {
  position: relative;
  overflow: hidden;
  background: var(--color-placeholder-bg);
}

@media (min-width: 768px) {
  .card--wide .slideshow {
    width: 38%;
    flex-shrink: 0;
    align-self: stretch;
  }
}

.slideshow .slides {
  display: flex;
  height: 100%;
  transition: transform 0.5s ease;
}

.slideshow .slide {
  flex: 0 0 100%;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  display: block;
}
@media (min-width: 768px) {
  .card--wide .slideshow .slide {
    aspect-ratio: 3 / 2;
    height: auto;
  }
}

/* --------------------------------------------------------------------------
   z-index: 2 AN ALLEN BEDIENELEMENTEN – BITTE NICHT ENTFERNEN
   --------------------------------------------------------------------------
   .slideshow .slides traegt ein transform (das Weiterschieben). Ein
   transform erzeugt einen eigenen Stapelkontext: Der Bilderstreifen
   verhaelt sich damit wie ein positioniertes Element mit z-index 0 und
   liegt ueber allem, was im Dokument VOR ihm steht.

   Pfeile und Punkte stehen im HTML hinter dem Streifen und lagen deshalb
   zufaellig richtig. Der Lupenknopf wird von script.js eingehaengt – er
   war dadurch beim ersten Versuch komplett unsichtbar, obwohl er die
   richtige Groesse und Position hatte. Mit einem ausdruecklichen z-index
   haengt die Sichtbarkeit nicht mehr an der Reihenfolge im Dokument.
   -------------------------------------------------------------------------- */

/* 46 statt der fruehern 40 px. In einer .card--wide ist die Diashow nur
   38 % breit – dort waren die Pfeile im Verhaeltnis zum Bild sehr klein
   und auf einem Trackpad muehsam zu treffen. 46 px liegt zugleich ueber
   den 44 px, die als komfortable Zielgroesse gelten. */
.slide-btn {
  position: absolute;
  z-index: 2;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: none;
  border-radius: 50%;
  background: rgba(7, 24, 38, 0.55);
  color: var(--color-white);
  cursor: pointer;
  transition: background-color 0.2s ease;
}
.slide-btn:hover { background: rgba(7, 24, 38, 0.82); }
.slide-prev { left: 0.6rem; }
.slide-next { right: 0.6rem; }

/* Lupe oben rechts: oeffnet die Grossansicht und zeigt vor allem, dass
   es sie gibt. Aufgebaut von script.js – ohne JavaScript ist sie nicht
   da, weil sie dann nichts tun koennte. */
.slide-zoom {
  position: absolute;
  z-index: 2;
  top: 0.6rem;
  right: 0.6rem;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: rgba(7, 24, 38, 0.55);
  color: var(--color-white);
  cursor: zoom-in;
  transition: background-color 0.2s ease;
}
.slide-zoom:hover { background: rgba(7, 24, 38, 0.82); }

/* Die Klasse setzt script.js erst, wenn der Klick auch wirklich etwas
   oeffnet – ein zoom-in-Zeiger ohne Grossansicht waere ein leeres
   Versprechen. */
.slideshow.is-zoomable .slides { cursor: zoom-in; }

.slide-dots {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: 0.7rem;
  display: flex;
  justify-content: center;
  gap: 0.45rem;
}
.slide-dot {
  width: 10px;
  height: 10px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.55);
  cursor: pointer;
  transition: background-color 0.2s ease, transform 0.2s ease;
}
.slide-dot[aria-selected="true"] {
  background: var(--color-highlight);
  transform: scale(1.25);
}

/* Bei nur einem Bild und ohne JavaScript gibt es nichts zu blaettern.
   Die Lupe ist hier bewusst NICHT aufgefuehrt: Auch ein einzelnes Foto
   soll sich gross ansehen lassen. */
.slideshow.is-static .slide-btn,
.slideshow.is-static .slide-dots,
.no-js .slide-btn,
.no-js .slide-dots { display: none; }

/* ==========================================================================
   17b. GROSSANSICHT EINES BILDES (Lightbox)
   ==========================================================================
   Aufgebaut von script.js, Abschnitt 5. In der Diashow sind die Fotos auf
   3:2 beschnitten und in einer Standortkarte nur rund 38 % breit; hier
   werden sie so gross gezeigt, wie der Bildschirm es zulaesst.

   object-fit ist contain und NICHT cover wie in der Diashow: Dort geht es
   um eine ruhige, immer gleich hohe Bildflaeche, hier darum, das ganze
   Bild zu sehen. Ein Beschnitt waere genau das Gegenteil dessen, wofuer
   jemand das Bild anklickt.
   ========================================================================== */
.lightbox {
  width: min(96vw, 1100px);
  max-height: 92vh;
  max-height: 92svh;
  overflow: hidden;
  border: none;
  border-radius: var(--radius-large);
  padding: 0;
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-hover);
}
.lightbox[open] { display: flex; flex-direction: column; animation: modal-in 0.22s ease; }
@media (prefers-reduced-motion: reduce) {
  .lightbox[open] { animation: none; }
}
/* Dunkler als bei den Textdialogen (0.6): Ein Foto soll fuer sich
   stehen, die Seite dahinter darf ruhig verschwinden. */
.lightbox::backdrop {
  background: rgba(5, 27, 43, 0.84);
  backdrop-filter: blur(3px);
}
.lightbox-body { display: flex; flex-direction: column; min-height: 0; }
.lightbox-figure { display: flex; flex-direction: column; min-height: 0; margin: 0; }

/* Fester dunkler Grund, bewusst OHNE Hell-/Dunkelmodus-Wert. Auf dieser
   Flaeche liegt ein Foto, und Fotos aendern sich beim Umschalten nicht –
   dieselbe Ueberlegung wie beim Etikett auf einem Bild weiter oben.
   Passt ein Bild nicht genau ins Fenster, bleiben links und rechts (oder
   oben und unten) Streifen frei. Dunkel wirken sie wie der Rahmen eines
   Bildbetrachters; hell sahen sie nach einem Fehler aus. */
.lightbox-stage {
  position: relative;
  background: #0A1822;
}
.lightbox-image {
  display: block;
  width: 100%;
  /* Die abgezogenen 4.5rem sind die Bildunterschrift darunter (gemessen
     rund 3,1rem, der Rest ist Reserve fuer laengere, umbrechende Texte).
     Ohne diese Grenze fiele die Unterschrift bei einem hohen Foto aus
     dem Dialog. */
  max-height: calc(92svh - 4.5rem);
  object-fit: contain;
}
.lightbox-caption {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.9rem;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.85rem 1.15rem;
  font-size: 0.95rem;
  color: var(--color-muted);
}
.lightbox-counter { flex-shrink: 0; font-weight: 700; color: var(--color-heading); }

/* Der Schliessen-Knopf liegt hier auf dem Foto, nicht auf hellem Grund.
   Deshalb bekommt er dieselbe dunkle Scheibe wie die Pfeile – sonst
   waere er auf einem hellen Bild praktisch unsichtbar. */
.lightbox .site-dialog-close {
  z-index: 1;
  background: rgba(7, 24, 38, 0.55);
  color: var(--color-white);
}
.lightbox .site-dialog-close:hover {
  background: rgba(7, 24, 38, 0.82);
  color: var(--color-white);
}

/* ==========================================================================
   18. GOOGLE-MAPS MIT EINWILLIGUNG
   ========================================================================== */
.map-consent {
  position: relative;
  margin-bottom: 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-small);
  overflow: hidden;
  background: var(--color-placeholder-bg);
}

.map-consent-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  min-height: 200px;
  padding: 1.5rem 1.25rem;
  border: none;
  background:
    repeating-linear-gradient(45deg, transparent 0 12px, rgba(47, 137, 196, 0.06) 12px 24px),
    var(--color-placeholder-bg);
  color: var(--color-heading);
  font: inherit;
  text-align: center;
  cursor: pointer;
  transition: background-color 0.2s ease;
}
.map-consent-btn:hover { background: rgba(47, 137, 196, 0.12); }
.map-consent-btn svg { color: var(--color-accent); }

.map-consent-title { font-weight: 700; font-size: 1.05rem; }
.map-consent-hint {
  max-width: 34ch;
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--color-muted);
  line-height: 1.45;
}
.map-consent-hint a { position: relative; z-index: 1; }

.map-embed {
  width: 100%;
  height: 240px;
  border: none;
  border-radius: var(--radius-small);
  margin-bottom: 0;
  display: block;
}

/* ==========================================================================
   19. INFO-MODALS & KLICKBARE KACHELN
   ========================================================================== */
.tile--link {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
/* Angehoben wird unter dem Zeiger und beim Durchtabben.
   ------------------------------------------------------------------------
   Bewusst :focus-visible (Tastatur) statt :focus-within (jeder Fokus):
   Nach dem Schliessen des Popups holt script.js den Fokus zurueck auf den
   "Mehr erfahren"-Knopf – der steht IN der Kachel. Mit :focus-within blieb
   die Kachel danach angehoben, obwohl der Zeiger laengst woanders war. Bei
   einem Klick mit der Maus setzt der Browser :focus-visible nicht, bei Esc
   oder Enter schon – die Tastaturbedienung behaelt ihre Rueckmeldung. */
.tile--link:hover,
.tile--link:has(.tile-more:focus-visible) {
  transform: translateY(-4px);
  box-shadow: var(--shadow);
}

/* max-width und flex-wrap sind noetig, weil das Etikett auch in Kacheln
   steht, die KEIN Flex-Container sind (dort greift align-self nicht).
   Ohne die beiden Angaben laufen lange Etiketten wie
   "Vormittags · Sozialraum Mitte" ueber den Kachelrand hinaus. */
.tile-badge {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  flex-wrap: wrap;
  max-width: 100%;
  gap: 0.4rem;
  margin: 0 0 0.35rem;
  padding: 0.2rem 0.65rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-secondary) 13%, transparent);
  color: var(--color-secondary-dark);
  font-size: 0.78rem;
  font-weight: 800;
  line-height: 1.5;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.tile-more {
  margin-top: auto;
  padding: 0;
  padding-top: 0.5rem;
  border: none;
  background: none;
  color: var(--color-link);
  font: inherit;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}
.tile-more::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
.tile--link:has(.tile-more:focus-visible) {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}
.tile-more:focus { outline: none; }
@supports not (selector(:has(*))) {
  .tile-more:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 2px; }
}

.more-btn { margin-top: 0.25rem; }

/* Die Leistungsbloecke auf hilfsangebote.html ("Betreutes Wohnen –
   Regulaer", "Sozialpaedagogische Familienhilfe" ...). Sie sehen aus wie
   Karten, tragen aber nicht die Klasse .card – deshalb bekommen sie
   dieselbe Rueckmeldung beim Anfahren hier ausdruecklich mit. Die
   gemeinsame :hover-Regel steht in Abschnitt 7 bei den Karten.

   Anheben waere hier falsch: Anklickbar ist nur der Knopf
   "Alle Schwerpunkte ansehen", nicht der ganze Block. */
.service-block {
  --card-accent: var(--color-teal);
  display: flex;
  flex-direction: column;
  padding: 1.65rem 1.75rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-top: 4px solid var(--card-accent);
  border-radius: var(--radius-large);
  box-shadow: var(--shadow);
  transition: box-shadow 0.22s ease, border-color 0.22s ease, background-color 0.3s ease;
}
.service-block .more-btn { margin-top: auto; }
/* Nur die Akzentfarbe umstellen – Oberkante, Rahmen und Einfaerbung
   ziehen dadurch gemeinsam mit. */
.area--stationaer .service-block { --card-accent: var(--color-secondary); }

/* svh statt dvh, aus demselben Grund wie bei .site-dialog – die
   ausfuehrliche Begruendung steht dort im Abschnitt "DIALOGE". */
.info-modal {
  width: min(92vw, 660px);
  max-height: min(80vh, 900px);
  max-height: min(86svh, 900px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-large);
  padding: 0;
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.info-modal::backdrop {
  background: rgba(5, 27, 43, 0.6);
  backdrop-filter: blur(2px);
}
.info-modal[open] { animation: modal-in 0.22s ease; }
@keyframes modal-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .info-modal[open] { animation: none; }
}

/* Bild im Kopf eines Info-Dialogs.
   FESTES SEITENVERHAELTNIS 16:9 fuer ALLE Dialogbilder – unabhaengig davon,
   welches Format die hochgeladene Datei mitbringt. object-fit: cover
   beschneidet mittig. Damit sehen alle Angebotsfotos gleich aus.
   Empfohlene Dateigroesse: 1200 x 675 px (siehe photos/angebote/bw/).

   Standardmaessig ausgeblendet: Erst wenn das Bild wirklich geladen ist,
   setzt script.js die Klasse .is-loaded. Sonst reserviert der Browser beim
   Oeffnen des Dialogs die 16:9-Flaeche fuer ein Bild, das es (noch) gar
   nicht gibt – der Dialog geht gross auf und schrumpft danach sichtbar. */
.info-modal-media {
  display: none;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--color-placeholder-bg);
}
.info-modal-media.is-loaded { display: block; }
/* Ohne JavaScript kann niemand .is-loaded setzen – dann normal anzeigen. */
html:not(.js) .info-modal-media { display: block; }

.info-modal-body { padding: 1.5rem 1.75rem 1.75rem; }
.info-modal-body h3 { font-size: 1.4rem; margin-top: 0.15rem; }
.info-modal-body h4 { font-size: 1.02rem; margin-top: 1.25em; }
.info-modal-body > :last-child { margin-bottom: 0; }
.info-modal-body .tile-badge { margin-bottom: 0.6rem; }

.info-modal-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  z-index: 1;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--shadow);
}
.info-modal-close:hover { background: color-mix(in srgb, var(--color-secondary) 12%, transparent); color: var(--color-heading); }

html:not(.js) [data-modal-target],
html:not(.js) .info-modal-close { display: none; }
html:not(.js) .info-modal {
  display: block;
  position: static;
  width: auto;
  max-height: none;
  margin: 1rem 0;
  overflow: visible;
}

/* ==========================================================================
   20. ZIELGRUPPEN-EINSTIEG
   ========================================================================== */
.audience-grid { display: grid; gap: 1.5rem; }
@media (min-width: 768px) { .audience-grid { grid-template-columns: repeat(3, 1fr); } }

.card--audience {
  --audience-color: var(--color-secondary);
  --audience-ink: var(--color-secondary-dark);
  /* Die Einfaerbung beim Anfahren soll die Farbe der Karte aufnehmen,
     nicht das globale Blau: "Fuer Eltern & Familien" ist teal, "Fuer
     junge Menschen" hell. Die Modifier unten setzen nur
     --audience-color; --card-accent zeigt darauf und zieht automatisch
     mit. Siehe Abschnitt 7, "HOVER". */
  --card-accent: var(--audience-color);
  padding: 1.9rem 1.65rem;
  border-top: 4px solid var(--audience-color);
  text-align: left;
}
.card--audience p { color: var(--color-muted); }
.card--audience .btn { align-self: flex-start; margin-top: auto; }
.card--audience.audience--youth {
  --audience-color: var(--color-highlight);
  --audience-ink: var(--color-secondary-dark);
}
.card--audience.audience--family {
  --audience-color: var(--color-teal);
  --audience-ink: var(--color-teal-ink);
}
.card--audience.audience--professional {
  --audience-color: var(--color-primary);
  --audience-ink: var(--color-primary);
}
/* --color-primary ist absichtlich ohne eigenen Dunkelmodus-Wert (siehe
   :root) – als Randfarbe auf hellem Kartengrund ist das dunkle Navy
   genau richtig. Im Dunkelmodus liegt dieselbe Karte aber auf dunklem
   Grund: Navy auf Navy kam dort nur auf ca. 1,9:1 Kontrast – Icon UND
   der umrandete Knopf "Leistungen ansehen" waren praktisch unlesbar.
   --color-highlight ist im Stylesheet bereits der etablierte
   Dunkelmodus-Ersatz fuer dunkle Navy-Akzente auf dunklem Grund (siehe
   .hero--split .eyebrow--hero) – hier aus demselben Grund wiederverwendet
   statt eine weitere Farbe einzufuehren. */
:root[data-theme="dark"] .card--audience.audience--professional {
  --audience-color: var(--color-highlight);
  --audience-ink: var(--color-highlight);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .card--audience.audience--professional {
    --audience-color: var(--color-highlight);
    --audience-ink: var(--color-highlight);
  }
}
.audience-icon {
  display: grid;
  place-items: center;
  width: 60px;
  height: 60px;
  margin-bottom: 1.1rem;
  border-radius: var(--radius-small);
  background: color-mix(in srgb, var(--audience-color) 14%, transparent);
  color: var(--audience-ink);
}
.card--audience .btn--secondary { color: var(--audience-ink); border-color: currentColor; }
.card--audience .btn--secondary:hover { background: color-mix(in srgb, var(--audience-color) 13%, transparent); }

/* ==========================================================================
   21. JUGEND-BANNER
   ========================================================================== */
.youth-banner {
  position: relative;
  overflow: hidden;
  margin: var(--panel-gap);
  padding-block: clamp(3.25rem, 7vw, 5.25rem);
  border-radius: var(--radius-large);
  background:
    radial-gradient(ellipse 45% 90% at 100% 100%, rgba(66, 183, 173, 0.17), transparent 62%),
    linear-gradient(135deg, var(--color-surface-warm), var(--color-surface-teal));
}
.youth-banner .split { align-items: center; }
.youth-banner h2 { font-size: clamp(1.9rem, 4.5vw, 2.85rem); }
.youth-art { width: min(100%, 420px); margin-inline: auto; }
.youth-art img,
.youth-art svg { width: 100%; height: auto; }


/* --------------------------------------------------------------------------
   22. KLEINE BILDSCHIRME UND FEINSCHLIFF
   -------------------------------------------------------------------------- */
@media (max-width: 520px) {
  .vacancy-fab {
    right: 0.75rem;
    bottom: 0.75rem;
    max-width: calc(100vw - 1.5rem);
    padding-inline: 1rem;
    font-size: 0.92rem;
  }
  .site-dialog .dialog-scroll { padding: 1.35rem; }
  .footer-bottom { align-items: flex-start; }
}

/* ==========================================================================
   22. QR-CODE-SEITE (qrcode.html)
   ==========================================================================
   Interne Hilfsseite: Name eintragen, QR-Code zum Einrichten des
   dienstlichen Postfachs bekommen. Steht bewusst in keiner Navigation
   und traegt noindex.
   ========================================================================== */
.qr-layout { display: grid; gap: 1.5rem; }
@media (min-width: 900px) {
  .qr-layout { grid-template-columns: 1fr 1fr; align-items: start; }
}

.qr-form { display: grid; gap: 1rem; margin: 1.25rem 0 0; }
.qr-form label {
  display: grid;
  gap: 0.35rem;
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--color-heading);
}
.qr-form input {
  width: 100%;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-small);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-weight: 400;
}
.qr-form input:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 1px;
}

/* Kontrollanzeige: zeigt, was tatsaechlich im Code landet. Wichtig, weil
   aus "Krueger" die Adresse "krueger" wird - das soll man vor dem Scannen
   sehen koennen. */
.qr-werte {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.35rem 1rem;
  margin: 1.35rem 0 0;
}
.qr-werte dt {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--color-muted);
  font-size: 0.9rem;
}
.qr-werte dd { margin: 0; }
/* Feste Schriftbreite: Bei einer Adresse zaehlt jedes Zeichen, und in
   einer Proportionalschrift sind l, I und 1 kaum zu unterscheiden. */
.qr-wert {
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.95rem;
  word-break: break-all;
  color: var(--color-heading);
}

/* Adresse und Absendername sind Eingabefelder, weil das Namensschema nicht
   immer passt: Funktionspostfaecher (praxis@) haben gar keinen Vor- und
   Nachnamen. Sie sollen aber weiter wie eine Anzeige wirken und nicht wie ein
   zweites Formular: gleiche Schrift, gleiche Groesse, kein Kasten, kein
   Innenabstand. Nur die gestrichelte Linie deutet an, dass man
   hineinschreiben kann. */
input.qr-wert {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  border-bottom: 1px dashed var(--color-border);
  border-radius: 0;
  background: transparent;
  line-height: inherit;
  /* Firefox legt um ein type="email"-Feld mit unfertiger Eingabe von sich
     aus einen roten Schein. Beim Tippen ist die Adresse zwangslaeufig
     unfertig - das waere ein Fehler, wo keiner ist. */
  box-shadow: none;
}
input.qr-wert:hover { border-bottom-color: var(--color-accent); }
input.qr-wert:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}
/* Von Hand geaendert: durchgezogene Linie. So ist auf einen Blick zu sehen,
   dass die Adresse nicht mehr aus dem Namen kommt. */
input.qr-wert.is-manuell { border-bottom-style: solid; }

.qr-werte-hinweis {
  margin: 0.55rem 0 0;
  font-size: 0.82rem;
  color: var(--color-muted);
}

.qr-buehne {
  display: grid;
  place-items: center;
  min-height: 260px;
  margin: 1.25rem 0 0;
  padding: 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-small);
  /* Immer heller Grund, auch im Dunkelmodus: Der QR-Code ist schwarz auf
     weiss gezeichnet und braucht seinen hellen Rand, sonst finden viele
     Lesegeraete ihn nicht. */
  background: #FFFFFF;
}
.qr-buehne canvas {
  display: block;
  width: 100%;
  max-width: 300px;
  height: auto;
  /* Keine Weichzeichnung beim Skalieren - ein verwaschener QR-Code
     laesst sich schlechter lesen. */
  image-rendering: pixelated;
}
.qr-leer { margin: 0; color: #6B7A88; font-size: 0.95rem; text-align: center; }

.qr-fussnote { margin: 1rem 0 0; font-size: 0.88rem; color: var(--color-muted); }
