@charset "UTF-8";
/* =============================================================================
   San TGA Consult GmbH - Stilvorlage der oeffentlichen Website
   -----------------------------------------------------------------------------
   Reines CSS, kein Build-Schritt, keine externen Anfragen. Die Schriften liegen
   selbst gehostet unter assets/fonts/ und werden von assets/css/fonts.css
   geladen (bewusst KEIN Google-Fonts-CDN - dafuer wurden Seitenbetreiber in
   Deutschland bereits abgemahnt).

   Einbindereihenfolge im <head>:
       1. assets/css/fonts.css     (@font-face)
       2. assets/css/site.css      (diese Datei)

   Klassennamen sind im Vertrag festgeschrieben: _extract/contract.classes.md
   Wer hier eine Klasse ergaenzt, ergaenzt sie dort zuerst.

   Gliederung
       1 - Token-Schicht
       2 - Grundlagen (Reset, Typografie, Fokus, Bewegung)
       3 - Geruest (Rahmen, Abschnitte, Raster)
       4 - Bausteine (Zeichnungsrahmen, Schaltflaechen, Marken, Karten)
       5 - Chrom (Kopfleiste, Navigation, Handlungsleiste, Fuss, Zeiger)
       6 - Seitenabschnitte
       7 - Druck (Referenzblatt auf weissem Papier)
   ========================================================================== */


/* =============================================================================
   1 - TOKEN-SCHICHT
   -----------------------------------------------------------------------------
   PHP schreibt zur Laufzeit --accent und --card-min als Inline-Stil auf das
   <html>-Element (Akzentfarbe und Rasterdichte aus den Einstellungen). Ein
   Inline-Stil schlaegt jeden Selektor, deshalb sind die Werte hier ausdruecklich
   nur Vorgaben. Genau diese Namen muessen bestehen bleiben.
   ========================================================================== */

:root {
  color-scheme: dark;

  /* --- Flaechen und Schrift ------------------------------------------------ */
  --bg:        #050907;   /* Seitengrund, fast schwarzes Gruen */
  --bg-alt:    #070c09;   /* abwechselndes Band (Kennzahlen, Referenzen, Ablauf, Fuss) */
  --surface:   #0a100c;   /* erhoehte Flaeche: Assistent, Projektdaten, Bildgrund */
  --surface-2: #0d1410;   /* Hover-Ton einer Rasterzelle */

  --fg:        #e4ede7;   /* Text */
  --fg-2:      #c9d6ce;   /* Listen, Navigation im Ruhezustand, Zellennamen */
  --fg-lead:   #b6c3bb;   /* Einleitungsabsaetze */
  --dim:       #8d9a92;   /* Nebentext, Beschriftungen */

  /* --- Akzent -------------------------------------------------------------- */
  --accent:    #26ca42;   /* Markengruen - exakt aus dem Logo (S) */
  --accent-2:  #12a438;   /* dunklere Stufe, Bus-Leitungen im Schema */
  --on-accent: #03140a;   /* Text auf gefuellter Akzentflaeche */
  --accent-hi: #5cdd7a;   /* Hover einer Akzentflaeche */
  --accent-lo: #12a438;   /* gedrueckte Akzentflaeche */

  /* Farbtreppe. Die festen Werte gelten, solange niemand den Akzent aendert;
     weiter unten werden sie aus --accent neu berechnet, sobald color-mix()
     verfuegbar ist - dann bleibt die Treppe auch bei fremdem Akzent stimmig. */
  --accent-100: #eafcee;
  --accent-200: #c2f5cd;
  --accent-300: #8fe8a6;
  --accent-400: #5cdd7a;
  --accent-500: #26ca42;
  --accent-600: #12a438;
  --accent-700: #0a7a2a;
  --accent-800: #06521d;
  --accent-900: #004818;

  /* --- Linien -------------------------------------------------------------- */
  /* Die Haarlinie ist die Signatur dieser Seite: jede Regel, jede Zellenfuge,
     jeder Kartenrand. Zuerst als rgba() (laeuft ueberall), darunter als
     color-mix() aus --fg, damit sie dem Textton folgt. */
  --line:   rgba(228, 237, 231, 0.13);
  --line-2: rgba(228, 237, 231, 0.24);

  /* Raender von BEDIENELEMENTEN brauchen nach WCAG 1.4.11 mindestens 3:1
     gegen den Grund. --line (1,32:1) und --line-2 (1,89:1) erfuellen das
     nicht - sie bleiben deshalb dekorativen Trennern und den Blueprint-Ecken
     vorbehalten. Alles, was man anklicken oder ausfuellen kann, nimmt
     --line-ui (#626865, 3,45:1). Optisch bleibt es ein dezentes Grau. */
  --line-ui: rgba(228, 237, 231, 0.42);
  --line-ui-strong: rgba(228, 237, 231, 0.55);
  --corner: rgba(42, 215, 69, 0.70);   /* Farbe der Registriermarken */

  /* --- Gruenes Handlungsfeld (die eine Vollfarbflaeche der Seite) ----------- */
  --field:        #004818;
  --on-field:     #ffffff;
  --on-field-dim: #7ff09a;
  --on-field-mut: rgba(255, 255, 255, 0.82);
  --field-line:   rgba(255, 255, 255, 0.45);
  --field-grid:   rgba(255, 255, 255, 0.055);

  /* --- Signalfarben -------------------------------------------------------- */
  --danger: #e05a4a;   /* Feldfehler und loeschende Aktionen (Quelle: Design, Admin-Entwurf) */
  --warn:   #e8b54a;   /* Entwurfsstatus (Quelle: Design, Admin-Entwurf --warn) */

  /* --- Schriftfamilien ----------------------------------------------------- */
  --head: "Barlow Condensed", system-ui, sans-serif;
  --body: "Barlow", system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* --- Masse --------------------------------------------------------------- */
  --shell:        1360px;  /* maximale Inhaltsbreite */
  --shell-narrow: 860px;   /* Rechtstexte: schmaler, damit Zeilen lesbar bleiben */
  --gutter:       clamp(18px, 3.5vw, 44px);
  --card-min:     330px;   /* Spaltenboden des Rasters (250 / 330 / 420 je Dichte) */
  --topbar-h:     34px;
  --nav-h:        74px;

  /* --- Typografische Treppe -------------------------------------------------
     Alle Groessen atmen zwischen 320px und 1920px. In rem, damit eine groesser
     eingestellte Browserschrift wirksam bleibt. */
  /* Beide Grenzen sind gemessen, nicht geschaetzt. Oben: "Gebaeudetechnik" muss
     in eine Spalte des Aufmachers passen (rund 640px bei 1440px Fenster) - bei
     104px tat es das nicht. Unten: "Ueberraschungen." muss bei 320px in die
     Zeile passen (284px zwischen den Seitenabstaenden). */
  --h-hero: clamp(2.5rem, 6.4vw, 5.75rem);      /*  40 -  92 px  Startseite */
  --h-page: clamp(2.375rem, 5.6vw, 4.75rem);    /*  38 -  76 px  Unterseiten */
  --h-proj: clamp(2rem, 4.8vw, 4rem);           /*  32 -  64 px  Projekttitel */
  --h-sec:  clamp(1.875rem, 3.6vw, 3rem);       /*  30 -  48 px  Abschnitt */
  --h-sub:  clamp(1.75rem, 3.2vw, 2.625rem);    /*  28 -  42 px  Unterabschnitt */
  --h-card: clamp(1.3125rem, 1.9vw, 1.6875rem); /*  21 -  27 px  Karte */
  --fs-lead:    clamp(1rem, 1.35vw, 1.1875rem); /*  16 -  19 px  Einleitung */
  --fs-body:    1rem;                           /*  16 px */
  --fs-sm:      0.9375rem;                      /*  15 px */
  --fs-xs:      0.875rem;                       /*  14 px */
  --fs-mono:    0.6875rem;                      /*  11 px */
  --fs-mono-sm: 0.625rem;                       /*  10 px */

  /* --- Abstaende ----------------------------------------------------------- */
  --pad-section:    clamp(3.75rem, 8vw, 6.875rem);    /* 60 - 110 px */
  --pad-section-sm: clamp(2.125rem, 4.2vw, 3.375rem); /* 34 -  54 px */
  --pad-card:       clamp(1.5rem, 2.6vw, 2.125rem);   /* 24 -  34 px */
  --gap:            clamp(1rem, 1.8vw, 1.625rem);     /* 16 -  26 px */
  --gap-lg:         clamp(1.25rem, 2.4vw, 2.125rem);  /* 20 -  34 px */
  --gap-xl:         clamp(1.625rem, 3.4vw, 3.5rem);   /* 26 -  56 px */

  /* --- Bewegung ------------------------------------------------------------ */
  --ease:   cubic-bezier(0.16, 1, 0.3, 1);  /* weiches Auslaufen, kein Zurueckfedern */
  --t-fast: 0.2s;
  --t:      0.3s;
  --t-slow: 0.5s;

  /* Grund einer Zelle im Haarlinienraster. .section--raised und .footer setzen
     ihn um - siehe Abschnitt 3, "Haarlinienraster". */
  --cell-bg: var(--bg);
}

/* Moderne Farbmischung: Linien und Akzentstufen folgen jetzt den Grundtoenen.
   Faellt ein Browser hier heraus, gelten die rgba()/Hex-Werte von oben. */
