/* Header & Navigation ------------------------------------------------------ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(11, 11, 11, 0.92);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--ink-line);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: 0.85rem;
}
.logo-link {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink-text);
  text-decoration: none;
}
/* Logo-Motiv liegt zentriert auf einer quadratischen, groesstenteils
   transparenten 2160x2160-Zeichenflaeche (Ring+Schriftzug fuellen nur
   ~73% Breite / ~43% Hoehe). .logo-mark schneidet per overflow:hidden
   den transparenten Rand weg: das <img> wird ueber die Containergroesse
   hinaus vergroessert und zentriert, sodass nur das Motiv sichtbar bleibt -
   die SVG-Datei selbst bleibt unveraendert. */
.logo-mark {
  position: relative;
  overflow: hidden;
  width: 62px;
  height: 40px;
}
.logo-mark img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 78px;
  height: 78px;
  max-width: none;
  transform: translate(-50%, -50%);
}
@media (min-width: 1024px) {
  .logo-mark { width: 71px; height: 46px; }
  .logo-mark img { width: 90px; height: 90px; }
}

.nav-toggle {
  display: none;
  background: none;
  border: 0;
  padding: 0.5rem;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  margin: 4px 0;
  background: var(--ink-text);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav-item { position: relative; }
.nav-links a {
  color: var(--ink-text);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: 500;
}
.nav-links a:hover { color: var(--brand-400); }

.nav-dropdown {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 560px;
  padding: var(--space-3);
  background: var(--ink-800);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius-md);
  gap: var(--space-3);
  grid-template-columns: repeat(3, 1fr);
}
.nav-item:hover .nav-dropdown,
.nav-item:focus-within .nav-dropdown { display: grid; }
.nav-dropdown-group h4 {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--brand-400);
  margin: 0 0 0.5em;
}
.nav-dropdown-group ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4em; }
.nav-dropdown-group a { font-size: var(--text-sm); }

.nav-cta {
  /* brand-600 statt brand-500 als Grundzustand: weisser Text auf brand-500
     misst nur 3,54:1 Kontrast (unter WCAG-AA 4,5:1), auf brand-600 5,07:1. */
  background: var(--brand-600);
  color: #fff !important;
  padding: 0.55em 1.1em;
  border-radius: var(--radius-sm);
}
.nav-cta:hover { background: var(--brand-500); color: #fff !important; }

@media (max-width: 1023px) {
  .nav-toggle { display: block; }
  .nav-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    background: var(--ink-900);
    border-bottom: 1px solid var(--ink-line);
    padding: var(--space-2) var(--container-padding) var(--space-3);
  }
  .nav-links.is-open { display: flex; }
  .nav-links a { padding: 0.6em 0; border-bottom: 1px solid var(--ink-line); }
  .nav-dropdown {
    position: static;
    display: none;
    min-width: 0;
    grid-template-columns: 1fr;
    border: 0;
    background: transparent;
    padding: 0 0 0.5em 1em;
  }
  .nav-item.is-open .nav-dropdown { display: grid; }
  .nav-cta { text-align: center; margin-top: 0.5em; border-bottom: none !important; }
}

/* Buttons ------------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.8em 1.4em;
  border-radius: var(--radius-sm);
  font-weight: 600;
  font-size: var(--text-sm);
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
/* brand-600 als Grundzustand (5,07:1 Kontrast fuer weissen Text), brand-500
   (das tatsaechliche Logo-Gruen) als hellerer Hover-Zustand. Behebt den
   WCAG-AA-Kontrastfehler von brand-500 als Flaechenfarbe (3,54:1), ohne eine
   neue Farbe einzufuehren. */