@supports (color: color-mix(in srgb, red 50%, blue)) {
  :root {
    --line:   color-mix(in srgb, var(--fg) 13%, transparent);
    --line-2: color-mix(in srgb, var(--fg) 24%, transparent);
    --line-ui: color-mix(in srgb, var(--fg) 42%, transparent);
    --line-ui-strong: color-mix(in srgb, var(--fg) 55%, transparent);
    --corner: color-mix(in srgb, var(--accent) 70%, transparent);

    --accent-100: color-mix(in srgb, var(--accent) 12%, #ffffff);
    --accent-200: color-mix(in srgb, var(--accent) 28%, #ffffff);
    --accent-300: color-mix(in srgb, var(--accent) 52%, #ffffff);
    --accent-400: color-mix(in srgb, var(--accent) 76%, #ffffff);
    --accent-500: var(--accent);
    --accent-600: color-mix(in srgb, var(--accent) 76%, #000000);
    --accent-700: color-mix(in srgb, var(--accent) 56%, #000000);
    --accent-800: color-mix(in srgb, var(--accent) 38%, #000000);
    --accent-900: color-mix(in srgb, var(--accent) 33%, #000000);

    --accent-hi: var(--accent-400);
    --accent-lo: var(--accent-600);
    --field:     var(--accent-900);
  }
}


/* =============================================================================
   2 - GRUNDLAGEN
   ========================================================================== */

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

html {
  scroll-behavior: smooth;
  /* Ein Sprungziel darf nicht unter der klebenden Navigation landen. */
  scroll-padding-top: calc(var(--nav-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--body);
  font-size: var(--fs-body);
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Lange Woerter (Normbezeichnungen, Adressen) duerfen die Seite nie breiter
     machen als das Fenster - sonst entsteht ein waagrechter Bildlauf. */
  overflow-wrap: break-word;
  /* Haelt den ueberhaengenden Lichtschein des Aufmachers fest. */
  overflow-x: hidden;
}
/* "clip" ist der bessere Riegel: es erzeugt - anders als "hidden" - keinen
   Bildlaufbereich und kann der klebenden Navigation nicht in die Quere kommen. */
@supports (overflow: clip) {
  body { overflow-x: clip; }
}

/* Bildlauf sperren, solange Schublade oder Grossansicht offen sind. */
body.scroll-lock { overflow: hidden; }

h1, h2, h3, h4, h5 {
  margin: 0;
  font-family: var(--head);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.015em;
  text-wrap: balance;
  /* Deutsche Komposita ("Grundlagenermittlung", "Ueberraschungen") sind laenger
     als manche Spalte. Zuerst wird sauber getrennt (braucht das lang-Attribut
     am <html>-Element); erst wenn das nicht greift, bricht die Notbremse von
     <body> hart um. Beides ist besser, als das Wort abzuschneiden. */
  -webkit-hyphens: auto;
  hyphens: auto;
  hyphenate-limit-chars: 10 5 4;
}
h1 { font-size: var(--h-page); }
h2 { font-size: var(--h-sec); }
h3 { font-size: var(--h-card); }
h4 { font-size: 1.25rem; }
h5 { font-size: 1.0625rem; }

p { margin: 0; text-wrap: pretty; }

a {
  color: inherit;
  text-decoration: none;
  transition: color var(--t);
}
a:hover { color: var(--accent); }

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

address { font-style: normal; }

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

figure { margin: 0; }

button {
  font: inherit;
  /* "font:" setzt die Laufweite zurueck - deshalb ausdruecklich erben. */
  letter-spacing: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
}
button:disabled { cursor: not-allowed; opacity: 0.45; }

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

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
}
th, td {
  text-align: left;
  vertical-align: top;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
}
th {
  font-family: var(--mono);
  font-weight: 400;
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}

hr {
  height: 1px;
  border: 0;
  margin: var(--gap) 0;
  background: var(--line);
}

::selection {
  background: var(--accent);
  color: var(--on-accent);
}

/* Der Fokusring ist auf dieser Seite die einzige Tastaturanzeige - fast jedes
   Bedienelement ist eine randlose Flaeche. Er darf nie verschwinden. */
/* Zweifarbiger Tastaturfokus.
 *
 * Ein einfarbig gruener Ring waere auf den gruenen Hauptschaltflaechen
 * unsichtbar (Akzent auf Akzent = 1:1). Der innere dunkle Ring hebt sich vom
 * gruenen Knopf ab (10,4:1), der aeussere helle vom Seitengrund (13,6:1) -
 * beide Uebergaenge liegen ueber 3:1, damit ist WCAG 1.4.11 erfuellt und der
 * Fokus auf JEDEM Untergrund sichtbar. Bewusst ueberall derselbe Ring, damit
 * er wiedererkennbar bleibt. */
:focus-visible {
  outline: 2px solid var(--bg);
  outline-offset: 0;
  box-shadow: 0 0 0 4px var(--accent-300, #8fe8a6);
  border-radius: 0;
}
/* Auf dem gruenen Vollfarbfeld ist der Seitengrund als Ring zu dunkel gegen
   das Feld - dort drehen wir die beiden Ringe um. */
.ctafield :focus-visible {
  outline-color: #ffffff;
  box-shadow: 0 0 0 4px var(--bg);
}
/* Nur die Maus-Umrandung faellt weg, nicht die der Tastatur. Das betrifft auch
   <main tabindex="-1">, das nach der Sprungmarke programmgesteuert Fokus bekommt. */
:focus:not(:focus-visible) { outline: none; }

[hidden] { display: none !important; }

/* Nur fuer Hilfsmittel: Bildbeschreibungen, Vorlesetexte, Feldzusaetze. */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Sprungmarke: erscheint erst beim Tastaturfokus, dann aber deutlich. */
.skiplink {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 400;
  transform: translateY(-120%);
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 12px 20px;
  transition: transform var(--t) var(--ease);
}
.skiplink:focus-visible {
  transform: none;
  outline-offset: -4px;
}

/* --- Bewegungsablaeufe ---------------------------------------------------- */

@keyframes pulseDot {
  0%, 100% { opacity: 0.25; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.5); }
}
@keyframes dashFlow { to { stroke-dashoffset: -320; } }
@keyframes riseIn {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}
/* Ein Lichtbalken wandert durch den Aufmacher - die Leitwarten-Anmutung, die
   der Entwurf vorsieht. */
@keyframes scanline {
  0%   { top: -2px; opacity: 0; }
  10%  { opacity: 0.9; }
  90%  { opacity: 0.9; }
  100% { top: 100%; opacity: 0; }
}

/* Einblenden beim Scrollen.
   Verborgen wird NUR, wenn site.js laeuft: es setzt als allererste Anweisung
   document.documentElement.classList.add("js"). Ohne JavaScript ist damit jeder
   Inhalt sofort sichtbar - das ist keine Kuer, sondern Bedingung. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  will-change: opacity, transform;
}
.js [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

/* Magnetische Schaltflaechen: site.js setzt nur --mx/--my, die Bewegung selbst
   macht das Blatt hier - so laeuft sie weich statt ruckartig. */
[data-magnetic] {
  transform: translate(var(--mx, 0px), var(--my, 0px));
}
/* Ebene, die beim Scrollen langsamer mitlaeuft (site.js setzt --py). */
[data-parallax] {
  transform: translate3d(0, var(--py, 0px), 0);
  will-change: transform;
}

/* --- Weniger Bewegung -----------------------------------------------------
   Alles steht still. Entscheidend: eingeblendete Inhalte bleiben SICHTBAR,
   sie duerfen niemals auf opacity:0 haengen bleiben. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .js [data-reveal],
  .js [data-reveal].is-revealed {
    opacity: 1 !important;
    transform: none !important;
  }
  [data-magnetic],
  [data-parallax] { transform: none !important; }

  .hero__scanline,
  .cursor { display: none !important; }
  .pulse { animation: none !important; opacity: 1 !important; }
}


/* =============================================================================
   3 - GERUEST
   ========================================================================== */

/* Der Inhaltsrahmen jedes Bandes - ohne Ausnahme. Daran haengt die optische
   Flucht der ganzen Seite. */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.shell--narrow { max-width: var(--shell-narrow); }

/* --- Abschnitte ----------------------------------------------------------- */
.section {
  position: relative;
  padding-block: var(--pad-section);
  border-bottom: 1px solid var(--line);
}
.section--tight { padding-block: var(--pad-section-sm); }
.section--flush { padding-block: 0; }
/* Abwechselndes Band. Setzt zugleich den Zellenton des Haarlinienrasters um,
   sonst lesen die Fugen im Band nicht mehr als Linien. */
.section--raised {
  background: var(--bg-alt);
  --cell-bg: var(--bg-alt);
}

/* Abschnittskopf: Nummer + Ueberschrift links, optionaler Verweis rechts. */
.section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px 18px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 16px;
  margin-bottom: clamp(34px, 4.5vw, 56px);
}
.section__head-main {
  display: flex;
  align-items: baseline;
  gap: 18px;
  min-width: 0;
}
.section__number {
  flex: none;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.18em;
  color: var(--accent);
}
.section__title {
  font-size: var(--h-sec);
  text-transform: uppercase;
}
/* Traegt der Abschnittskopf die Seitenueberschrift, ist er kein Abschnitt mehr,
   sondern der Seitentitel - und bekommt dessen Groesse. */
h1.section__title { font-size: var(--h-page); }
.section__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  white-space: nowrap;
}
.section__link:hover { color: var(--accent); }
.section__arrow { transition: transform var(--t) var(--ease); }
.section__link:hover .section__arrow { transform: translateX(4px); }

.section__intro {
  max-width: 62ch;
  font-size: 1.125rem;
  line-height: 1.65;
  color: var(--fg-lead);
  margin-bottom: clamp(34px, 4.5vw, 56px);
}

/* --- Kleine Mono-Beschriftung --------------------------------------------- */
.kicker {
  display: block;
  font-family: var(--mono);
  /* 400 ist Pflicht: die Klasse sitzt auch auf <h2>/<h3>, und die Mono-Schrift
     ist nur in 400 und 500 vorhanden - ein geerbtes 600 wuerde der Browser
     kuenstlich fetten. */
  font-weight: 400;
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1.4;
}
/* Als Ueberschrift ist der Kicker die Beschriftung eines Blocks und braucht
   Luft nach unten. Als Absatz oder <span> steht er in Zeilen (Kopfzeilen,
   Symbolreihen) und bekommt sie gezielt dort, wo sie hingehoert. */
h2.kicker,
h3.kicker { margin-bottom: 16px; }

.rule {
  height: 1px;
  border: 0;
  margin: 0;
  background: var(--line);
}

/* --- Raster ---------------------------------------------------------------
   DAS ist die automatische Spaltenerkennung, nach der der Auftraggeber gefragt
   hat: die Spaltenzahl folgt der Bildschirmbreite, nicht festen Haltepunkten.
   Grundstellung ist eine Spalte - damit bleibt das Layout auch dort brauchbar,
   wo min() oder auto-fit fehlen. */
.grid {
  display: grid;
  gap: var(--gap);
  grid-template-columns: 1fr;
}
/* Die Abstandsvarianten setzen --gap um statt nur gap: die Spaltenobergrenze
   weiter unten rechnet mit demselben Wert und bliebe sonst falsch. */
.grid--tight { --gap: clamp(0.75rem, 1.2vw, 1.125rem); }
.grid--wide  { --gap: var(--gap-xl); }
.grid--1     { grid-template-columns: 1fr; }

@supports (width: min(330px, 100%)) {
  .grid {
    grid-template-columns: repeat(auto-fit, minmax(min(var(--card-min), 100%), 1fr));
  }

  /* Obergrenze der Spaltenzahl: die Mindestbreite einer Spur waechst so weit,
     dass rechnerisch nie mehr als --cols Spalten nebeneinander passen. */
  .grid--2, .grid--3, .grid--4 {
    grid-template-columns: repeat(auto-fit, minmax(
      min(100%, max(var(--card-min), (100% - (var(--cols) - 1) * var(--gap)) / var(--cols))
    ), 1fr));
  }
  .grid--2 { --cols: 2; }
  .grid--3 { --cols: 3; }
  .grid--4 { --cols: 4; }

  /* auto-fill statt auto-fit: eine angefangene letzte Reihe behaelt die
     Spaltenbreite, statt eine einzelne Kachel breitzuziehen. */
  .grid--fill {
    grid-template-columns: repeat(auto-fill, minmax(min(var(--card-min), 100%), 1fr));
  }
  .grid--1 { grid-template-columns: 1fr; }
}

/* Haarlinienraster - die Signatur der Seite.
   Der Behaelter faerbt sich in Linienfarbe, die Fugen von 1px lassen ihn
   durchscheinen und lesen als gezeichnete Regeln. Jede Zelle muss deshalb
   ihren eigenen deckenden Grund malen; bleibt eine Zelle durchsichtig, wird
   sie zum Linienblock. Genau dafuer ist --cell-bg da. */
.grid--rule {
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
.grid--rule > * { background: var(--cell-bg); }

/* --- Zweispaltiger Textsatz ------------------------------------------------ */
.split {
  display: grid;
  gap: var(--gap-xl);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; }
  /* Fliesstext links, schmale Datenspalte rechts (Projektseite). */
  .split--aside { grid-template-columns: minmax(0, 1fr) minmax(280px, 360px); }
}


/* =============================================================================
   4 - BAUSTEINE
   ========================================================================== */

/* --- Zeichnungsrahmen mit Registriermarken --------------------------------
   Die vier Marken sind Pseudo-Elemente auf den <i>-Kindern: 1px Haarlinien,
   absolut gesetzt, 6px ausserhalb der Kante. Sie haben keinen Platzbedarf und
   verschieben deshalb nichts. Wichtig: der Rahmen darf NICHT beschneiden, sonst
   schneidet er seine eigenen Marken ab (der bekannte Fehler aus dem Entwurf).
   Ein Bild bekommt seine Beschneidung in einer inneren .duotone. */
.blueprint {
  position: relative;
  border: 1px solid var(--line);
  border-radius: 0;
  overflow: visible;
}
.corner {
  position: absolute;
  width: 11px;
  height: 11px;
  color: var(--corner);
  pointer-events: none;
}
.corner::before,
.corner::after {
  content: "";
  position: absolute;
  background: currentColor;
}
.corner::before { left: 5px; top: 0; width: 1px; height: 100%; }
.corner::after  { top: 5px; left: 0; width: 100%; height: 1px; }
.corner--tl { top: -6px;    left: -6px; }
.corner--tr { top: -6px;    right: -6px; }
.corner--bl { bottom: -6px; left: -6px; }
.corner--br { bottom: -6px; right: -6px; }

/* Ein blanker .blueprint ohne eigene Komponentenklasse ist nur ein gezeichneter
   Rahmen und bringt keinen Innenabstand mit. Wo er unmittelbar ein Datenblatt
   oder einen zweispaltigen Block umschliesst, klebte der Inhalt sonst an der
   Linie. */
.blueprint > .facts,
.blueprint > .split { padding: var(--pad-card); }
.blueprint > .split { align-items: center; }
/* Einziger Fall: die Wortmarke der Schwestergesellschaft im Rahmen auf
   "Ueber uns". Sie ist dunkel auf hell gezeichnet und muss fuer den dunklen
   Grund aufgehellt werden - solange keine helle Fassung vorliegt. */
.blueprint > .split img {
  margin-bottom: 16px;
  filter: brightness(1.7);
}

/* --- Bildbehandlung -------------------------------------------------------
   Das Foto wird entsaettigt und abgedunkelt, dann mit tiefem Gruen gewaschen:
   die Haeuser lesen als gruen getoente Platten, nie als Farbfotos.
   Nachkommen-Selektor, weil die Vorlagen <picture> verwenden. */
.duotone {
  position: relative;
  overflow: hidden;
  background: var(--surface);
}
.duotone img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.12) brightness(0.74);
}
.duotone::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: var(--accent-700);
  opacity: 0.42;
}
/* mix-blend-mode ist die eigentliche Wirkung; wo sie fehlt, bleibt eine
   schlichte Gruenwaesche uebrig - das ist als Rueckfall in Ordnung. */
@supports (mix-blend-mode: color) {
  .duotone::after { mix-blend-mode: color; }
}
/* Ohne Farbwaesche - fuer Plaene und Schemata, die lesbar bleiben muessen. */
.duotone--flat::after { display: none; }
.duotone--flat img { filter: grayscale(1) contrast(1.05) brightness(0.9); }

/* --- Schaltflaechen -------------------------------------------------------
   Grundform: eckig, durchsichtig, Haarlinie. Die gefuellte Akzentflaeche
   (.btn--primary) ist die einzige bewusste Ausnahme der ganzen Seite. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 11px;
  border: 1px solid var(--line-2);
  border-radius: 0;
  background: transparent;
  color: var(--fg);
  font-family: var(--head);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.15;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  text-align: center;
  padding: 15px 26px;
  cursor: pointer;
  transition: background var(--t), color var(--t), border-color var(--t),
              transform var(--t) var(--ease);
}
.btn svg { flex: none; }
.btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.btn:active { transform: translateY(1px); }
.btn:disabled,
.btn[aria-disabled="true"] { opacity: 0.4; pointer-events: none; }

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.btn--primary:hover {
  background: var(--accent-hi);
  border-color: var(--accent-hi);
  color: var(--on-accent);
}
.btn--primary:active {
  background: var(--accent-lo);
  border-color: var(--accent-lo);
}

.btn--ghost {
  background: transparent;
  border-color: var(--line-ui);
  color: var(--fg);
}
.btn--ghost:hover { border-color: var(--accent); color: var(--accent); }

/* Stille Fassung - Mono-Verweis ohne Rahmen (Zurueck, Blaettern, Abbrechen). */
.btn--quiet {
  border-color: transparent;
  background: none;
  padding: 6px 2px;
  font-family: var(--mono);
  font-weight: 400;
  font-size: var(--fs-mono);
  letter-spacing: 0.14em;
  color: var(--dim);
}
.btn--quiet:hover { color: var(--accent); border-color: transparent; }
.btn--quiet:active { transform: none; }

.btn--sm    { padding: 9px 16px; font-size: 0.9375rem; gap: 8px; }
.btn--lg    { padding: 17px 30px; font-size: 1.0625rem; }
.btn--block { width: 100%; }

/* Auf dem gruenen Handlungsfeld kehren sich die Werte um. */
.btn--invert {
  background: var(--on-field);
  border-color: var(--on-field);
  color: var(--field);
}
.btn--invert:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.btn--onfield {
  background: transparent;
  border-color: var(--field-line);
  color: var(--on-field);
}
.btn--onfield:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: var(--on-field);
  color: var(--on-field);
}
/* Auf dem hellgruenen Feld braucht der Fokusring einen hellen Kontrast. */
.btn--invert:focus-visible,
.btn--onfield:focus-visible { outline-color: var(--on-field); }

/* --- Kleine Beschriftungen und Marken -------------------------------------- */
.tag {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 4px 9px;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  white-space: nowrap;
}
.tag--accent  { color: var(--accent); border-color: var(--corner); }
/* Normbezeichnungen tragen ihre eigene Schreibweise (DIN VDE, VDI, GEG) -
   sie duerfen deshalb nicht versalisiert werden. */
.tag--outline {
  color: var(--dim);
  border-color: var(--line-ui);
  text-transform: none;
  letter-spacing: 0.06em;
}
.tag--muted { color: var(--dim); border-color: transparent; }

/* Anklickbarer Filter. Ohne JavaScript ist das ein <a href="?filter=...">
   und filtert serverseitig genauso. */
.chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line-ui);
  border-radius: 0;
  background: transparent;
  color: var(--fg);
  padding: 7px 15px;
  font-family: var(--mono);
  font-size: 0.65625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--t), color var(--t), border-color var(--t);
}
.chip:hover { border-color: var(--accent); color: var(--accent); }
.chip--active,
.chip[aria-current],
.chip[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.chip--active:hover,
.chip[aria-current]:hover,
.chip[aria-pressed="true"]:hover {
  background: var(--accent-hi);
  border-color: var(--accent-hi);
  color: var(--on-accent);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.badge::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.badge--live    { color: var(--accent); }
.badge--draft   { color: var(--warn); }
.badge--archive { color: var(--dim); }

/* Pulsierender Punkt (Oeffnungszeiten). */
.pulse {
  display: block;
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulseDot 2.4s ease-in-out infinite;
}

/* --- Hinweisfelder --------------------------------------------------------- */
.alert {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  border: 1px solid var(--line-2);
  border-left-width: 2px;
  padding: 16px 18px;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--fg-2);
}
.alert--success { border-left-color: var(--accent); }
.alert--error   { border-left-color: var(--danger); color: var(--fg); }
.alert--info    { border-left-color: var(--line-2); }
.alert [data-dismiss] {
  margin-left: auto;
  flex: none;
  padding: 2px 4px;
  color: var(--dim);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  line-height: 1;
}
.alert [data-dismiss]:hover { color: var(--accent); }

/* --- Fliesstext ------------------------------------------------------------
   Nur fuer laengere redaktionelle Bloecke: Rechtstexte, Projektbeschreibung. */
.prose {
  font-size: 0.96875rem;
  line-height: 1.75;
  color: var(--fg-lead);
  max-width: 70ch;
}
.prose > * + * { margin-top: 1em; }
.prose h2 {
  font-size: 1.375rem;
  text-transform: uppercase;
  color: var(--accent);
  margin-top: 1.6em;
}
.prose h3 { font-size: 1.1875rem; text-transform: uppercase; margin-top: 1.4em; }
.prose a  { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.prose ul { display: flex; flex-direction: column; gap: 8px; }
.prose li { display: flex; gap: 11px; }
.prose li::before {
  content: "+";
  flex: none;
  color: var(--accent);
  font-family: var(--mono);
}
.prose strong { font-weight: 600; color: var(--fg); }
.prose h2:first-child,
.prose h3:first-child,
.prose > :first-child { margin-top: 0; }

/* Liste mit vorangestelltem gruenen Pluszeichen. Das Zeichen kommt hier aus dem
   Stylesheet, weil es keine Bedeutung traegt - Vorlagen, die es als eigenes
   <span> setzen, benutzen stattdessen .discipline__plus bzw. .vergabe__plus. */
.pluslist {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.pluslist__item {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--fg-2);
}
.pluslist__item::before {
  content: "+";
  flex: none;
  color: var(--accent);
  font-family: var(--mono);
  line-height: 1.55;
}
/* Als Haarlinienraster gefasst: die technischen Highlights einer Referenz. */
.pluslist--boxed {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
@supports (width: min(230px, 100%)) {
  .pluslist--boxed { grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }
}
.pluslist--boxed .pluslist__item {
  background: var(--cell-bg);
  padding: 16px 18px;
}

/* --- Kennzahl --------------------------------------------------------------- */
.stat { padding: 6px 22px 6px 0; }
.stat__label {
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 10px;
}
.stat__value {
  font-family: var(--head);
  font-weight: 600;
  font-size: clamp(2.5rem, 4.6vw, 3.75rem);
  line-height: 1;
  letter-spacing: -0.02em;
  /* Ohne Tabellenziffern zappelt die Zahl waehrend des Hochzaehlens. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.stat__unit { color: var(--accent); }
.stat__caption {
  margin-top: 8px;
  font-size: var(--fs-xs);
  line-height: 1.4;
  color: var(--dim);
}

/* --- Inhaltskarte ----------------------------------------------------------
   Bleibt eine Strichzeichnung: durchsichtig, eckig, Haarlinie. Keine Fuellung,
   kein Schlagschatten - das ist die Doktrin dieses Entwurfs. */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 0;
  color: inherit;
  text-align: left;
  transition: border-color 0.4s, transform 0.4s var(--ease);
}
.card:hover,
.card:focus-within { border-color: var(--accent); }
.card__media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--surface);
}
@supports not (aspect-ratio: 4 / 3) {
  .card__media { height: 0; padding-top: 75%; }
  .card__media > * { position: absolute; inset: 0; }
}
.card__body {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 20px;
  flex: 1;
}
.card__kicker {
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.card__title { font-size: 1.4375rem; line-height: 1.1; text-transform: uppercase; }
.card__text  { font-size: var(--fs-sm); line-height: 1.65; color: var(--dim); }
.card__meta  { font-family: var(--mono); font-size: var(--fs-mono); letter-spacing: 0.05em; color: var(--dim); }
/* margin-top:auto heftet die Fusszeile an den unteren Rand - dafuer braucht
   .card__body sein flex:1. */
.card__footer {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}


/* =============================================================================
   5 - CHROM
   ========================================================================== */

/* --- Dienstleiste ganz oben ------------------------------------------------- */
.topbar {
  position: relative;
  z-index: 60;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Beide Gruppen sind bewusst umbruchfrei (Zeiten und Rufnummer duerfen nie
     mitten im Wort brechen). Deshalb muss die LEISTE umbrechen duerfen - sonst
     schieben sich die Gruppen auf schmalen Telefonen uebereinander. */
  flex-wrap: wrap;
  gap: 4px 16px;
  padding-block: 5px;
  min-height: var(--topbar-h);
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}
.topbar__status {
  display: flex;
  align-items: center;
  gap: 22px;
  min-width: 0;
}
.topbar__hours {
  display: flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
}
.topbar__address {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.topbar__contact {
  display: flex;
  align-items: center;
  gap: 18px;
  white-space: nowrap;
}
.topbar__phone { color: var(--dim); }
.topbar a:hover { color: var(--accent); }
/* Auf schmalen Geraeten bleibt nur das Wesentliche: Zeiten und Telefon. */
@media (max-width: 760px) {
  .topbar__address { display: none; }
}
@media (max-width: 420px) {
  .topbar__inner { font-size: 0.5625rem; letter-spacing: 0.1em; gap: 10px; }
  .topbar__contact { gap: 10px; }
}

.langswitch {
  display: flex;
  border: 1px solid var(--line);
  /* Die einzige Stelle, an der ein Radius ueberlebt - eine bewusste Ausnahme. */
  border-radius: 2px;
  overflow: hidden;
}
.langswitch__item {
  padding: 2px 8px;
  color: var(--dim);
  font: inherit;
  letter-spacing: inherit;
  transition: background var(--t), color var(--t);
}
.langswitch__item:hover { color: var(--accent); }
/* Die aktive Sprache ist keine Handlung, sondern ein Zustand - deshalb Text
   und Unterstrich statt einer gefuellten Akzentflaeche. Die eine gefuellte
   Flaeche je Bildschirm gehoert dem Nav-CTA (Gutachten Designer, Punkt 4). */
.langswitch__item--active {
  color: var(--fg);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.langswitch__item--active:hover { color: var(--fg); }

/* --- Klebende Navigation ---------------------------------------------------
   Deckender Rueckfall zuerst; erst wo ein Weichzeichner moeglich ist, loest
   sich der Inhalt beim Scrollen unter der Leiste auf. Das setzt einen
   deckenden Seitengrund voraus - body darf nie durchsichtig werden. */
.nav {
  position: sticky;
  top: 0;
  z-index: 70;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
@supports ((backdrop-filter: blur(14px)) or (-webkit-backdrop-filter: blur(14px))) {
  .nav {
    background: rgba(5, 9, 7, 0.88);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
  }
}
.nav__inner {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--nav-h);
}
.nav__brand {
  display: flex;
  align-items: center;
  flex: none;
  margin-right: auto;
}
/* Die Wortmarke faehrt beim Laden sanft ein und reagiert auf den Zeiger -
   groesser als zuvor, damit sie den Auftritt traegt. */
.nav__brand { animation: brandIn .7s cubic-bezier(.2, .7, .2, 1) both; }
.nav__brand img {
  height: 54px;
  width: auto;
  /* Die Wortmarke ist dunkel auf hell gezeichnet; bis eine helle Fassung vom
     Auftraggeber vorliegt, wird sie hier aufgehellt. */
  filter: brightness(1.9) saturate(1.15);
  transition: transform .28s ease, filter .28s ease;
}
.nav__brand:hover img,
.nav__brand:focus-visible img {
  transform: scale(1.05);
  filter: brightness(2.1) saturate(1.25);
}
@keyframes brandIn {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (max-width: 560px) { .nav__brand img { height: 46px; } }
@media (prefers-reduced-motion: reduce) { .nav__brand { animation: none; } }
:root[data-motion="reduced"] .nav__brand { animation: none; }
.nav__links {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: nowrap;
}
.nav__link {
  display: inline-block;
  padding: 9px 13px;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--fg-2);
  border-bottom: 1px solid transparent;
  transition: color var(--t), border-color var(--t);
}
.nav__link:hover { color: var(--accent); }
.nav__link--active,
.nav__link[aria-current="page"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.nav__cta {
  flex: none;
  margin-left: 14px;
  padding: 11px 20px;
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
}

/* Drei Striche, die sich zum Kreuz drehen. */
.nav__burger {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  flex: none;
  border: 1px solid var(--line);
  color: var(--fg);
  transition: border-color var(--t), color var(--t);
}
.nav__burger:hover { border-color: var(--accent); color: var(--accent); }
.nav__burger span {
  display: block;
  width: 18px;
  height: 1px;
  background: currentColor;
  transition: transform var(--t) var(--ease), opacity var(--t-fast);
}
.nav__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Schublade. Geschlossen traegt sie [hidden] und ist damit auch aus der
   Tastaturfolge; site.js nimmt [hidden] weg und setzt im naechsten Bild
   .nav__drawer--open, damit die Bewegung sichtbar wird. */
.nav__drawer {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: calc(var(--nav-h) + 24px) var(--gutter) 40px;
  background: var(--bg);
  overflow-y: auto;
  overscroll-behavior: contain;
  opacity: 0;
  transform: translateY(-12px);
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
.nav__drawer--open { opacity: 1; transform: none; }
.nav--offen { backdrop-filter: none; -webkit-backdrop-filter: none; }
.nav__drawer-list { display: flex; flex-direction: column; }
.nav__drawer-link {
  display: block;
  padding: 18px 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--head);
  font-weight: 600;
  font-size: 1.75rem;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--fg);
}
.nav__drawer-link:hover,
.nav__drawer-link.nav__link--active,
.nav__drawer-link[aria-current="page"] { color: var(--accent); }
.nav__drawer-link--cta { color: var(--accent); }
.nav__drawer-contact {
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.12em;
  color: var(--dim);
}

/* Vier Eintraege plus Handlungsflaeche brauchen rund 900px. Darunter wandert
   alles in die Schublade - der Entwurf hatte dafuer keinen Ausweichweg. */
@media (max-width: 900px) {
  .nav__links,
  .nav__cta { display: none; }
  .nav__burger { display: flex; }
}
@media (min-width: 901px) {
  /* Oberhalb des Umbruchs darf die Schublade nie im Weg stehen. */
  .nav__drawer { display: none; }
}

/* Ohne JavaScript oeffnet die Schublade niemand: der Knopf haengt am Skript.
   Damit die Navigation auf dem Telefon trotzdem erreichbar bleibt, kehren die
   Links dann zurueck und brechen einfach um. site.js setzt .js auf <html> als
   allererste Anweisung - diese Regeln greifen also nur, wenn es nicht laeuft.
   Kein Ausweg waere hier kein Schoenheitsfehler, sondern eine Sackgasse. */
@media (max-width: 900px) {
  html:not(.js) .nav__burger { display: none; }
  html:not(.js) .nav__links {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 6px;
    justify-content: flex-end;
  }
  html:not(.js) .nav__inner {
    flex-wrap: wrap;
    height: auto;
    padding-block: 12px;
    row-gap: 6px;
  }
  html:not(.js) .nav__cta {
    display: inline-flex;
    margin-left: 0;
  }
  html:not(.js) .nav__drawer { display: none; }
}

/* --- Schwebende Handlungsleiste ---------------------------------------------
   Immer im Dokument, nur verschoben. 110% statt 100% raeumt Rahmen und
   Rundungsreste sicher aus dem Bild. */
.ctabar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 90;
  transform: translateY(110%);
  transition: transform var(--t-slow) var(--ease);
  border-top: 1px solid var(--corner);
  background: var(--bg);
}
@supports ((backdrop-filter: blur(14px)) or (-webkit-backdrop-filter: blur(14px))) {
  .ctabar {
    background: rgba(5, 9, 7, 0.94);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
  }
}
.ctabar--visible { transform: none; }
.ctabar__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding-block: 12px;
}
.ctabar__text {
  display: flex;
  align-items: baseline;
  gap: 13px;
  min-width: 0;
}
.ctabar__text strong {
  font-family: var(--head);
  font-weight: 600;
  font-size: 1.125rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ctabar__sub {
  font-family: var(--mono);
  font-size: 0.65625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  white-space: nowrap;
}
.ctabar__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}
@media (max-width: 640px) {
  /* Auf dem Telefon zaehlt nur der naechste Schritt; der Beitext faellt weg. */
  .ctabar__sub { display: none; }
  .ctabar__actions { width: 100%; }
  .ctabar__actions .btn--primary { flex: 1; }
}

/* --- Fussbereich ------------------------------------------------------------- */
.footer {
  border-top: 1px solid var(--line);
  background: var(--bg-alt);
  --cell-bg: var(--bg-alt);
}
.footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap-xl);
  padding-block: clamp(44px, 5.5vw, 76px) 28px;
}
@supports (width: min(200px, 100%)) {
  .footer__grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr)); }
}
.footer__col { min-width: 0; }
.footer__col--brand { max-width: 36ch; }
.footer__logo { margin-bottom: 18px; }
.footer__logo img {
  height: 40px;
  width: auto;
  filter: brightness(1.9) saturate(1.15);
}
.footer__claim {
  font-size: 0.90625rem;
  line-height: 1.7;
  color: var(--dim);
  max-width: 34ch;
  margin-bottom: 16px;
}
.footer__address {
  font-size: 0.90625rem;
  line-height: 1.7;
  color: var(--dim);
}
.footer__address strong { color: var(--fg); font-weight: 500; }
.footer__title {
  font-family: var(--mono);
  font-weight: 400;
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 16px;
  line-height: 1.4;
}
.footer__list {
  display: flex;
  flex-direction: column;
  gap: 9px;
  align-items: flex-start;
  font-size: var(--fs-sm);
  color: var(--dim);
}
.footer__list a:hover { color: var(--accent); }
/* Die Kontaktliste bekommt eine Beschriftungsspalte, damit Telefon, Fax und
   E-Mail auch beim Ueberfliegen zuzuordnen sind. */