.btn-primary { background: var(--brand-600); color: #fff; }
.btn-primary:hover { background: var(--brand-500); }
.btn-ghost { background: transparent; border-color: currentColor; color: inherit; }
.btn-ghost:hover { background: rgba(74, 154, 31, 0.08); border-color: var(--brand-500); }

/* Cards ---------------------------------------------------------------------*/
.card {
  background: var(--paper-000);
  border: 1px solid var(--paper-line);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  box-shadow: var(--shadow-card);
}
.card--dark {
  background: var(--ink-800);
  border-color: var(--ink-line);
  color: var(--ink-text);
}
.card-media {
  margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1) var(--space-3);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  overflow: hidden;
}
.card-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  display: block;
  transition: transform 0.3s ease;
}
.card:hover .card-media img { transform: scale(1.03); }

/* Icon-Badge fuer Karten (Beauftragungsmodelle, Leistungscluster) ----------- */
.icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-sm);
  background: rgba(74, 154, 31, 0.1);
  color: var(--brand-600);
  margin-bottom: var(--space-2);
}
.icon-badge svg { width: 24px; height: 24px; }
:where(.dark-section) .icon-badge,
.card--dark .icon-badge {
  background: rgba(143, 201, 58, 0.16);
  color: var(--brand-400);
}

/* Breadcrumbs ---------------------------------------------------------------*/
.breadcrumbs {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--paper-text-muted);
  margin-bottom: var(--space-3);
}
.breadcrumbs a { color: inherit; text-decoration: none; }
.breadcrumbs a:hover { color: var(--brand-600); }
.breadcrumbs .sep { margin-inline: 0.4em; opacity: 0.5; }

/* Hero -----------------------------------------------------------------------
   .hero-media ist die Bildflaeche hinter dem Text. Solange kein Bild darin
   liegt, zeigt sie als Fallback ein technisches Platzhaltermuster (Raster +
   sanftes Markengruen-Glimmen) statt eines erfundenen Fotos (via
   background-* auf .hero-media selbst). Liegt ein <img> vor (aktuell: eine
   klar als KI-Visualisierung gekennzeichnete Atmosphaeren-Aufnahme, KEIN
   echtes Referenzprojekt), deckt es das Platzhaltermuster ab; das
   ::after-Overlay sorgt in beiden Faellen fuer Textlesbarkeit. ------------ */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-6);
  color: var(--ink-text);
}
@media (min-width: 1024px) {
  .hero { padding-block: var(--space-7); min-height: 640px; display: flex; align-items: center; }
}
/* Kompaktere Variante fuer Unterseiten (z. B. Leistungsseiten-Hero via
   layouts/leistung.njk) - gleiche Bild+Overlay-Mechanik wie der Startseiten-
   Hero, aber ohne dessen grosse Landingpage-Hoehe. */
@media (min-width: 1024px) {
  .hero--compact { padding-block: var(--space-6); min-height: 420px; }
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-color: var(--ink-900);
  background-image:
    radial-gradient(ellipse 60% 55% at 25% 20%, rgba(143, 201, 58, 0.16), transparent 65%),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.045) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.045) 0 1px, transparent 1px 56px);
}
.hero-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
}
@media (max-width: 767px) {
  .hero-media img { object-position: center 30%; }
}
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, rgba(11, 11, 11, 0.94) 0%, rgba(11, 11, 11, 0.82) 45%, rgba(11, 11, 11, 0.6) 100%);
}
.hero-content { position: relative; z-index: 1; width: 100%; }

/* Optionaler, seitenbezogener Hero-Zoom-out (heroImageScale in layouts/leistung.njk) --------
   Bei object-fit:cover ist der sichtbare Bildausschnitt allein durch das Seitenverhaeltnis von
   Hero-Flaeche zu Bild bestimmt; object-position kann nur verschieben, nicht mehr vom Motiv
   zeigen. Um auf einer einzelnen Seite wirklich mehr Bildinhalt sichtbar zu machen, wird das
   Vordergrundbild (.hero-media-fg) schmaler als die volle Hero-Breite dargestellt - dadurch
   sinkt die Cover-Skalierung und mehr Bildhoehe wird sichtbar. Die dadurch seitlich entstehenden
   Raender werden mit demselben, staerker geblurrten/abgedunkelten Bild (.hero-media-bg) gefuellt,
   kein Leerraum. Nur ab 1024px aktiv, da der Hero darunter eine andere, inhaltsgetriebene
   Geometrie hat. Rein additiv (neue Klassen), betrifft ausschliesslich Seiten, die
   heroImageScale setzen - alle anderen Hero-Bilder nutzen weiterhin unveraendert die Basisregeln
   oben. ------------------------------------------------------------------------------------- */
.hero-media-bg { display: none; }
@media (min-width: 1024px) {
  .hero-media--scaled .hero-media-bg {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: blur(28px) brightness(0.55);
    transform: scale(1.1);
  }
  .hero-media--scaled .hero-media-fg {
    position: absolute;
    top: 0;
    left: 50%;
    right: auto;
    bottom: auto;
    width: var(--hero-image-scale, 100%);
    height: 100%;
    transform: translateX(-50%);
    object-fit: cover;
  }
}

/* Optionale, seitenbezogene Mobile-Bildposition (heroImagePositionMobile in
   layouts/leistung.njk): auf schmalen Viewports ist die Hero-Flaeche meist
   hochkant/quadratisch, waehrend das Foto breit (Panorama) ist - object-fit:
   cover schneidet dann per Definition einen Grossteil der Breite weg. Manche
   Motive brauchen deshalb auf Mobile einen anderen Ausschnitt als auf Desktop.
   Nur unter 768px aktiv und nur mit gesetzter CSS-Variable - Seiten ohne
   heroImagePositionMobile nutzen weiterhin unveraendert die globale
   Mobile-Regel oben (.hero-media img { object-position: center 30%; }). ---- */
@media (max-width: 767px) {
  .hero-media--mobile-pos .hero-media-fg {
    object-position: var(--hero-image-position-mobile);
  }
}

/* Leistungsseiten -------------------------------------------------------------
   Der optionale Bild-Slot (layouts/leistung.njk, Felder heroImage/heroImageAlt/
   heroImageIsAi) rendert bei gesetztem heroImage einen kompakten Hero
   (.hero.hero--compact, gleiche Bild+Overlay+Kennzeichnung-Mechanik wie die
   Startseite) mit H1/Intro auf dem Bild. Ohne heroImage entfaellt der Hero
   komplett (siehe Layout), kein leerer Platzhalter.
   .leistung-intro/.leistung-intro-text/.leistung-media sind das
   wiederverwendbare Text+Medienblock-Muster fuer einzelne Inhaltsabschnitte
   im Seitentext (z. B. "Neubau, Umbau und Modernisierung", "Zaehleranlagen")
   - Text und Bild bzw. Platzhalter (.leistung-media--placeholder, solange
   noch kein passendes Bild vorliegt) nebeneinander statt als eigener Hero.
   .leistung-content begrenzt lange Fliesstexte (Absaetze/Listen/Ueberschriften
   als direkte Kinder) auf eine lesbare Breite; strukturierte Bloecke wie
   .grid-Karten, .card und .leistung-intro sind KEINE dieser Elemente und
   bleiben automatisch auf voller Containerbreite. -------------------------- */
.leistung-intro {
  display: grid;
  gap: var(--space-3);
  align-items: center;
}
.leistung-intro-text { max-width: 42rem; }
@media (min-width: 768px) {
  .leistung-intro {
    grid-template-columns: 3fr 2fr;
    gap: var(--space-5);
  }
  .leistung-intro-text { max-width: none; }
}
/* Modifier fuer Abschnitte, die einen ausgewogeneren Text/Bild-Split (statt
   60/40) brauchen (z. B. "Zaehleranlagen" auf /leistungen/elektroinstallation/)
   - additiv, aendert nicht die Basis-.leistung-intro, die andere Abschnitte
   weiter im urspruenglichen 60/40-Verhaeltnis nutzen. Vertikale Ausrichtung
   (align-items: center) kommt unveraendert von der Basisklasse. */