.footer__list--contact li {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
}
.footer__label {
  flex: none;
  min-width: 5.5em;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  opacity: 0.8;
}
.footer__sister {
  padding-block: 22px;
  border-top: 1px solid var(--line);
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--dim);
}
.footer__sister .kicker { margin-bottom: 12px; }
.footer__sister strong { color: var(--fg); font-weight: 600; display: block; }

/* Schwesterfirma mit Logo: das blaue Wortzeichen braucht einen hellen Grund,
   sonst verschwindet es im dunklen Fuss. Logo links, Text rechts, verlinkt
   auf san-tga.de. */
.footer__sister-inner {
  display: flex;
  align-items: center;
  gap: 20px 28px;
  flex-wrap: wrap;
}
.footer__sister-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border-radius: 12px;
  padding: 14px 22px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
  transition: transform .2s ease, box-shadow .2s ease;
  flex: 0 0 auto;
}
.footer__sister-logo:hover,
.footer__sister-logo:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.5);
}
.footer__sister-logo img {
  display: block;
  height: 56px;
  width: auto;
}
.footer__sister-text { min-width: 220px; flex: 1 1 280px; }
/* Logo-Karte der Schwestergesellschaft auf der Ueber-uns-Seite (gleiche Sprache wie im Footer) */
.sister-logo-card { display: inline-flex; align-items: center; background: #fff; border-radius: 12px; padding: 14px 22px; margin-bottom: 14px; box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35); }
.blueprint > .split .sister-logo-card img,
.sister-logo-card img { display: block; height: 80px; width: auto; margin: 0; filter: none; }   /* kein Aufhellen: das Original-Logo liegt auf weisser Karte */
.footer__sister-body { display: block; margin-top: 4px; }
.footer__sister-link {
  display: inline-block;
  margin-top: 8px;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: var(--fs-xs, 0.82rem);
  letter-spacing: 0.04em;
  text-decoration: none;
}
.footer__sister-link:hover,
.footer__sister-link:focus-visible { text-decoration: underline; }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  border-top: 1px solid var(--line);
  padding-top: 20px;
  /* Die schwebende Leiste deckt rund 56px ab - die Rechtsverweise duerfen
     nicht dauerhaft darunter verschwinden. */
  padding-bottom: 84px;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  line-height: 1.6;
}
/* Wo die schwebende Leiste fehlt (Anfrage- und Fehlerseite), faellt der
   Platzhalter weg. Ohne :has() bleibt der Abstand stehen - das ist der
   harmlosere Fehler, denn verdeckte Rechtsverweise waeren einer. */
@supports selector(:has(*)) {
  body:not(:has(.ctabar)) .footer__bottom { padding-bottom: 20px; }
}
.footer__copyright { max-width: 70ch; }
.footer__sep { color: var(--line-2); }
.footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}
.footer__legal a:hover { color: var(--accent); }

/* --- Eigener Zeigerring -------------------------------------------------------
   Nur an feinen Zeigegeraeten; der Systemzeiger bleibt sichtbar. Ausserdem
   abschaltbar: <html data-pointer-fx="aus">. */
.cursor { display: none; }
@media (hover: hover) and (pointer: fine) {
  .cursor {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 200;
    width: 26px;
    height: 26px;
    border: 1px solid var(--accent);
    border-radius: 50%;
    pointer-events: none;
    opacity: 0;
    transform: translate(-50%, -50%);
    transition: width var(--t-fast), height var(--t-fast),
                opacity var(--t-fast), background var(--t-fast);
    mix-blend-mode: screen;
  }
  .cursor--active {
    width: 48px;
    height: 48px;
    background: rgba(42, 215, 69, 0.16);
  }
}
[data-pointer-fx="aus"] .cursor { display: none !important; }
@supports (color: color-mix(in srgb, red 50%, blue)) {
  .cursor--active { background: color-mix(in srgb, var(--accent) 16%, transparent); }
}


/* =============================================================================
   6 - SEITENABSCHNITTE
   ========================================================================== */

/* --- 6.1 Aufmacher (Start) ----------------------------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}
/* Blaupausenraster. Der Einzug von -10% oben ist Kopffreiheit fuer die
   Parallaxe: sie schiebt die Ebene nach unten und darf die Kante nicht zeigen. */
.hero__grid-lines {
  position: absolute;
  inset: -10% 0 0 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right,  rgba(228, 237, 231, 0.04) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(228, 237, 231, 0.04) 1px, transparent 1px);
  background-size: 54px 54px;
}
.hero__glow {
  position: absolute;
  top: -30%;
  right: -15%;
  z-index: 0;
  width: 70vw;
  height: 70vw;
  max-width: 900px;
  max-height: 900px;
  pointer-events: none;
  background: radial-gradient(circle, rgba(42, 215, 69, 0.13) 0%, transparent 62%);
}
.hero__scanline {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.hero__scanline::before {
  content: "";
  position: absolute;
  top: -2px;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(42, 215, 69, 0.55), transparent);
  animation: scanline 9s linear infinite;
}
.hero__inner,
.hero__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(36px, 5vw, 72px);
  /* Die Datentafel sitzt bewusst buendig mit der unteren Nachweiszeile. */
  align-items: end;
  padding-block: clamp(52px, 7vw, 96px) clamp(44px, 6vw, 80px);
}
@supports (width: min(420px, 100%)) {
  .hero__inner,
  .hero__grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); }
}
.hero__main { min-width: 0; }
.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 26px;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  /* Nebentext: der Akzent im Aufmacher gehoert dem "ohne" und dem CTA. */
  color: var(--dim);
}
.hero__eyebrow-rule {
  display: block;
  flex: none;
  width: 34px;
  height: 1px;
  /* Nur die Linie traegt den Akzent - sie weist auf die Zeile, ohne zu rufen. */
  background: var(--accent);
}
.hero__title {
  font-size: var(--h-hero);
  line-height: 0.92;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  margin-bottom: 28px;
}
.hero__title-accent { color: var(--accent); }
.hero__lead {
  max-width: 56ch;
  font-size: var(--fs-lead);
  line-height: 1.65;
  color: var(--fg-lead);
  margin-bottom: 34px;
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 38px;
}
.hero__meta,
.hero__figure { min-width: 0; }

/* Der Schraegstrich ist ein eigenes Listenelement, deshalb steht hier der
   halbe Abstand: links und rechts davon ergibt sich wieder die volle Fuge. */
.trustbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  font-family: var(--mono);
  font-size: 0.65625rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
}
.trustbar__item { min-width: 0; }
.trustbar__sep { color: var(--line-2); }

/* Das Leistungsbild als technisches Datenblatt. Durchscheinende Flaeche, damit
   das Blaupausenraster darunter sichtbar bleibt. */
.specpanel {
  position: relative;
  border: 1px solid var(--line);
  padding: clamp(22px, 2.6vw, 34px);
  background: rgba(10, 16, 12, 0.7);
}
.specpanel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 22px;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.specpanel__title {
  font-family: var(--mono);
  font-weight: 400;
  font-size: inherit;
  letter-spacing: inherit;
  color: var(--accent);
}
.specpanel__norm { color: var(--dim); }
/* Das einzige feste Raster der Website: die neun Leistungsphasen bilden eine
   3x3-Matrix und sollen genau so gelesen werden - nicht umbrechen. */
.specpanel__phases {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  margin-bottom: 24px;
}
.specpanel__phase {
  background: var(--bg);
  /* Der seitliche Abstand schrumpft mit: drei feste Spalten auf 320px lassen
     je Zelle nur rund 78px, davon darf die Polsterung nicht die Haelfte
     nehmen. */
  padding: 13px clamp(4px, 2vw, 10px);
  text-align: center;
}
.specpanel__phase-code {
  display: block;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.1em;
  /* Neun Codes in Akzentfarbe waren neun Rufzeichen; die Ordnung tragen sie
     auch in Nebentextfarbe. */
  color: var(--dim);
  margin-bottom: 5px;
}
.specpanel__phase-name {
  display: block;
  font-family: var(--head);
  font-weight: 600;
  /* Bei 320px bleiben je Zelle rund 65px Textbreite. Damit "Ausschreibung"
     dort nicht aus der Zelle laeuft, schrumpft die Schrift mit. */
  font-size: clamp(0.75rem, 2.4vw, 0.9375rem);
  line-height: 1.15;
  color: var(--fg-2);
  -webkit-hyphens: auto;
  hyphens: auto;
  overflow-wrap: break-word;
}
.specpanel__rows {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin: 0;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.05em;
  color: var(--dim);
}
.specpanel__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}
.specpanel__row dd { margin: 0; color: var(--fg); text-align: right; }
/* Nur der Wert der Auftragsannahme traegt den Akzent; das Label bleibt --fg
   wie alle anderen Beschriftungen (das dt erbt --dim aus .specpanel__rows). */
.specpanel__row--accent dd { color: var(--accent); }

/* --- 6.2 Kennzahlenband --------------------------------------------------------- */
.statsband {
  background: var(--bg-alt);
  border-bottom: 1px solid var(--line);
  --cell-bg: var(--bg-alt);
}
.statsband__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  padding-block: var(--pad-section-sm);
  background: var(--line);
  /* Der Behaelter traegt zugleich .shell, also einen Seitenabstand. Ohne
     content-box wuerde die Linienfarbe bis in diesen Abstand laufen und das
     Band einrahmen - gewollt sind nur die senkrechten Spaltenregeln. */
  background-clip: content-box;
}
@supports (width: min(190px, 100%)) {
  .statsband__grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); }
}
/* Die asymmetrische Polsterung laesst die 1px-Fugen als Spaltenregeln lesen
   und den Text am linken Rand jeder Zelle stehen. */
.statsband__grid > .stat { background: var(--cell-bg); }

/* --- 6.3 Argumente je Zielgruppe -------------------------------------------------- */
.reason {
  position: relative;
  border: 1px solid var(--line);
  padding: var(--pad-card);
  /* Bewusst ohne Fuellung: reine Strichzeichnung. */
  background: transparent;
  transition: border-color 0.4s;
}
.reason:hover { border-color: var(--corner); }
.reason__who {
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 18px;
}
.reason__head {
  font-size: clamp(1.375rem, 2vw, 1.5625rem);
  line-height: 1.12;
  margin-bottom: 14px;
}
.reason__body {
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--dim);
}

/* --- 6.4 Anlagenschema ------------------------------------------------------------
   Zwei Darstellungen statt waagerechtem Scrollen (das empfand der Kunde als
   Fremdkoerper): ab 760px skaliert die breite Zeichnung fluessig mit dem
   Container, darunter uebernimmt die kompakte Symbol-Variante (Abschnitt
   "Arbeitsstrang D" am Dateiende). Hier bleibt nur die breite Zeichnung. */
.schema {
  position: relative;
  border: 1px solid var(--line);
  padding: clamp(20px, 3vw, 40px) clamp(14px, 2.4vw, 34px);
  background: rgba(10, 16, 12, 0.6);
}
.schema__svg {
  width: 100%;
  height: auto;
  max-height: 72vh;
  display: block;
}
/* Beschriftungen und Linien tragen keine Praesentationsattribute im Markup -
   die Zeichnung wird vollstaendig hier eingefaerbt. */
.schema__caption text {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 1.6px;
  fill: var(--dim);
}
.schema__flow path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.4;
  stroke-dasharray: 7 11;
  animation: dashFlow 5s linear infinite;
}
/* Zulauf und Ablauf laufen unterschiedlich schnell - das laesst die Anlage
   arbeiten statt gleichfoermig blinken. */
.schema__flow--in path  { animation-duration: 5s; }
.schema__flow--out path { opacity: 0.8; animation-duration: 4s; }
.schema__bus path {
  fill: none;
  stroke: var(--accent-2);
  stroke-width: 1;
  stroke-dasharray: 3 7;
  animation: dashFlow 9s linear infinite;
}
.schema__riser path {
  fill: none;
  stroke: var(--accent-2);
  stroke-width: 1;
  opacity: 0.55;
}
.schema__bus-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 1.8px;
  fill: var(--accent-2);
}
.schema__box {
  fill: none;
  stroke: var(--line-2);
  stroke-width: 1;
}
.schema__box--central { stroke: var(--corner); }
.schema__title {
  font-family: var(--head);
  font-size: 21px;
  font-weight: 600;
  fill: var(--fg);
}
.schema__norm {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 1.2px;
  fill: var(--dim);
}
.schema__central {
  font-family: var(--head);
  font-size: 26px;
  font-weight: 600;
  letter-spacing: 0.5px;
  fill: var(--accent);
}
.schema__dot circle { fill: var(--accent); }

/* --- 6.5 Leistungsbereiche ---------------------------------------------------------
   Der dreiteilige Streifen teilt sich die untere Linie mit dem Schema darueber:
   border-top:0 plus margin-top:-1px legt beide Kanten aufeinander. Die fehlende
   rechte Rahmenlinie liefert die letzte Karte selbst. */
.disciplines {
  display: grid;
  grid-template-columns: 1fr;
  border: 1px solid var(--line);
  border-top: 0;
  border-right: 0;
  margin-top: -1px;
}
@supports (width: min(290px, 100%)) {
  .disciplines { grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr)); }
}
/* Ein Leistungsbereich wird an zwei Stellen gezeigt: auf der Startseite als
   schmale Karte im Dreierstreifen, auf der Leistungsseite als breiter Rahmen
   ueber die volle Inhaltsbreite. Beides ist dasselbe Raster - es entscheidet
   allein die verfuegbare Breite, ob Beschreibung und Umfang neben- oder
   untereinander stehen. */
.discipline {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap-xl);
  padding: var(--pad-card);
  background: transparent;
  transition: background 0.4s;
}
@supports (width: min(280px, 100%)) {
  .discipline { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
}
.discipline:hover { background: var(--surface); }
/* Im Streifen zieht jede Karte ihre eigene rechte Linie - so liefert die
   letzte Karte den rechten Rahmen, der dem Streifen selbst fehlt. */
.disciplines > .discipline {
  background: var(--cell-bg);
  border-right: 1px solid var(--line);
  padding: var(--pad-card);
}
/* :where() haelt die Auszeichnung spezifitaetsfrei, damit ein .kicker im selben
   Block nicht ueberschrieben wird - und schliesst ihn zusaetzlich aus. */
.discipline :where(h2, h3:not(.kicker)),
.discipline__title {
  font-size: var(--h-sub);
  text-transform: uppercase;
  margin-bottom: 16px;
}
.disciplines .discipline :where(h2, h3),
.disciplines .discipline__title { font-size: 1.6875rem; margin-bottom: 12px; }
.discipline :where(p:not(.kicker)),
.discipline__body {
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--fg-lead);
}
.disciplines .discipline :where(p:not(.kicker)),
.disciplines .discipline__body {
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--dim);
  margin-bottom: 20px;
}
.discipline p.kicker { margin-bottom: 16px; }
.discipline__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 20px;
}
.discipline__head .discipline__icon { margin-bottom: 0; }
.discipline__icon {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
  color: var(--accent);
}
.discipline__icon .kicker { color: var(--dim); margin-bottom: 0; }
.discipline__code {
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dim);
}
/* Umfangsliste: auf der Leistungsseite gelineert (sie ist dort das Kernstueck
   und wird Zeile fuer Zeile gelesen), im Streifen der Startseite als knappe
   Mono-Aufzaehlung. */
.discipline__list { display: flex; flex-direction: column; }
.discipline__list li {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--fg-2);
}
.disciplines .discipline__list { gap: 7px; }
.disciplines .discipline__list li {
  padding: 0;
  border-bottom: 0;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.05em;
  line-height: 1.5;
}
.discipline__plus {
  flex: none;
  color: var(--accent);
  font-family: var(--mono);
  line-height: 1.55;
}
.discipline__norms {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* --- 6.6 Ablauf ---------------------------------------------------------------------
   Die Liste ist selbst das Haarlinienraster. */
.process {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
@supports (width: min(250px, 100%)) {
  .process { grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr)); }
}
.process__step {
  position: relative;
  background: var(--cell-bg);
  padding: clamp(20px, 2.2vw, 28px);
  transition: background 0.4s;
}
.process__step:hover { background: var(--surface-2); }
.process__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.process__num {
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.12em;
  color: var(--accent);
}
/* Verbindungsstrich zwischen Schrittnummer und Leistungsphase. */
.process__line {
  flex: 1;
  height: 1px;
  background: var(--line);
  display: block;
}
.process__lp {
  font-family: var(--mono);
  font-size: 0.59375rem;
  letter-spacing: 0.12em;
  color: var(--dim);
}
.process__title {
  font-size: 1.3125rem;
  line-height: 1.14;
  text-transform: uppercase;
  margin-bottom: 9px;
}
.process__desc {
  font-size: var(--fs-xs);
  line-height: 1.55;
  color: var(--dim);
}

/* Leistungsphasen 1-9 (Leistungsseite). Steht als .phases zusaetzlich zu .grid
   im Markup und macht daraus ein Haarlinienraster: engerer Spaltenboden,
   1px-Fugen, Zellen mit eigenem Grund. Bewusst ohne Einblendung - der Block
   ist ein Nachschlagewerk, keine Inszenierung. */