@media (min-width: 768px) {
  .leistung-intro--balanced { grid-template-columns: 11fr 9fr; }
}
.leistung-media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  background: var(--ink-900);
}
.leistung-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 25% 45%;
  display: block;
}
/* Neutraler Platzhalter fuer noch nicht vorhandene Bilder - dasselbe
   technische Muster (Raster + dezentes Markengruen-Glimmen) wie der
   Hero-/CTA-Bildflaechen-Fallback ohne Foto, plus kleines Textlabel, damit
   der Block eindeutig als bewusster Platzhalter erkennbar ist und nicht wie
   ein fehlendes Bild wirkt. */
.leistung-media--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-3);
  background-image:
    radial-gradient(ellipse 60% 60% at 30% 30%, rgba(143, 201, 58, 0.14), transparent 65%),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.045) 0 1px, transparent 1px 40px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.045) 0 1px, transparent 1px 40px);
}
.leistung-media-placeholder-label {
  position: relative;
  z-index: 1;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
  color: rgba(234, 243, 237, 0.55);
}
/* In vollflaechigen .hero-media/.cta-media-Kontexten (Hero, Abschluss-CTA)
   wuerde eine zentrierte Positionierung mit H1 bzw. Headline kollidieren -
   dort daher als kleiner Hinweis oben rechts statt mittig. */
.hero-media > .leistung-media-placeholder-label,
.cta-media > .leistung-media-placeholder-label {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
}
.leistung-content > p,
.leistung-content > ul,
.leistung-content > ol,
.leistung-content > blockquote,
.leistung-content > h2,
.leistung-content > h3 {
  max-width: 42rem;
}

/* Dezente, aber eindeutige KI-Kennzeichnung von KI-generierten Bildern
   (Startseiten-Hero, optionale Leistungsseiten-Bilder). Bewusst immer
   sichtbar (keine display:none-Media-Query, keine Animation), damit sie auf
   keiner Bildschirmgroesse verschwindet - aber als kleine Herkunftsangabe am
   Bildrand, nicht als eigenes Designelement. Zentral hier gepflegt, damit
   jedes KI-Bild auf der Website automatisch dieselbe, konsistente
   Kennzeichnung erhaelt. */
.hero-ai-label {
  position: absolute;
  right: var(--space-1);
  bottom: calc(var(--space-1) / 2);
  z-index: 2;
  font-family: var(--font-mono);
  font-size: 0.4375rem;
  letter-spacing: 0.02em;
  line-height: 1;
  color: rgba(234, 243, 237, 0.75);
  background: rgba(11, 11, 11, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.14);
  padding: 0.25em 0.45em;
  border-radius: calc(var(--radius-sm) / 2);
  backdrop-filter: blur(2px);
}

/* CTA-Bereich ---------------------------------------------------------------*/
.cta-band {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--ink-900);
  color: var(--ink-text);
}

/* Abschluss-CTA mit Bildflaeche (gleiches Platzhalter-Prinzip wie .hero) ---
   .cta-media zeigt ohne <img> weiterhin nur das Platzhaltermuster (Startseite,
   noch kein Foto verfuegbar). Optionale Leistungsseiten (Feld ctaImage in
   layouts/leistung.njk) legen ein <img> hinein, das dieselbe Overlay-Mechanik
   fuer Textlesbarkeit nutzt wie .hero-media. -------------------------------- */
.cta-final { position: relative; overflow: hidden; }
/* Nur der grosse Startseiten-CTA (.cta-final .cta-band): Text und Button
   ruecken mit festem Gap zusammen statt per justify-content:space-between
   maximal auseinandergedrueckt zu werden. Bewusst auf .cta-final gescoped,
   damit die kleinen .cta-band-CTAs auf Leistungs-/Projektseiten unveraendert
   bleiben (dort greift weiterhin nur die allgemeine .cta-band-Regel oben). */
.cta-final .cta-band {
  background: transparent;
  padding: 0;
  justify-content: flex-start;
  gap: var(--space-5);
}
/* Optionaler, seitenbezogener kompakterer Abstand zwischen Headline und
   Button (ctaCompact: true in Frontmatter, siehe layouts/leistung.njk) -
   additiver Modifier auf .cta-band, ruehrt den Standard-Gap oben (var(--space-5),
   von allen anderen Foto-CTAs genutzt) nicht an. Ohne ctaCompact bleibt jeder
   Standard-CTA unveraendert. */
@media (min-width: 768px) {
  .cta-final .cta-band--compact { gap: var(--space-4); }
}
.cta-final-text { max-width: 30rem; }
@media (min-width: 768px) {
  .cta-final { padding-block: 3.75rem; }
}
/* Variante mit Bildhintergrund (ctaImage, siehe layouts/leistung.njk): etwas
   mehr Hoehe als der Platzhalter-CTA der Startseite, damit das Foto als
   eigener Abschlussbereich wirkt statt als schmaler Streifen. Headline und
   Button bleiben im selben .container/.cta-band vertikal zentriert
   zueinander - nur zusaetzlich gescoped, damit die Startseiten-CTA (noch
   ohne Foto) unveraendert bleibt. */
.cta-final--photo .cta-band { align-items: center; }
@media (min-width: 768px) {
  .cta-final--photo { padding-block: var(--space-6); }
}
.cta-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-color: var(--ink-900);
  background-image:
    radial-gradient(ellipse 50% 80% at 80% 50%, rgba(143, 201, 58, 0.14), transparent 65%),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 56px);
}
.cta-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 40%;
}
.cta-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(11, 11, 11, 0.93) 0%, rgba(11, 11, 11, 0.75) 55%, rgba(11, 11, 11, 0.5) 100%);
}
.cta-final .container { position: relative; z-index: 1; }

/* Optionaler, seitenbezogener CTA-Bild-Zoom-out (ctaImageScale in
   layouts/leistung.njk) - .cta-media ist sehr breit/flach (Standard-CTA),
   object-fit:cover ist dadurch breitengetrieben (volle Bildbreite sichtbar,
   nur ein schmaler Hoehenstreifen). Exakt dieselbe additive Technik wie beim
   Hero-Zoom-out (.hero-media--scaled oben): das Vordergrundbild wird schmaler
   als die volle CTA-Breite dargestellt, wodurch die Cover-Skalierung sinkt
   und mehr Bildhoehe sichtbar wird; die seitlich entstehenden Raender werden
   mit demselben, geblurrten/abgedunkelten Bild gefuellt. Nur ab 1024px aktiv
   (gleiche Grenze wie beim Hero). Rein additiv (neue Klassen), betrifft
   ausschliesslich Seiten, die ctaImageScale setzen - alle anderen
   Standard-CTA-Bilder nutzen weiterhin unveraendert die Basisregeln oben. -- */
.cta-media-bg { display: none; }
@media (min-width: 1024px) {
  .cta-media--scaled .cta-media-bg {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: blur(28px) brightness(0.5);
    transform: scale(1.1);
  }
  .cta-media--scaled .cta-media-fg {
    position: absolute;
    top: 0;
    left: 50%;
    right: auto;
    bottom: auto;
    width: var(--cta-image-scale, 100%);
    height: 100%;
    transform: translateX(-50%);
    object-fit: cover;
  }
}

/* Optionale CTA-Variante "feature" (ctaVariant: "feature" in Frontmatter) ---
   Bewusst eigenstaendiger, ausfuehrlicherer Abschluss-CTA fuer einzelne
   Leistungsseiten zum Testen (aktuell nur Waermepumpenanschluss) - komplett
   additiv (eigene .cta-feature-* Klassen), ruehrt die bestehenden .cta-final/
   .cta-band-Regeln oben nicht an. Seiten ohne ctaVariant: "feature" bleiben
   unveraendert beim bisherigen Standard-CTA (siehe layouts/leistung.njk).
   Als rundes, dunkles Card-Element INNERHALB des normalen .container/.section
   platziert (nicht vollflaechig wie .cta-final), damit es als eigener,
   hochwertiger Abschlussblock auf dem hellen Seitenhintergrund wirkt. ------ */