.phases {
  --card-min: 200px;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
.phase {
  background: var(--cell-bg);
  padding: 22px;
}
.phase__n {
  display: block;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.1em;
  color: var(--accent);
  margin-bottom: 10px;
}
.phase__t {
  font-size: 1.25rem;
  line-height: 1.15;
  text-transform: uppercase;
}

/* --- 6.7 Projektkachel ------------------------------------------------------------- */
.projectcard {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  background: transparent;
  color: inherit;
  transition: border-color 0.4s, transform 0.4s var(--ease);
}
.projectcard:hover,
.projectcard:focus-within {
  border-color: var(--accent);
  transform: translateY(-3px);
}
.projectcard__media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--surface);
}
@supports not (aspect-ratio: 4 / 3) {
  .projectcard__media { height: 0; padding-top: 75%; }
  .projectcard__media > picture,
  .projectcard__media > img,
  .projectcard__placeholder { position: absolute; inset: 0; }
}
.projectcard__media picture { display: block; height: 100%; }
.projectcard__media img { transition: transform 0.6s var(--ease); }
.projectcard:hover .projectcard__media img { transform: scale(1.03); }
/* Fehlt ein Foto, bleibt eine gezeichnete Flaeche stehen - kein leeres Loch. */
.projectcard__placeholder {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right,  var(--line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line) 1px, transparent 1px);
  background-size: 26px 26px;
}
.projectcard__body {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 20px;
  flex: 1;
}
.projectcard__top {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.projectcard__ref  { color: var(--accent); }
.projectcard__type { color: var(--dim); }
.projectcard__title {
  font-size: 1.4375rem;
  line-height: 1.1;
  text-transform: uppercase;
}
/* Die ganze Kachel ist anklickbar, aber nur der Titel ist der Link: das
   Pseudo-Element legt sich ueber die Flaeche. Der Text bleibt markierbar,
   die Adresse laesst sich kopieren und in einem neuen Tab oeffnen. */
.projectcard__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
}
.projectcard__link:hover { color: var(--accent); }
.projectcard__meta {
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.05em;
  color: var(--dim);
}
.projectcard__sep { color: var(--line-2); }
.projectcard__trades {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
/* Wo Behaelterabfragen laufen, atmet die Kachel mit ihrer eigenen Breite -
   nicht mit der des Fensters. Reiner Zugewinn, nichts haengt daran. */
@supports (container-type: inline-size) {
  .grid > .projectcard { container-type: inline-size; }
  @container (min-width: 420px) {
    .projectcard__body { padding: 24px; }
    .projectcard__title { font-size: 1.5625rem; }
  }
}

/* --- 6.8 Filterzeile ----------------------------------------------------------------- */
.filters {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding-block: 14px;
  margin-bottom: clamp(24px, 3vw, 40px);
}
.filters__group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.filters__count {
  font-family: var(--mono);
  font-size: 0.65625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  margin-left: auto;
}

/* --- 6.9 Projektseite ------------------------------------------------------------------ */
.crumbs {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding-block: 16px;
  font-family: var(--mono);
  font-size: 0.65625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}
.crumbs__item:hover,
.crumbs__item[aria-current="page"] { color: var(--accent); }
.crumbs__sep { color: var(--line-2); }

.projecthead { padding-block: clamp(40px, 5vw, 72px) clamp(28px, 3.5vw, 44px); }
.projecthead .kicker { margin-bottom: 18px; }
.projecthead h1 {
  font-size: var(--h-proj);
  text-transform: uppercase;
  letter-spacing: -0.02em;
  max-width: 24ch;
}
/* Aufmacherbild 21:9, ab 900 px flacher (3:1 - siehe Block "Projektseite"
   am Ende). Der Rahmen beschneidet nicht - das tut die innere
   .projecthead__media; so bleiben die Registriermarken stehen.
   Kein Filter und keine Farbwaesche: auf der Detailseite will der Pruefer
   die Unterlage sehen, nicht eine Stimmung (Strategie 1.3.8). */
.projecthead__figure {
  position: relative;
  border: 1px solid var(--line);
}
.projecthead__media {
  position: relative;
  overflow: hidden;
  background: var(--surface);
  aspect-ratio: 21 / 9;
}
/* Die Renderings sind helle Plandarstellungen: nie beschneiden (contain),
   sondern wie ein aufgelegtes Blatt vollstaendig und mittig zeigen. */
.projecthead__media img { width: 100%; height: 100%; object-fit: contain; }
@supports not (aspect-ratio: 21 / 9) {
  .projecthead__media { height: 0; padding-top: 42.85%; }
  .projecthead__media picture,
  .projecthead__media img { position: absolute; inset: 0; }
}

/* Die Beschriftung ueber jedem Absatz ist bewusst eine <h2>, die auf Mono
   heruntergesetzt wird: Gliederung fuer Hilfsmittel, ruhige Optik fuers Auge. */
.projectbody h2 {
  font-family: var(--mono);
  font-weight: 400;
  font-size: 0.65625rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1.4;
  margin-bottom: 16px;
}
.projectbody > * + h2 { margin-top: 34px; }
.projectbody p {
  font-size: 1.0625rem;
  line-height: 1.75;
  color: var(--fg-2);
}
.projectbody p + p { margin-top: 16px; }
.projectaside {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
@media (min-width: 900px) {
  /* 96px = 74px Navigation plus Luft. Die obere Dienstleiste scrollt weg und
     wird hier absichtlich nicht mitgerechnet. */
  .projectaside { position: sticky; top: 96px; }
}

/* Datenblatt fuer Vergabestellen. */
.facts {
  display: flex;
  flex-direction: column;
  margin: 0;
}
.fact {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.fact:last-child { border-bottom: 0; }
.fact__label {
  flex: none;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.fact__value {
  margin: 0;
  font-size: var(--fs-xs);
  text-align: right;
  color: var(--fg);
}

.projectnav {
  display: flex;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
.projectnav__prev,
.projectnav__next {
  flex: 1;
  background: var(--bg);
  padding: 14px;
  font-family: var(--mono);
  font-size: 0.65625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  transition: color var(--t), background var(--t);
}
.projectnav__prev { text-align: left; }
.projectnav__next { text-align: right; }
.projectnav__prev:hover,
.projectnav__next:hover { color: var(--accent); background: var(--surface); }

/* --- 6.10 Bildstrecke und Grossansicht --------------------------------------------------- */
.gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(12px, 1.5vw, 20px);
}
/* Feste zwei Spalten statt auto-fit: ein einzelnes Bild wuerde sich sonst
   ueber die volle Breite aufblasen und wie ein Fremdkoerper wirken. */
@media (min-width: 700px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
}
.gallery__item {
  position: relative;
  display: block;
  width: 100%;
  border: 1px solid var(--line);
  background: transparent;
  padding: 0;
  cursor: zoom-in;
  transition: border-color var(--t);
}
.gallery__item:hover { border-color: var(--accent); }
/* Die Bildhuelle der Bildstrecke - ohne Filter und ohne Farbwaesche, aus
   demselben Grund wie beim Aufmacher: Plaene und Details muessen lesbar sein. */
.gallery__media {
  position: relative;
  overflow: hidden;
  background: var(--surface);
  aspect-ratio: 4 / 3;
}
/* Auch hier: Plaene und Renderings vollstaendig zeigen, nicht anschneiden. */
.gallery__media img { width: 100%; height: 100%; object-fit: contain; }
@supports not (aspect-ratio: 4 / 3) {
  .gallery__media { height: 0; padding-top: 75%; }
  .gallery__media picture,
  .gallery__media img { position: absolute; inset: 0; }
}
.gallery__caption {
  display: block;
  padding: 10px 12px;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  text-align: left;
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: none;
  place-items: center;
  padding: clamp(16px, 4vw, 48px);
  background: rgba(5, 9, 7, 0.95);
}
.lightbox--open { display: grid; }
.lightbox__img {
  max-width: 100%;
  max-height: 82vh;
  width: auto;
  object-fit: contain;
  border: 1px solid var(--line-2);
}
.lightbox__close,
.lightbox__nav {
  position: absolute;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: 1px solid var(--line-2);
  color: var(--fg);
  background: rgba(5, 9, 7, 0.6);
  transition: border-color var(--t), color var(--t);
}
.lightbox__close:hover,
.lightbox__nav:hover { border-color: var(--accent); color: var(--accent); }
.lightbox__close {
  top: clamp(12px, 2vw, 24px);
  right: clamp(12px, 2vw, 24px);
  font-family: var(--mono);
  font-size: 1rem;
}
.lightbox__nav { top: 50%; transform: translateY(-50%); }
.lightbox__nav[data-gallery-prev] { left: clamp(8px, 2vw, 24px); }
.lightbox__nav[data-gallery-next] { right: clamp(8px, 2vw, 24px); }

/* --- 6.11 Assistent (Anfrage) -------------------------------------------------------------- */
.wizard {
  position: relative;
  border: 1px solid var(--line);
  padding: clamp(24px, 3vw, 40px);
  background: var(--surface);
}
.wizard__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 12px;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.wizard__head > :last-child { color: var(--dim); }
/* Vier Segmente, eines je Schritt: gefuellt ist genau so viel, wie getan ist
   (25/50/75/100 %). Ein Balken, der schon vor dem ersten Schritt bei 12 %
   stand, war Fortschrittstaeuschung - vor einem Publikum, das Taeuschung
   beruflich sucht. site.js schaltet .wizard__segment--done beim Blaettern. */
.wizard__progress {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  height: 3px;
  margin-bottom: 28px;
}
.wizard__segment {
  display: block;
  height: 100%;
  background: var(--line);
  transition: background var(--t-slow) var(--ease);
}
.wizard__segment--done { background: var(--accent); }
/* Jeder Schritt ist ein <fieldset> mit <legend> - nur so gehoeren die
   Auswahlkacheln fuer Hilfsmittel hoerbar zusammen. Der Browser malt um ein
   Fieldset von Haus aus einen Rahmen; der muss weg, den Rahmen zeichnet
   .wizard. */
.wizard__step {
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0;
}
.wizard__step > h2 {
  font-size: 1.75rem;
  text-transform: uppercase;
  margin-bottom: 22px;
}
/* Mit JavaScript ist immer genau ein Schritt sichtbar. Ohne JavaScript stehen
   alle Schritte untereinander und werden in einem Rutsch abgesendet - das
   Formular bleibt damit vollstaendig benutzbar. */
.js .wizard__step { display: none; }
.js .wizard__step--active { display: block; }
html:not(.js) .wizard__step + .wizard__step {
  border-top: 1px solid var(--line);
  padding-top: 24px;
  margin-top: 24px;
}
html:not(.js) .wizard__progress { display: none; }
.wizard__options {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  margin-bottom: 26px;
}
@supports (width: min(150px, 100%)) {
  .wizard__options { grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr)); }
}
.wizard__summary {
  font-size: var(--fs-xs);
  color: var(--dim);
  margin-bottom: 22px;
}
.wizard__nav {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  border-top: 1px solid var(--line-ui);
  padding-top: 20px;
}
/* visibility statt display: die Weiter-Schaltflaeche bleibt rechtsbuendig,
   auch wenn "Zurueck" im ersten Schritt fehlt. */
.wizard__nav [data-wizard-back][hidden] {
  display: inline-flex !important;
  visibility: hidden;
}
.wizard__done {
  text-align: center;
  padding: 26px 0;
  animation: riseIn 0.6s var(--ease) both;
}
.wizard__check {
  display: grid;
  place-items: center;
  width: 62px;
  height: 62px;
  margin: 0 auto 22px;
  border: 1px solid var(--accent);
  color: var(--accent);
}
.wizard__done h2 {
  font-size: 1.875rem;
  text-transform: uppercase;
  margin-bottom: 10px;
}
.wizard__done p {
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--dim);
  max-width: 40ch;
  margin: 0 auto 24px;
}

/* Auswaehlbare Kachel. Das eigentliche Bedienelement ist ein <input> darin -
   damit funktioniert die Auswahl ohne JavaScript und mit der Tastatur. */
.option {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  border: 1px solid var(--line-ui);
  background: transparent;
  color: var(--fg);
  padding: 15px 12px;
  font-family: var(--head);
  font-weight: 600;
  font-size: var(--fs-body);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
  transition: background var(--t), color var(--t), border-color var(--t);
}
.option:hover { border-color: var(--accent); }
.option input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}
.option__mark {
  flex: none;
  font-family: var(--mono);
  font-weight: 400;
  font-size: 0.75rem;
}
.option--selected {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
/* Das Feld selbst ist unsichtbar, also muss die Kachel seinen Fokus zeigen.
   :focus-within laeuft ueberall - es reagiert allerdings auch auf den Mausklick. */
.option:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Wo :has() laeuft, folgt die Kachel unmittelbar dem Zustand des Feldes -
   ohne JavaScript und ohne Klassenpflege - und der Ring erscheint nur noch
   bei Tastaturbedienung. */
@supports selector(:has(*)) {
  .option:focus-within { outline: none; }
  .option:has(input:checked) {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--on-accent);
  }
  .option:has(input:focus-visible) {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }
}

/* --- 6.12 Formular ----------------------------------------------------------------------- */
.form { display: flex; flex-direction: column; gap: 16px; }
.form__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}
@supports (width: min(150px, 100%)) {
  .form__row { grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr)); }
}
.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}
.field__label {
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}
/* Pflichtfelder werden im Text markiert, nicht nur farblich. */
.field__label abbr {
  color: var(--accent);
  text-decoration: none;
  border: 0;
}
.field__hint,
.field__error {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  line-height: 1.5;
}
.field__hint  { color: var(--dim); }
.field__error { color: var(--danger); }

.input,
.textarea,
.select {
  width: 100%;
  background-color: var(--bg);
  border: 1px solid var(--line-ui);
  border-radius: 0;
  padding: 11px 13px;
  color: var(--fg);
  font-family: var(--body);
  font-size: var(--fs-sm);
  line-height: 1.5;
  caret-color: var(--accent);
  transition: border-color var(--t);
}
.input::placeholder,
.textarea::placeholder { color: var(--dim); opacity: 1; }
.input:hover,
.textarea:hover,
.select:hover { border-color: var(--line-ui); }
.input:focus,
.textarea:focus,
.select:focus { border-color: var(--accent); outline: none; }
/* Der Tastaturring darf durch das obige outline:none NICHT verloren gehen -
   im Entwurf war genau das der Fall. */
.input:focus-visible,
.textarea:focus-visible,
.select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 0;
}
.textarea { resize: vertical; min-height: 120px; }
.select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 38px;
  /* Der Pfeil ist aus zwei Farbverlaeufen gezeichnet: kein Bild, keine
     Symbolschrift, keine externe Anfrage. */
  background-image:
    linear-gradient(45deg, transparent 50%, var(--dim) 50%),
    linear-gradient(135deg, var(--dim) 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(50% + 1px), calc(100% - 13px) calc(50% + 1px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}
.field--error .input,
.field--error .textarea,
.field--error .select { border-color: var(--danger); }

.checkbox {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  cursor: pointer;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--dim);
}
.checkbox input {
  margin-top: 4px;
  width: 16px;
  height: 16px;
  flex: none;
  accent-color: var(--accent);
}
.checkbox a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }

/* Fallenfeld gegen Werbeeintraege. Muss unsichtbar bleiben, darf aber nicht
   display:none sein - sonst fuellen es manche Programme gar nicht erst aus. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- 6.13 Karriere ------------------------------------------------------------------------- */
.job {
  background: var(--cell-bg);
  padding: clamp(24px, 3vw, 38px);
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
  align-items: center;
  transition: background 0.4s;
}
@supports (width: min(240px, 100%)) {
  .job { grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
}
.job:hover { background: var(--surface); }
.job__code {
  display: block;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 10px;
}
.job__mode { color: var(--dim); }
.job h2 {
  font-size: clamp(1.5rem, 2.6vw, 2.125rem);
  text-transform: uppercase;
  margin-bottom: 10px;
}
.job p {
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--dim);
  max-width: 52ch;
}
.job__tags {
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: flex-start;
}
.job__tags ul {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* --- 6.14 Ansprechpartner (Ueber uns) ----------------------------------------------------------
   Ein benannter Ingenieur mit Kammernummer entscheidet in der Vorauswahl einer
   Vergabestelle oft mehr als jeder Werbetext. Deshalb Bild, Name, Funktion und
   Erreichbarkeit als Datenblatt - nicht als Stimmungsbild. */
.person {
  position: relative;
  display: flex;
  flex-direction: column;
  background: transparent;
}
.person__photo { aspect-ratio: 1 / 1; }
@supports not (aspect-ratio: 1 / 1) {
  .person__photo { height: 0; padding-top: 100%; }
  .person__photo img { position: absolute; inset: 0; }
}
.person__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 20px;
  flex: 1;
}
.person__name {
  font-size: 1.375rem;
  line-height: 1.1;
  text-transform: uppercase;
}
.person__role {
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.person__field {
  font-size: var(--fs-xs);
  line-height: 1.55;
  color: var(--dim);
}
.person__facts {
  display: flex;
  flex-direction: column;
  margin: 14px 0 0;
}
.person__fact {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}
.person__fact:last-child { border-bottom: 0; }
.person__fact dt {
  flex: none;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.person__fact dd {
  margin: 0;
  font-size: var(--fs-xs);
  text-align: right;
}

/* --- 6.15 Fuer Vergabestellen -------------------------------------------------------------------
   Eine Vergabestelle prueft in wenigen Minuten: geeignet, vergleichbar,
   nachgewiesen, erreichbar. Der Block beantwortet das in dieser Reihenfolge -
   Text und Nachweise nebeneinander, Handlung darunter. */
.vergabe {
  padding-block: var(--pad-section);
  border-bottom: 1px solid var(--line);
}
.vergabe--compact { padding-block: var(--pad-section-sm); }
.vergabe__inner {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap-xl);
  align-items: start;
  border: 1px solid var(--line);
  padding: clamp(26px, 3vw, 44px);
  background: var(--surface);
}
@supports (width: min(320px, 100%)) {
  .vergabe__inner { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
}
.vergabe__text { min-width: 0; }
.vergabe__title {
  font-size: var(--h-sub);
  text-transform: uppercase;
  margin-bottom: 14px;
}
.vergabe__body {
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--fg-lead);
  margin-bottom: 18px;
}
.vergabe__list {
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.vergabe__list li {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--fg-2);
}
.vergabe__plus {
  flex: none;
  color: var(--accent);
  font-family: var(--mono);
  line-height: 1.55;
}
.vergabe__facts {
  display: flex;
  flex-direction: column;
  margin: 0;
}
.vergabe__fact {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.vergabe__fact:last-child { border-bottom: 0; }
.vergabe__fact dt {
  flex: none;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.vergabe__fact dd {
  margin: 0;
  font-size: var(--fs-xs);
  text-align: right;
  color: var(--fg);
}
/* Handlung und Direktkontakt laufen ueber die volle Breite des Rahmens - sie
   gehoeren zu beiden Spalten. */
.vergabe__actions,
.vergabe__contact { grid-column: 1 / -1; }
.vergabe__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
.vergabe__contact {
  font-size: var(--fs-xs);
  line-height: 1.6;
  color: var(--dim);
}
.vergabe__contact strong { color: var(--fg); font-weight: 500; }
.vergabe__contact a { color: var(--accent); }

/* --- 6.15 Gruenes Handlungsfeld ----------------------------------------------------------------
   Die eine Vollfarbflaeche der Seite. Ohne untere Linie - der Fuss schliesst
   sie mit seiner eigenen oberen Linie ab. */
.ctafield {
  position: relative;
  overflow: hidden;
  background: var(--field);
  color: var(--on-field);
}
.ctafield__lines {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right,  var(--field-grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--field-grid) 1px, transparent 1px);
  /* 44px statt 54px wie im Aufmacher: auf dem helleren Grund traegt ein
     feineres Gewebe. Das ist Absicht, kein Versehen. */
  background-size: 44px 44px;
}
.ctafield__inner {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(30px, 4vw, 60px);
  align-items: center;
  padding-block: clamp(56px, 7vw, 96px);
}
@supports (width: min(340px, 100%)) {
  .ctafield__inner { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
}
.ctafield__text { min-width: 0; }
.ctafield__kicker {
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--on-field-dim);
  margin-bottom: 18px;
}
.ctafield__title {
  font-size: clamp(2rem, 4.4vw, 3.625rem);
  text-transform: uppercase;
  color: var(--on-field);
  line-height: 1;
  margin-bottom: 18px;
}
.ctafield__body {
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--on-field-mut);
  max-width: 50ch;
}
.ctafield__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

/* --- 6.16 Rechtstexte ---------------------------------------------------------------------------- */
.legal__tabs {
  display: flex;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line-ui);
  margin-bottom: clamp(30px, 4vw, 52px);
}
.legal__tab {
  flex: 1;
  background: var(--bg);
  color: var(--dim);
  padding: 14px 10px;
  font-family: var(--mono);
  font-size: 0.65625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  transition: background var(--t), color var(--t);
}
.legal__tab:hover { color: var(--accent); }
.legal__tab--active,
.legal__tab[aria-current="page"] {
  background: var(--surface);
  color: var(--accent);
}
.legal__body {
  display: flex;
  flex-direction: column;
  gap: 30px;
}
.legal__block h2 {
  font-size: 1.375rem;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 10px;
}
.legal__block p {
  font-size: 0.96875rem;
  line-height: 1.75;
  color: var(--fg-lead);
  /* Tragend: die Rechtstexte enthalten echte Zeilenumbrueche (Anschrift,
     Kontaktblock), die im Ausgabetext erhalten bleiben muessen. */
  white-space: pre-line;
}