.cta-feature {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--ink-900);
  color: var(--ink-text);
}
@media (min-width: 768px) {
  .cta-feature { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); min-height: 320px; }
}
.cta-feature-media {
  position: relative;
  min-width: 0;
  min-height: 220px;
  background-color: var(--ink-900);
  background-image:
    radial-gradient(ellipse 50% 80% at 30% 40%, rgba(143, 201, 58, 0.14), transparent 65%),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 56px);
}
.cta-feature-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* Weicher Uebergang statt harter Kante zwischen Bild- und Inhaltsflaeche:
   unten (Mobile, Bild oben) bzw. rechts (Desktop, Bild links) faedet das
   Bild dezent in dasselbe .ink-900 wie der Inhaltsbereich aus. */
.cta-feature-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(11, 11, 11, 0) 45%, rgba(11, 11, 11, 0.55) 85%, var(--ink-900) 100%);
}
@media (min-width: 768px) {
  .cta-feature-media::after {
    background: linear-gradient(90deg, rgba(11, 11, 11, 0) 45%, rgba(11, 11, 11, 0.6) 82%, var(--ink-900) 100%);
  }
}
.cta-feature-media > .leistung-media-placeholder-label {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
}
.cta-feature-content {
  position: relative;
  min-width: 0;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--space-2);
}
@media (min-width: 768px) {
  .cta-feature-content { padding: var(--space-4) var(--space-5); }
}
.cta-feature-content h2 { align-self: stretch; margin: 0; font-size: var(--text-xl); line-height: 1.2; overflow-wrap: break-word; }
.cta-feature-text { align-self: stretch; margin: 0; color: var(--ink-text-muted); max-width: 34rem; overflow-wrap: break-word; }
.cta-feature-list {
  align-self: stretch;
  list-style: none;
  margin: var(--space-1) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}
.cta-feature-list li { display: flex; align-items: center; gap: 0.6rem; font-size: var(--text-sm); }
.cta-feature-list .icon-badge { width: 32px; height: 32px; margin-bottom: 0; flex-shrink: 0; }
.cta-feature-list .icon-badge svg { width: 18px; height: 18px; }

/* Projekt-Bildergalerie (Bild + Text im Wechsel) ----------------------------
   Wiederverwendbare Komponente fuer alle Projektseiten, siehe
   components/project-gallery.njk + layouts/projekt.njk. ------------------ */
.project-gallery {
  margin-block: var(--space-6);
}
.project-gallery-item {
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  gap: var(--space-2);
}
.project-gallery-item + .project-gallery-item {
  margin-top: var(--space-5);
}
@media (min-width: 768px) {
  .project-gallery-item {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-5);
  }
  .project-gallery-item.is-reversed .project-photo-btn { order: 2; }
  .project-gallery-item.is-reversed .project-gallery-text { order: 1; }
}
/* Normale Ansicht bewusst ohne Rahmen/Schatten/Farbcontainer und ohne
   festes Seitenverhaeltnis: die Bildhoehe ergibt sich automatisch aus der
   Originalbreite, dadurch wird nie beschnitten - auch nicht bei Hoch- oder
   ungewoehnlichen Formaten. Nur die Breite ist gedeckelt ("etwas kleiner"). */
.project-photo-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.project-photo {
  display: block;
  width: 100%;
  max-width: 460px;
  height: auto;
  border-radius: var(--radius-sm);
  transition: opacity 0.2s ease;
}
.project-photo-btn:hover .project-photo,
.project-photo-btn:focus-visible .project-photo { opacity: 0.9; }
.project-gallery-text p {
  color: var(--paper-text-muted);
  font-size: var(--text-base);
  margin: 0;
}

/* Lightbox -------------------------------------------------------------------
   Eigenes, abhaengigkeitsfreies Overlay (kein Plugin). Wird pro Projektseite
   einmal ins Markup gerendert (layouts/projekt.njk) und von
   assets/js/project-gallery.js gesteuert. ---------------------------------*/
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease;
}
.lightbox.is-open { opacity: 1; visibility: visible; }
.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(11, 11, 11, 0.82);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
/* .lightbox-frame ist inline-flex und schrumpft exakt auf die tatsaechliche
   Bildgroesse (das <img> gibt seine Groesse ueber max-width/max-height vor,
   die Frame-eigenen max-Werte sind nur eine Sicherheitsgrenze). Dadurch ist
   das 8px-Padding auf allen vier Seiten wirklich gleich gross - unabhaengig
   vom Seitenverhaeltnis des jeweiligen Fotos. */
.lightbox-frame {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  max-width: min(92vw, 1100px);
  max-height: 88vh;
  padding: 8px;
  background: var(--ink-900);
  border: 3px solid var(--brand-500);
  border-radius: var(--radius-md);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
  transform: scale(0.97);
  transition: transform 0.2s ease;
}
.lightbox.is-open .lightbox-frame { transform: scale(1); }
.lightbox-img {
  display: block;
  max-width: calc(min(92vw, 1100px) - 22px);
  max-height: calc(88vh - 22px);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: calc(var(--radius-md) - 4px);
}
.lightbox-close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  z-index: 2;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.75rem;
  line-height: 1;
  color: var(--ink-text);
  background: rgba(11, 11, 11, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  cursor: pointer;
}
.lightbox-close:hover { background: var(--brand-600); border-color: var(--brand-600); }
.lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  line-height: 1;
  color: var(--ink-text);
  background: rgba(11, 11, 11, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  cursor: pointer;
}
.lightbox-nav:hover { background: var(--brand-600); border-color: var(--brand-600); }
.lightbox-prev { left: var(--space-2); }
.lightbox-next { right: var(--space-2); }
@media (max-width: 767px) {
  .lightbox-frame { max-width: 94vw; padding: 6px; }
  .lightbox-img { max-width: calc(94vw - 18px); max-height: calc(88vh - 18px); }
  .lightbox-close { top: var(--space-1); right: var(--space-1); width: 40px; height: 40px; }
  .lightbox-nav { width: 40px; height: 40px; font-size: 1.5rem; }
  .lightbox-prev { left: var(--space-1); }
  .lightbox-next { right: var(--space-1); }
}

/* Kontaktbereich / Formular --------------------------------------------------*/
.contact-grid {
  display: grid;
  gap: var(--space-4);
}
@media (min-width: 768px) {
  .contact-grid { grid-template-columns: 1fr 1.2fr; }
}
.contact-form { display: grid; gap: var(--space-2); }
.form-note { font-size: var(--text-xs); color: var(--paper-text-muted); }

/* Footer ---------------------------------------------------------------------*/
/* Footer: Mobile einspaltig, Tablet 2x2, Desktop vier Bereiche. */
.site-footer {
  background: var(--ink-900);
  color: var(--ink-text-muted);
  padding-top: var(--space-6);
  font-size: var(--text-sm);
  border-top: 1px solid var(--ink-line);
}
.site-footer a,
.footer-link-button {
  color: var(--ink-text);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.site-footer a:hover,
.footer-link-button:hover {
  color: var(--brand-400);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.footer-grid {
  display: grid;
  gap: var(--space-5) var(--space-4);
  align-items: start;
}
.footer-grid > * { min-width: 0; }
@media (max-width: 767px) {
  .site-footer { padding-top: var(--space-5); }
  .footer-grid { gap: var(--space-4); }
}
@media (min-width: 768px) {
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .footer-grid { grid-template-columns: 1.5fr 1fr 1fr 1fr; }
}
.footer-heading {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--brand-400);
  margin: 0 0 var(--space-2);
}
.footer-logo { display: inline-block; margin-bottom: var(--space-2); }
.footer-logo .logo-mark { display: block; }
.footer-name {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--ink-text);
  margin: 0 0 0.25rem;
}
.footer-claim { margin: 0 0 var(--space-3); max-width: 22rem; }
.footer-contact {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-style: normal;
}
.footer-contact a { align-self: flex-start; }
.footer-contact span:nth-child(2) { margin-bottom: 0.6rem; }
.footer-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.15rem;
}
.footer-list a,
.footer-link-button {
  display: inline-block;
  padding-block: 0.2rem;
}
.footer-link-button {
  background: none;
  border: 0;
  padding-inline: 0;
  cursor: pointer;
  text-align: left;
}
/* Orte: ruhige Liste, auf Mobile zweispaltig (spart Hoehe), sonst untereinander. */
.footer-places li { padding-block: 0.2rem; }
@media (max-width: 767px) {
  .footer-places { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--space-3); }
}
.footer-note { margin: var(--space-2) 0 0; font-size: var(--text-xs); }
/* Ab Tablet: Spaltenueberschriften optisch an der Hoehe des Logos ausrichten. */
@media (min-width: 768px) {
  .footer-col:not(.footer-brand) .footer-heading { margin-top: 0.85rem; }
}
.footer-bottom {
  margin-top: var(--space-5);
  padding-block: var(--space-3);
  border-top: 1px solid var(--ink-line);
  font-size: var(--text-xs);
}