/* --- 6.17 Fehlerseite ------------------------------------------------------------------------------ */
.errorpage {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  padding-block: clamp(70px, 12vw, 160px);
  min-height: 52vh;
}
.errorpage__code {
  font-family: var(--head);
  font-weight: 600;
  font-size: clamp(5rem, 18vw, 12rem);
  line-height: 0.85;
  letter-spacing: -0.03em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.errorpage h1 { font-size: var(--h-sec); text-transform: uppercase; }
.errorpage p {
  font-size: var(--fs-lead);
  line-height: 1.65;
  color: var(--fg-lead);
  max-width: 52ch;
}

/* --- 6.18 Unterseitenkopf (gemeinsames Muster) ------------------------------------------------------- */
.pagehead {
  display: flex;
  align-items: baseline;
  gap: 18px;
  margin-bottom: 20px;
}
.pagehead h1 {
  font-size: var(--h-page);
  text-transform: uppercase;
  letter-spacing: -0.02em;
}
.pagelead {
  max-width: 62ch;
  font-size: 1.125rem;
  line-height: 1.65;
  color: var(--fg-lead);
  margin-bottom: clamp(34px, 4.5vw, 60px);
}

/* Kurze Rueckmeldung nach dem Kopieren einer Referenznummer. */
[data-copy].is-copied { color: var(--accent); }
[data-copy].is-copied::after {
  content: " kopiert";
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
}


/* =============================================================================
   7 - DRUCK
   -----------------------------------------------------------------------------
   Eine Referenz muss als sauberes Datenblatt auf weissem Papier herauskommen:
   Vergabestellen drucken Referenzblaetter aus und heften sie zur Akte. Alles
   Dekorative faellt weg, Ziel ist EINE Seite.
   ========================================================================== */

@media print {
  @page {
    size: A4 portrait;
    margin: 16mm 14mm;
  }

  :root {
    --bg: #ffffff;
    --bg-alt: #ffffff;
    --surface: #ffffff;
    --surface-2: #ffffff;
    --cell-bg: #ffffff;
    --fg: #000000;
    --fg-2: #000000;
    --fg-lead: #1a1a1a;
    --dim: #3a3a3a;
    --accent: #000000;
    --on-accent: #ffffff;
    --line: #9a9a9a;
    --line-2: #6a6a6a;
    /* Auch die kraeftigeren Bedienlinien muessen umgestellt werden - sonst
       drucken Formularfelder in einem hellen Grau, das auf Papier verschwindet. */
    --line-ui: #6a6a6a;
    --line-ui-strong: #4a4a4a;
    --corner: #9a9a9a;
  }

  html, body {
    background: #fff !important;
    color: #000 !important;
    font-size: 10.5pt;
    line-height: 1.45;
    overflow: visible;
  }

  /* Chrom, Dekor und alles Anklickbare, das auf Papier sinnlos ist. */
  .topbar,
  .nav,
  .nav__drawer,
  .nav__burger,
  .ctabar,
  .cursor,
  .skiplink,
  .langswitch,
  .lightbox,
  .filters,
  .projectnav,
  .wizard,
  .ctafield,
  .hero__grid-lines,
  .hero__glow,
  .hero__scanline,
  .footer__grid,
  .footer__sister,
  .corner,
  .btn,
  .chip,
  .section__link {
    display: none !important;
  }

  /* Eingeblendete Inhalte muessen auf Papier stehen, auch wenn nie gescrollt
     wurde. */
  .js [data-reveal],
  .js [data-reveal].is-revealed {
    opacity: 1 !important;
    transform: none !important;
  }

  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    box-shadow: none !important;
    text-shadow: none !important;
  }

  .shell,
  .shell--narrow {
    max-width: none;
    padding-inline: 0;
  }

  .section,
  .section--raised,
  .statsband {
    padding-block: 8mm;
    background: #fff !important;
    border-color: #9a9a9a;
  }
  /* Die Spaltenregeln des Kennzahlenbandes wuerden auf Papier als graue
     Flaeche kommen - hier reichen die Zellen selbst. */
  .statsband__grid { background: none !important; padding-block: 4mm; }

  h1, h2, h3 {
    color: #000 !important;
    break-after: avoid;
    page-break-after: avoid;
  }

  .projecthead { padding-block: 0 4mm; }
  .projecthead h1 { font-size: 20pt; }
  .projectbody h2 { color: #000 !important; }
  .projectbody p  { color: #000 !important; font-size: 10pt; }

  /* Das Datenblatt ist der Kern des Ausdrucks: nie umbrechen. */
  .facts,
  .fact,
  .vergabe__fact,
  .pluslist__item {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .facts { border: 1px solid #6a6a6a; padding: 3mm 4mm; }
  .fact__label { color: #333 !important; }
  .fact__value { color: #000 !important; }

  /* Bilder bleiben - sie belegen die Referenz. Graustufen statt Gruenwaesche,
     damit sie auf Schwarz-Weiss-Geraeten nicht zulaufen. */
  .duotone::after { display: none !important; }
  .duotone img,
  .projecthead__figure img,
  .gallery__item img,
  .projectcard__media img {
    filter: grayscale(1) contrast(1.05) brightness(1) !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .projecthead__figure { border-color: #6a6a6a; }
  .projecthead__media { max-height: 62mm; }
  .gallery { grid-template-columns: 1fr 1fr; gap: 4mm; }
  .gallery__item {
    border-color: #9a9a9a;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .split,
  .split--aside { display: block; }
  .projectaside {
    position: static;
    margin-top: 6mm;
    gap: 4mm;
  }

  /* Ziel eines Verweises hinter den Text setzen - auf Papier ist ein Link
     sonst wertlos. Interne Sprungmarken bleiben stumm. */
  a[href^="http"]::after,
  a[href^="mailto:"]::after,
  a[href^="tel:"]::after {
    content: " (" attr(href) ")";
    font-family: var(--mono);
    font-size: 8pt;
    color: #444;
    word-break: break-all;
  }
  a[href^="#"]::after { content: ""; }

  .prose,
  .legal__block p { color: #000 !important; }

  /* Fusszeile des Ausdrucks: wer, woher - ohne Platz fuer die schwebende
     Leiste, die es auf Papier nicht gibt. */
  .footer { border-top: 1px solid #9a9a9a; }
  .footer__bottom {
    padding-bottom: 0;
    color: #333 !important;
    font-size: 8pt;
  }
}


/* =============================================================================
   BEWEGUNG AUF WUNSCH ABSCHALTEN
   -----------------------------------------------------------------------------
   Nicht jeder stellt die Systemeinstellung um, und manche merken erst auf der
   Seite, dass ihnen die Bewegung zu viel ist. Der Schalter in der Fusszeile
   setzt data-motion="reduced" auf <html>; gespeichert wird das in localStorage,
   also ohne Cookie und ohne Einwilligung.
   ========================================================================== */
:root[data-motion="reduced"] *,
:root[data-motion="reduced"] *::before,
:root[data-motion="reduced"] *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}
:root[data-motion="reduced"] [data-reveal],
:root[data-motion="reduced"] [data-reveal].is-revealed {
  opacity: 1 !important;
  transform: none !important;
}
:root[data-motion="reduced"] [data-magnetic] { transform: none !important; }
:root[data-motion="reduced"] .hero__scanline,
:root[data-motion="reduced"] .cursor { display: none !important; }

/* Der Schalter selbst */
.motion-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 1px solid var(--line-ui);
  border-radius: 0;
  padding: 7px 12px;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.3s, border-color 0.3s;
}
.motion-toggle:hover { color: var(--accent); border-color: var(--accent); }
.motion-toggle__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}
:root[data-motion="reduced"] .motion-toggle__dot { background: var(--dim); }

/* =============================================================================
   NACHTRAG · Bausteine der zuletzt gebauten Seiten
   ========================================================================== */

/* Wird vom Skript gesetzt und entfernt: gefilterte Kacheln, der Leer-Hinweis
   der Referenzliste und die Schritt-Schaltflaechen des Assistenten, die ohne
   JavaScript nichts zu tun haetten. */
.is-hidden { display: none !important; }

/* Ruhiger Hinweiskasten - kein Alarm, nur eine Erklaerung am Rand. */
.note {
  border-left: 2px solid var(--line-ui);
  padding: 14px 0 14px 18px;
  color: var(--dim);
  font-size: var(--fs-sm);
  line-height: 1.6;
}
.note strong { color: var(--fg); font-weight: 600; }
.note a { color: var(--accent); text-underline-offset: 3px; }

/* Was das Buero Bewerberinnen und Bewerbern bietet - Strichzeichnung wie die
   uebrigen Karten, ohne Fuellung. */
.perk {
  border: 1px solid var(--line);
  padding: var(--pad-card, clamp(22px, 2.4vw, 32px));
  background: transparent;
  list-style: none;
}
.perk__title {
  font-family: var(--head);
  font-size: clamp(19px, 1.6vw, 22px);
  line-height: 1.15;
  margin: 0 0 8px;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
.perk__text {
  margin: 0;
  color: var(--dim);
  font-size: var(--fs-sm);
  line-height: 1.6;
}


/* =============================================================================
   STANDORTKARTE  (.map3d)
   -----------------------------------------------------------------------------
   Drei Stufen: SVG vom Server (immer), 3D-Buehne (Desktop + WebGL), Panel
   des angeflogenen Projekts. Rechts die Projektliste, die in Stufe 2 zur
   Steuerung wird. Vertrag: _extract/contract.map3d.md
   ========================================================================== */
.map3d {
  position: relative;
  padding-block: clamp(56px, 7vw, 100px) clamp(40px, 5vw, 72px);
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(ellipse at 30% 20%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 60%),
    var(--bg);
}
.map3d__head { margin-bottom: clamp(22px, 3vw, 36px); }
.map3d__head .section__head { margin-bottom: 14px; }
.map3d__hint {
  margin: 0;
  color: var(--dim);
  font-size: var(--fs-sm);
  transition: opacity 0.4s;
}
/* Im Anflug bleibt der Hinweis sichtbar - map3d.js tauscht ihn gegen den
   Text zu Chips und Rueckweg (data-map3d-hint-focus). In der Uebersicht
   blendet map3d.js ihn per hidden-Attribut aus und nach 8 s Stille wieder
   ein. Er behaelt seinen Platz, damit der Abschnittskopf nicht springt. */
.map3d__hint[hidden] { display: block; visibility: hidden; }

/* Zweispaltig: Karte links, Liste rechts. Unter 900 px untereinander -
   dort laeuft ohnehin nur die SVG. */
.map3d__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(18px, 2.4vw, 32px);
}
@media (min-width: 900px) {
  .map3d__body { grid-template-columns: minmax(0, 1fr) clamp(240px, 24vw, 320px); align-items: start; }
}

/* Die Hoehe gibt in Stufe 0 die SVG vor, in Stufe 2 das Format 16:10 (siehe
   .map3d--ready weiter unten) - keine vh-Mindesthoehe, die auf flachen
   Bildschirmen Leerraum unter der Karte liesse. */
.map3d__canvas {
  position: relative;
}

/* --- Stufe 0: SVG ------------------------------------------------------------ */
.map3d__fallback {
  position: relative;
  margin: 0;
  padding: clamp(10px, 1.4vw, 18px);
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 60%, transparent);
}
.map3d__svg { display: block; width: 100%; height: auto; }
.map3d__svg-grid line { stroke: var(--fg); stroke-opacity: 0.06; stroke-width: 1; vector-effect: non-scaling-stroke; }
/* Fluesse in der Textfarbe, durchgezogen: Gruen bedeutet auf dieser Karte
   "Projekt" und sonst nichts; gestrichelt laese man sie als Bahn oder Strasse. */
.map3d__svg-river { fill: none; stroke: var(--fg); stroke-opacity: 0.1; stroke-width: 1.4; vector-effect: non-scaling-stroke; }
.map3d__svg-river-name { font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; fill: var(--fg); fill-opacity: 0.45; }
.map3d__svg-link { stroke: var(--dim); stroke-opacity: 0.45; stroke-width: 1; stroke-dasharray: 2 6; vector-effect: non-scaling-stroke; }
.map3d__svg-km,
.map3d__svg-label,
.map3d__svg-office text,
.map3d__svg-pin-text {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  fill: var(--dim);
}
.map3d__svg-label--major { font-family: var(--head); font-size: 20px; font-weight: 600; letter-spacing: 0.02em; text-transform: none; fill: var(--fg); }
.map3d__svg-office circle { fill: none; stroke: var(--fg); stroke-opacity: 0.7; stroke-width: 1; vector-effect: non-scaling-stroke; }
.map3d__svg-office .map3d__svg-office-dot { fill: var(--fg); stroke: none; }
.map3d__svg-pin { cursor: pointer; outline: none; }
/* Unsichtbare Zielflaeche: transparent gefuellt (nicht fill: none, sonst
   faengt sie keine Zeiger). Unter 700 px wird sie per CSS-Geometrie groesser. */
.map3d__svg-pin-hit { fill: transparent; stroke: none; }
.map3d__svg-pin-glow { fill: var(--accent); fill-opacity: 0.12; transition: fill-opacity 0.3s; }
.map3d__svg-pin-dot { fill: var(--accent); }
.map3d__svg-pin-mark { fill: var(--accent); fill-opacity: 0.85; }
/* Die Nummer steht immer - auf dem Telefon gibt es kein Hover. */
.map3d__svg-pin-text { fill: var(--accent); font-size: 10px; }
.map3d__svg-pin:hover .map3d__svg-pin-glow,
.map3d__svg-pin:focus-visible .map3d__svg-pin-glow { fill-opacity: 0.32; }
.map3d__svg-pin:focus-visible .map3d__svg-pin-dot { stroke: var(--bg); stroke-width: 2; }

/* --- Stufe 2: Buehne ---------------------------------------------------------- */
.map3d__stage {
  position: absolute;
  inset: 0;
  border: 1px solid var(--line);
  overflow: hidden;
  background: transparent;
  cursor: default;
}
.map3d__stage canvas { display: block; width: 100%; height: 100%; }
.map3d__stage:focus-visible { outline-offset: -2px; }
.map3d--ready .map3d__fallback { display: none; }
/* Buehnenformat 16:10 (Entscheid der Synthese): die Bounds von 70 x 45 km
   passen hinein, 16:7 schnitte Nord und Sued ab. map3d.js liest die echte
   Groesse per ResizeObserver und rahmt die Kamera neu. */
.map3d--ready .map3d__canvas { aspect-ratio: 16 / 10; }
@supports not (aspect-ratio: 16 / 10) {
  .map3d--ready .map3d__canvas { min-height: min(62vw, 760px); }
}
/* Laeuft die 3D-Buehne, rueckt die Legende als Kartenlegende in die obere
   linke Ecke der Buehne - sonst stuende sie als einziges Element im Fluss
   ueber dem Rahmen. Panel und Zurueck-Knopf behalten die unteren Ecken. */
.map3d--ready .map3d__legend {
  position: absolute;
  top: 12px;
  left: 14px;
  right: 14px;
  z-index: 2;
  margin: 0;
  pointer-events: none;
  transition: opacity 0.4s;
}
/* Waehrend ein Projekt angeflogen ist, braucht niemand die Legende - und das
   Panel darf bis unter die obere Kante wachsen. */
.map3d--focused .map3d__legend { opacity: 0; }

/* --- Panel des angeflogenen Projekts ------------------------------------------
   Titelbild oben randlos, darunter der Textkoerper mit Innenabstand. Das Panel
   selbst darf nicht beschneiden (Registriermarken), deshalb rollt im Notfall
   nur der Textkoerper. */
.map3d__panel {
  position: absolute;
  left: clamp(14px, 2vw, 28px);
  bottom: clamp(14px, 2vw, 28px);
  z-index: 3;
  display: flex;
  flex-direction: column;
  width: min(380px, calc(100% - 2 * clamp(14px, 2vw, 28px)));
  max-height: calc(100% - 2 * clamp(14px, 2vw, 28px));
  padding: 0;
  background: color-mix(in srgb, var(--bg) 84%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--line-ui);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease);
  pointer-events: none;
}
.map3d__panel--open { opacity: 1; transform: none; pointer-events: auto; }
.map3d__panel-kicker { margin: 0 0 8px; color: var(--accent); }
.map3d__panel-title {
  margin: 0 0 4px;
  font-size: clamp(20px, 1.7vw, 24px);
  line-height: 1.08;
  text-transform: uppercase;
}
.map3d__panel-title:focus-visible { outline-offset: 4px; }
.map3d__panel-meta { margin: 0 0 10px; color: var(--dim); font-size: var(--fs-sm); }
.map3d__panel-facts { margin: 0 0 12px; }
.map3d__panel-facts .fact { padding-block: 6px; }
/* Gewerke als eine Mono-Zeile mit Punkten statt Etiketten: das Panel steht
   ueber der Karte und hat die Hoehe nicht, die eine Kachel hat. */
.map3d__panel-trades {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.06em;
  line-height: 1.7;
  color: var(--dim);
}
.map3d__panel-trade { display: inline; }
.map3d__panel-trade + .map3d__panel-trade::before { content: " \00b7 "; }

/* --- Zurueck, Legende ----------------------------------------------------------- */
.map3d__back {
  position: absolute;
  right: clamp(14px, 2vw, 28px);
  bottom: clamp(14px, 2vw, 28px);
  z-index: 3;
  background: color-mix(in srgb, var(--bg) 84%, transparent);
}
.map3d__legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin: 10px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}
.map3d__legend-dot,
.map3d__legend-office {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: none;
}
.map3d__legend-dot { background: var(--accent); }
.map3d__legend-office { border: 1px solid var(--fg); }
.map3d__legend-note { margin-left: auto; text-transform: none; letter-spacing: 0.02em; }

/* --- Liste rechts ---------------------------------------------------------------- */
.map3d__side { display: flex; flex-direction: column; gap: 14px; }
.map3d__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
@media (min-width: 900px) {
  .map3d__list { max-height: min(72vh, 760px); overflow-y: auto; scrollbar-width: thin; }
}
.map3d__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 2px 12px;
  padding: 11px 14px;
  background: var(--bg);
  color: var(--fg);
  text-decoration: none;
  transition: background 0.3s, color 0.3s;
}
/* Hover muss man sehen: --surface auf --bg ist 1,1:1 und damit unsichtbar.
   Deshalb ein halber Akzentbalken und der Titel in Akzent; aktiv behaelt den
   vollen Balken (steht spaeter im Stylesheet und gewinnt). */
.map3d__item:hover,
.map3d__item--hover { background: var(--surface); color: var(--fg); box-shadow: inset 3px 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
.map3d__item:hover .map3d__item-title,
.map3d__item--hover .map3d__item-title { color: var(--accent); }
.map3d__item--active,
.map3d__item[aria-current="true"] { background: var(--surface); box-shadow: inset 3px 0 0 var(--accent); }
.map3d__item-ref { grid-row: 1 / span 2; align-self: start; font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; color: var(--accent); padding-top: 4px; }
.map3d__item-title { font-family: var(--head); font-size: 17px; line-height: 1.15; text-transform: uppercase; transition: color 0.3s; }
.map3d__item-loc { font-family: var(--mono); font-size: 11px; line-height: 1.5; letter-spacing: 0.06em; color: var(--dim); text-transform: uppercase; }
.map3d__all { align-self: flex-start; }

/* --- Reduzierte Bewegung: keine Uebergaenge, die Karte bleibt bedienbar ---------- */
@media (prefers-reduced-motion: reduce) {
  .map3d__panel { transition: opacity 0.15s linear; transform: none; }
  .map3d__svg-pin-glow, .map3d__svg-pin-text, .map3d__hint, .map3d__item { transition: none; }
}
:root[data-motion="reduced"] .map3d__panel { transition: opacity 0.15s linear; transform: none; }

/* --- Druck: die SVG-Karte ist die Druckfassung -------------------------------------- */
@media print {
  .map3d__stage, .map3d__panel, .map3d__back, .map3d__hint { display: none !important; }
  .map3d--ready .map3d__fallback { display: block; }
  .map3d__svg-grid line { stroke: #000; stroke-opacity: 0.08; }
  .map3d__svg-river { stroke: #333; stroke-opacity: 0.6; }
  .map3d__svg-pin-dot, .map3d__svg-pin-mark { fill: #000; }
  .map3d__svg-label--major, .map3d__svg-office text, .map3d__svg-label, .map3d__svg-km, .map3d__svg-river-name, .map3d__svg-pin-text { fill: #000; fill-opacity: 1; }
}


/* =============================================================================
   STANDORTKARTE - Nachtrag Arbeitsstrang "Karte" (Synthese Punkt 11)
   -----------------------------------------------------------------------------
   Panel mit Titelbild, Legende mit Massstab und Nordpfeil, SVG-Karte auf dem
   Telefon mit greifbaren Zielflaechen. Ergaenzt den Block STANDORTKARTE oben.
   ========================================================================== */

/* --- Panel: Titelbild oben, Textkoerper darunter -------------------------------- */
/* 16:9, aber nachgiebig: reicht die Buehnenhoehe nicht fuer Bild und Text,
   gibt zuerst das Bild nach (vierfaches Schrumpfgewicht), der Text rollt
   erst, wenn auch das nicht reicht. */
.map3d__panel-media {
  flex: 0 4 auto;
  min-height: 96px;
  aspect-ratio: 16 / 9;
  border-bottom: 1px solid var(--line);
}
@supports not (aspect-ratio: 16 / 9) {
  .map3d__panel-media { height: 0; padding-top: 56.25%; }
  .map3d__panel-media picture,
  .map3d__panel-media img { position: absolute; inset: 0; }
}
.map3d__panel-media picture { display: block; height: 100%; }
/* Renderings sind helle Planblaetter: ganz zeigen statt anschneiden - der
   Kunde hat die beschnittene Fassung zu Recht moniert. */
.map3d__panel-media img { width: 100%; height: 100%; object-fit: contain; background: var(--surface); }
.map3d__panel-media img { transition: filter 0.6s var(--ease), transform 0.6s var(--ease); }
.map3d__panel-media::after { transition: opacity 0.6s var(--ease); }
/* Dieselbe Belohnung wie auf den Projektkacheln: aus der gruenen Platte wird
   beim Hover das Foto. */
.map3d__panel:hover .map3d__panel-media img,
.map3d__panel:focus-within .map3d__panel-media img { filter: none; transform: scale(1.03); }
.map3d__panel:hover .map3d__panel-media::after,
.map3d__panel:focus-within .map3d__panel-media::after { opacity: 0; }
.map3d__panel-body {
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  padding: clamp(14px, 1.6vw, 20px) clamp(18px, 2vw, 24px) clamp(16px, 1.8vw, 22px);
}
.map3d__panel-facts .fact__value { font-size: var(--fs-sm); }

/* --- Legende: Zeichen, Gitterzelle, Nordpfeil ---------------------------------- */
.map3d__legend-item { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.map3d__legend abbr { text-decoration: none; }
/* Eine Gitterzelle als kleines Quadrat - der Massstab der Karte (5 km). */
.map3d__legend-cell {
  display: inline-block;
  width: 9px;
  height: 9px;
  flex: none;
  border: 1px solid var(--fg);
  opacity: 0.55;
}
/* Nordpfeil: ein Dreieck, Norden ist oben. */
.map3d__legend-north {
  display: inline-block;
  width: 0;
  height: 0;
  flex: none;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 9px solid var(--fg);
  opacity: 0.8;
}

/* --- Telefon: die SVG-Karte wird mit dem viewBox auf ein Drittel verkleinert.
   Zielflaechen und Nummern wachsen per CSS-Geometrie (r, font-size) wieder
   auf greifbare Groessen; Hilfstexte, die bei 4 px unlesbar waeren, fallen
   weg. Ohne Unterstuetzung der CSS-Geometrie bleiben die Attributwerte. ----- */
@media (max-width: 699.98px) {
  .map3d__svg-km,
  .map3d__svg-office-text,
  .map3d__svg-river-name,
  .map3d__svg-pin-mark { display: none; }
  .map3d__svg-pin-hit { r: 40; }   /* bei ~320 px Kartenbreite: 25 px Zielflaeche */
  .map3d__svg-pin-glow { r: 24; }
  .map3d__svg-pin-dot { r: 10; }
  .map3d__svg-pin-text { font-size: 26px; }
  .map3d__svg-label { font-size: 24px; }
  .map3d__svg-label--major { font-size: 42px; }
  .map3d__svg-office circle { r: 18; }
  .map3d__svg-office .map3d__svg-office-dot { r: 5; }
  .map3d__legend {
    justify-content: flex-start;
    font-size: 11px;
    gap: 8px 14px;
  }
  .map3d__legend-note { margin-left: 0; flex-basis: 100%; }
}


/* =============================================================================
   WORKSTREAM B - PROJEKTSEITE, REFERENZEN, REFERENZBLATT
   -----------------------------------------------------------------------------
   Eckdatenleiste unter dem Projekttitel, Brotkrumen-Nummer, Erklaerzeile im
   Datenblatt, Filtergruppen der Referenzliste und das druckbare Referenzblatt
   (views/layout-sheet.php + pages/referenzblatt.php).
   ========================================================================== */

/* --- Eckdaten unter der Ueberschrift ------------------------------------------
   Eine Zeile, Mono 11 px, Haarlinie oben und unten: das, was eine Vergabestelle
   zuerst sucht, steht so VOR dem Bild - nicht erst nach 1000 px Scrollweg. */
.projecthead__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  margin: 28px 0 0;
  padding-block: 12px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.08em;
}
.projecthead__fact { display: flex; gap: 8px; align-items: baseline; }
.projecthead__factlabel {
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: var(--fs-mono-sm);
}
.projecthead__factvalue { margin: 0; color: var(--fg); }

/* Ab 900 px wird der Aufmacher flacher (2:1): die Unterlage bleibt dank
   object-fit: contain vollstaendig sichtbar, und Fliesstext und Datenblatt
   ruecken trotzdem in den ersten Bildschirm. */
@media (min-width: 900px) {
  .projecthead__media { aspect-ratio: 2 / 1; max-height: min(60vh, 600px); margin-inline: auto; }
  @supports not (aspect-ratio: 2 / 1) {
    .projecthead__media { padding-top: 50%; }
  }
}

/* Die Referenznummer im Pfad - ein Zusatz hinter dem Kurztitel, nicht der Ort selbst. */
.crumbs__ref { color: var(--dim); margin-left: 6px; }

/* Erklaerzeile unter einem Datenblattwert (Kostengruppen): Nebentext, kleiner.
   Die Nummern selbst tragen als <abbr> den ausgeschriebenen Titel. */
.fact__note {
  display: block;
  margin-top: 4px;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--dim);
}
.fact__value abbr[title] {
  text-decoration: underline dotted;
  text-underline-offset: 2px;
  cursor: help;
}

/* --- Filtergruppen der Referenzliste -------------------------------------------
   Bis zu drei Reihen (Art/Region, Leistungsphasen, Gewerke) uebereinander, der
   Zaehler rechts daneben. Die Gruppenbeschriftung ist Mono wie die Chips, aber
   ohne Rahmen - sie ist Beschriftung, keine Schaltflaeche. */
.filters__groups {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1 1 auto;
}
.filters__group { align-items: center; }
.filters__label {
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  margin-right: 4px;
  min-width: 11ch;
}

/* --- Referenzblatt --------------------------------------------------------------
   Weiss, Schwarz, DIN A4. Am Bildschirm liegt das Blatt als weisse Flaeche auf
   hellem Grund, im Druck IST es das Papier. Die Farbtoken der Website bleiben
   unangetastet - das Blatt setzt seine wenigen Farben selbst, damit es auch am
   Bildschirm so aussieht, wie es aus dem Drucker kommt. */
.sheet-root { background: #e8ebe9; }
.sheet-body {
  background: #e8ebe9;
  color: #111;
  font-family: var(--body);
  min-height: 100vh;
  padding: clamp(16px, 3vw, 40px) 16px;
}
.sheet {
  box-sizing: border-box;
  max-width: 210mm;
  margin: 0 auto;
  padding: 16mm 14mm;
  background: #fff;
  color: #111;
  box-shadow: 0 2px 24px rgba(0, 0, 0, 0.12);
  font-size: 11pt;
  line-height: 1.5;
}
.sheet a { color: #111; text-decoration: underline; text-underline-offset: 2px; }
.sheet__head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px 32px;
  padding-bottom: 6mm;
  border-bottom: 1px solid #000;
}
.sheet__brand { margin: 0; }
.sheet__brand img { display: block; width: 176px; height: auto; }
.sheet__company {
  font-style: normal;
  font-size: 9.5pt;
  line-height: 1.55;
  text-align: right;
  color: #222;
}
.sheet__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  margin: 6mm 0 0;
  padding: 10px 12px;
  border: 1px dashed #9a9a9a;
}
.sheet__hint {
  flex: 1 1 100%;
  margin: 0;
  font-size: 9pt;
  line-height: 1.5;
  color: #444;
}
/* Die stillen Schaltflaechen der Website sind fuer dunklen Grund gezeichnet -
   auf Weiss brauchen sie eine eigene Kontrastfarbe. */
.sheet__actions .btn--quiet { color: #111; border-color: #6a6a6a; }
.sheet__actions .btn--quiet:hover { color: #000; border-color: #000; }
.sheet__kicker {
  margin: 8mm 0 2mm;
  font-family: var(--mono);
  font-size: 9pt;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #444;
}
.sheet__title {
  margin: 0;
  font-family: var(--head);
  font-weight: 600;
  font-size: 22pt;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: #000;
}
.sheet__meta {
  margin: 2mm 0 0;
  font-family: var(--mono);
  font-size: 9.5pt;
  letter-spacing: 0.06em;
  color: #222;
}
.sheet__figure {
  margin: 6mm 0 0;
  border: 1px solid #9a9a9a;
}
.sheet__figure img { display: block; width: 100%; height: auto; max-height: 70mm; object-fit: cover; }
.sheet__caption {
  padding: 2mm 3mm;
  font-family: var(--mono);
  font-size: 8pt;
  letter-spacing: 0.08em;
  color: #444;
  border-top: 1px solid #9a9a9a;
}
.sheet__section { margin-top: 6mm; break-inside: avoid; page-break-inside: avoid; }
.sheet__h2 {
  margin: 0 0 2.5mm;
  padding-bottom: 1.5mm;
  border-bottom: 1px solid #000;
  font-family: var(--mono);
  font-weight: 400;
  font-size: 8.5pt;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #000;
}
.sheet__facts { display: grid; grid-template-columns: 1fr; margin: 0; }
@media (min-width: 560px) {
  .sheet__facts { grid-template-columns: 1fr 1fr; column-gap: 8mm; }
}
.sheet__fact {
  display: grid;
  grid-template-columns: 34% 1fr;
  gap: 4mm;
  padding: 2mm 0;
  border-bottom: 1px solid #c8c8c8;
  break-inside: avoid;
  page-break-inside: avoid;
}
.sheet__label {
  padding-top: 1px;
  font-family: var(--mono);
  font-size: 8pt;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #444;
}
.sheet__value { margin: 0; font-size: 10.5pt; color: #000; }
.sheet__value abbr[title] { text-decoration: underline dotted; text-underline-offset: 2px; }
.sheet__note { display: block; margin-top: 1mm; font-size: 8.5pt; line-height: 1.45; color: #444; }
.sheet__text { margin: 0 0 2.5mm; font-size: 10.5pt; line-height: 1.55; color: #111; }
.sheet__list { margin: 0; padding-left: 5mm; font-size: 10.5pt; line-height: 1.55; }
.sheet__list li { margin-bottom: 1mm; }
.sheet__foot {
  margin-top: 10mm;
  padding-top: 3mm;
  border-top: 1px solid #000;
  font-size: 8.5pt;
  line-height: 1.5;
  color: #333;
}
.sheet__stand,
.sheet__footnote { margin: 0 0 1.5mm; }
.sheet__sign {
  display: flex;
  flex-direction: column;
  gap: 1.5mm;
  max-width: 80mm;
  margin: 12mm 0 0;
}
.sheet__signline { display: block; height: 0; border-top: 1px solid #000; }
.sheet__signlabel {
  font-family: var(--mono);
  font-size: 8pt;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #444;
}

@media print {
  .sheet-root,
  .sheet-body { background: #fff !important; padding: 0; }
  .sheet { max-width: none; margin: 0; padding: 0; box-shadow: none; }
  /* Bedienung und Druckknopf sind auf Papier sinnlos */
  .sheet__actions,
  [data-print] { display: none !important; }
  .sheet__figure { break-inside: avoid; page-break-inside: avoid; }
  .sheet__figure img { max-height: 62mm; }
  /* Adressen hinter Links stehen im Blatt bereits ausgeschrieben - der
     globale Zusatz " (href)" wuerde sie verdoppeln. */
  .sheet a[href^="http"]::after,
  .sheet a[href^="mailto:"]::after { content: ""; }
  .projecthead__facts { border-color: #9a9a9a; }
  .projecthead__factlabel,
  .fact__note,
  .crumbs__ref { color: #333 !important; }
  .projecthead__factvalue { color: #000 !important; }
}


/* =========================================================================
   Workstream C - Kontakt, Assistent, Vergabe-Baustein (Korrekturrunde 10/2026)
   ========================================================================= */

/* Topbar: der Punkt vor den Oeffnungszeiten ist eine Markierung, keine
   Statusanzeige. Pulsieren liest sich als "jetzt erreichbar" - auch sonntags
   um 23 Uhr. Deshalb statisch; der Punkt bleibt. */
.topbar__hours .pulse {
  animation: none;
  opacity: 1;
  transform: none;
}

/* Kachel mit Klartextzeile (Schritt 3 des Assistenten): Beschriftung oben,
   Erklaerung darunter - 12 px in Nebentextfarbe, damit "LP 1-5" auch versteht,
   wer die HOAI nicht kennt. Im gewaehlten Zustand erbt die Zeile die Textfarbe
   der gefuellten Kachel, nur leicht zurueckgenommen. */
.option--stacked { align-items: flex-start; }
/* Die eigentliche Beschriftung - site.js liest fuer die Zusammenfassung nur
   diesen Teil, nicht die Klartextzeile darunter. */
.option__label {
  display: block;
  min-width: 0;
}
.option__text {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.option__sub {
  font-family: var(--body);
  font-weight: 400;
  font-size: 0.75rem;
  line-height: 1.35;
  letter-spacing: 0;
  text-transform: none;
  color: var(--dim);
}
.option--selected .option__sub { color: var(--on-accent); opacity: 0.8; }
@supports selector(:has(*)) {
  .option:has(input:checked) .option__sub { color: var(--on-accent); opacity: 0.8; }
}
/* Fuenf Phasen-Kacheln mit zwei Zeilen brauchen mehr Breite als die kurzen
   Vorhaben-Kacheln. */
@supports (width: min(220px, 100%)) {
  .wizard__options--phases { grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }
}

/* Der Weg am Assistenten vorbei (Schritt 1): Hinweis links, Verweis rechts. */
.wizard__direct {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 8px 16px;
  margin-bottom: 26px;
  font-size: var(--fs-xs);
  color: var(--dim);
}
.wizard__direct a {
  /* Zielgroesse mindestens 24 px (WCAG 2.5.8), sonst eine normale Textverknuepfung. */
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  color: var(--accent);
  text-underline-offset: 3px;
}
.wizard__direct a:hover { color: var(--accent-hi); }

/* Schliesser der Handlungsleiste: 32 px Zielflaeche, Haarlinie wie die
   uebrigen Bedienelemente der Leiste. */
.ctabar__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px;
  height: 32px;
  border: 1px solid var(--line-ui);
  background: transparent;
  color: var(--dim);
  font-size: 1.125rem;
  line-height: 1;
  cursor: pointer;
  transition: color var(--t), border-color var(--t);
}
.ctabar__close:hover { color: var(--fg); border-color: var(--accent); }
.ctabar__close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Vergabe-Baustein: die beiden beschrifteten Fristen und die Anforderungszeile,
   die auch dann stehen bleibt, wenn noch kein Nachweis hinterlegt ist. */
.vergabe__timing {
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 18px;
}
.vergabe__request {
  grid-column: 1 / -1;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--fg-2);
}
.vergabe__request a {
  color: var(--accent);
  text-underline-offset: 3px;
  overflow-wrap: anywhere;
}
.vergabe--compact .vergabe__title { font-size: 1.375rem; }
/* Eingebettet in die Seitenspalte der Kontaktseite: kein eigener Abschnitt,
   keine .shell, eine Spalte - der Rahmen traegt die Karte wie ihre Nachbarn. */
.vergabe--embedded {
  padding-block: 0;
  border-bottom: 0;
}
.vergabe--embedded .vergabe__inner {
  grid-template-columns: 1fr;
  gap: var(--gap-lg, 24px);
  padding: clamp(22px, 2.6vw, 32px);
}


/* ==========================================================================
   WORKSTREAM E - STARTSEITE, HERO, SPRACHE, LAYOUT (Korrekturrunde 10/2026)
   Nachtraege zum Leistungsbild und zum Abschnittskopf. Die Aenderungen an
   bestehenden Regeln (.langswitch__item--active, .hero__eyebrow,
   .specpanel__phase-code) stehen bei den Regeln selbst.
   ========================================================================== */

/* Ein Satz Legende unter dem Kopf des Leistungsbilds: wer die HOAI nicht
   kennt, liest das 3x3-Raster sonst wie einen Fahrplan ohne Erklaerung.
   Nebentextfarbe, keine Mono-Schrift - es ist ein Satz, kein Datenfeld. */
.specpanel__intro {
  margin: -10px 0 20px;
  font-family: var(--body);
  font-size: 0.8125rem;
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  color: var(--dim);
}

/* Das Pflegedatum der Auftragsannahme: steht als eigene Zeile unter dem Wert,
   Mono 11px, in Nebentextfarbe - der Akzent bleibt dem Wert vorbehalten. */
.specpanel__stamp {
  display: block;
  margin-top: 3px;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--dim);
}

/* Die Gewerkezeile traegt <abbr> fuer die Kuerzel; die Browser-Punktlinie
   bleibt als Hinweis, dass ein Titel hinterlegt ist. */
.specpanel__row abbr[title] {
  text-decoration: underline dotted;
  text-underline-offset: 2px;
  cursor: help;
}

/* Verweis unter einem Kachelraster ("Alle Projekte"), wenn der Platz rechts
   im Abschnittskopf schon vergeben ist. Gleiches Aussehen wie .section__link,
   nur unter statt neben der Ueberschrift. */
.section__more {
  margin-top: clamp(22px, 3vw, 34px);
  text-align: right;
}

/* ================================================================================================
   GATE - Nachtrag der technischen Abnahme (Korrekturrunde)
   Textverweis auf dem grünen Handlungsfeld: führt Vergabestellen vom Leistungs-CTA zum
   Vergabe-Baustein (#vergabestellen) auf der Kontaktseite, ohne eine dritte Schaltfläche ins Feld
   zu setzen. Farben kommen aus der Feld-Schicht, damit der Kontrast auf dem Grün gesichert bleibt.
   ================================================================================================ */
.ctafield__link {
  color: var(--on-field);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-color: var(--on-field-dim);
  transition: text-decoration-color var(--t-fast) var(--ease);
}
.ctafield__link:hover,
.ctafield__link:focus-visible { text-decoration-color: var(--on-field); }


/* =============================================================================
   STANDORTKARTE - Nachtrag Arbeitsstrang "3D: Gebaeude-Generator, Anlagen"
   -----------------------------------------------------------------------------
   Gewerke-Chips und Ausruestung im Panel des angeflogenen Projekts. Die
   Farben der Punkte sind dieselben wie die der Leitungen in 3D (GEWERKE in
   assets/js/building3d.js) - wer eine aendert, aendert beide. Die Chips sind
   die Legende der Anlagen; die Kartenlegende oben bleibt frei davon.
   ========================================================================== */
.map3d__systems { margin: 0 0 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.map3d__systems-title {
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}
.map3d__chips { display: flex; flex-wrap: wrap; gap: 6px; }
/* Chip: Schaltflaeche mit farbigem Punkt; gedrueckt = heller Rahmen. Mindestens
   24 px hoch (WCAG 2.5.8), Fokusring wie ueberall. */
.map3d__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  padding: 3px 10px;
  border: 1px solid var(--line-ui);
  border-radius: 999px;
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  color: var(--fg);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s, color 0.2s;
}
.map3d__chip:hover { border-color: var(--fg); }
.map3d__chip[aria-pressed="true"] { border-color: var(--fg); background: color-mix(in srgb, var(--fg) 10%, transparent); }
.map3d__chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.map3d__chip-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--dim); box-shadow: 0 0 6px currentColor; }
.map3d__chip[data-gewerk="heizung"] .map3d__chip-dot     { background: #ff6a3d; color: #ff6a3d; }
.map3d__chip[data-gewerk="sanitaer"] .map3d__chip-dot    { background: #4da3ff; color: #4da3ff; }
.map3d__chip[data-gewerk="elektro"] .map3d__chip-dot     { background: #ffd23f; color: #ffd23f; }
.map3d__chip[data-gewerk="lueftung"] .map3d__chip-dot    { background: #39d2c0; color: #39d2c0; }
.map3d__chip[data-gewerk="msr"] .map3d__chip-dot         { background: #c08cff; color: #c08cff; }
.map3d__chip[data-gewerk="brandschutz"] .map3d__chip-dot { background: #ff3b5c; color: #ff3b5c; }
/* Ausruestung: eine Mono-Zeile wie die Gewerke darueber, keine erfundenen Zahlen. */
.map3d__equipment {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.06em;
  line-height: 1.7;
  color: var(--fg);
}
.map3d__equipment-item { display: inline; }
.map3d__equipment-item + .map3d__equipment-item::before { content: " \00b7 "; color: var(--dim); }
.map3d__systems-hint { margin: 6px 0 0; font-size: 11px; color: var(--dim); }
@media (prefers-reduced-motion: reduce) {
  .map3d__chip { transition: none; }
}


/* =============================================================================
   PROJEKTSEITE - 3D-MODELL - Strang "3D-Modell auf der Projektseite"
   -----------------------------------------------------------------------------
   Abschnitt #modell (partials/project3d.php, assets/js/project3d.js): das
   Gebaeude der Referenz mit seinen Anlagen. Bauart wie ein Messinstrument:
   Buehne links mit Registriermarken und Metergitter, rechts die Steuerspalte
   mit Erklaersatz, Gewerke-Chips, Ausstattung und Fussnote. Ohne JavaScript
   steht das Titelbild in der Buehne und die Chips sind eine Legende
   (`disabled`); .p3d--ready (vom Modul nach dem ersten Bild gesetzt) blendet
   das Bild aus und gibt die Chips frei. Die Punktfarben sind dieselben wie
   die der Leitungen in 3D (GEWERKE in building3d.js) - wer eine aendert,
   aendert beide.
   ========================================================================== */
.p3d__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap-lg) var(--gap-xl);
  margin-top: var(--gap-xl);
}
@media (min-width: 900px) {
  .p3d__body {
    grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr);
    align-items: start;
  }
}

/* --- Buehne -------------------------------------------------------------------
   Transparentes Canvas ueber dem Seitengrund; die Vignette macht das CSS
   (::after), nicht WebGL. 4:3 auf dem Telefon, ab 900 px 16:10. Die Hoehe
   kommt vom Format, nie aus vh - sonst liesse ein flacher Bildschirm Luft. */
.p3d__stage {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background:
    radial-gradient(ellipse 70% 60% at 50% 58%, color-mix(in srgb, var(--surface) 85%, transparent), transparent 100%),
    var(--bg-alt);
}
@media (min-width: 900px) {
  .p3d__stage { aspect-ratio: 16 / 10; }
}
@supports not (aspect-ratio: 4 / 3) {
  .p3d__stage { min-height: min(75vw, 560px); }
}
/* Vignette: weiche Abdunkelung zum Rand, liegt ueber dem Canvas, faengt
   keine Zeiger. */
.p3d__stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(ellipse 85% 80% at 50% 50%, transparent 58%, color-mix(in srgb, var(--bg-alt) 85%, transparent) 100%);
}
.p3d__stage:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
/* Das Canvas haengt project3d.js hinein. Senkrechtes Wischen rollt weiter die
   Seite (pan-y), waagerechtes dreht das Modell; das Mausrad tut nichts. */
.p3d__canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  touch-action: pan-y;
  cursor: grab;
}
.p3d__stage--zieht .p3d__canvas { cursor: grabbing; }

/* Platzhalter: das Titelbild in der Waesche der Kacheln. Es liegt ueber dem
   Canvas, bis das erste Bild steht, und blendet dann weich aus. */
.p3d__poster {
  position: absolute;
  inset: 0;
  z-index: 3;
  transition: opacity 0.9s var(--ease);
}
.p3d__poster .duotone,
.p3d__poster picture,
.p3d__poster img { position: absolute; inset: 0; width: 100%; height: 100%; }
.p3d--ready .p3d__poster { opacity: 0; pointer-events: none; }
/* Bedienhinweis unten links in der Buehne - erst, wenn es etwas zu bedienen
   gibt (waehrend des Ladens steht dort "wird geladen"). */
.p3d__hint {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 10px;
  z-index: 4;
  margin: 0;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  /* Waehrend des Ladens steht die Zeile noch auf dem Titelbild - der Schatten
     haelt sie auch auf hellen Fotos lesbar. */
  text-shadow: 0 1px 2px var(--bg), 0 0 6px var(--bg);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s var(--ease);
}
.p3d[data-p3d-state="loading"] .p3d__hint,
.p3d--ready .p3d__hint { opacity: 1; }

/* Mass-Schild: "ca. 24 m" unter der Masslinie des Sockels. project3d.js setzt
   left/top bei jedem gezeichneten Bild (Weltpunkt projiziert) - DOM-Text statt
   Canvas-Textur, damit die Zahl so scharf ist wie jede andere Beschriftung. */
.p3d__mass {
  position: absolute;
  z-index: 2;
  transform: translate(-50%, 7px);
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.1em;
  color: var(--dim);
  white-space: nowrap;
  pointer-events: none;
}
.p3d__mass[hidden] { display: none; }

/* --- Steuerspalte ------------------------------------------------------------- */
.p3d__controls {
  display: flex;
  flex-direction: column;
  gap: 22px;
  min-width: 0;
}
@media (min-width: 900px) {
  .p3d__controls { padding-top: 4px; }
}
.p3d__intro {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--fg-lead);
}
.p3d__label {
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}
.p3d__chips { display: flex; flex-wrap: wrap; gap: 6px; }
/* Chip: Schaltflaeche mit farbigem Punkt, mindestens 26 px hoch (WCAG 2.5.8).
   `disabled` heisst hier nicht "kaputt", sondern "Legende" - deshalb volle
   Deckkraft, nur kein Hover und kein Zeiger. */
.p3d__chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 28px;
  padding: 4px 11px;
  border: 1px solid var(--line-ui);
  border-radius: 999px;
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  color: var(--fg);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.p3d__chip:disabled { cursor: default; border-color: var(--line-2); }
.p3d__chip:not(:disabled):hover { border-color: var(--fg); }
.p3d__chip:not(:disabled)[aria-pressed="true"] {
  border-color: var(--fg);
  background: color-mix(in srgb, var(--fg) 10%, transparent);
}
.p3d__chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* "Alle Gewerke" ist nur sinnvoll, wenn es etwas hervorzuheben gibt. */
.p3d:not(.p3d--ready) .p3d__chip--all { display: none; }
.p3d__chip-dot {
  display: inline-block;
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dim);
  box-shadow: 0 0 6px currentColor;
}
.p3d__chip[data-gewerk="heizung"] .p3d__chip-dot     { background: #ff6a3d; color: #ff6a3d; }
.p3d__chip[data-gewerk="sanitaer"] .p3d__chip-dot    { background: #4da3ff; color: #4da3ff; }
.p3d__chip[data-gewerk="elektro"] .p3d__chip-dot     { background: #ffd23f; color: #ffd23f; }
.p3d__chip[data-gewerk="lueftung"] .p3d__chip-dot    { background: #39d2c0; color: #39d2c0; }
.p3d__chip[data-gewerk="msr"] .p3d__chip-dot         { background: #c08cff; color: #c08cff; }
.p3d__chip[data-gewerk="brandschutz"] .p3d__chip-dot { background: #ff3b5c; color: #ff3b5c; }

/* Ausstattung: Mono-Zeile, nur Vorhandenes, keine Zahlen. */
.p3d__equipment {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.06em;
  line-height: 1.8;
  color: var(--fg);
}
.p3d__equipment-item { display: inline; }
.p3d__equipment-item + .p3d__equipment-item::before { content: " \00b7 "; color: var(--dim); }
.p3d__footnote {
  margin: 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: 0.08em;
  color: var(--dim);
}

@media (prefers-reduced-motion: reduce) {
  .p3d__poster,
  .p3d__hint,
  .p3d__chip { transition: none; }
}
/* Im Druck der Projektseite faellt das Instrument weg - gedruckt wird das
   Referenzblatt, und ein halb geladenes Canvas gehoert auf kein Papier. */
@media print {
  .p3d { display: none !important; }
}


/* =============================================================================
   STANDORTKARTE - Nachtrag Arbeitsstrang B "Karte: der Anflug" (10/2026)
   -----------------------------------------------------------------------------
   Vignette ueber der Buehne, solange ein Projekt angeflogen ist: Die Fokus-
   szene ist ein isoliertes Haus auf seinem Sockel (map3d.js blendet Gitter,
   Fluesse, Ortsnamen und Nachbarn aus) - der weiche Rand nimmt dem leeren
   Schwarz die Haerte und lenkt den Blick auf das Haus rechts vom Panel.
   Kein Zeigerziel, damit Klick ins Leere weiter "Zurueck" bedeutet.
   ========================================================================== */
.map3d__stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(ellipse 72% 78% at 62% 46%,
    transparent 0%,
    transparent 48%,
    color-mix(in srgb, var(--bg) 72%, transparent) 100%);
  opacity: 0;
  transition: opacity 0.9s var(--ease);
}
.map3d--focused .map3d__stage::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .map3d__stage::after { transition: none; }
}
:root[data-motion="reduced"] .map3d__stage::after { transition: none; }


/* =============================================================================
   ANLAGENSCHEMA KOMPAKT - Nachtrag Arbeitsstrang D "Fit to screen" (10/2026)
   -----------------------------------------------------------------------------
   Unter 760px ersetzt eine Symbol-Variante die breite Zeichnung: drei
   Erzeuger-Karten oben, die Technikzentrale als Verteiler-Knoten in der
   Mitte, drei Uebergabe-Karten darunter, der KNX-Bus als Haarlinie am Fuss.
   Alles passt ohne waagerechtes Scrollen auf ein Telefon (375px), nichts ist
   klickbar. Der Wechsel laeuft rein ueber display:none im Media-Query -
   dadurch starten die CSS-Animationen beim Unterschreiten der Schwelle neu,
   und die Karten "poppen" ohne eine Zeile JavaScript.
   ========================================================================== */
.schema__wide { display: none; }
.schema-compact {
  display: grid;
  gap: 10px;
}
@media (min-width: 760px) {
  .schema__wide { display: block; }
  .schema-compact { display: none; }
}

.schema-compact__caption {
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 1.6px;
  color: var(--dim);
}
.schema-compact__row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
.schema-compact__card {
  display: grid;
  justify-items: center;
  align-content: start;
  gap: 8px;
  padding: 12px 6px 10px;
  border: 1px solid var(--line-2);
}
/* Die Symbole sind Strichzeichnungen im Blueprint-Duktus; eingefaerbt wird
   ausschliesslich hier, das Markup traegt keine Praesentationsattribute. */
.schema-compact__icon {
  width: 38px;
  height: 38px;
  fill: none;
  stroke: var(--fg);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Nur der Verteiler traegt den Akzent - ein gruener Punkt pro Bild reicht. */
.schema-compact__icon--hub { stroke: var(--accent); }
.schema-compact__label {
  font-family: var(--head);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  color: var(--fg);
}
.schema-compact__hub {
  display: grid;
  justify-items: center;
  gap: 4px;
  justify-self: center;
  min-width: min(260px, 82%);
  padding: 14px 12px 12px;
  border: 1px solid var(--corner);
}
.schema-compact__hub-title {
  font-family: var(--head);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--accent);
}
.schema-compact__hub-norm {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 1.1px;
  color: var(--dim);
  text-align: center;
}
/* Haarlinien-Verbinder: drei Stiche aus den Karten, eine Sammelschiene,
   ein Stich in den Verteiler - gezeichnet als Hintergrundverlaeufe, damit
   kein zusaetzliches Markup noetig ist. --down ist die gespiegelte Fassung
   (Verteiler -> Uebergabe), bewusst ohne transform ausgeschrieben. */
.schema-compact__link {
  height: 20px;
  background:
    linear-gradient(var(--line-2), var(--line-2)) 16.6% 0 / 1px 10px no-repeat,
    linear-gradient(var(--line-2), var(--line-2)) 50% 0 / 1px 10px no-repeat,
    linear-gradient(var(--line-2), var(--line-2)) 83.4% 0 / 1px 10px no-repeat,
    linear-gradient(var(--line-2), var(--line-2)) 50% 9.5px / 66.8% 1px no-repeat,
    linear-gradient(var(--line-2), var(--line-2)) 50% 10px / 1px 10px no-repeat;
}
.schema-compact__link--down {
  background:
    linear-gradient(var(--line-2), var(--line-2)) 50% 0 / 1px 10px no-repeat,
    linear-gradient(var(--line-2), var(--line-2)) 50% 9.5px / 66.8% 1px no-repeat,
    linear-gradient(var(--line-2), var(--line-2)) 16.6% 10px / 1px 10px no-repeat,
    linear-gradient(var(--line-2), var(--line-2)) 50% 10px / 1px 10px no-repeat,
    linear-gradient(var(--line-2), var(--line-2)) 83.4% 10px / 1px 10px no-repeat;
}
.schema-compact__bus {
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px dashed var(--accent-2);
  text-align: center;
}
.schema-compact__bus-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 1.4px;
  color: var(--accent-2);
}

/* Pop-Animation: Verteiler zuerst, dann die Karten mit 40ms Versatz.
   animation-fill-mode:backwards haelt verzoegerte Karten bis zum Start
   unsichtbar - deshalb unten das explizite animation:none bei reduzierter
   Bewegung: die globale Regel kuerzt nur die Dauer, nicht die Verzoegerung,
   und wuerde die Karten waehrend des Delays verschwinden lassen. */
@keyframes schemaPop {
  0%   { opacity: 0; transform: scale(0.6); }
  70%  { opacity: 1; transform: scale(1.06); }
  100% { opacity: 1; transform: scale(1); }
}
.schema-compact__card,
.schema-compact__hub {
  animation: schemaPop 0.45s cubic-bezier(0.22, 0.9, 0.3, 1.2) backwards;
}
.schema-compact__row .schema-compact__card:nth-child(1) { animation-delay: 0.04s; }
.schema-compact__row .schema-compact__card:nth-child(2) { animation-delay: 0.08s; }
.schema-compact__row .schema-compact__card:nth-child(3) { animation-delay: 0.12s; }
.schema-compact__row--out .schema-compact__card:nth-child(1) { animation-delay: 0.16s; }
.schema-compact__row--out .schema-compact__card:nth-child(2) { animation-delay: 0.20s; }
.schema-compact__row--out .schema-compact__card:nth-child(3) { animation-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
  .schema-compact__card,
  .schema-compact__hub { animation: none; transform: none; }
}
:root[data-motion="reduced"] .schema-compact__card,
:root[data-motion="reduced"] .schema-compact__hub { animation: none; transform: none; }

/* =====================================================================
   TECHNIKZENTRALE 3D (zentrale3d.js) - Stufe 2 des Anlagenschemas.
   Das Raster steht im hidden-Attribut, bis das Modul es aktiviert;
   .schema--3d blendet die SVG-Zeichnung aus.
   ===================================================================== */
.schema--3d .schema__wide { display: none; }
.z3d {
  display: grid;
  grid-template-columns: 230px minmax(0, 1fr) 230px;
  gap: 18px 24px;
  align-items: center;
}
.z3d__spalte { display: grid; gap: 14px; align-content: center; }
.z3d__caption {
  margin: 0 0 2px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--dim);
}
.z3d__box {
  display: grid;
  gap: 5px;
  padding: 12px 14px;
  text-align: left;
  font: inherit;
  color: var(--fg);
  background: transparent;
  border: 1px solid var(--line);
  cursor: pointer;
  transition: border-color var(--t), background-color var(--t);
}
.z3d__box:hover,
.z3d__box:focus-visible { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); }
.z3d__box--aktiv,
.z3d__box[aria-pressed="true"] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.z3d__box:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.z3d__box-title { font-size: 15px; font-weight: 600; line-height: 1.25; }
.z3d__box-norm {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: var(--dim);
}
.z3d__mitte { position: relative; display: grid; gap: 8px; min-width: 0; }
.z3d__stage {
  position: relative;
  aspect-ratio: 16 / 11;
  touch-action: none;        /* Ziehen und Pinch gehoeren der Buehne */
  cursor: grab;
}
.z3d__stage:active { cursor: grabbing; }
.z3d__stage:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.z3d__canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* Nur ein Hauch Vignette: die Buehne darf nicht als dunklerer Kasten im
   Seitenhintergrund stehen (Kundenwunsch "gleichmaessig"). */
.z3d__stage::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 42%, transparent 72%, rgba(2, 6, 4, 0.18) 100%);
}
.z3d__hub {
  position: absolute;
  left: 50%; bottom: 10px;
  transform: translateX(-50%);
  text-align: center;
  pointer-events: none;
  display: grid; gap: 2px;
}
.z3d__hub-title {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  color: var(--accent);
}
.z3d__hub-norm {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--dim);
}
.z3d__hint {
  margin: 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--dim);
}
.z3d__bus {
  grid-column: 1 / -1;
  padding: 10px 0 0;
  background: transparent;
  border: 0;
  border-top: 1px dashed color-mix(in srgb, var(--accent) 45%, transparent);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--dim);
  cursor: pointer;
  transition: color var(--t);
}
.z3d__bus:hover,
.z3d__bus:focus-visible,
.z3d__bus[aria-pressed="true"] { color: var(--accent); }
.z3d__bus:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Pop beim Aktivieren - dieselbe Sprache wie die Symbolkarten der Mobilfassung */
.schema--3d .z3d__box,
.schema--3d .z3d__bus { animation: z3dPop 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.15) backwards; }
.schema--3d .z3d__spalte .z3d__box:nth-child(2) { animation-delay: 0.05s; }
.schema--3d .z3d__spalte .z3d__box:nth-child(3) { animation-delay: 0.1s; }
.schema--3d .z3d__spalte .z3d__box:nth-child(4) { animation-delay: 0.15s; }
.schema--3d .z3d__bus { animation-delay: 0.2s; }
@keyframes z3dPop {
  from { opacity: 0; transform: scale(0.82); }
  70%  { opacity: 1; transform: scale(1.04); }
  to   { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .schema--3d .z3d__box,
  .schema--3d .z3d__bus { animation: none; }
}
:root[data-motion="reduced"] .schema--3d .z3d__box,
:root[data-motion="reduced"] .schema--3d .z3d__bus { animation: none; }
/* Unter 1100 px gibt es keine Stufe 2 - Sicherheitsnetz, falls das Fenster
   nach der Aktivierung schmaler gezogen wird (das Modul schaltet zusaetzlich um). */
/* Mit 3D-Stufe verschwindet das Render-Video (Rueckfall) ebenfalls. */
.schema--3d .schema__render { display: none; }
/* Zwischen 760 und 1099 px: Buehne oben, die Kaesten in zwei Reihen darunter
   (die Lidhese-Linien entfallen dort - sie braeuchten die drei Spalten). */
@media (max-width: 1099px) {
  .z3d { grid-template-columns: 1fr; gap: 12px; }
  .z3d__spalte { grid-template-columns: repeat(3, 1fr); grid-auto-flow: row; }
  .z3d__caption { grid-column: 1 / -1; }
  .z3d__mitte { order: -1; }
  .z3d__links { display: none; }
}
/* Telefon: die 3D-Stufe laeuft auch hier (Kundenwunsch) - Buehne oben, die
   Kaesten darunter in zwei Spalten; die Symbolkarten weichen ihr. */
@media (max-width: 759px) {
  .schema--3d .schema-compact { display: none; }
  .z3d__spalte { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .z3d__stage { aspect-ratio: 4 / 3; }
  .z3d__box { padding: 10px 12px; }
  .z3d__box-title { font-size: 13.5px; }
}
/* Wetter-/Tageszeit-Badge oben links auf der Buehne */
.z3d__wetter {
  position: absolute; left: 12px; top: 12px; z-index: 3; max-width: 54%; text-align: left; white-space: normal; line-height: 1.35;
  padding: 6px 10px; font: inherit; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em;
  color: var(--fg); background: color-mix(in srgb, var(--bg) 82%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--line)); cursor: pointer;
}
.z3d__wetter:hover, .z3d__wetter:focus-visible { border-color: var(--accent); }
.z3d__wetter--sturm { border-color: #ff7a5c; color: #ffd0c4; animation: z3dSturm 0.9s ease-in-out infinite; }
@keyframes z3dSturm { 0%, 100% { box-shadow: 0 0 0 rgba(255,122,92,0); } 50% { box-shadow: 0 0 14px rgba(255,122,92,0.6); } }
/* Jahresleiste oben rechts: vier Jahreszeiten, laufende Marke */
.z3d__jahr { position: absolute; right: 12px; top: 12px; z-index: 3; width: min(42%, 300px); display: grid; gap: 4px; }
.z3d__jahr-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; color: var(--accent); text-align: right; }
.z3d__jahr-spur { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line)); background: color-mix(in srgb, var(--bg) 82%, transparent); }
.z3d__jahr-seg { padding: 4px 2px; font: inherit; font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.06em; color: var(--dim); background: transparent; border: 0; border-right: 1px solid color-mix(in srgb, var(--accent) 25%, transparent); cursor: pointer; }
.z3d__jahr-seg:last-of-type { border-right: 0; }
.z3d__jahr-seg--aktiv { color: var(--fg); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.z3d__jahr-marke { position: absolute; top: -3px; bottom: -3px; width: 2px; margin-left: -1px; background: var(--accent); box-shadow: 0 0 8px var(--accent); pointer-events: none; transition: left 0.3s linear; }
@media (max-width: 759px) {
  /* Telefon: Buehne im Hochformat, Badge und Jahresleiste als schmale Zeilen oben */
  .z3d__stage { aspect-ratio: 3 / 4; }
  .z3d__wetter { left: 8px; right: 8px; top: 8px; max-width: none; font-size: 10px; padding: 5px 8px; }
  .z3d__jahr { left: 8px; right: 8px; top: 58px; width: auto; }
  .z3d__jahr-label { display: none; }
  .z3d__info { left: 8px; right: 8px; bottom: 8px; padding: 8px 10px; }
  .z3d__info-text { font-size: 11.5px; line-height: 1.35; }
}
/* Tooltip am Zeiger (Name des Bauteils beim Zeigen) */
.z3d__tip {
  position: absolute; z-index: 4; pointer-events: none;
  padding: 4px 9px; white-space: nowrap;
  font-size: 12px; font-weight: 600; color: var(--fg);
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 60%, var(--line));
  border-radius: 4px;
}
/* Beschreibung der angeflogenen Anlage */
.z3d__info {
  /* Flacher Streifen am unteren Rand (volle Breite): das Modell und seine
     Etiketten bleiben darueber frei sichtbar. Links Titel + Gewerk + Knopf,
     rechts der Text in zwei Spalten. */
  position: absolute;
  left: 12px; right: 12px; bottom: 12px;
  padding: 10px 14px;
  display: grid;
  grid-template-columns: minmax(200px, 1fr) 2fr;
  grid-template-areas: "label text" "title text" "gewerk text" "back text";
  gap: 4px 18px;
  align-content: start;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--line));
  backdrop-filter: blur(6px);
  z-index: 3;
  animation: z3dPop 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.15) backwards;
}
.z3d__info-label { grid-area: label; margin: 0; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.18em; color: var(--accent); }
.z3d__info-title { grid-area: title; margin: 0; font-size: 16px; font-weight: 600; line-height: 1.25; }
.z3d__info-text { grid-area: text; margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--fg); columns: 2; column-gap: 16px; }
.z3d__info-gewerk { grid-area: gewerk; margin: 0; font-size: 11.5px; line-height: 1.4; color: var(--dim); }
.z3d__info-gewerk-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; color: var(--accent); margin-right: 4px; }
.z3d__back {
  grid-area: back;
  justify-self: start;
  margin-top: 4px;
  padding: 6px 10px;
  font: inherit; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.12em;
  color: var(--accent); background: transparent;
  border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--line));
  cursor: pointer;
}
.z3d__back:hover, .z3d__back:focus-visible { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.z3d__info-knoepfe { grid-area: back; display: flex; gap: 8px; align-items: center; }
.z3d__info-mehr { display: none; }
@media (max-width: 1099px) { .z3d__info { grid-template-columns: 1fr; grid-template-areas: "label" "title" "gewerk" "text" "back"; } .z3d__info-text { columns: 1; } }
@media (max-width: 759px) {
  /* Telefon: nur Titel + Gewerk + Knoepfe, der Text klappt auf Wunsch auf - das Modell bleibt sichtbar */
  .z3d__info { grid-template-areas: "title" "gewerk" "back" "text"; gap: 3px; background: color-mix(in srgb, var(--bg) 78%, transparent); }
  .z3d__info-label { display: none; }
  .z3d__info-title { font-size: 14px; }
  .z3d__info-gewerk { font-size: 10.5px; }
  .z3d__info-text { display: none; margin-top: 4px; max-height: 38vh; overflow: auto; }
  .z3d__info--offen .z3d__info-text { display: block; }
  .z3d__info-mehr { display: inline-block; }
  .z3d__info-knoepfe .z3d__back { margin-top: 2px; padding: 5px 8px; font-size: 10px; }
}
.z3d__bus-label { padding: 0 10px; background: var(--bg); }

/* --- Lidhese Kasten -> Haus (zentrale3d.js schreibt die Pfade) ----------- */
.z3d { position: relative; }
.z3d__spalte, .z3d__mitte, .z3d__bus { position: relative; z-index: 2; }
.z3d__links {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
  overflow: visible;
}
.z3d__link {
  fill: none;
  stroke-linecap: round;
  opacity: 0;
  transition: opacity 0.4s linear;
  animation: z3dFluss 1.6s linear infinite;
}
.z3d--verbunden .z3d__link { opacity: 0.75; }
.z3d__link--gedimmt { opacity: 0.1 !important; }
@keyframes z3dFluss {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: calc(var(--richtung, -1) * var(--periode, 24px)); }
}
/* Jede Kategorie mit eigenem Charakter: Strom fein und flink, Waerme
   gemaechlich, Luft breit mit langen, seltenen Schueben, Wasser tropfenweise. */
.z3d__link--strom  { stroke: #ffd23f; stroke-width: 1.6; stroke-dasharray: 7 19;  animation-duration: 0.9s; }
.z3d__link--waerme { stroke: #ff6a3d; stroke-width: 2.2; stroke-dasharray: 14 20; animation-duration: 1.7s; }
.z3d__link--luft   { stroke: #39d2c0; stroke-width: 4;   stroke-dasharray: 26 30; animation-duration: 2.6s; opacity: 0; }
.z3d--verbunden .z3d__link--luft { opacity: 0.45; }
.z3d__link--wasser { stroke: #4da3ff; stroke-width: 2;   stroke-dasharray: 4 18;  animation-duration: 1.3s; }
.z3d__sonne { opacity: 0; transition: opacity 0.4s linear; }
.z3d--verbunden .z3d__sonne { opacity: 1; }
.z3d__sonne-kern { fill: none; stroke: #ffd23f; stroke-width: 1.6; }
.z3d__sonne-strahlen { stroke: #ffd23f; stroke-width: 1.6; animation: z3dSonne 2.4s ease-in-out infinite; transform-origin: 0 0; }
@keyframes z3dSonne {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .z3d__link, .z3d__sonne-strahlen { animation: none; }
}
:root[data-motion="reduced"] .z3d__link,
:root[data-motion="reduced"] .z3d__sonne-strahlen { animation: none; }

/* --- Gewerke-Kacheln der Startseite (visuell statt textlastig) ----------- */
.gewtiles {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(12px, 1.6vw, 20px);
}
@media (min-width: 640px) { .gewtiles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .gewtiles { grid-template-columns: repeat(3, 1fr); } }
.gewtile {
  position: relative;
  display: grid;
  gap: 10px;
  align-content: start;
  padding: clamp(18px, 2.2vw, 26px);
  border: 1px solid var(--line);
  color: var(--fg);
  text-decoration: none;
  transition: border-color var(--t), transform var(--t), background-color var(--t);
}
.gewtile:hover,
.gewtile:focus-visible {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 5%, transparent);
  transform: translateY(-2px);
}
.gewtile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gewtile__icon { color: var(--accent); line-height: 0; }
.gewtile__title { margin: 0; font-size: clamp(17px, 1.6vw, 20px); line-height: 1.2; }
.gewtile__kurz {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--dim);
}
.gewtile__mehr {
  position: absolute;
  right: 16px;
  bottom: 12px;
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--accent);
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity var(--t), transform var(--t);
}
.gewtile:hover .gewtile__mehr,
.gewtile:focus-visible .gewtile__mehr { opacity: 1; transform: translateX(0); }
@media (prefers-reduced-motion: reduce) {
  .gewtile, .gewtile__mehr { transition: none; }
  .gewtile:hover { transform: none; }
}
:root[data-motion="reduced"] .gewtile:hover { transform: none; }

/* --- Alpenprofil im Aufmacher: dezentes Bayern-Zeichen -------------------- */
.hero__alpen {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  width: 100%;
  height: clamp(60px, 9vw, 120px);
  pointer-events: none;
}
.hero__alpen-linie {
  fill: none;
  stroke: color-mix(in srgb, var(--fg) 9%, transparent);
  stroke-width: 1.5;
  stroke-linejoin: round;
}
.hero__alpen-marke { stroke: color-mix(in srgb, var(--fg) 18%, transparent); stroke-width: 1; }
.hero__alpen-text {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  fill: color-mix(in srgb, var(--fg) 26%, transparent);
}
@media (max-width: 700px) { .hero__alpen-text, .hero__alpen-marke { display: none; } }

/* Regie-Stufe der Technikzentrale: der gerade erzaehlte Kasten */
.z3d__box--takt,
.z3d__bus--takt { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); }
.z3d__bus--takt { color: var(--accent); }
.z3d__link--leise { opacity: 0.28 !important; }

/* Eine einzelne Personenkarte soll nicht die volle Breite fuellen
   (grid--3 arbeitet mit auto-fit) - und das Portraitblatt bleibt kompakt. */
.person { max-width: 440px; }
.person__photo img { width: 100%; height: auto; display: block; }

/* --- Gewerke-Datenblaetter der Leistungsseite (gewerk3d.js) --------------- */
.gdetail {
  position: relative;
  display: grid;
  gap: clamp(20px, 2.5vw, 32px);
  padding: clamp(20px, 2.5vw, 34px);
}
@media (min-width: 1100px) {
  .gdetail { grid-template-columns: minmax(260px, 340px) minmax(0, 1fr) minmax(240px, 300px); align-items: center; }
}
.gdetail__code {
  margin: 0 0 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--dim);
}
.gdetail__title { margin: 0 0 14px; font-size: clamp(26px, 2.6vw, 34px); line-height: 1.05; }
.gdetail__body {
  margin: 0;
  padding: 14px 16px;
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--fg) 3%, transparent);
  font-size: 14.5px;
  line-height: 1.55;
  color: color-mix(in srgb, var(--fg) 86%, transparent);
}
.gdetail__mitte { min-width: 0; }
.g3d-stage {
  position: relative;
  aspect-ratio: 16 / 11;
  display: grid;
  place-items: center;
  touch-action: none;
  cursor: grab;
}
.g3d-stage:active { cursor: grabbing; }
.g3d-stage:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.g3d-stage__icon { color: var(--accent); opacity: 0.55; line-height: 0; }
.g3d-stage--live .g3d-stage__icon { display: none; }
.g3d-stage__canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.g3d-hint {
  margin: 6px 0 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--dim);
}
@media (max-width: 1099px) {
  /* Auf schmalen Schirmen / Handy: die 3D-Buehne gross genug, dass man die
     Anlage erkennt und bedienen kann (drehen, pinch-zoom). */
  .g3d-stage { aspect-ratio: 4 / 3; min-height: 300px; }
  .g3d-hint { display: block; font-size: 10.5px; margin-top: 6px; }
}
@media (max-width: 560px) {
  .g3d-stage { aspect-ratio: 1 / 1; min-height: 320px; }
}