/* Cookie-Consent ---------------------------------------------------------------
   Eigener, abhaengigkeitsfreier Banner + Einstellungsdialog (kein externes
   Consent-Tool). Logik in assets/js/consent.js. Bewusst ohne Animationen,
   Sichtbarkeit ueber das hidden-Attribut. -------------------------------- */
.consent-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 300;
  background: var(--ink-900);
  color: var(--ink-text);
  border-top: 1px solid var(--ink-line);
  box-shadow: 0 -12px 28px rgba(11, 11, 11, 0.25);
}
.consent-banner[hidden] { display: none; }
.consent-banner__inner {
  max-width: var(--container-width);
  margin-inline: auto;
  padding: var(--space-3) var(--container-padding);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.consent-banner__text {
  flex: 1 1 320px;
  margin: 0;
  font-size: var(--text-sm);
  color: var(--ink-text-muted);
}
.consent-banner__text a { color: var(--ink-text); }
.consent-banner__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
@media (max-width: 640px) {
  .consent-banner__actions { width: 100%; }
  .consent-banner__actions .btn { flex: 1 1 auto; }
}

.consent-modal {
  position: fixed;
  inset: 0;
  z-index: 310;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3);
}
.consent-modal[hidden] { display: none; }
.consent-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(11, 11, 11, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.consent-modal__panel {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 32rem;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--ink-900);
  color: var(--ink-text);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
}
.consent-modal__panel h2 { margin-top: 0; font-size: var(--text-xl); }
.consent-modal__category {
  padding-block: var(--space-3);
  border-top: 1px solid var(--ink-line);
}
.consent-modal__category:first-of-type { border-top: none; padding-top: 0; }
.consent-modal__category-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: 0.4em;
}
.consent-modal__category p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--ink-text-muted);
}
.consent-modal__badge {
  font-size: var(--text-xs);
  color: var(--ink-text-muted);
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.consent-modal__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
@media (max-width: 480px) {
  .consent-modal__actions { flex-direction: column; align-items: stretch; }
}

.consent-modal__switch {
  position: relative;
  display: inline-block;
  width: 42px;
  height: 24px;
  flex-shrink: 0;
}
.consent-modal__switch input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.consent-modal__switch span {
  position: absolute;
  inset: 0;
  background: var(--ink-700);
  border: 1px solid var(--ink-line);
  border-radius: 999px;
}
.consent-modal__switch span::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  background: var(--ink-text);
  border-radius: 50%;
  transition: transform 0.15s ease;
}
.consent-modal__switch input:checked + span { background: var(--brand-600); }
.consent-modal__switch input:checked + span::before { transform: translateX(18px); }
.consent-modal__switch input:focus-visible + span { outline: 2px solid var(--brand-500); outline-offset: 2px; }