/* --- Kompakte Chef-Karte im Kopf von "Ueber uns" -------------------------- */
.abouthead { display: grid; gap: clamp(20px, 3vw, 36px); }
@media (min-width: 1000px) {
  .abouthead--mit-chef { grid-template-columns: minmax(0, 1fr) 360px; align-items: center; }
}
.chefkarte {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  gap: 16px;
  align-items: center;
  padding: 14px 16px;
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--fg) 3%, transparent);
}
.chefkarte__foto { display: block; width: 104px; border: 1px solid var(--line); }
.chefkarte__foto img { display: block; width: 100%; height: auto; }
.chefkarte__text { display: grid; gap: 3px; }
.chefkarte__name { font-size: 15.5px; line-height: 1.25; }
.chefkarte__role { font-size: 12.5px; color: color-mix(in srgb, var(--fg) 78%, transparent); }
.chefkarte__field {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: var(--dim);
}
.abouthead__main { min-width: 0; }
.gdetail__links, .gdetail__rechts { min-width: 0; }

/* =====================================================================
   PROJEKTFOTOS ALS PLANBLAETTER (Designer-Gutachten Oktober 2026)
   Die hellen Renderings liegen als "aufgelegtes Blatt" im Passepartout:
   Haarlinie und Schattenfuge sitzen am Blattrand, nicht am Kasten -
   keine toten Dunkelstreifen mehr, kein Letterboxing.
   ===================================================================== */
:root { --sheet-pad: clamp(14px, 2vw, 28px); }

.projecthead__figure {
  max-width: min(100%, 1080px);
  margin-inline: auto;
}
.projecthead__media,
.projecthead__media[class] {
  aspect-ratio: auto;
  max-height: none;
  height: auto;
  padding: var(--sheet-pad) var(--sheet-pad) calc(var(--sheet-pad) * 0.75);
  display: flex;
  justify-content: center;
  align-items: center;
}
@supports not (aspect-ratio: 1) {
  .projecthead__media { padding-top: var(--sheet-pad); }
  .projecthead__media picture,
  .projecthead__media img { position: static; }
}
.projecthead__media picture { display: contents; }
.projecthead__media img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: min(52vh, 520px);
  border: 1px solid color-mix(in srgb, var(--fg) 22%, transparent);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.55), 0 16px 36px rgba(0, 0, 0, 0.45);
}
.plankopf {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  margin: 0;
  padding: 10px var(--sheet-pad) 12px;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}
.plankopf__blatt { min-width: 0; }
.plankopf__ref { color: var(--accent); white-space: nowrap; }

/* Bildstrecke: dieselbe Fassung, Unterschrift als Plankopf-Zeile */
.gallery__media,
.gallery__media[class] {
  aspect-ratio: auto;
  height: auto;
  padding: var(--sheet-pad);
  display: flex;
  justify-content: center;
  align-items: center;
}
@supports not (aspect-ratio: 1) {
  .gallery__media { padding-top: var(--sheet-pad); }
  .gallery__media picture,
  .gallery__media img { position: static; }
}
.gallery__media picture { display: contents; }
.gallery__media img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: min(44vh, 420px);
  border: 1px solid color-mix(in srgb, var(--fg) 22%, transparent);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.4);
}
.gallery__caption {
  display: flex;
  align-items: baseline;
  gap: 14px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.gallery__blatt { color: var(--fg); white-space: nowrap; }
.gallery__captext { min-width: 0; }
.gallery__zoom {
  margin-left: auto;
  white-space: nowrap;
  color: var(--dim);
  transition: color var(--t);
}
.gallery__item:hover .gallery__zoom,
.gallery__item:focus-visible .gallery__zoom { color: var(--accent); }

/* Ein einzelnes Blatt verwaist nicht mehr links unten: volle Zeile,
   Plankopf als rechte Spalte wie auf einem Werksplan. */
@media (min-width: 900px) {
  .gallery__item:only-child {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
  }
  .gallery__item:only-child .gallery__media { border-right: 1px solid var(--line); }
  .gallery__item:only-child .gallery__caption {
    border-top: 0;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    gap: 10px;
    padding: var(--sheet-pad);
  }
  .gallery__item:only-child .gallery__zoom { margin-left: 0; }
}

/* =====================================================================
   Gerendertes Anlagenbild  (render_media / render-media.php)
   Ersetzt ein 3D-Drahtgitter durch ein fertig gerendertes Video oder
   Standbild - dort, wo im Haus eine Datei unter media/renders/ liegt.
   ===================================================================== */
.rmedia {
  position: relative;
  margin: 0;
  width: 100%;
  aspect-ratio: var(--rmedia-ratio, 16 / 9);
  background: #050907;
  overflow: hidden;
}
.rmedia picture { display: contents; }
.rmedia__video,
.rmedia__still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* --- Startseite: Zentrale-Render statt Zeichnung + Drahtgitter --------
   Liegt ein Render vor (figure.schema--has-render), zeigt die Seite ab
   760px das Video; darunter bleiben die kompakten Karten, weil die in das
   Bild gebrannte Beschriftung sonst zu klein zum Lesen wird. */
.schema__render { display: none; }
.schema--has-render { padding: 0; border: none; background: none; }
.schema__render { position: relative; }
.schema__render .rmedia { background: #060a08; }

/* Die vollstaendigen Beschriftungen sind jetzt direkt ins Video gerendert und
   sitzen ganz am Bildrand - deshalb das ganze Bild zeigen (contain), nie
   beschneiden. Der Grund ist nahezu schwarz wie das Video, der schmale Rand
   oben/unten faellt nicht auf. */
.schema__render .rmedia__video,
.schema__render .rmedia__still { object-fit: contain; }
@media (min-width: 760px) {
  .schema--has-render .schema__wide { display: none; }
  .schema--has-render .schema__render { display: block; }
  /* Video in angemessener Groesse, mittig im Inhalt - NICHT mehr randlos
     (full-bleed war zu gross). Die eingebrannten Beschriftungen bleiben bei
     dieser Breite gut lesbar. */
  .schema--has-render .schema__render .rmedia {
    aspect-ratio: 16 / 9;
    max-width: 820px;
    margin-inline: auto;
  }
}
/* Laeuft die 3D-Stufe (zentrale3d.js), ersetzt sie das Video vollstaendig -
   die Regel steht bewusst NACH dem Render-Block, damit sie gewinnt. */
.schema--has-render.schema--3d .schema__render { display: none; }
.schema--has-render.schema--3d { padding: clamp(14px, 2vw, 22px); border: 1px solid var(--line); }

/* --- Leistungen: Render fuellt die Mittelbuehne eines Gewerks --------- */
.g3d-stage--render { cursor: default; }
.g3d-stage--render .g3d-stage__icon { display: none; }
.g3d-stage .rmedia {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
  background: transparent;
}

/* Echtzeit-3D-Leinwand der Gewerke (gewerk-render3d.js) */
.g3d-canvas {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  display: block;
  border-radius: inherit;
}
.g3d-stage--live { cursor: grab; }
.g3d-stage--live:active { cursor: grabbing; }
