/* ============================================================
   TIG Terra Ingenieurgesellschaft · Relaunch-Konzept
   Collective Brain · Volle Breite, Fira Sans + Noto Serif
   ============================================================ */

:root {
  --rot: #E30613;
  --rot-dunkel: #B8050F;
  --rot-hell: #FF4D55; /* Akzent auf dunklen Flächen (Kontrast ≥ 4,5:1) */
  --anthrazit: #16181B;
  --anthrazit-2: #1E2126;
  --grau: #616264;
  --grau-hell: #8D8D8F;
  --linie: #D8DADC;
  --linie-dunkel: #2E3238;
  --papier: #F4F4F2;
  --weiss: #FFFFFF;
  --text: #23252A;
  --text-invert: #E9EAEB;
  --font-sans: "Fira Sans", system-ui, sans-serif;
  --font-serif: "Noto Serif", Georgia, serif;
  /* Das Seitenmass waechst ueber 1956 px weiter, statt bei 88 px stehen zu
     bleiben. Vorher lief der Inhalt darueber ungebremst mit dem Fenster
     auseinander: im Kopf klafften zwischen Marke und Navigation 1349 px.
     Die Seite bleibt randlos gebaut, sie bekommt nur einen Inhaltskorridor
     von 1780 px. Bis 1956 px aendert die Ergaenzung nichts, dort gewinnt
     weiterhin der 88-px-Wert. */
  --pad: max(clamp(20px, 4.5vw, 88px), (100vw - 1780px) / 2);
  --radius: 2px;

  /* ---------- Schriftstufen ----------
     Das Blatt trug 44 verschiedene Quellwerte fuer font-size, davon 14 Stufen
     im Band 10 bis 17 px mit je 0,5 px Abstand. Ein halber Pixel ist am
     Bildschirm nicht zu sehen, in der Pflege aber jedes Mal eine Entscheidung.
     Fuenf Stufen mit rund 11 Prozent Schrittweite, alles andere wird darauf
     gezogen. Die grossen Grade bleiben clamp-Ausdruecke, die tragen ihre
     eigene Logik. */
  --t-3xs: 11px;
  --t-2xs: 12.5px;
  --t-xs: 14px;
  --t-sm: 15.5px;
  --t-md: 17px;

  /* Versale Kleintypografie hatte zehn Laufweiten fuer eine Rolle. Dieselbe
     Bildunterschrift stand im Bildband auf 0,16em und in der Feldnotiz auf
     0,08em, bei gleicher Groesse und gleicher Aufgabe. */
  --versal: 0.16em;
  /* Zweite Stufe fuer laengere versale Zeichenketten. Bei "ICL INGENIEUR
     CONSULT · 2025/2026" wuerden 0,16em rund 36 px zusetzen und die Zeile in
     einer 268-px-Kachel umbrechen. Kurze Labels bleiben auf der weiten
     Stufe, lange Ketten bekommen die enge. */
  --versal-eng: 0.08em;

  /* Drei Schwarztoene fuer eine Rolle, nur einer davon als Variable. Der
     Fussgrund und die Bildverlaeufe liefen auf eigenen Werten. */
  --anthrazit-tief: #101215;

  /* Vierter Grauton, dreimal fest im Blatt als bewusste Kontrastkorrektur
     ueber dunklem Grund. Damit ist es ein Systemwert. */
  --grau-invert: #C9CACB;

  /* Der Grund der Bildverlaeufe ist bewusst dunkler als --anthrazit und wird
     NICHT mit ihm zusammengelegt. Nachgerechnet: auf #16181B faellt der rote
     Kacheltext ueber dem hellsten Motiv auf 4,49:1 und damit unter die
     Schwelle, auf #0B0C0E haelt er 4,89:1. Die Differenz sieht man nicht,
     die Messung schon. */
  --verlauf-grund: 11, 12, 14;
  /* Hoerer fuer die Kopfzeile auf schmalen Schirmen. Als Maske eingesetzt,
     damit das Symbol die Textfarbe erbt und im Fokus mitgeht. */
  --hoerer: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.6 10.8c1.4 2.8 3.8 5.2 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.4.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.7 21 3 13.3 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .8-.2 1l-2.3 2.2z'/%3E%3C/svg%3E");
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: 96px; }

body {
  font-family: var(--font-sans);
  font-size: var(--t-md);
  line-height: 1.6;
  color: var(--text);
  background: var(--papier);
  -webkit-font-smoothing: antialiased;
}

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

/* width und height stehen im Markup, damit der Platz vor dem Laden steht.
   Ohne "height: auto" wuerde ein Bild, das max-width bremst, in der Hoehe
   stehen bleiben und gestaucht aussehen. Bausteine mit eigenem Zuschnitt
   (Bildband, Kacheln, Logos) setzen ihre Hoehe selbst und gewinnen ueber
   ihre Klasse. Vorher stand hier img[width][height], das schlug mit seiner
   hoeheren Spezifitaet die Logohoehen: das Kopflogo wuchs auf 160 x 103 px
   und ragte aus dem 80 px hohen Kopf heraus. */
img { height: auto; }

.hero-video { height: 100%; }

a { color: inherit; }

/* Volle Breite: der Rahmen ist der Viewport, Luft kommt aus dem Padding */
.wrap { width: 100%; padding-inline: var(--pad); }

.label {
  font-family: var(--font-sans);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--versal);
  text-transform: uppercase;
}

/* Leitmotiv „Aufschlusspunkt": gefüllter Punkt mit Ring,
   ersetzt alle bisherigen Strich-Akzente */
/* ---------- Der Aufschlusspunkt ----------
   Das Leitmotiv der Seite: ein Ring mit gefuelltem Punkt in der Mitte, das
   Zeichen fuer einen Aufschluss im Baugrund. Es ersetzt jeden Strich und
   jeden Standardpunkt.

   Bis 25.08.2026 gab es dafuer acht Geometrien: Durchmesser von 8 bis 14 px,
   Rahmenstaerken von 2 bis 2,5 px, mal mit Punkt, mal ohne, und der Punkt aus
   einem zweiten Pseudoelement, dessen Bezugsrahmen nicht der Ring war. Der
   sass deshalb an zwei Stellen 2 px neben der Mitte.

   Jetzt zeichnet EIN Element beides: der Rahmen macht den Ring, ein
   Kreisverlauf den Punkt. background-clip: padding-box haelt den Verlauf
   innerhalb des Rahmens, dadurch sitzt der Punkt zwangslaeufig mittig und
   skaliert mit jeder Groesse mit. Groesse und Farbe kommen aus Variablen. */
.marker,
.stat::before,
.ref-facts li::before,
.cred-list li::before,
.ref-detail-body ul li::before,
.image-band figcaption .label::before {
  /* Das Mass haengt an der Schrift, nicht an einer festen Pixelzahl: bei
     14 px auf 15,5-px-Text nahm der Punkt 90 Prozent der Schriftgroesse ein
     und war damit fetter als das Wort daneben. 0,66em ergibt rund 10 px im
     Fliesstext und schrumpft in kleineren Zusammenhaengen von selbst mit.
     Der Rahmen bleibt bei 1,5 px: auf einem 10-px-Ring waeren 2 px vierzig
     Prozent des Durchmessers, der Ring wuerde den Punkt erdruecken. */
  width: var(--marker-mass, 0.66em);
  height: var(--marker-mass, 0.66em);
  border: 1.5px solid var(--marker-farbe, var(--rot));
  border-radius: 50%;
  background: radial-gradient(
    circle at center,
    var(--marker-farbe, var(--rot)) 0 40%,
    transparent 41%
  );
  background-clip: padding-box;
  flex: none;
}

.marker {
  display: inline-block;
  /* Unterkante des Kastens bezogen auf die Grundlinie: so liegt seine Mitte
     auf der optischen Mitte der Versalien statt auf der Zeilenmitte. */
  vertical-align: calc(0.45em - var(--marker-mass, 0.66em) / 2);
}

/* Auf dunklem Grund traegt der Punkt das hellere Rot, sonst steht er nicht. */
.section-dark,
.image-band figcaption,
.feldnotiz,
.karriere-strip { --marker-farbe: var(--rot-hell); }

/* ---------- Typografie ---------- */

h1, h2, h3 {
  font-family: var(--font-sans);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* Ein Durchschuss fuer drei Groessen ging nicht auf. 1,05 ist fuer die H1
   richtig, die bei 108 px als Plakat steht: dort ist enges Setzen die
   Absicht. Dieselbe Zahl bei einer H3 mit 20 px ergibt 21 px Zeilenabstand,
   und weil Ober- und Unterlaengen zusammen mehr Platz brauchen, beruehren
   sich zwei Zeilen fast. Gemessen auf /referenz/sol/: eine zweizeilige H2 mit
   40 px Schrift und 42 px Abstand. Je kleiner der Grad, desto mehr Luft. */
h2 { line-height: 1.12; }
h3 { line-height: 1.3; }

h1 { font-size: clamp(46px, 6.2vw, 108px); }

/* Der Serif-Akzent: Noto Serif kursiv, wie die editorialen Momente
   im bestehenden TIG-Auftritt */
h1 em {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--rot);
}

h2 { font-size: clamp(34px, 3.8vw, 64px); }

h3 { font-size: clamp(20px, 1.5vw, 24px); }

/* ---------- Buttons ---------- */

.btn {
  display: inline-block;
  padding: 16px 34px;
  font-family: var(--font-sans);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  border: 1.5px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease,
              border-color 0.15s ease, box-shadow 0.15s ease;
}

.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--rot);
  color: var(--weiss);
}

.btn-primary:hover {
  background: var(--rot-dunkel);
  box-shadow: 0 6px 20px rgba(227, 6, 19, 0.25);
}

.btn-ghost {
  border-color: currentColor;
  color: var(--anthrazit);
}

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

.btn-light {
  background: var(--weiss);
  color: var(--anthrazit);
}

.btn-light:hover { background: var(--papier); }

.btn-sm { padding: 10px 22px; font-size: var(--t-xs); }

.btn-block { width: 100%; text-align: center; }

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(244, 244, 242, 0.94);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--linie);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 36px;
  height: 80px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  margin-right: auto;
}

/* Logo-SVG enthält unten eine kleine Wortmarke, die bei Headergröße
   unleserlich wird: oben ausgerichtet beschneiden. */
/* Die Kopf-Fassung des Logos ist bereits richtig beschnitten (siehe
   TIG_Logo_Kopf.svg). Frueher schnitt object-fit: cover hier bei 154 von
   206 Einheiten und damit mitten durch die Welle und den roten Bohrer. */
.brand-logo {
  height: 42px;
  width: auto;
}

.brand-text {
  font-size: var(--t-sm);
  line-height: 1.2;
  color: var(--grau);
  display: flex;
  flex-direction: column;
}

.brand-text strong { color: var(--anthrazit); font-weight: 600; }

.main-nav { display: flex; gap: 30px; }

.main-nav a {
  font-size: var(--t-sm);
  font-weight: 500;
  text-decoration: none;
  color: var(--text);
  padding: 6px 0;
  border-bottom: 2px solid transparent;
  transition: border-color 0.15s ease, color 0.15s ease;
}

/* Die sichtbare Linie kommt aus ::before und waechst von links auf. Der
   Rahmen bleibt transparent als Platzhalter, damit nichts springt. */
.main-nav a:hover { color: var(--rot); }

.header-actions { display: flex; align-items: center; gap: 22px; }

.header-phone {
  font-size: var(--t-sm);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  color: var(--anthrazit);
}

.header-phone:hover { color: var(--rot); }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  /* 44 mal 44 ist das Mindestmass fuer Finger (WCAG 2.5.5). Vorher 42 x 26. */
  width: 44px;
  height: 44px;
  padding: 0;
  cursor: pointer;
}

.nav-toggle span {
  display: block;
  width: 26px;
  height: 2px;
  background: var(--anthrazit);
  transition: transform 380ms cubic-bezier(0.16, 0.84, 0.44, 1),
              background 200ms ease;
}

/* Zwei Striche werden zum Kreuz. Die Balken sind 2 px hoch mit 6 px Abstand,
   die Mitte liegt also 4 px von jedem Balken entfernt. */
.nav-toggle[aria-expanded="true"] span:first-child {
  transform: translateY(4px) rotate(45deg);
  background: var(--rot);
}

.nav-toggle[aria-expanded="true"] span:last-child {
  transform: translateY(-4px) rotate(-45deg);
  background: var(--rot);
}

/* Das Menue faehrt von oben herunter, wie ein Bohrgestaenge. Kein Ein- und
   Ausblenden, sondern eine Kante, die nach unten laeuft: clip-path statt
   opacity, damit die Bewegung eine Richtung hat. Das Element bleibt im
   Dokument, sonst gaebe es keine Animation beim Schliessen. */
.mobile-menu {
  position: fixed;
  inset: 80px 0 0 0;
  z-index: 99;
  background: var(--papier);
  padding: 40px var(--pad) 64px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  visibility: hidden;
  pointer-events: none;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 340ms cubic-bezier(0.65, 0, 0.35, 1),
              visibility 0s linear 340ms;
}

.mobile-menu.open {
  visibility: visible;
  pointer-events: auto;
  clip-path: inset(0 0 0 0);
  transition: clip-path 460ms cubic-bezier(0.16, 0.84, 0.44, 1), visibility 0s;
}

.mobile-menu nav { display: flex; flex-direction: column; gap: 4px; }

/* Die Eintraege kommen gestaffelt nach, jeder ein Stueck spaeter als der
   ueber ihm. Zusammen mit der Kante ergibt das eine Abfolge statt eines
   Aufblitzens. */
.mobile-menu nav > * {
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 260ms ease, transform 420ms cubic-bezier(0.16, 0.84, 0.44, 1);
}

.mobile-menu.open nav > * { opacity: 1; transform: none; }

.mobile-menu.open nav > *:nth-child(1) { transition-delay: 110ms; }
.mobile-menu.open nav > *:nth-child(2) { transition-delay: 155ms; }
.mobile-menu.open nav > *:nth-child(3) { transition-delay: 200ms; }
.mobile-menu.open nav > *:nth-child(4) { transition-delay: 245ms; }
.mobile-menu.open nav > *:nth-child(5) { transition-delay: 290ms; }
.mobile-menu.open nav > *:nth-child(6) { transition-delay: 335ms; }
.mobile-menu.open nav > *:nth-child(7) { transition-delay: 380ms; }

/* Jeder Eintrag traegt den Aufschlusspunkt der Marke, der beim Oeffnen
   mitwaechst. Getrennt werden die Eintraege durch Haarlinien, wie ueberall
   sonst im Raster. */
.mobile-menu nav > a:not(.btn),
.mobile-menu .mobil-gruppe-kopf > a {
  font-size: 23px;
  font-weight: 600;
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 0;
  border-bottom: 1px solid var(--linie);
  min-height: 44px;
}

.mobile-menu nav > a:not(.btn)::before,
.mobile-menu .mobil-gruppe-kopf > a::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 2px solid var(--rot);
  flex: none;
  transform: scale(0);
  transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.mobile-menu.open nav > a:not(.btn)::before,
.mobile-menu.open .mobil-gruppe-kopf > a::before { transform: scale(1); }

.mobile-menu.open nav > *:nth-child(1) a::before,
.mobile-menu.open nav > a:nth-child(1)::before { transition-delay: 180ms; }
.mobile-menu.open nav > a:nth-child(2)::before { transition-delay: 225ms; }
.mobile-menu.open nav > a:nth-child(3)::before { transition-delay: 270ms; }
.mobile-menu.open nav > a:nth-child(4)::before { transition-delay: 315ms; }
.mobile-menu.open nav > a:nth-child(5)::before { transition-delay: 360ms; }

.mobile-menu nav > a[aria-current]::before,
.mobile-menu .mobil-gruppe-kopf > a[aria-current]::before { background: var(--rot); }

.mobile-menu .btn { text-align: center; margin-top: 12px; }

.mobile-phone { font-size: var(--t-md); font-variant-numeric: tabular-nums; }

/* ---------- Hero ---------- */

.hero {
  background: linear-gradient(to bottom, var(--weiss) 0%, var(--papier) 100%);
  border-bottom: 1px solid var(--linie);
  overflow: hidden;
}

.hero-grid {
  display: grid;
  /* Der Film traegt den Hero, deshalb bekommt er die groessere Spalte und der
     Abstand faellt schmaler aus. Zusammen rund ein Viertel mehr Bildflaeche. */
  grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
  gap: clamp(36px, 4vw, 80px);
  align-items: center;
  padding-top: clamp(56px, 8vh, 120px);
  padding-bottom: clamp(48px, 7vh, 96px);
}

.eyebrow {
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--versal);
  text-transform: uppercase;
  color: var(--grau);
  margin-bottom: 26px;
}

.hero-sub {
  font-size: clamp(18px, 1.35vw, 22px);
  line-height: 1.6;
  font-weight: 300;
  color: var(--grau);
  max-width: 32em;
  margin-top: 30px;
}

.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 40px;
}

.hero-trust {
  margin-top: 32px;
  font-size: var(--t-sm);
  color: var(--grau);
  max-width: 34em;
}

.hero-trust strong { color: var(--anthrazit); font-weight: 600; }

/* Video-Slot rechts: Intro-Film im nativen Querformat */

.hero-media {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
}

.hero-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--radius);
  background: var(--anthrazit);
  box-shadow: 0 24px 60px rgba(22, 24, 27, 0.18);
}

.video-toggle {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 42px;
  height: 42px;
  border: none;
  border-radius: 50%;
  background: rgba(22, 24, 27, 0.72);
  color: var(--weiss);
  font-size: var(--t-2xs);
  cursor: pointer;
  z-index: 2;
}

.video-toggle:hover { background: rgba(22, 24, 27, 0.9); }

/* Stats */

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--linie);
  margin-top: 8px;
  padding-block: clamp(36px, 4vh, 56px);
  gap: clamp(28px, 3vw, 64px);
}

.stat { position: relative; padding-top: 26px; }

/* Aufschlusspunkt-Marker statt Randstrich */
.stat::before {
  content: "";
  position: absolute;
  left: 0; top: 0;
}

.stat dt { color: var(--grau); margin-bottom: 8px; }

.stat dd {
  font-size: clamp(40px, 3.6vw, 68px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--anthrazit);
  font-variant-numeric: tabular-nums;
}

.stat .unit { font-size: 0.5em; font-weight: 500; color: var(--grau); }

.stat-note {
  display: block;
  font-size: var(--t-xs);
  font-weight: 400;
  color: var(--grau);
  margin-top: 10px;
  letter-spacing: 0;
  text-transform: none;
}

/* ---------- Partner-Band (Serif, rote Fläche wie im TIG-Auftritt) ---------- */

.partner-strip {
  background: var(--rot);
  color: var(--weiss);
}

.partner-inner {
  padding-block: clamp(28px, 4vh, 44px);
  text-align: center;
}

.partner-claim {
  font-family: var(--font-serif);
  font-size: clamp(19px, 1.8vw, 27px);
  font-weight: 400;
  line-height: 1.5;
  text-wrap: balance;
  max-width: 42em;
  margin-inline: auto;
}

.partner-claim a {
  color: var(--weiss);
  font-weight: 600;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 4px;
}

/* Verweiszeile unter dem Anspruch. Dieselbe Bauart wie die Sozialverweise im
   Fuss: Versalien, gesperrt, Linie darunter. Damit ist erkennbar, dass hier
   Ziele stehen und keine Fortsetzung des Satzes.
   flex mit wrap statt eines Rasters: die Beschriftungen sind unterschiedlich
   lang, feste Spalten liessen bei "Drucksondierung (CPT)" neben
   "Grundwassermessstelle" ein Loch. */
.partner-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px 36px;
  margin-top: clamp(20px, 2.4vh, 30px);
}

.partner-links a {
  color: var(--weiss);
  font-size: var(--t-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--versal-eng);
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.45);
  padding-bottom: 3px;
}

.partner-links a:hover { border-bottom-color: var(--weiss); }

/* ---------- Sektionen ---------- */

.section { padding-block: clamp(80px, 10vh, 140px); position: relative; }

.section-light { background: var(--weiss); }

.section-grey { background: var(--papier); }

.section-dark {
  background: var(--anthrazit);
  color: var(--text-invert);
}

.section-dark h2, .section-dark h3 { color: var(--weiss); }

.section-head {
  max-width: 880px;
  margin-bottom: clamp(44px, 5vh, 72px);
}

/* Editorialer Kicker in Noto Serif statt Tech-Label */
.kicker {
  display: block;
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(18px, 1.5vw, 23px);
  letter-spacing: 0.01em;
  color: var(--rot-dunkel);
  margin-bottom: 18px;
}

.section-dark .kicker { color: var(--rot-hell); }

/* Nur fuer rote Flaechen. Auf dunklen Sektionen bleibt der Kicker rot,
   das ist ueber die ganze Seite hinweg dieselbe Sprache. */
.karriere-strip .kicker-light { color: var(--weiss); }

.section-intro {
  margin-top: 22px;
  font-size: clamp(17px, 1.25vw, 20px);
  font-weight: 300;
  color: var(--grau);
  line-height: 1.65;
  max-width: 42em;
}

.section-dark .section-intro { color: var(--grau-hell); }

/* ---------- Leistungen ---------- */

.services-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--linie);
  border: 1px solid var(--linie);
}

.service {
  background: var(--weiss);
  padding: clamp(28px, 2.4vw, 44px) clamp(24px, 2vw, 36px);
  position: relative;
  transition: background 0.2s ease;
}

.service:hover { background: var(--papier); }

.service-icon {
  display: block;
  width: 52px;
  height: 52px;
  margin-bottom: 20px;
  color: var(--anthrazit);
}

.service-icon svg { width: 100%; height: 100%; }

.service-icon .dot {
  fill: var(--rot);
  stroke: none;
  transform-origin: center;
  transition: transform 0.25s ease;
}

.service:hover .service-icon .dot { transform: scale(1.35); }

.service h3 { margin-bottom: 12px; }

.service p {
  font-size: var(--t-sm);
  font-weight: 300;
  color: var(--grau);
  line-height: 1.6;
}

/* ---------- Bildband (volle Breite) ---------- */

.image-band {
  position: relative;
  height: clamp(320px, 52vh, 620px);
  overflow: hidden;
}

.image-band img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-band figcaption {
  position: absolute;
  left: var(--pad);
  bottom: clamp(24px, 4vh, 44px);
  background: rgba(22, 24, 27, 0.84);
  color: var(--text-invert);
  padding: 16px 24px;
  font-size: var(--t-xs);
  backdrop-filter: blur(4px);
}

.image-band figcaption .label {
  /* Das Label lag als Rot auf dem abgedunkelten Bild bei 3,44:1. Weiss
     bringt 11,21:1, der rote Akzent bleibt als Punkt davor erhalten. */
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--weiss);
  font-size: var(--t-3xs);
  margin-bottom: 3px;
}

/* ---------- Prozess ---------- */

.process {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 48px clamp(28px, 3vw, 56px);
  counter-reset: step;
}

.process-step {
  position: relative;
  counter-increment: step;
}

/* Nummern in Bohrloch-Ringen statt Strich-Kante */
.process-step::before {
  content: counter(step);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  margin-bottom: 20px;
  border: 2px solid var(--rot);
  border-radius: 50%;
  font-size: 21px;
  font-weight: 700;
  color: var(--rot-dunkel);
  font-variant-numeric: tabular-nums;
  background: var(--weiss);
}

.process-step h3 { margin-bottom: 12px; }

.process-step p { font-size: var(--t-sm); font-weight: 300; color: var(--grau); }

/* ---------- Referenzen ---------- */

.ref-featured {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: clamp(36px, 5vw, 96px);
  align-items: center;
  margin-bottom: clamp(48px, 6vh, 80px);
  padding-bottom: clamp(48px, 6vh, 80px);
  border-bottom: 1px solid var(--linie-dunkel);
}

.ref-featured-media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius);
}

.ref-meta {
  color: var(--rot-hell);
  margin-bottom: 16px;
  display: block;
}

.ref-featured-body h3 {
  font-size: clamp(30px, 2.8vw, 46px);
  /* Als h3 erbte diese 46-px-Zeile den Durchschuss 1,3 und stand damit auf
     60 px. Der Durchschuss gehoert an die Groesse, nicht an die Stufe im
     Dokument: je groesser der Grad, desto enger. */
  line-height: 1.12;
  margin-bottom: 18px;
}

/* Ohne eigene Regel lief hier die Browservorgabe: eine Unterstreichung quer
   unter einer 46-px-Zeile. Alle anderen Projekttitel tragen keine. */
.ref-featured-body h3 a { color: inherit; text-decoration: none; }
.ref-featured-body h3 a:hover { color: var(--rot-hell); }

.ref-featured-body > p {
  color: var(--grau-hell);
  font-weight: 300;
  margin-bottom: 26px;
  max-width: 36em;
}

.ref-facts {
  list-style: none;
  display: grid;
  gap: 12px;
}

.ref-facts li {
  padding-left: 24px;
  position: relative;
  font-size: var(--t-sm);
  color: var(--text-invert);
}

.ref-facts li::before {
  content: "";
  position: absolute;
  left: 0;
  /* Mitte der Zeilenbox, minus die optische Korrektur nach oben. */
  top: calc((1lh - var(--marker-mass, 0.66em)) / 2 - 0.08em);
}

.ref-facts strong { color: var(--weiss); font-weight: 600; }

.ref-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 2.5vw, 44px);
}

.ref-card {
  background: var(--anthrazit-2);
  border: 1px solid var(--linie-dunkel);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform 0.2s ease, border-color 0.2s ease;
}

.ref-card:hover { transform: translateY(-4px); border-color: var(--grau); }

.ref-card img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}

.ref-card-body { padding: clamp(24px, 2vw, 34px); }

.ref-card h3 { margin-bottom: 12px; }

.ref-card p { font-size: var(--t-sm); font-weight: 300; color: var(--grau-hell); }

/* 11 px versal ergaben 1,76 px Laufweite, das liest niemand gern. */
.ref-card .ref-meta { margin-bottom: 12px; font-size: var(--t-2xs); }

.ref-more {
  margin-top: clamp(36px, 4vh, 56px);
  font-size: var(--t-sm);
  color: var(--grau-hell);
  text-align: center;
}

.ref-cta {
  margin-top: clamp(40px, 5vh, 64px);
  padding: clamp(32px, 4vh, 52px) clamp(28px, 4vw, 72px);
  background: var(--anthrazit-2);
  border: 1px solid var(--linie-dunkel);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  flex-wrap: wrap;
}

.ref-cta p {
  font-family: var(--font-serif);
  font-size: clamp(20px, 1.8vw, 27px);
  font-weight: 400;
  color: var(--weiss);
  max-width: 26em;
  text-wrap: balance;
  line-height: 1.45;
}

.ref-cta-actions {
  display: flex;
  align-items: center;
  gap: 26px;
  flex-wrap: wrap;
}

.ref-cta-phone {
  color: var(--text-invert);
  text-decoration: none;
  font-size: var(--t-sm);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.ref-cta-phone:hover { color: var(--rot-hell); }

/* ---------- Über / Team ---------- */

.about-grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(44px, 6vw, 120px);
  align-items: center;
  margin-bottom: clamp(52px, 7vh, 96px);
}

.about-copy p {
  margin-top: 20px;
  font-weight: 300;
  color: var(--grau);
  max-width: 38em;
}

.about-copy h2 { margin-bottom: 6px; }

.cred-list {
  list-style: none;
  margin-top: 30px;
  display: grid;
  gap: 14px;
}

.cred-list li {
  padding-left: 28px;
  position: relative;
  font-size: var(--t-sm);
  font-weight: 500;
}

.cred-list li::before {
  content: "";
  position: absolute;
  left: 0;
  /* Mitte der Zeilenbox, minus die optische Korrektur nach oben. */
  top: calc((1lh - var(--marker-mass, 0.66em)) / 2 - 0.08em);
}

.about-media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius);
  box-shadow: 0 24px 60px rgba(22, 24, 27, 0.14);
}

.about-media figcaption {
  margin-top: 14px;
  color: var(--grau);
  font-size: var(--t-2xs);
}

.people {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 2.5vw, 44px);
}

.person img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radius);
  filter: grayscale(18%);
  transition: filter 0.25s ease;
}

.person:hover img { filter: grayscale(0%); }

.person figcaption { margin-top: 16px; }

.person strong { display: block; font-size: 18px; font-weight: 600; }

.person span {
  display: block;
  font-size: var(--t-xs);
  font-weight: 300;
  color: var(--grau);
  margin-top: 4px;
}

/* ---------- Kontakt ---------- */

.section-contact { border-top: 1px solid var(--linie-dunkel); }

.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(44px, 7vw, 140px);
  align-items: start;
}

.contact-copy > p {
  margin-top: 22px;
  font-weight: 300;
  color: var(--grau-hell);
  max-width: 30em;
}

.contact-person {
  display: flex;
  gap: 22px;
  align-items: center;
  margin-top: 40px;
  padding: 26px;
  background: var(--anthrazit-2);
  border: 1px solid var(--linie-dunkel);
  border-radius: var(--radius);
  max-width: 480px;
}

.contact-person img {
  width: 88px;
  height: 88px;
  object-fit: cover;
  border-radius: 50%;
  flex-shrink: 0;
}

.contact-person strong { display: block; font-size: 18px; font-weight: 600; }

.contact-person span {
  display: block;
  font-size: var(--t-xs);
  font-weight: 300;
  color: var(--grau-hell);
  margin-bottom: 10px;
}

.contact-person a {
  display: block;
  font-size: var(--t-sm);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-invert);
  text-decoration: none;
  line-height: 1.75;
}

.contact-person a:hover { color: var(--rot-hell); }

.contact-address {
  display: block;
  margin-top: 30px;
  font-style: normal;
  font-size: var(--t-xs);
  color: var(--grau-hell);
  line-height: 1.8;
}

/* Formular */

.contact-form {
  background: var(--weiss);
  color: var(--text);
  padding: clamp(30px, 3vw, 52px);
  border-radius: var(--radius);
  display: grid;
  gap: 22px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.25);
}

.field { display: grid; gap: 8px; }

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}

.field label {
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.optional { color: var(--grau); font-weight: 400; text-transform: none; }

.field input,
.field textarea {
  font-family: var(--font-sans);
  font-size: var(--t-sm);
  padding: 14px 15px;
  border: 1.5px solid var(--grau-hell);
  border-radius: var(--radius);
  background: var(--papier);
  transition: border-color 0.15s ease;
  resize: vertical;
}

.field input:focus,
.field textarea:focus {
  border-color: var(--rot);
  background: var(--weiss);
}

/* Hinweis statt Zustimmungshaken: Eine Datenschutzerklaerung ist eine
   Information nach Art. 13 DSGVO, kein Gegenstand einer Einwilligung. */
/* Grundwerte fuer hellen Grund: dort steht das Formular tatsaechlich
   (gemessen auf Weiss). --grau-hell und --rot-hell lagen bei 3,31:1 und
   3,26:1, --grau bringt 6,11:1 und --rot 4,88:1. Die Sonderregeln fuer
   dunkle Traeger stehen darunter. */
.form-note {
  font-size: var(--t-xs);
  line-height: 1.55;
  color: var(--grau);
}

.form-note a {
  color: var(--rot);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.section-light .form-note { color: var(--grau); }

.section-light .form-note a { color: var(--rot); }

.form-alt {
  text-align: center;
  font-size: var(--t-xs);
  color: var(--grau);
}

.form-alt a {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--anthrazit);
  text-decoration: none;
}

.form-alt a:hover { color: var(--rot); }

/* ---------- Karriere ---------- */

.karriere-strip {
  background: var(--rot);
  color: var(--weiss);
}

.karriere-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 44px;
  padding-block: clamp(52px, 7vh, 80px);
}

.karriere-strip h2 {
  font-size: clamp(30px, 3vw, 52px);
  margin-bottom: 12px;
}

.karriere-strip p {
  max-width: 48em;
  font-size: var(--t-md);
  font-weight: 300;
}

.karriere-strip .btn { flex-shrink: 0; }

/* ---------- Footer ---------- */

.site-footer {
  background: var(--anthrazit-tief);
  color: var(--grau-hell);
  font-size: var(--t-xs);
}

.footer-grid {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  gap: clamp(32px, 4vw, 96px);
  padding-block: clamp(52px, 7vh, 80px) 48px;
  align-items: start;
}

.footer-logo { height: 64px; width: auto; }

/* Die Wortmarke steht als Text statt im SVG: im Logo misst sie 10,5 von
   206,68 Einheiten und waere bei 64 px Logohoehe 3,3 px hoch. Als Text ist
   sie lesbar, markierbar und laesst sich auf dunklem Grund faerben.
   Aufbau wie im Kopf, "Terra" traegt, der Rest bleibt ruhig. */
.footer-wortmarke {
  display: flex;
  flex-direction: column;
  margin-top: 14px;
  font-size: var(--t-sm);
  line-height: 1.25;
  color: var(--grau-hell);
}

.footer-wortmarke strong { color: var(--text-invert); font-weight: 600; }

.footer-brand .label { display: block; margin-top: 10px; color: var(--grau-hell); }

/* max-content mal drei sprengte schmale Geraete: "Baugrunderkundungen" und
   "Nearshore / Offshore" ergaben zusammen eine Mindestbreite von 487 px,
   der Fuss lief bei 320 px waagerecht ueber. auto-fill nimmt so viele
   Spalten, wie hineinpassen. */
.footer-nav {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), max-content));
  gap: 14px 52px;
}

.footer-nav a { text-decoration: none; color: var(--text-invert); }

.footer-nav a:hover { color: var(--rot-hell); }

.footer-contact p { margin-bottom: 14px; line-height: 1.7; }

.footer-contact a { color: var(--text-invert); text-decoration: none; }

.footer-contact a:hover { color: var(--rot-hell); }

.footer-social { display: flex; gap: 20px; margin-top: 6px; }

.footer-social a {
  font-size: var(--t-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--versal-eng);
  text-decoration: none;
  /* var(--linie-dunkel) brachte der Linie 1,46:1, der Verweis war im
     Ruhezustand nicht als Verweis zu erkennen. */
  border-bottom: 1px solid var(--grau-hell);
  padding-bottom: 2px;
}

/* Partnerzeile zwischen Fussraster und Rechtszeile. Sie traegt die Trennlinie
   nach oben, die Rechtszeile darunter behaelt ihre eigene: sonst stossen zwei
   Bereiche ohne Kante aneinander. */
.footer-partner {
  padding-block: 20px;
  border-top: 1px solid var(--linie-dunkel);
  font-size: var(--t-xs);
  line-height: 1.7;
  color: var(--grau-hell);
  max-width: 70em;
}

.footer-partner a { color: var(--text-invert); text-decoration: none; border-bottom: 1px solid var(--linie-dunkel); }

.footer-partner a:hover { color: var(--rot-hell); border-bottom-color: var(--rot-hell); }

.footer-legal {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  padding-block: 22px 30px;
  border-top: 1px solid var(--linie-dunkel);
  font-size: var(--t-2xs);
  color: var(--grau-hell);
}

.footer-legal a { color: var(--grau-hell); text-decoration: none; }

.footer-legal a:hover { color: var(--text-invert); }

/* ---------- Bohrtiefen-Zähler ---------- */

/* Stand bis 25.08. unten links und lag damit genau auf der Textecke der
   Referenzkacheln: der Titel der ersten Kachel war zur Haelfte verdeckt.
   Links beginnt jede Ueberschrift der Seite, rechts ist die ruhigere Kante. */
.depth-counter {
  position: fixed;
  right: clamp(16px, 2vw, 32px);
  bottom: clamp(16px, 3vh, 32px);
  z-index: 90;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 12px 18px;
  background: rgba(22, 24, 27, 0.86);
  color: var(--weiss);
  border-radius: var(--radius);
  backdrop-filter: blur(8px);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
  pointer-events: none;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

/* erscheint erst, wenn die „Bohrung" beginnt (Scroll unterhalb des Heros) */
.depth-counter.visible {
  opacity: 1;
  transform: none;
}

/* ... und geht wieder, sobald die Zeile mit Impressum und Datenschutz im Bild
   ist. Beide sitzen unten rechts, der Zaehler lag also auf den beiden Woertern.
   Er faehrt nach unten aus dem Bild, in derselben Richtung, aus der er kam. */
.depth-counter.visible.abgetaucht {
  opacity: 0;
  transform: translateY(12px);
}

/* 10,5 px Grau auf dem abgedunkelten Zaehler lagen bei 3,61:1 */
.depth-counter-label {
  font-size: var(--t-3xs);
  font-weight: 600;
  letter-spacing: var(--versal);
  text-transform: uppercase;
  color: var(--grau-invert);
}

.depth-counter-value {
  font-size: 21px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

.depth-counter-value #depthValue { color: var(--rot-hell); }

@media (max-width: 860px) {
  .depth-counter { display: none; }
}

/* ---------- Skip-Link & Fokus ---------- */

.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 200;
}

.skip-link:focus {
  left: 16px;
  top: 16px;
  background: var(--weiss);
  color: var(--anthrazit);
  padding: 12px 18px;
  font-weight: 600;
  border: 2px solid var(--rot);
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--rot);
  outline-offset: 2px;
  border-radius: 1px;
}

/* Auf roten und dunklen Flaechen waere ein roter Ring nicht zu sehen.
   Dort steht ein weisser Ring mit dunklem Saum. */
.partner-strip :focus-visible,
.karriere-strip :focus-visible,
.section-dark :focus-visible,
.site-footer :focus-visible,
.image-band :focus-visible {
  outline-color: var(--weiss);
  box-shadow: 0 0 0 6px rgba(22, 24, 27, 0.9);
}

/* ---------- Reveal-Animationen (nur mit aktivem JS) ---------- */

.js .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.js .reveal.in {
  opacity: 1;
  transform: none;
}

/* Die Verzoegerung setzt main.js als --reveal-i je Kind eines Rasters.
   60 ms je Schritt: schnell genug, dass man nicht wartet, langsam genug,
   dass eine Reihenfolge erkennbar wird. */
.js .reveal { transition-delay: calc(var(--reveal-i, 0) * 60ms); }

/* Der Hero ist ausgenommen. Er steht im ersten Bildschirm, und was dort steht,
   ist der LCP-Kandidat: auf dem Handy die H1, am Schirm das Standbild des
   Films. Beide lagen auf opacity 0, bis main.js gelaufen war, das Skript haengt
   aber am Seitenende. Damit haing der wichtigste Messwert der Seite am
   Skript-Download statt am Bildaufbau. Unterhalb der Falz bleibt die
   Einblendung, dort kostet sie nichts. */
.js .hero .reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; transition-delay: 0s; }
  html { scroll-behavior: auto; }

  /* Wer weniger Bewegung eingestellt hat, bekommt dieselben Zustaende ohne
     den Weg dorthin. Das Menue ist auf, zu oder nichts dazwischen. */
  .mobile-menu,
  .mobile-menu.open,
  .mobile-menu nav > *,
  .mobile-menu nav > a::before,
  .nav-toggle span,
  .stat dd,
  .bohrkern,
  .bohrkern-schicht {
    transition: none !important;
    animation: none !important;
  }

  .mobile-menu nav > * { opacity: 1; transform: none; }
  .mobile-menu.open nav > a:not(.btn)::before,
.mobile-menu.open .mobil-gruppe-kopf > a::before { transform: scale(1); }
  .bohrkern-schicht { transform: scaleY(1); animation: none; }
  .bohrkern.offen, .bohrkern { transition: none; }
}

/* ---------- Responsive ---------- */

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

  /* Die Rufnummer stand hier auf display: none und war damit unter 1180 px
     nur noch hinter zwei Klicks im Menue zu finden. Der Anruf ist im B2B der
     kuerzeste Weg zur Anfrage, und auf dem Handy ist er ein Fingertipp.
     Statt sie auszublenden, wird sie kurz: die Ziffern weichen dem Hoerer,
     der Link bleibt derselbe. aria-label am Element traegt die Ansage. */
  .header-phone {
    font-size: 0;
    padding: 8px;
    margin-right: 4px;
    line-height: 0;
    color: var(--anthrazit);
  }

  .header-phone::before {
    content: "";
    display: block;
    width: 22px;
    height: 22px;
    background: currentColor;
    /* Hoerer-Symbol als Maske, damit es die Textfarbe erbt und im
       Fokuszustand mitgeht. */
    -webkit-mask: var(--hoerer) center / contain no-repeat;
    mask: var(--hoerer) center / contain no-repeat;
  }
  .services-grid { grid-template-columns: 1fr 1fr; }
  .process { grid-template-columns: 1fr 1fr; }
  .ref-grid { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 860px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-media { max-width: 640px; }
  .ref-featured { grid-template-columns: 1fr; }
  .about-grid { grid-template-columns: 1fr; }
  .contact-grid { grid-template-columns: 1fr; }
  .people { grid-template-columns: 1fr; max-width: 460px; }
  .karriere-inner { flex-direction: column; align-items: flex-start; }
  .footer-grid { grid-template-columns: 1fr; gap: 40px; }
}

@media (max-width: 600px) {
  .services-grid { grid-template-columns: 1fr; }
  .process { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr; }
  .field-row { grid-template-columns: 1fr; }
  /* CTA bleibt auch mobil im Header sichtbar, nur kompakter */
  .header-inner { gap: 16px; }
  .header-actions .btn { padding: 9px 14px; font-size: var(--t-2xs); white-space: nowrap; }
  .brand-text { display: none; }
  .ref-cta { flex-direction: column; align-items: flex-start; }
}

/* ============================================================
   UNTERSEITEN
   Startseite bleibt unveraendert. Alles ab hier gehoert zu den
   Seiten, die aus den Inhalten von terra-ing.de entstanden sind:
   Leistungen, Referenzen, Karriere, Historie, Kontakt, Recht.
   Gleiche Bausteine wie oben, nur ruhiger: Haarlinien-Raster,
   kein Schatten, kein Radius, roter Punkt als einziger Akzent.
   ============================================================ */

/* ---------- Seitenkopf ---------- */

.page-hero {
  background: var(--weiss);
  border-bottom: 1px solid var(--linie);
  padding-block: clamp(40px, 7vh, 96px) clamp(48px, 8vh, 104px);
}

.page-hero h1 {
  font-size: clamp(38px, 5vw, 84px);
  max-width: 17em;
}

.page-lead {
  margin-top: clamp(20px, 2.5vh, 32px);
  font-size: clamp(17px, 1.35vw, 21px);
  font-weight: 300;
  line-height: 1.6;
  color: var(--grau);
  max-width: 44em;
}

.page-badge {
  margin-top: 24px;
  font-size: var(--t-sm);
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 10px;
}

/* ---------- Brotkrumen ---------- */

.breadcrumb { margin-bottom: clamp(24px, 3vh, 40px); }

.breadcrumb ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  font-size: var(--t-xs);
  color: var(--grau);
}

.breadcrumb li + li::before {
  content: "›";
  margin-right: 10px;
  color: var(--grau-hell);
}

.breadcrumb a {
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.breadcrumb a:hover { color: var(--rot); border-bottom-color: var(--rot); }

.breadcrumb [aria-current] { color: var(--anthrazit); font-weight: 500; }

/* ---------- Fliesstext ---------- */

/* Zeilenlaenge: 46em ergaben gemessene 87 Zeichen pro Zeile, das ist zu breit
   zum Lesen. 40em landen bei rund 76 Zeichen, Rechtstexte noch enger. */
.prose { max-width: 40em; }

.prose-narrow { max-width: 37em; }

.prose > * + * { margin-top: 22px; }

.prose h2 {
  font-size: clamp(26px, 2.4vw, 40px);
  line-height: 1.15;
  margin-top: clamp(48px, 6vh, 80px);
  padding-top: clamp(20px, 2.5vh, 32px);
  border-top: 1px solid var(--linie);
}

.prose > h2:first-child { margin-top: 0; border-top: 0; padding-top: 0; }

.prose h3 {
  font-size: clamp(19px, 1.5vw, 23px);
  margin-top: clamp(32px, 4vh, 48px);
}

.prose h4 {
  font-family: var(--font-sans);
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: 0;
  margin-top: 32px;
}

.prose p {
  font-weight: 300;
  line-height: 1.7;
  color: var(--text);
}

.prose ul, .prose ol {
  padding-left: 22px;
  display: grid;
  gap: 10px;
}

/* Marker bleiben schwarz, Rot ist Akzentfarbe und kein Aufzaehlungszeichen */
.prose li {
  font-weight: 300;
  line-height: 1.65;
  color: var(--text);
}

.prose li::marker { color: var(--anthrazit); }

.prose a {
  color: var(--rot);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.prose a:hover { color: var(--rot-dunkel); }

.prose strong { font-weight: 600; }

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
}

.prose th, .prose td {
  border: 1px solid var(--linie);
  padding: 10px 14px;
  text-align: left;
}

/* ---------- Fachkarten (Leistungsspektrum) ---------- */

/* Dieselbe Linienfuehrung wie bei den Stellenkarten und aus demselben Grund:
   die Spaltenzahl richtet sich nach der Breite, die Zahl der Fachkarten nach
   der Leistung. Sechs Karten in vier Spalten lassen zwei Zellen leer, und die
   zeigten vorher den grauen Rasterhintergrund. */
.spec-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 1px;
  background: var(--weiss);
  border: 1px solid var(--linie);
  margin-top: clamp(32px, 4vh, 48px);
  max-width: none;
}

.spec {
  background: var(--weiss);
  box-shadow: 0 0 0 1px var(--linie);
  padding: clamp(24px, 2.2vw, 38px);
}

.spec h3 {
  margin: 0 0 14px;
  font-size: clamp(18px, 1.35vw, 22px);
}

.spec p, .spec li {
  font-size: var(--t-sm);
  font-weight: 300;
  color: var(--grau);
  line-height: 1.6;
}

.spec ul, .spec ol { padding-left: 20px; display: grid; gap: 8px; }

.spec li::marker { color: var(--anthrazit); }

.spec > * + * { margin-top: 12px; }

.section-grey .spec { background: var(--weiss); }

/* ---------- Referenzdetail ---------- */

.ref-detail {
  display: grid;
  /* Die Seitenspalte darf mitwachsen. Sie traegt den Faktenkasten und nimmt
     dem Satz die Breite ab, die ihn sonst zu lang machen wuerde. */
  grid-template-columns: minmax(0, 1fr) minmax(280px, min(30%, 460px));
  gap: clamp(40px, 3.5vw, 72px);
  align-items: start;
}

.ref-detail-body { max-width: none; }

.ref-detail-body .ref-facts,
.ref-detail-body ul { list-style: none; padding-left: 0; }

.ref-detail-body ul li {
  padding-left: 26px;
  position: relative;
}

.ref-detail-body ul li::before {
  content: "";
  position: absolute;
  left: 0;
  /* Mitte der Zeilenbox, minus die optische Korrektur nach oben. */
  top: calc((1lh - var(--marker-mass, 0.66em)) / 2 - 0.08em);
}

.ref-detail-meta {
  border: 1px solid var(--linie);
  padding: clamp(24px, 2.2vw, 34px);
  position: sticky;
  top: 112px;
}

.fact-list { display: grid; gap: 22px; margin-bottom: 28px; }

.fact dt { color: var(--grau); margin-bottom: 6px; }

.fact dd { font-size: var(--t-sm); font-weight: 500; line-height: 1.45; }

/* ---------- Bildstrecke ---------- */

/* Die Bilder der TIG kommen in vier Formaten: Panoramen von Trassen, hochkant
   fotografierte Bodenprofile, quadratische Portraets und normale Querformate.
   Zwei Anlaeufe davor: ein Spaltenraster mit Originalformaten liess Loecher
   stehen, justierte Zeilen zogen zwei Bilder auf 718 px breite Streifen.

   Jetzt gleich grosse Quadrate mit gedeckelter Kantenlaenge. Sie tragen jede
   Bildzahl von zwei bis sechs, ohne Streifen und ohne Loch, und die Reihe
   bleibt ruhig. Der Zuschnitt an den Raendern ist der Preis dafuer. */

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 300px));
  gap: clamp(8px, 0.8vw, 14px);
  justify-content: start;
}

.gallery-item {
  aspect-ratio: 1 / 1;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin: 0;
  background: var(--anthrazit);
}

.gallery .gallery-item img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  object-fit: cover;
  transition: transform 0.5s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.gallery-item:hover img { transform: scale(1.04); }

/* Die Unterschrift liegt im Bild. Stuende sie darunter, waeren die Kacheln
   je nach Textlaenge verschieden hoch und das Quadrat waere hin. */
.gallery-item figcaption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: clamp(24px, 4vw, 40px) 14px 12px;
  font-size: var(--t-2xs);
  line-height: 1.4;
  color: var(--weiss);
  background: linear-gradient(to top,
    rgba(var(--verlauf-grund), 0.94) 0%,
    rgba(var(--verlauf-grund), 0.82) 44%,
    rgba(var(--verlauf-grund), 0.36) 74%,
    rgba(var(--verlauf-grund), 0) 100%);
}

@media (prefers-reduced-motion: reduce) {
  .gallery .gallery-item img { transition: none; }
  .gallery-item:hover img { transform: none; }
}

/* Auf dem Telefon zwei Kacheln nebeneinander: eine einzelne waere 350 px
   gross und die Strecke damit laenger als der halbe Seiteninhalt. */
@media (max-width: 700px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- Referenzuebersicht ---------- */

/* Vier statt drei Spalten. Das Raster bleibt ein Raster, damit die
   Reihenfolge stimmt (die Uebersicht ist nach Projektbeginn sortiert), aber
   die Karten sind unterschiedlich hoch: jedes Bild bekommt den Kasten seines
   Formats. Das ergibt die abwechslungsreiche Kante von selbst. */
/* Uebersicht heisst Ueberblick. Neun Projekte in vier Spalten, alle Kacheln
   gleich gross, damit die Reihe stimmt und nichts wegkippt.
   Der Zuschnitt ist hier "contain" statt "cover": Panorama, Bodenprofil,
   BIM-Bildschirmfoto und Bahnfoto haben nichts gemeinsam ausser dem Rahmen.
   Wer sie in einen Einheitskasten presst, schneidet bis zu 51 Prozent weg,
   gemessen. Vollstaendig und klein zeigt mehr als angeschnitten und gross.
   Das Papierfeld dahinter ist das Markenpapier, kein Loch. */
.ref-grid-wide {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(14px, 1.4vw, 22px);
  align-items: stretch;
}

.section-light .ref-card {
  background: var(--weiss);
  border: 1px solid var(--linie);
}

.section-light .ref-card:hover { border-color: var(--grau); }

.section-light .ref-card p { color: var(--grau); }

.section-light .ref-card .ref-meta { color: var(--rot); }

.ref-card-media { display: block; }

.ref-card h3 a { text-decoration: none; }

.ref-card h3 a:hover { color: var(--rot); }

.ref-card-place {
  margin-top: 16px;
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: var(--t-xs);
}

.ref-card-place .marker { --marker-mass: 0.72em; }

.ref-more-all {
  display: inline-block;
  margin-left: 8px;
  color: var(--rot-hell);
  font-weight: 500;
}

/* ---------- Stellen ---------- */

/* Die Trennlinien kamen bisher aus dem Rasterhintergrund, den die Karten mit
   1 px Abstand freiliessen. Bei fuenf Stellen in drei Spalten bleibt die
   sechste Zelle leer, und dort stand statt einer Linie eine graue Flaeche.
   Der Hintergrund ist deshalb weiss, die Linie zieht jede Karte selbst als
   1 px breiten Schatten. Das haelt auch, wenn eine Stelle dazukommt oder
   wegfaellt, und in jeder Spaltenzahl. */
.job-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--weiss);
  border: 1px solid var(--linie);
}

.job-card {
  background: var(--weiss);
  box-shadow: 0 0 0 1px var(--linie);
  padding: clamp(28px, 2.4vw, 44px);
  display: flex;
  flex-direction: column;
}

.job-card-type { color: var(--rot); margin-bottom: 16px; }

.job-card h2 {
  font-size: clamp(21px, 1.6vw, 27px);
  line-height: 1.2;
  margin-bottom: 14px;
}

.job-card h2 a { text-decoration: none; }

.job-card h2 a:hover { color: var(--rot); }

.job-card p {
  font-size: var(--t-sm);
  font-weight: 300;
  color: var(--grau);
  line-height: 1.6;
}

.job-card-link {
  margin-top: auto;
  padding-top: 22px;
  font-weight: 600;
  font-size: var(--t-sm);
  text-decoration: none;
  color: var(--rot);
}

.job-card-link:hover { color: var(--rot-dunkel); text-decoration: underline; }

.job-card-open { background: var(--papier); }

.job-detail {
  display: grid;
  /* Die Seitenspalte darf mitwachsen. Sie traegt den Faktenkasten und nimmt
     dem Satz die Breite ab, die ihn sonst zu lang machen wuerde. */
  grid-template-columns: minmax(0, 1fr) minmax(280px, min(30%, 460px));
  gap: clamp(40px, 3.5vw, 72px);
  align-items: start;
}

.job-body { max-width: none; }

.job-aside { display: grid; gap: 24px; position: sticky; top: 112px; }

.job-contact, .job-links {
  border: 1px solid var(--linie);
  padding: clamp(24px, 2.2vw, 34px);
}

/* Kopfzeile des Ansprechpartner-Kastens: rundes Portrait neben der
   Ueberschrift. Dieselben 88 px wie in .contact-person auf /kontakt/, damit
   dieselbe Person auf beiden Seiten gleich gross erscheint. Das Bild liegt
   quadratisch vor, object-fit deckt trotzdem ab, falls spaeter ein anderes
   Seitenverhaeltnis nachgereicht wird. */
.job-contact-kopf {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-bottom: 16px;
}

.portrait {
  width: 88px;
  height: 88px;
  object-fit: cover;
  border-radius: 50%;
  flex-shrink: 0;
}

/* Die Ueberschrift traegt ihren Abstand schon ueber den Kopf-Container. */
.job-contact-kopf h2 { margin-bottom: 0; }

/* 20 px mit dem Durchschuss der 64-px-H2 waeren 22,4 px und damit zu eng. */
.job-contact h2 { font-size: 20px; line-height: 1.25; margin-bottom: 16px; }

.job-contact p { font-size: var(--t-sm); font-weight: 300; line-height: 1.65; margin-bottom: 22px; }

.job-contact a { color: var(--rot); }

.job-links { display: grid; gap: 10px; }

.job-links .label { color: var(--grau); margin-bottom: 4px; }

/* Der Kasten trug bisher nur Verweise. Der Partnerkasten braucht einen Satz
   davor, sonst steht "TerraTec: offene Stellenboerse" ohne Grund im Raum. */
.job-links-text {
  font-size: var(--t-sm);
  font-weight: 300;
  line-height: 1.6;
  color: var(--grau);
  margin-bottom: 6px;
}

.job-links a { font-size: var(--t-sm); color: var(--rot); text-decoration: none; }

.job-links a:hover { text-decoration: underline; }

/* ---------- Querverweise ---------- */

.section-head-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  max-width: none;
}

.section-head-cta { margin-top: 28px; }

.chip-grid { display: flex; flex-wrap: wrap; gap: 1px; background: var(--linie); border: 1px solid var(--linie); }

.chip {
  background: var(--weiss);
  padding: 18px 26px;
  font-size: var(--t-sm);
  font-weight: 500;
  text-decoration: none;
  flex: 1 1 220px;
  transition: background 0.15s ease, color 0.15s ease;
}

.chip:hover { background: var(--anthrazit); color: var(--weiss); }

/* ---------- Querverweis zwischen Leistung und Referenz ----------
   Verbindet die beiden Cluster, die vorher keinen einzigen Link teilten.
   Bewusst kein weiteres Vollband: die Seiten tragen schon ein chip-Band und
   ein CTA-Band, ein drittes haette daraus einen Streifenteppich gemacht.
   Eine Haarlinie oben genuegt als Abgrenzung. */
.querverweis {
  border-top: 1px solid var(--linie);
  padding-block: clamp(22px, 2.4vw, 34px);
}

.querverweis-kicker {
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--versal-eng);
  text-transform: uppercase;
  color: var(--grau);
  margin-bottom: 10px;
}

.querverweis-links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 0;
  font-size: var(--t-md);
}

/* Trenner als Linie, nicht als Zeichen. Ein ::before am Link liegt INNERHALB
   des Links und wird von Screenreadern als Teil des Linktextes vorgelesen
   ("Punkt Geotechnik"). Eine Rahmenlinie sagt niemand an. */
.querverweis-links a:not(:last-child) {
  border-right: 1px solid var(--linie);
  padding-right: 14px;
  margin-right: 14px;
}

.querverweis-links a {
  color: var(--rot-dunkel);
  text-decoration: none;
  /* Tippziel nach WCAG 2.5.8: 24 px Hoehe, auch wenn die Zeile kuerzer ist. */
  padding-block: 3px;
  min-height: 24px;
}

.querverweis-links a:hover { text-decoration: underline; text-underline-offset: 4px; }

/* ---------- CTA-Band ---------- */

.cta-band { padding-block: clamp(56px, 7vh, 96px); }

.cta-band-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(28px, 4vw, 72px);
  flex-wrap: wrap;
}

.cta-band h2 { font-size: clamp(28px, 3vw, 50px); }

.cta-band p {
  margin-top: 18px;
  color: var(--grau-hell);
  font-weight: 300;
  max-width: 40em;
}

.cta-band-actions { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; }

.cta-band-phone {
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--text-invert);
  text-decoration: none;
}

.cta-band-phone:hover { color: var(--rot-hell); }

/* ---------- Historie ---------- */

.bio-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--linie);
  border: 1px solid var(--linie);
}

.bio { background: var(--weiss); }

.bio img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

.bio-body { padding: clamp(24px, 2.2vw, 36px); }

.bio-body h3 { margin-bottom: 8px; }

.bio-role { color: var(--rot); margin-bottom: 16px; }

.bio-body p { font-size: var(--t-sm); font-weight: 300; color: var(--grau); line-height: 1.65; }

.about-grid-reverse .about-copy { order: 2; }

.about-grid-reverse .about-media { order: 1; }

/* ---------- Kontaktseite ---------- */

.contact-facts {
  margin-top: 36px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 26px;
  border-top: 1px solid var(--linie-dunkel);
  padding-top: 26px;
}

.contact-facts dt { color: var(--grau-hell); margin-bottom: 8px; }

.contact-facts dd { font-size: var(--t-sm); font-weight: 300; line-height: 1.6; }

.contact-facts a { color: var(--rot-hell); }

/* ---------- Verlinkte Leistungskarten ---------- */

.service h3 a { text-decoration: none; }

.service h3 a:hover { color: var(--rot); }

/* Die Karten stehen im Raster gleich hoch, ihr Inhalt ist verschieden lang.
   Ohne diesen Griff haengt der Link mal hoeher, mal tiefer. */
.service-linked { display: flex; flex-direction: column; }

.service-linked p { flex: 1; }

.service-more {
  display: inline-block;
  align-self: flex-start;
  margin-top: 18px;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--rot);
  text-decoration: none;
}

.service-more:hover { text-decoration: underline; }

/* ---------- Footer: zweite Spalte mit Leistungen ---------- */

.footer-nav-services a { font-size: var(--t-xs); color: var(--grau-hell); }

/* ---------- Hilfsklassen ---------- */

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

/* Unterseiten haben keinen Vollbild-Hero, der Header darf ruhiger sitzen */
.page-sub .site-header { border-bottom-color: var(--linie); }

.main-nav a[aria-current] {
  color: var(--rot-dunkel);
  border-bottom-color: var(--rot);
}

/* Im mobilen Menue markiert der gefuellte Punkt die aktuelle Seite, die
   Haarlinie darunter bleibt die Trennlinie des Rasters. */
.mobile-menu a[aria-current] { color: var(--rot-dunkel); }

/* ---------- Responsive Unterseiten ---------- */

/* Nur das mittlere Fenster bekommt zwei Spalten. Ohne die untere Grenze
   ueberschreibt diese Regel die Einspalten-Regel weiter oben, weil sie
   spaeter in der Datei steht: bei 320 px lagen dann zwei Spalten plus Abstand
   bei 292 px in einem 280 px breiten Rahmen. */
@media (min-width: 861px) and (max-width: 1180px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 1180px) {
  .ref-detail, .job-detail { grid-template-columns: 1fr; }
  .ref-detail-meta, .job-aside { position: static; }
  .bio-grid { grid-template-columns: 1fr; }
  .job-grid { grid-template-columns: 1fr 1fr; }
  .ref-grid-wide { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 860px) {
  .ref-grid-wide { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 860px) {
  .spec-grid { grid-template-columns: 1fr; }
  .section-head-row { flex-direction: column; align-items: flex-start; }
  .about-grid-reverse .about-copy,
  .about-grid-reverse .about-media { order: initial; }
}

@media (max-width: 600px) {
  .job-grid { grid-template-columns: 1fr; }
  .ref-grid-wide { grid-template-columns: 1fr; }
  .contact-facts { grid-template-columns: 1fr; }
  .cta-band-inner { flex-direction: column; align-items: flex-start; }
}

/* Unterzeile der Leistungsseiten: fuehrt den Titel fort, ohne ihn zu ueberlagern */
.page-tagline {
  margin-top: 14px;
  font-size: clamp(20px, 2.1vw, 32px);
  font-weight: 300;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--anthrazit);
  max-width: 22em;
}

.fact-list-boxed {
  border: 1px solid var(--linie);
  padding: clamp(24px, 2.2vw, 34px);
  margin-bottom: 0;
}

.ref-grid-wide .ref-card {
  display: flex;
  flex-direction: column;
  background: var(--weiss);
  border: 1px solid var(--linie);
}

.ref-grid-wide .ref-card:hover { transform: none; border-color: var(--grau); }

/* Das Bild liegt absolut im Kasten. Stuende es im Fluss, wuerde es mit
   height 100 Prozent den Kasten aufspannen, den es fuellen soll, und
   aspect-ratio bliebe wirkungslos: gemessen 429 statt 204 px. */
.ref-grid-wide .ref-card-media {
  position: relative;
  background: var(--papier);
  border-bottom: 1px solid var(--linie);
  aspect-ratio: 16 / 10;
}

/* Bis 25.08. stand hier object-fit: contain mit 8 px Rand. Das zeigte jedes
   Motiv vollstaendig, liess aber bei jedem Hochformat zwei graue Balken von
   je 88 px stehen: die Kachel war zu einem Drittel leer. Die Uebersicht lebt
   vom Wiedererkennen, nicht vom vollstaendigen Motiv, deshalb jetzt fuellend.
   Die Motive sind dieselben wie in den Kacheln der Startseite. */
.ref-grid-wide .ref-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  object-fit: cover;
  transition: transform 0.5s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.ref-grid-wide .ref-card:hover img { transform: scale(1.04); }

@media (prefers-reduced-motion: reduce) {
  .ref-grid-wide .ref-card img { transition: none; }
  .ref-grid-wide .ref-card:hover img { transform: none; }
}

.ref-grid-wide .ref-card-body { flex: 1; display: flex; flex-direction: column; }

/* ---------- Formatkaesten ----------
   Gemessen im alten 3:2-Einheitskasten: Panoramen verloren 51 Prozent,
   Bodenprofile 50 Prozent des Motivs. Jedes Format bekommt jetzt einen
   Kasten nahe an seinem eigenen Seitenverhaeltnis, der groesste Verlust
   liegt damit bei 13 Prozent. */
img[data-format="panorama"] { aspect-ratio: 8 / 3; object-fit: cover; }

img[data-format="quer"] { aspect-ratio: 3 / 2; object-fit: cover; }

img[data-format="quadrat"] { aspect-ratio: 1 / 1; object-fit: cover; }

img[data-format="hoch"] { aspect-ratio: 3 / 4; object-fit: cover; }

/* Bausteine mit eigenem Zuschnitt behalten ihren.
   .person img stand hier mit und hob damit sein eigenes aspect-ratio 1/1
   (Zeile 919) wieder auf: gleiche Spezifitaet, spaeter notiert, also gewann
   diese Regel. Die Personenbilder tragen im Markup weder width noch height,
   dadurch war ihre Hoehe vor dem Laden gar nicht reserviert und das Layout
   sprang nach. .contact-person bleibt, dort stehen feste 88 x 88 px. */
.image-band img,
.hero-media img,
.contact-person img { aspect-ratio: auto; }

/* Die beiden Logos brauchen eine eigene Zeile. Als blosse Klassen (0,1,0)
   verloren sie gegen img[data-format="quer"] (0,1,1), und object-fit wurde
   nie zurueckgenommen: das Fusslogo lief mit 3/2 statt 1,353 und verlor
   oben wie unten die Wortmarke. Mit img davor gewinnt die Regel, contain
   haelt die Marke vollstaendig im Kasten. */
img.brand-logo,
img.footer-logo {
  aspect-ratio: auto;
  object-fit: contain;
}

.ref-grid-wide .ref-card-body { padding: 18px 18px 20px; }

.ref-grid-wide .ref-card h3 { font-size: clamp(17px, 1.2vw, 20px); margin-bottom: 8px; }

/* Drei Zeilen reichen fuer den Ueberblick, der Rest steht auf der
   Projektseite. Ohne die Begrenzung wurden die Karten 716 px hoch. */
.ref-grid-wide .ref-card p {
  font-size: var(--t-xs);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ref-grid-wide .ref-card-place {
  display: flex;
  -webkit-line-clamp: none;
  overflow: visible;
}

.ref-grid-wide .ref-card-place { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--linie); font-size: var(--t-2xs); }

.ref-grid-wide .ref-meta { font-size: var(--t-3xs); margin-bottom: 8px; }

/* Der Bewerbungsknopf steht in einem Kasten, dessen Links rot sind.
   Ohne diese Zeile stuende roter Text auf rotem Grund. */
.job-contact .btn-primary,
.job-contact .btn-primary:hover { color: var(--weiss); }

/* ---------- Tippziele ----------
   WCAG 2.2, 2.5.8 verlangt mindestens 24 mal 24 CSS-Pixel. Brotkrumen,
   Fusszeilen-Links und die Rechtszeile lagen darunter (15 bis 23 px). */

.breadcrumb a,
.breadcrumb [aria-current] {
  display: inline-block;
  padding-block: 4px;
  min-height: 24px;
}

.footer-nav a,
.footer-contact a,
.footer-social a,
.footer-legal a {
  display: inline-block;
  padding-block: 3px;
  min-height: 24px;
}

/* Der Videoknopf sass bei 36 px, Finger brauchen mehr */
.video-toggle { min-width: 44px; min-height: 44px; }

/* Eingabefelder brauchen eine erkennbare Umrandung (WCAG 1.4.11, 3:1).
   Die Haarlinie --linie auf --papier lag bei 1,15:1. */
.field input,
.field textarea { border-color: var(--grau-hell); }

.field input:hover,
.field textarea:hover { border-color: var(--grau); }

/* Platzhalter hatten keine eigene Regel. Jede Engine setzt dann ihren eigenen
   Wert: Chromium landete gemessen bei 4,18:1, andere mischen die Textfarbe mit
   eigener Deckkraft und kommen tiefer heraus. Mit fester Farbe steht der Wert
   ueberall gleich bei 5,54:1. Das opacity: 1 ist noetig, weil Firefox sonst
   seine eigene Deckkraft zusaetzlich abzieht. */
.field input::placeholder,
.field textarea::placeholder {
  color: var(--grau);
  opacity: 1;
}

/* Vorschau-Zustand der Projektanfrage. Ohne KONTAKT_ENDPUNKT (tools/build.mjs)
   setzt der Bau diese Klasse. Felder anzubieten, die nichts weitertragen,
   kostet den Absender seine Zeit und uns die Anfrage. Stehen bleiben der
   Hinweis, der Mailweg und die Rufnummer darunter.
   Die frueheren .form-status-Regeln stehen hier nicht mehr: das Element wurde
   allein vom Vorfuehrmodus in main.js erzeugt, der Empfang meldete, ohne etwas
   zu senden. Mit dem Modus ist auch sein Stil weg. */
/* ============================================================
   STANDORTKARTE
   Die Karte selbst zeichnet MapLibre, hier steht nur der Rahmen, der
   Ladeknopf und die Ersatzdarstellung fuer Browser ohne WebGL.
   ============================================================ */

.standort-raster {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(280px, 0.6fr);
  gap: clamp(28px, 3vw, 56px);
  align-items: start;
}

.karte-rahmen {
  position: relative;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--papier);
}

/* Hoehe und Breite fest, nicht ueber inset. MapLibre haengt seine Klasse
   maplibregl-map an genau dieses Element, und sein Blatt laedt zur Laufzeit,
   also nach diesem: seine Regel position:relative gewann, inset:0 wirkte
   nicht mehr, und die Flaeche fiel auf Hoehe 0 zusammen. Gemessen: Rahmen
   887x554, Flaeche 885x0, Karte leer. Mit 100 Prozent Hoehe ist es egal, wer
   die Positionierung gewinnt. */
.karte-rahmen .karte-flaeche {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* Der Ladeknopf sitzt in der Mitte und verschwindet, sobald geladen wird. */
.karte-start {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
}

.karte-ersatz {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: clamp(24px, 3vw, 48px);
  text-align: center;
  font-size: var(--t-sm);
  font-weight: 300;
  line-height: 1.6;
  color: var(--grau);
}

/* Nur wenn WebGL fehlt oder das Laden schiefgeht, tritt der Ersatz an die
   Stelle der Karte. Sonst waere er ein Kasten, den niemand sieht. */
.karte-rahmen[data-karte-zustand="kein-webgl"] .karte-ersatz,
.karte-rahmen[data-karte-zustand="fehler"] .karte-ersatz { display: flex; }

.karte-rahmen[data-karte-zustand="kein-webgl"] .karte-start,
.karte-rahmen[data-karte-zustand="fehler"] .karte-start,
.karte-rahmen[data-karte-zustand="laedt"] .karte-start,
.karte-rahmen[data-karte-zustand="bereit"] .karte-start { display: none; }

/* Die Nadel auf dem eigenen Haus. Ein Kreis mit Ring, dieselbe Geometrie wie
   der Aufschlusspunkt im Rest der Seite. */
.karte-nadel {
  width: 18px;
  height: 18px;
  border: 3px solid var(--weiss);
  border-radius: 50%;
  background: var(--rot);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}

.standort-adresse { font-size: var(--t-sm); line-height: 1.7; margin: 0 0 24px; }

.standort-liste { margin: 0 0 20px; }

.standort-liste dt {
  font-size: var(--t-3xs);
  font-weight: 600;
  letter-spacing: var(--versal);
  text-transform: uppercase;
  color: var(--grau);
  margin-bottom: 5px;
}

.standort-liste dd {
  margin: 0 0 18px;
  font-size: var(--t-sm);
  font-weight: 300;
  line-height: 1.6;
}

.standort-hinweis {
  margin: 0;
  padding-top: 16px;
  border-top: 1px solid var(--linie);
  font-size: var(--t-2xs);
  color: var(--grau);
}

/* Die Bedienknoepfe von MapLibre bringen eigene Farben mit. */
.karte-rahmen .maplibregl-ctrl-group { border-radius: var(--radius-klein, 4px); }

@media (max-width: 900px) {
  .standort-raster { grid-template-columns: 1fr; }
  .karte-rahmen { aspect-ratio: 4 / 3; }
}

/* Der Kontaktblock der Startseite. Er traegt kein eigenes Formular mehr,
   sondern den Weg zu dem einen, das es gibt. */
.contact-wege {
  align-self: start;
  background: var(--weiss);
  color: var(--text);
  padding: clamp(30px, 3vw, 46px);
  border-radius: var(--radius);
  display: grid;
  gap: 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.25);
}

.contact-wege-titel {
  margin: 0;
  font-size: var(--t-3xs);
  font-weight: 600;
  letter-spacing: var(--versal);
  text-transform: uppercase;
  color: var(--grau);
}

.contact-wege p { margin: 0; font-size: var(--t-sm); font-weight: 300; line-height: 1.6; }

.contact-wege-alt { color: var(--grau); }

.contact-wege-alt a { color: var(--rot-dunkel); }

/* ============================================================
   ANFRAGEFORMULAR
   Aus dienst/felder.mjs erzeugt: eine Auswahlgruppe als Einstieg, drei Bloecke
   Pflichtangaben, ein aufklappbarer Block mit freiwilligen Angaben. Die
   Klassen heissen .feld statt .field wie die aelteren Formulare: sie kommen
   aus dem Erzeuger und nicht aus der Hand, das soll man am Namen sehen.
   ============================================================ */

.feld { display: grid; gap: 8px; }

.feld-block { display: grid; gap: 22px; }

.feld-block-titel {
  margin: 0;
  font-size: var(--t-3xs);
  font-weight: 600;
  letter-spacing: var(--versal);
  text-transform: uppercase;
  color: var(--grau);
}

.feld label,
.feld-gruppe legend {
  font-size: var(--t-2xs);
  font-weight: 600;
  color: var(--text);
}

.feld .optional { font-weight: 400; color: var(--grau); }

.feld-hilfe {
  margin: 0;
  font-size: var(--t-2xs);
  font-weight: 300;
  line-height: 1.5;
  color: var(--grau);
}

.feld input[type="text"],
.feld input[type="email"],
.feld input[type="tel"],
.feld input[type="file"],
.feld select,
.feld textarea {
  width: 100%;
  padding: 13px 14px;
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein, 4px);
  background: var(--papier);
  font: inherit;
  font-size: var(--t-sm);
  color: var(--text);
}

.feld textarea { resize: vertical; min-height: 140px; }

.feld input:focus-visible,
.feld select:focus-visible,
.feld textarea:focus-visible {
  outline: 2px solid var(--rot-dunkel);
  outline-offset: 1px;
}

/* Die Auswahlgruppe. Ein fieldset bringt eigene Raender und Innenabstaende
   mit, die hier nur stoeren. */
.feld-gruppe {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  border: 0;
}

.feld-gruppe legend { padding: 0; }

.wahl-liste { display: grid; gap: 2px; margin-top: 4px; }

/* Das ganze Feld ist die Klickflaeche, nicht nur der Kasten: ein 14-px-Kasten
   ist auf dem Handy kein Tippziel. */
.wahl {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 9px 10px;
  border-radius: var(--radius-klein, 4px);
  font-size: var(--t-sm);
  font-weight: 300;
  line-height: 1.45;
  cursor: pointer;
}

.wahl:hover { background: var(--papier); }

.wahl input {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  accent-color: var(--rot);
}

.wahl:has(input:checked) { background: var(--papier); font-weight: 400; }

.wahl:has(input:focus-visible) {
  outline: 2px solid var(--rot-dunkel);
  outline-offset: 1px;
}

/* Der freiwillige Block. Zugeklappt ist er eine Zeile, aufgeklappt sechs
   Fragen, die eine Rueckfrage sparen. */
.feld-block-frei {
  border-top: 1px solid var(--linie);
  padding-top: 20px;
  display: grid;
  gap: 22px;
}

.feld-block-frei summary {
  cursor: pointer;
  font-size: var(--t-2xs);
  font-weight: 600;
  color: var(--rot-dunkel);
  list-style: none;
}

.feld-block-frei summary::-webkit-details-marker { display: none; }

.feld-block-frei summary::before {
  content: "+";
  display: inline-block;
  width: 1.1em;
  font-weight: 700;
}

.feld-block-frei[open] summary::before { content: "\2212"; }

.feld-block-frei summary:focus-visible {
  outline: 2px solid var(--rot-dunkel);
  outline-offset: 2px;
}

.feld-gruppe[data-fehlt] { outline: 2px solid var(--rot-dunkel); outline-offset: 8px; }

.feld-fehler {
  margin: 4px 0 0;
  font-size: var(--t-2xs);
  font-weight: 600;
  color: var(--rot-dunkel);
}

/* Der Honigtopf. Nicht display:none: Skripte pruefen das und lassen das Feld
   dann leer. Aus dem Blick genommen, aus dem Tabulatorlauf genommen, fuer
   Vorleseprogramme ueber aria-hidden am Behaelter weg. */
.honigtopf {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

@media (max-width: 620px) {
  .wahl { padding: 11px 10px; }
}

.contact-form-vorschau .field-row,
.contact-form-vorschau .field,
.contact-form-vorschau .feld-block,
.contact-form-vorschau .feld-block-frei,
.contact-form-vorschau .form-note { display: none; }

.contact-form-vorschau .form-hinweis { margin-bottom: 22px; }

/* Dasselbe fuer die Bewerbung, solange BEWERBUNG_ENDPUNKT leer ist. Der
   Mailweg nimmt weder Eingaben noch Dateien mit; die Ablagezone erlaubte
   bis zu zwoelf Dateien und 25 MB, die anschliessend niemand bekommen haette. */
.bewerbung-form-vorschau .form-block:not(.form-block-schluss) { display: none; }

.bewerbung-form-vorschau .form-hinweis { margin-bottom: 22px; }

/* ---------- Nachgemessene Kontrastkorrekturen ----------
   Alle drei Werte sind mit der WCAG-Formel gerechnet, inklusive
   Alpha-Compositing bei den halbtransparenten Flaechen. */

/* Rot auf Papier lag bei 4,43:1, das dunklere Rot bringt 6,22:1 */
.job-card-open .job-card-type,
.section-grey .job-card-type { color: var(--rot-dunkel); }

.image-band figcaption .label::before {
  content: "";
  /* Kleiner als im Fliesstext, die Zeile ist nur 11 px hoch. */
  --marker-mass: 0.7em;
}

/* ---------- Lange deutsche Woerter auf schmalen Geraeten ----------
   "Datenschutzerklaerung" ist als h1 bei 320 px 368 px breit und schiebt die
   ganze Seite zur Seite. break-word greift nur, wenn ein Wort wirklich nicht
   passt; die Silbentrennung sorgt dafuer, dass dabei ein Trennstrich steht
   und nicht mitten im Wort umbrochen wird. */
h1, h2, h3, h4, .page-tagline, .stat dd, .job-card h2 {
  overflow-wrap: break-word;
}

@media (max-width: 700px) {
  h1, h2, h3, h4, .page-tagline {
    hyphens: auto;
    -webkit-hyphens: auto;
  }

  .prose p, .prose li, .page-lead, .section-intro, .spec p {
    hyphens: auto;
    -webkit-hyphens: auto;
  }
}

/* ---------- Osterei: Bohrkern ----------
   Faehrt von rechts herein wie ein gezogener Kern. Die Schichten setzen
   sich von oben nach unten ab, jede ein Stueck spaeter. */

.bohrkern {
  position: fixed;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 300;
  width: min(320px, 88vw);
  background: var(--anthrazit);
  color: var(--text-invert);
  padding: 24px 22px 28px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  transform: translateX(100%);
  transition: transform 420ms cubic-bezier(0.16, 0.84, 0.44, 1);
  box-shadow: -24px 0 60px rgba(0, 0, 0, 0.35);
  overflow-y: auto;
}

.bohrkern.offen { transform: none; }

.bohrkern-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.bohrkern-kopf .label { color: var(--rot-hell); }

.bohrkern-zu {
  background: none;
  border: 1px solid var(--linie-dunkel);
  color: var(--text-invert);
  font-size: 22px;
  line-height: 1;
  width: 44px;
  height: 44px;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.bohrkern-zu:hover { border-color: var(--rot-hell); color: var(--rot-hell); }

.bohrkern-saeule {
  flex: 1;
  display: grid;
  grid-template-rows: repeat(6, 1fr);
  border: 1px solid var(--linie-dunkel);
  min-height: 320px;
}

.bohrkern-schicht {
  background: var(--ton);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 14px;
  font-size: var(--t-2xs);
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
  transform: scaleY(0);
  transform-origin: top;
  animation: schicht-absetzen 380ms cubic-bezier(0.16, 0.84, 0.44, 1) forwards;
  animation-delay: var(--verzug);
}

@keyframes schicht-absetzen {
  to { transform: scaleY(1); }
}

.bohrkern-tiefe {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  min-width: 52px;
}

.bohrkern-fuss {
  font-size: var(--t-2xs);
  line-height: 1.5;
  color: var(--grau-hell);
}

.bohrkern-fuss a { color: var(--rot-hell); }

/* Der Zaehler quittiert die Endteufe */
.depth-counter.endteufe .depth-counter-label { color: var(--rot-hell); }

.depth-counter.endteufe .depth-counter-value { color: #fff; }

/* ============================================================
   MEGAMENUE
   Acht Leistungen sind das Angebot. Sie hinter einem einzigen
   Navigationspunkt zu verstecken, kostet jeden Besucher einen
   Zwischenschritt. Das Feld faehrt unter dem Kopf hervor, in derselben
   Bewegungssprache wie das mobile Menue: eine Kante laeuft nach unten,
   die Karten setzen sich gestaffelt ab.
   ============================================================ */

.nav-mega-halter {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.mega-schalter {
  background: none;
  border: none;
  padding: 8px 4px;
  cursor: pointer;
  color: var(--grau);
  display: flex;
  align-items: center;
  min-height: 32px;
}

.mega-schalter svg {
  width: 11px;
  transition: transform 300ms cubic-bezier(0.16, 0.84, 0.44, 1);
}

.mega-schalter:hover { color: var(--rot); }

.mega-schalter[aria-expanded="true"] { color: var(--rot); }

.mega-schalter[aria-expanded="true"] svg { transform: rotate(180deg); }

.mega {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  background: var(--weiss);
  border-bottom: 1px solid var(--linie);
  box-shadow: 0 24px 48px rgba(22, 24, 27, 0.1);
  z-index: 98;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 380ms cubic-bezier(0.16, 0.84, 0.44, 1);
}

.mega[hidden] { display: none; }

.mega.offen { clip-path: inset(0 0 0 0); }

.mega-inner {
  display: grid;
  grid-template-columns: 1fr minmax(240px, 300px);
  gap: clamp(32px, 4vw, 72px);
  padding-block: clamp(28px, 3vh, 44px) clamp(32px, 4vh, 52px);
}

.mega-kopf { color: var(--rot); margin-bottom: 20px; }

.mega-raster {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--linie);
  border: 1px solid var(--linie);
}

.mega-karte {
  background: var(--weiss);
  padding: 20px 20px 22px;
  text-decoration: none;
  display: grid;
  gap: 8px;
  align-content: start;
  opacity: 0;
  transform: translateY(-8px);
  transition: background 0.15s ease, opacity 260ms ease,
              transform 360ms cubic-bezier(0.16, 0.84, 0.44, 1);
}

.mega.offen .mega-karte { opacity: 1; transform: none; }

/* Die Staffelung stand als style-Attribut am Element. Die eigene
   Content-Security-Policy (style-src 'self') hat sie geblockt: acht
   Verstoesse in der Konsole auf jeder Seite, und die Verzoegerung war tot.
   Als Regel im Stylesheet gibt es beides nicht. */
.mega.offen .mega-karte:nth-child(1) { transition-delay: 40ms; }
.mega.offen .mega-karte:nth-child(2) { transition-delay: 62ms; }
.mega.offen .mega-karte:nth-child(3) { transition-delay: 84ms; }
.mega.offen .mega-karte:nth-child(4) { transition-delay: 106ms; }
.mega.offen .mega-karte:nth-child(5) { transition-delay: 128ms; }
.mega.offen .mega-karte:nth-child(6) { transition-delay: 150ms; }
.mega.offen .mega-karte:nth-child(7) { transition-delay: 172ms; }
.mega.offen .mega-karte:nth-child(8) { transition-delay: 194ms; }

.mega-karte:hover { background: var(--papier); }

.mega-karte-aktiv { background: var(--papier); }

.mega-icon {
  width: 30px;
  height: 30px;
  color: var(--anthrazit);
  margin-bottom: 4px;
}

.mega-icon svg { width: 100%; height: 100%; }

.mega-icon .dot {
  fill: var(--rot);
  stroke: none;
  transform-origin: center;
  transition: transform 0.25s ease;
}

.mega-karte:hover .mega-icon .dot { transform: scale(1.35); }

.mega-titel {
  font-weight: 600;
  font-size: var(--t-sm);
  line-height: 1.25;
}

.mega-karte:hover .mega-titel { color: var(--rot); }

.mega-karte-aktiv .mega-titel { color: var(--rot); }

.mega-text {
  font-size: var(--t-xs);
  font-weight: 300;
  line-height: 1.45;
  color: var(--grau);
}

.mega-spalte-seite {
  border-left: 1px solid var(--linie);
  padding-left: clamp(24px, 2.5vw, 44px);
}

.mega-seite-text {
  font-size: var(--t-xs);
  font-weight: 300;
  line-height: 1.6;
  color: var(--grau);
  margin-bottom: 22px;
}

.mega-seite-kontakt {
  margin-top: 28px;
  padding-top: 22px;
  border-top: 1px solid var(--linie);
  display: grid;
  gap: 6px;
}

.mega-seite-kontakt .label { color: var(--grau); margin-bottom: 4px; }

.mega-seite-kontakt a {
  font-size: var(--t-sm);
  text-decoration: none;
  color: var(--anthrazit);
}

.mega-seite-kontakt a:hover { color: var(--rot); }

.mega-tel {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Der Kopf ist klebend; das Feld haengt darunter und braucht denselben
   Stapelbezug, sonst verschwindet es hinter dem Inhalt. */
.site-header { position: sticky; }

@media (max-width: 1320px) {
  .mega-raster { grid-template-columns: repeat(3, 1fr); }
  /* Acht Kacheln in drei Spalten lassen die neunte Zelle leer, dort stand
     sonst der graue Rasterhintergrund. Gefuellt wird sie hier und nicht wie
     bei den Stellen- und Fachkarten ueber einen Schatten an der Kachel: die
     Kacheln blenden beim Oeffnen gestaffelt ein, ein Schatten an ihnen wuerde
     die Trennlinien mitblenden lassen. */
  .mega-raster::after { content: ""; background: var(--weiss); }
}

/* ---------- Mobiles Aufklappen der Leistungen ---------- */

.mobil-gruppe { display: block; }

.mobil-gruppe-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--linie);
}

.mobil-gruppe-kopf > a { border-bottom: 0 !important; flex: 1; }

.mobil-aufklapp {
  background: none;
  border: none;
  padding: 12px;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
  color: var(--grau);
  display: flex;
  align-items: center;
  justify-content: center;
}

.mobil-aufklapp svg {
  width: 14px;
  transition: transform 300ms cubic-bezier(0.16, 0.84, 0.44, 1);
}

.mobil-aufklapp[aria-expanded="true"] { color: var(--rot-dunkel); }

.mobil-aufklapp[aria-expanded="true"] svg { transform: rotate(180deg); }

/* Die Hoehe wird in main.js gemessen und gesetzt. Der Umweg ueber
   grid-template-rows 0fr auf 1fr ist eleganter, loeste sich hier aber
   nicht auf: die Zeile blieb bei 0 px. Gemessene Hoehen sind langweilig
   und funktionieren. */
.mobil-unterliste { display: block; }

.mobil-unterliste[hidden] { display: none; }

/* Die Unterliste bekommt bewusst keine eigene Einblendung: in diesem
   Teilbaum starten Animationen nicht zuverlaessig, und eine Bewegung, die
   mal laeuft und mal nicht, ist schlechter als gar keine. Der Pfeil dreht
   sich, die Liste ist da. */

/* Der Aufklapp-Trick ueber grid-template-rows braucht genau EIN Kind.
   Mit neun Links entstehen acht implizite Zeilen auf auto, und die Liste
   steht dauerhaft offen. */
.mobil-unterliste-inhalt { display: block; }


.mobil-unterliste a {
  display: block;
  font-size: var(--t-md);
  font-weight: 500;
  text-decoration: none;
  padding: 13px 0 13px 24px;
  border-bottom: 1px solid var(--linie);
  color: var(--grau);
}

.mobil-unterliste a[aria-current] { color: var(--rot-dunkel); font-weight: 600; }

.mobil-unterliste .mobil-alle { color: var(--rot); font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
  .mega, .mega .mega-karte, .mega-schalter svg,
  .mobil-unterliste, .mobil-aufklapp svg {
    transition: none !important;
  }
  .mega.offen .mega-karte { opacity: 1; transform: none; }
}

/* Unterhalb der Umbruchbreite gibt es keinen Auslöser für das Megamenü,
   das mobile Menü klappt die Leistungen selbst auf. Falls jemand das
   Fenster verkleinert, während das Feld offen steht, verschwindet es. */
@media (max-width: 1180px) {
  .mega { display: none !important; }
}

@media (min-width: 1181px) {
  .mobil-gruppe-kopf .mobil-aufklapp { display: none; }
}

/* ---------- Zeilenlaenge auf mittleren Breiten ----------
   Zwischen Handy und Desktop wird die Spalte breit, ohne dass ein Raster
   sie begrenzt: gemessene 120 Zeichen im Stellentext bei 1024 px, 96 im
   Vorspann bei 768 px. Lesbar sind 45 bis 80. */

.page-lead,
.section-intro { max-width: 40em; }

.job-body,
.ref-detail-body { max-width: 42em; }

@media (min-width: 1181px) {
  /* Hier stand erst max-width: none: bei 1920 px kam der Referenztext damit
     auf 1119 px und 136 Zeichen je Zeile. Der Deckel auf 36em brachte die
     Zeile auf 74 Zeichen, riss dafuer aber ein Loch zwischen Text und
     Faktenkasten, gemessen rund 400 px bei 1600 px Fenster: dasselbe Problem
     wie auf den Leistungsseiten.

     Jetzt fuellt der Satz seine Spalte, und die Schrift waechst mit, wie in
     .prosa-mit-schiene. Kein Deckel mehr, kein Loch, und die Zeile bleibt
     unter 80 Zeichen, weil groessere Buchstaben weniger davon in dieselbe
     Breite lassen. */
  .job-body,
  .ref-detail-body { max-width: none; }

  .job-body p, .job-body li,
  .ref-detail-body p, .ref-detail-body li {
    font-size: clamp(17px, 0.85vw + 6px, 22px);
    line-height: 1.8;
  }
}

/* Die Projektzeile ueber der Referenzueberschrift stand auf 11 px mit
   1,76 px Laufweite. Versalien in dieser Groesse liest niemand gern. */

/* Der Bohrtiefen-Zaehler schwebte auf Tablets ueber dem Inhalt. Er gehoert
   auf Schirme, die breit genug fuer eine freie Randspalte sind. */
@media (max-width: 1180px) {
  .depth-counter { display: none; }
}

/* Das offene Menue reicht auf kleinen Geraeten ueber die Bildkante hinaus
   und scrollt. Etwas Luft am Fuss macht sichtbar, dass es zu Ende ist. */
.mobile-menu { padding-bottom: 96px; }

/* ---------- Nachlese der Mobilpruefung ---------- */

/* Der Telefonlink im Referenzband war 24,8 px hoch, reine Zeilenhoehe */
.ref-cta-phone,
.cta-band-phone,
.mega-tel {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.header-actions .btn-sm { min-height: 44px; display: inline-flex; align-items: center; }

/* Telefon und E-Mail im Fuss klebten aneinander */
.footer-contact a {
  display: inline-block;
  padding-block: 4px;
  min-height: 24px;
}

.footer-contact p + p { margin-top: 14px; }

@media (max-width: 860px) {
  /* Der rote Versatzrahmen im Hero endete bei 320 px genau auf der Kante */
}

@media (max-width: 600px) {
  /* 28 px Polster je Seite liessen in einer 280-px-Spalte 22 Zeichen uebrig */
  .ref-cta { padding-inline: 20px; }
  .ref-cta p { font-size: 18px; }
}

/* Kurze Bildschirme: sieben Menuezeilen a 68 px passen bei 568 px Hoehe
   nicht in die 488 px, die unter dem Kopf bleiben. */
@media (max-height: 640px) {
  .mobile-menu { padding-top: 24px; padding-bottom: 64px; }
  .mobile-menu nav > a:not(.btn),
  .mobile-menu .mobil-gruppe-kopf > a {
    padding-block: 10px;
    font-size: 20px;
  }
  .mobile-menu .btn { padding-block: 12px; }
}

/* Die Fachkarten stehen im Raster gleich hoch, ihr Text ist verschieden
   lang. Ohne diesen Griff endet der letzte Absatz auf verschiedenen Linien. */
.spec { display: flex; flex-direction: column; }

.spec > :last-child { margin-bottom: 0; }

/* ============================================================
   VOLLFLAECHIG KLICKBARE KACHELN
   Eine Kachel, die aussieht wie ein Knopf, muss sich auch wie einer
   verhalten. Bisher traf nur die Ueberschrift oder der kleine Fusslink.
   Umgesetzt ueber einen unsichtbaren Deckel am Kachel-Link: es bleibt
   genau EIN Link im Zugaenglichkeitsbaum, mit dem Ueberschriftentext als
   Beschriftung. Zwei Links auf dasselbe Ziel waeren fuer Screenreader
   und Tastatur eine Dopplung ohne Nutzen.
   ============================================================ */

.ref-card,
.ref-featured,
.service,
.job-card,
.gallery-item { position: relative; }

.ref-card h3 a::after,
.ref-featured h3 a::after,
.service h3 a::after,
.job-card h2 a::after,
.job-card-open .job-card-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.ref-card:hover,
.ref-featured:hover,
.service:hover,
.job-card:hover { cursor: pointer; }

/* Die Fussbeschriftung ist kein Link mehr, sondern ein span: sie zeigte auf
   dasselbe Ziel wie die Ueberschrift und waere ein doppelter Eintrag im
   Zugaenglichkeitsbaum plus ein Tabulatorhalt ohne neues Ziel. Aussehen
   bleibt, Klick kommt vom Deckel. */
.service-more,
.job-card-link { display: inline-block; }

/* Rueckmeldung auf der ganzen Flaeche, nicht nur auf dem Wort */
.ref-card:hover .ref-card-media { background: #ECECE9; }

.ref-card:hover h3 a,
.service:hover h3 a,
.job-card:hover h2 a { color: var(--rot); }

/* Auf dunklem Grund waere Rot zu dunkel */
.section-dark .ref-card:hover h3 a,
.ref-featured:hover h3 a { color: var(--rot-hell); }

.service:hover .service-more,
.job-card:hover .job-card-link { text-decoration: underline; }

/* Der Fokusrahmen gehoert um die ganze Kachel, nicht um zwei Woerter */
.ref-card:has(a:focus-visible),
.ref-featured:has(a:focus-visible),
.service:has(a:focus-visible),
.job-card:has(a:focus-visible) {
  outline: 3px solid var(--rot);
  outline-offset: 2px;
}

.ref-card h3 a:focus-visible,
.ref-featured h3 a:focus-visible,
.service h3 a:focus-visible,
.job-card h2 a:focus-visible,
.job-card-open .job-card-link:focus-visible { outline: none; }

/* ============================================================
   BEWERBUNGSPORTAL  /karriere/bewerben/
   ============================================================ */

.bewerbung-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
}

.bewerbung-form { display: grid; gap: clamp(26px, 3vw, 40px); }

.form-block {
  border: 0;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 20px;
}

.form-block legend {
  font-family: var(--font-serif);
  font-size: clamp(21px, 2.1vw, 27px);
  line-height: 1.25;
  padding: 0;
  margin-bottom: 4px;
  display: flex;
  align-items: baseline;
  gap: 12px;
}

/* Die Schrittzahl ist Schmuck, der Text der Legende traegt die Bedeutung.
   Deshalb keine eigene Auszeichnung fuer Screenreader. */
.schritt {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--rot);
  color: var(--weiss);
  font-family: var(--font-sans);
  font-size: var(--t-xs);
  font-weight: 700;
  display: inline-grid;
  place-items: center;
  align-self: center;
}

.form-block .field select {
  font-family: var(--font-sans);
  font-size: var(--t-sm);
  padding: 14px 15px;
  border: 1.5px solid var(--grau-hell);
  border-radius: var(--radius);
  background: var(--papier);
  color: var(--text);
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%2316181B' stroke-width='1.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 15px center;
  background-size: 12px;
  padding-right: 40px;
}

.form-block .field select:focus { border-color: var(--rot); background-color: var(--weiss); }

/* ---------- Ablagefeld ---------- */

.dropzone {
  position: relative;
  border: 2px dashed var(--grau-hell);
  border-radius: var(--radius);
  background: var(--weiss);
  padding: clamp(28px, 4vw, 46px) 24px;
  text-align: center;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

/* Das echte Feld liegt unsichtbar ueber der Flaeche, bleibt aber im
   Tabulator und meldet sich der Vorlesesoftware selbst. Ein nachgebautes
   div mit Klick-Handler koennte das nicht. */
.dropzone-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.dropzone-inner { pointer-events: none; display: grid; gap: 6px; justify-items: center; }

.dropzone-icon { color: var(--grau-hell); transition: color 0.15s ease, transform 0.2s ease; }

.dropzone-titel {
  font-family: var(--font-serif);
  font-size: clamp(18px, 1.8vw, 21px);
  color: var(--text);
}

.dropzone-oder { font-size: var(--t-sm); color: var(--grau); }

.dropzone-knopf {
  color: var(--rot);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Beschriftung nur fuer die Vorlesesoftware: sichtbar steht sie im Feld. */
.dropzone-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.dropzone:hover,
.dropzone-input:focus-visible ~ .dropzone-inner { border-color: var(--grau); }

.dropzone:hover .dropzone-icon { color: var(--grau); }

.dropzone:has(.dropzone-input:focus-visible) {
  border-color: var(--rot);
  outline: 3px solid var(--rot);
  outline-offset: 3px;
}

.dropzone.ueber {
  border-color: var(--rot);
  border-style: solid;
  background: color-mix(in srgb, var(--rot) 4%, var(--weiss));
}

.dropzone.ueber .dropzone-icon { color: var(--rot); transform: translateY(-4px); }

.dropzone-regeln {
  font-size: var(--t-xs);
  line-height: 1.55;
  color: var(--grau);
  margin-top: -8px;
}

.dropzone-fehler {
  font-size: var(--t-xs);
  line-height: 1.5;
  color: var(--rot-dunkel);
  font-weight: 600;
}

.dropzone-fehler:empty { display: none; }

/* ---------- Liste der gewaehlten Dateien ---------- */

.dateiliste { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }

.dateiliste:empty { display: none; }

.datei {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: var(--weiss);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
}

.datei-typ {
  font-size: var(--t-3xs);
  font-weight: 700;
  letter-spacing: var(--versal);
  text-align: center;
  padding: 5px 0;
  border-radius: var(--radius);
  background: var(--papier);
  color: var(--grau);
}

.datei-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--t-sm);
}

.datei-groesse { font-size: var(--t-xs); color: var(--grau); font-variant-numeric: tabular-nums; }

.datei-weg {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--grau);
  border-radius: 50%;
  cursor: pointer;
  font-size: 19px;
  line-height: 1;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.datei-weg:hover { background: var(--rot); color: var(--weiss); }

.dateiliste-summe { font-size: var(--t-xs); color: var(--grau); }

.dateiliste-summe:empty { display: none; }

/* ---------- Zustimmung, Fortschritt, Abschluss ---------- */

.form-block-schluss { gap: 18px; }

.checkbox {
  display: grid;
  grid-template-columns: 24px 1fr;
  gap: 12px;
  align-items: start;
  font-size: var(--t-xs);
  line-height: 1.55;
  color: var(--grau);
  cursor: pointer;
}

.checkbox input {
  /* 24 px ist das Mindestmass fuer ein Ankreuzfeld auf Fingergeraeten. */
  width: 24px;
  height: 24px;
  margin: 0;
  accent-color: var(--rot);
}

.fortschritt { display: grid; gap: 8px; }

.fortschritt-bahn {
  height: 6px;
  background: var(--linie);
  border-radius: 99px;
  overflow: hidden;
}

.fortschritt-balken {
  height: 100%;
  width: 0;
  background: var(--rot);
  transition: width 0.2s ease;
}

.fortschritt-text { font-size: var(--t-xs); color: var(--grau); }

.bewerbung-aside { display: grid; gap: 22px; position: sticky; top: 104px; }

/* 13 px versal mit dem Durchschuss der grossen H2 waeren 14,6 px: zu eng
   fuer zwei Zeilen. Je kleiner der Grad, desto mehr Luft. */
.ablauf h2,
.bewerbung-aside .job-contact h2 {
  line-height: 1.3;
  font-family: var(--font-sans);
  font-size: var(--t-2xs);
  font-weight: 700;
  letter-spacing: var(--versal-eng);
  text-transform: uppercase;
  margin-bottom: 12px;
}

.ablauf {
  background: var(--weiss);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  padding: 22px;
}

.ablauf-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; }

.ablauf-liste li { display: grid; grid-template-columns: 26px 1fr; gap: 12px; align-items: start; }

.ablauf-nr {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--rot);
  color: var(--rot);
  font-size: var(--t-2xs);
  font-weight: 700;
  display: grid;
  place-items: center;
}

.ablauf-liste strong { display: block; font-size: var(--t-sm); margin-bottom: 2px; }

.ablauf-liste div { font-size: var(--t-xs); line-height: 1.5; color: var(--grau); }

.job-contact-alt { font-size: var(--t-xs); color: var(--grau); margin-top: 10px; text-align: center; }

.job-contact-alt a { color: var(--rot); text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 900px) {
  .bewerbung-layout { grid-template-columns: 1fr; }
  .bewerbung-aside { position: static; order: 2; }
}

@media (max-width: 560px) {
  .datei { grid-template-columns: 30px minmax(0, 1fr) auto; row-gap: 4px; }
  .datei-groesse { grid-column: 2; }
  .datei-weg { grid-row: 1 / 3; grid-column: 3; }
}

@media (prefers-reduced-motion: reduce) {
  .dropzone-icon,
  .fortschritt-balken { transition: none; }
}

.form-hinweis {
  font-size: var(--t-xs);
  line-height: 1.55;
  color: var(--text);
  background: color-mix(in srgb, var(--rot) 6%, var(--weiss));
  border: 1px solid color-mix(in srgb, var(--rot) 30%, var(--weiss));
  border-radius: var(--radius);
  padding: 14px 16px;
}

.form-hinweis a { color: var(--rot); text-decoration: underline; text-underline-offset: 3px; }

/* Tippziele nach WCAG 2.2 (2.5.8, 24 px). Fuer Links mitten im Satz gilt
   die Ausnahme, fuer untereinander gestapelte Kontaktzeilen nicht: dort
   liegen Mailadresse und Rufnummer sonst 18 px hoch direkt aneinander. */
.bewerbung-aside .job-contact p a {
  display: inline-block;
  padding: 3px 0;
  min-height: 24px;
}



/* ---------- Referenzkacheln auf der Startseite ----------
   Vorher standen hier drei breite Karten mit Bild oben und Text darunter.
   Weil das erste Bild hochkant ist, zog die Formatregel img[data-format="hoch"]
   den Kasten auf 3:4 (gemessen 585 statt 349 px) und riss die Reihe auf: neben
   Karte 1 blieben ueber 200 px leere Flaeche. Die Kachel setzt ihr Mass jetzt
   selbst, das Bild fuellt sie. Zwei Klassen Spezifitaet schlagen die
   Formatregel, unabhaengig davon, wo im Blatt sie steht.
   Statt drei Projekten stehen jetzt alle acht neben dem Aufmacher. */

.ref-tiles {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(12px, 1.1vw, 18px);
}

.ref-tile {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--linie-dunkel);
  background: var(--anthrazit-2);
  transition: border-color 0.25s ease;
}

.ref-tiles .ref-tile img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  object-fit: cover;
  transition: transform 0.55s cubic-bezier(0.2, 0.6, 0.2, 1);
}

/* Der Verlauf traegt den Text. Im Browser nachgemessen statt geschaetzt: Bild
   in den echten Zuschnitt gerechnet, Verlauf darueber, dann der hellste
   Bildpunkt hinter jeder Textzeile. Schlechtester der acht Faelle ist
   Suedafrika mit den weissen Beschriftungsschildern: Rot-hell 4,89:1,
   Weiss 16,5:1, Textgrau 10,29:1.

   Nachgemessen am 26.08.: Der Textblock endet bei 37 Prozent der Kachelhoehe,
   nicht bei 45. Die Deckung haelt deshalb bis 38 Prozent und faellt darueber
   zuegig ab, statt das Foto bis 86 Prozent hinauf zu verschleiern. Hinter dem
   Text aendert sich nichts: An der obersten Textzeile liegt die Deckung bei
   0,911 gegenueber vorher 0,910, die gemessenen Kontraste gelten also weiter.
   Oberhalb des Textes traegt der Verlauf nichts und darf verschwinden. */
.ref-tile::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top,
    rgba(var(--verlauf-grund), 0.95) 0%,
    rgba(var(--verlauf-grund), 0.91) 38%,
    rgba(var(--verlauf-grund), 0.38) 56%,
    rgba(var(--verlauf-grund), 0.08) 74%,
    rgba(var(--verlauf-grund), 0) 88%);
}

.ref-tile-body {
  position: relative;
  width: 100%;
  padding: clamp(14px, 1.2vw, 22px);
}

.ref-tile-meta {
  color: var(--rot-hell);
  font-size: var(--t-3xs);
  font-weight: 500;
  letter-spacing: var(--versal-eng);
  text-transform: uppercase;
  margin-bottom: 6px;
}

.ref-tile h3 {
  font-size: clamp(17px, 1.25vw, 21px);
  line-height: 1.2;
  color: var(--weiss);
  margin-bottom: 7px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ref-tile h3 a {
  color: inherit;
  text-decoration: none;
}

/* Die ganze Kachel ist der Klickbereich, der Linktext bleibt der Projektname. */
.ref-tile h3 a::before {
  content: "";
  position: absolute;
  inset: 0;
}

/* --grau-hell lag ueber dem hellsten Motiv bei 4,78:1 und damit dicht an der
   Schwelle. Dasselbe Grau wie beim Bohrtiefenzaehler bringt 9,65:1. */
.ref-tile-fact {
  font-size: var(--t-2xs);
  font-weight: 300;
  line-height: 1.45;
  color: var(--grau-invert);
}

.ref-tile:hover { border-color: var(--rot-hell); }
.ref-tile:hover img { transform: scale(1.05); }
.ref-tile:hover h3 a { color: var(--rot-hell); }

/* Der Ring gehoert um die Kachel, nicht um die zwei Woerter des Titels. */
.ref-tile:has(a:focus-visible) {
  outline: 3px solid var(--weiss);
  outline-offset: 2px;
}

.ref-tiles .ref-tile h3 a:focus-visible {
  outline: none;
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .ref-tiles .ref-tile img { transition: none; }
  .ref-tile:hover img { transform: none; }
}

@media (max-width: 1180px) {
  .ref-tiles { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 860px) {
  .ref-tiles { grid-template-columns: repeat(2, 1fr); }
}

/* Auf dem Telefon waere eine 4:3-Kachel in halber Breite 170 px breit,
   der Titel braeuchte dort drei Zeilen. Eine Spalte im Querformat. */
/* Im 16:9-Format nimmt derselbe Textblock einen groesseren Anteil der
   Kachelhoehe ein, damit rutscht die oberste Zeile in den helleren Teil des
   Verlaufs: gemessen fiel das Rot dort auf 3,02:1. Der Verlauf haelt hier
   laenger durch. */
@media (max-width: 520px) {
  .ref-tiles { grid-template-columns: 1fr; }
  .ref-tile { aspect-ratio: 16 / 9; }
  .ref-tile::after {
    background: linear-gradient(to top,
      rgba(var(--verlauf-grund), 0.95) 0%,
      rgba(var(--verlauf-grund), 0.92) 62%,
      rgba(var(--verlauf-grund), 0.58) 78%,
      rgba(var(--verlauf-grund), 0.16) 92%,
      rgba(var(--verlauf-grund), 0) 100%);
  }
}

/* Der Knopf unter den Kacheln steht mittig, die alte Fliesstextzeile ist weg.
   btn-ghost erbt sonst das Anthrazit der hellen Sektionen und war auf der
   dunklen Flaeche unsichtbar: Schrift 22,24,27 auf Grund 22,24,27. */
.ref-more .btn-ghost { margin-top: 4px; }

.section-dark .btn-ghost {
  color: var(--weiss);
  border-color: rgba(255, 255, 255, 0.45);
}

.section-dark .btn-ghost:hover {
  color: var(--rot-hell);
  border-color: var(--rot-hell);
}

/* ---------- Feldnotiz (kleines Bild mit Text daneben) ----------
   Ersetzt das vollflaechige Bildband. Das Band war 100vw breit und bis 620 px
   hoch, das Foto trug dabei nur eine Bildunterschrift. Jetzt steht es klein
   neben einem Text, der die Aufnahme einordnet. */

.feldnotiz-grid {
  display: grid;
  grid-template-columns: minmax(240px, 400px) minmax(0, 620px);
  gap: clamp(32px, 5vw, 88px);
  align-items: center;
  max-width: 1110px;
  margin-inline: auto;
}

.feldnotiz-bild { margin: 0; }

.feldnotiz-bild img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius);
}

/* Label links, Angabe rechts, eine Zeile unter dem Bild. Vorher stand beides
   hintereinander im Fliesstext, mit einem roten Punkt davor. Der Punkt ist hier
   raus: er stammt aus dem Bildband, wo die Unterschrift ueber die volle Breite
   laeuft und eine Marke braucht. Unter einem 400 px breiten Bild markiert er
   nichts, er steht nur davor. */
.feldnotiz-bild figcaption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 4px 16px;
  margin-top: 14px;
  /* Eine Stufe unter der Regel: bei --t-xs bricht die Zeile unter dem
     400-px-Bild um und "Güteklasse 2" steht allein. Nachgemessen auf / und
     /leistungen/ bei 1440 px. */
  font-size: var(--t-2xs);
  line-height: 1.5;
  color: var(--grau-invert);
}

/* Derselbe rote Punkt wie im alten Bildband, damit die Bildsprache bleibt. */
.feldnotiz-bild figcaption .label {
  /* Enger als das Label im Bildband, und das mit Absicht: dort laeuft die
     Unterschrift ueber die volle Fensterbreite, hier steht sie unter einem
     400 px breiten Bild. Mit den 0,16em des Bildbands bricht die Zeile um.
     Nachgemessen auf / und /leistungen/ bei 1440 px. */
  letter-spacing: var(--versal-eng);
  color: var(--weiss);
  font-size: var(--t-3xs);
  font-weight: 600;
  text-transform: uppercase;
}

/* Die Angabe rechts. Bricht die Zeile um, steht sie linksbuendig unter dem
   Label statt in der Luft zu haengen. */
.feldnotiz-bild figcaption .feldnotiz-detail { text-align: right; }

@media (max-width: 520px) {
  .feldnotiz-bild figcaption { justify-content: flex-start; }
  .feldnotiz-bild figcaption .feldnotiz-detail { text-align: left; }
}

.feldnotiz-text h2 {
  font-size: clamp(26px, 2.3vw, 38px);
  line-height: 1.18;
  margin-bottom: 22px;
  text-wrap: balance;
}

.feldnotiz-text p {
  color: var(--grau-hell);
  font-weight: 300;
  max-width: 36em;
}

.feldnotiz-text p + p { margin-top: 16px; }

.feldnotiz-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
  margin-top: 26px;
}

.feldnotiz-links a {
  color: var(--weiss);
  font-size: var(--t-sm);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 1px solid var(--rot-hell);
  padding-bottom: 3px;
}

.feldnotiz-links a:hover { color: var(--rot-hell); }

/* Unter 900 px steht das Bild ueber dem Text, dort darf es wieder breiter
   werden: eine 400-px-Spalte neben 300 px Text waere auf dem Telefon nichts. */
@media (max-width: 900px) {
  .feldnotiz-grid {
    grid-template-columns: 1fr;
    gap: 28px;
    max-width: 620px;
  }
  .feldnotiz-bild img { aspect-ratio: 16 / 10; }
}

/* ---------- Feldnotiz: Bild rechts, Hochformat, helle Flaeche ----------
   Auf der Karriereseite steht ein hochkantes Motiv (Eingang mit dem Schild
   beider Firmen). Ein Hochformat in einer 620-px-Spalte waere 826 px hoch,
   deshalb bekommt es die schmale Spalte und wechselt die Seite. */

/* Anders als die Fassung mit Bild links steht dieser Block nicht als Insel in
   der Mitte: der Text beginnt an derselben Kante wie jede Ueberschrift der
   Seite, das Bild sitzt am rechten Rand des Inhaltskorridors. Zentriert stand
   die erste Textzeile 93 px weiter rechts als die Ueberschrift darunter. */
.feldnotiz-rechts .feldnotiz-grid {
  grid-template-columns: minmax(0, 1fr) 460px;
  max-width: none;
  margin-inline: 0;
}

/* Gemessen bei 1440 px lagen zwischen der letzten Textzeile und der Bildkante
   295 px: 72 px Rinne plus 223 px tote Restspalte, weil der Text bei 620 px
   endete, seine Spalte aber 843 px breit war. Text auf 680 und Bild auf 460
   halbieren den Zwischenraum auf 155 px, ohne dass das Bild seine Kante am
   rechten Rand des Inhaltskorridors verlaesst. Die Vorlage liegt mit 900 px
   Breite vor, 460 px Anzeige bleiben damit auch auf dichten Schirmen scharf. */
.feldnotiz-rechts .feldnotiz-text { max-width: 680px; }

/* Das Bild steht im Quelltext vor dem Text, damit auf dem Telefon zuerst das
   Motiv kommt. Es traegt keine Bedienelemente, deshalb aendert die Umstellung
   nichts an der Reihenfolge fuer Tastatur und Screenreader. */
.feldnotiz-rechts .feldnotiz-bild { order: 2; }

.feldnotiz-bild-hoch img { aspect-ratio: 3 / 4; }

/* Auf heller Flaeche traegt das Grau der dunklen Sektionen nur 2,9:1.
   --grau bringt auf Weiss 5,9:1. */
.section-light.feldnotiz .feldnotiz-text p,
.section-light.feldnotiz .feldnotiz-bild figcaption {
  color: var(--grau);
}

.section-light.feldnotiz .feldnotiz-bild figcaption .label,
.section-light.feldnotiz .feldnotiz-links a {
  color: var(--anthrazit);
}

.section-light.feldnotiz .feldnotiz-bild figcaption .label::before {
  background: var(--rot);
}

.section-light.feldnotiz .feldnotiz-links a {
  border-bottom-color: var(--rot);
}

.section-light.feldnotiz .feldnotiz-links a:hover { color: var(--rot); }

@media (max-width: 900px) {
  .feldnotiz-rechts .feldnotiz-grid { grid-template-columns: 1fr; }
  .feldnotiz-rechts .feldnotiz-bild { order: 0; }
  /* Ein 3:4-Bild ueber die volle Spaltenbreite waere auf dem Telefon
     467 px hoch und schoebe den Text unter den Falz. */
  .feldnotiz-bild-hoch img { aspect-ratio: 4 / 3; object-position: center 62%; }
}

/* ---------- Seitenkopf mit Bild (Referenzen) ---------- */

.page-hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 44%);
  gap: clamp(32px, 4vw, 80px);
  align-items: center;
}

.page-hero-media h1 { max-width: 12em; }

.page-hero-bild { margin: 0; }

.page-hero-bild figcaption {
  margin-top: 12px;
  font-size: var(--t-2xs);
  line-height: 1.45;
  color: var(--grau);
  max-width: 34em;
}

.page-hero-bild img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius);
}

/* Zuerst stand hier eine Ausnahme, die hochkanten Motiven 3:4 gab. Der Kopf
   wurde damit 490 px hoch und die Ueberschrift schwamm in der Mitte einer
   halbleeren Spalte. Alle Kopfbilder tragen jetzt dasselbe Format, das haelt
   die Koepfe der neun Referenzen auf einer Hoehe. Hochformate werden aus der
   oberen Bildhaelfte beschnitten, dort steht bei diesen Motiven das Objekt. */
.page-hero-bild img[data-format="hoch"] { object-position: center 38%; }

@media (max-width: 900px) {
  .page-hero-grid { grid-template-columns: 1fr; gap: 28px; }
  .page-hero-media h1 { max-width: none; }
  .page-hero-bild img,
  .page-hero-bild img[data-format="hoch"] { aspect-ratio: 16 / 10; }
}

/* ---------- Leistungsseiten: Schiene neben dem Fliesstext ----------
   Gemessen auf /leistung/geotechnik/: Fliesstext 680 px, Inhaltskorridor
   1425 px, rechts davon 680 px leer. Die halbe Seite trug nichts. Die Schiene
   fuellt sie mit der Ansprechkarte und gibt diesen acht Seiten damit
   ueberhaupt erst einen Weg zum Kontakt oberhalb des Fusses. */

/* Zwei Anlaeufe, zwei Loecher, hier der dritte.

   Erst war die Textspalte 1fr, der Satz darin aber auf 40em gedeckelt: der
   Ueberschuss fiel als Loch zwischen Text und Schiene, bei 1920 px Fenster
   757 px, breiter als die Textspalte selbst. Dann war die Spalte so breit wie
   der Satz: das Loch wanderte an den rechten Rand, bei 1920 px 778 px.

   Jetzt fuellt der Satz die Spalte. Damit die Zeile dabei lesbar bleibt,
   waechst die Schrift mit: laengere Zeilen brauchen groessere Buchstaben und
   mehr Durchschuss, sonst findet das Auge den Zeilenanfang nicht wieder. Die
   Werte sind im Browser nachgemessen, nicht geschaetzt, siehe .prose p weiter
   unten. Der Deckel liegt bei 90 Zeichen: darueber hilft auch Durchschuss
   nicht mehr. */
.prosa-mit-schiene {
  display: grid;
  /* Die Schiene waechst mit dem Fenster. Sie traegt echten Inhalt, das
     Verzeichnis und die Ansprechkarte, und nimmt dem Satz damit genau die
     Breite ab, die ihn sonst zu lang machen wuerde. Gemessen: ohne das
     Mitwachsen stand die Zeile bei 1600 px bei 104 Zeichen, mit ihm bei 85. */
  grid-template-columns: minmax(0, 1fr) minmax(280px, min(32%, 500px));
  gap: clamp(36px, 3.2vw, 64px);
  align-items: start;
}

/* In dieser Spalte gilt der 40em-Deckel nicht: die Spalte selbst ist das Mass,
   der Satz laeuft bis an die Schiene. */
.prosa-mit-schiene > .prose { max-width: none; }

/* Schrift und Durchschuss folgen der Breite. 17 px bei schmalem Fenster wie
   ueberall sonst, 21 px ab 1870 px. Ohne das Mitwachsen laege die Zeile bei
   1920 px gemessen bei 128 Zeichen; mit ihm bei rund 100. */
.prosa-mit-schiene > .prose p,
.prosa-mit-schiene > .prose li {
  font-size: clamp(17px, 0.85vw + 6px, 22px);
  line-height: 1.8;
}

/* Alles ausser der Schiene bleibt in der Textspalte. Die Fachkarten behalten
   ihren Ausbruch ueber die volle Breite, dafuer die zweite Regel. */
.prosa-mit-schiene > *:not(.leistung-schiene) { grid-column: 1; }
/* Nur wo keine Schiene steht, duerfen die Fachkarten ueber beide Spalten
   gehen. Sonst laufen sie unter die klebende Karte. */
.prosa-mit-schiene:not(:has(.leistung-schiene)) > .spec-grid { grid-column: 1 / -1; }

/* grid-row: 1 hielt die Schiene in der ersten Rasterzeile fest. Ein klebendes
   Element kann sich nur innerhalb seines eigenen Bereichs bewegen, und dieser
   Bereich war so hoch wie der erste Absatz. Die Karte war deshalb nach zwei
   Bildschirmhoehen weg, und rechts blieben auf der laengsten Seite ueber
   3.000 px leer. Ueber alle Zeilen gespannt klebt sie, solange der Abschnitt
   laeuft. */
.leistung-schiene {
  grid-column: 2;
  grid-row: 1 / -1;
  align-self: start;
  position: sticky;
  top: 108px;
  /* Zwoelf Indexeintraege plus Karte sind hoeher als mancher Bildschirm.
     Dann scrollt die Schiene in sich, statt unten abgeschnitten zu werden. */
  max-height: calc(100vh - 128px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* ---------- Abschnittsindex ----------
   Die acht Leistungsseiten laufen ueber 4.300 bis 7.800 px Hoehe. Wer wissen
   will, wo die HSE-Anforderungen stehen, hat bisher blind gescrollt. */
.schiene-index {
  margin-bottom: 20px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--linie);
}

.schiene-index-label {
  margin-bottom: 12px;
  font-size: var(--t-3xs);
  font-weight: 600;
  letter-spacing: var(--versal);
  text-transform: uppercase;
  color: var(--grau);
}

.schiene-index ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.schiene-index a {
  display: block;
  padding: 5px 0 5px 12px;
  border-left: 2px solid var(--linie);
  font-size: var(--t-2xs);
  line-height: 1.35;
  color: var(--grau);
  text-decoration: none;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.schiene-index a:hover { color: var(--text); border-left-color: var(--grau); }

/* Der gelesene Abschnitt wird markiert, sonst ist der Index eine Liste ohne
   Standortangabe. Die Klasse setzt main.js. */
.schiene-index a.hier {
  color: var(--rot-dunkel);
  border-left-color: var(--rot);
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .schiene-index a { transition: none; }
}

.schiene-karte {
  padding: 24px;
  background: var(--papier);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
}

.schiene-label {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 18px;
  line-height: 1.3;
  color: var(--text);
  margin-bottom: 18px;
}

.schiene-person {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 20px;
}

.schiene-person img {
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  aspect-ratio: 1 / 1;
}

.schiene-person span {
  display: block;
  font-size: var(--t-xs);
  line-height: 1.35;
  color: var(--grau);
}

.schiene-person strong {
  display: block;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--text);
}

.schiene-tel {
  display: block;
  margin-top: 12px;
  text-align: center;
  font-size: var(--t-sm);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  text-decoration: none;
}

.schiene-tel:hover { color: var(--rot); }

/* Unter 1180 px ist keine zweite Spalte mehr da. Die Karte rutscht unter den
   Text und hoert auf zu kleben, sonst wandert sie ueber den Fliesstext. */
@media (max-width: 1180px) {
  .prosa-mit-schiene { grid-template-columns: 1fr; }
  .leistung-schiene {
    grid-column: 1;
    grid-row: auto;
    position: static;
    max-height: none;
    overflow: visible;
    max-width: 420px;
  }
  /* Ohne Klebefunktion waere der Index eine Liste mitten im Artikel: man
     scrollt an ihr vorbei und sie zeigt danach nichts mehr an. Auf schmalen
     Geraeten traegt die Schiene nur die Ansprechkarte. */
  .schiene-index { display: none; }
}

/* ============================================================
   MIKRO-RUECKMELDUNGEN
   Vier Stellen, an denen eine Bewegung eine Frage beantwortet:
   Wo bin ich, was ist anklickbar, wohin fuehrt das, hat es geklappt.
   Mehr nicht. Jede davon ist unter prefers-reduced-motion abgeschaltet.
   ============================================================ */

/* ---------- Navigation: die Linie waechst mit ----------
   Vorher sprang eine 2-px-Linie ueber die volle Wortbreite an und wieder aus.
   Der Rahmen bleibt als Platzhalter stehen, damit beim Zeigen nichts springt,
   die sichtbare Linie kommt jetzt aus einem eigenen Element und laeuft von
   links auf. */
.main-nav a { position: relative; }



.main-nav a::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background: var(--rot);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.24s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.main-nav a:hover::before,
.main-nav a:focus-visible::before { transform: scaleX(1); }

/* Die aktuelle Seite traegt ihre Linie dauerhaft, nicht als Bewegung. */
.main-nav a[aria-current]::before { transform: scaleX(1); }

/* ---------- Knoepfe: ein Millimeter Weg ----------
   Der rote Knopf hatte beim Zeigen nur einen Schatten. Ein Pixel Anhebung
   macht aus der Farbaenderung eine Rueckmeldung, die man auch sieht, wenn
   der Schatten auf dunklem Grund untergeht. */
.btn-primary:hover,
.btn-light:hover { transform: translateY(-1px); }

/* ---------- Richtungszeichen an den Kartenlinks ----------
   "Zur Leistung" und "Stelle ansehen" sind der Fuss einer Karte, deren ganze
   Flaeche klickt. Der Pfeil ruecht beim Zeigen ueber die Karte nach, damit
   sichtbar wird, dass die Karte selbst das Ziel ist. */
.service-more::after,
.job-card-link::after {
  content: "\2192";
  display: inline-block;
  margin-left: 8px;
  transition: transform 0.25s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.service:hover .service-more::after,
.job-card:hover .job-card-link::after { transform: translateX(5px); }

/* ---------- Bildkarten: das Motiv atmet ----------
   Gleiche Sprache wie die Referenzkacheln, damit Uebersicht und Startseite
   sich gleich anfuehlen. */
.ref-featured-media img,
.page-hero-bild img {
  transition: transform 0.5s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.ref-featured:hover .ref-featured-media img { transform: scale(1.03); }

@media (prefers-reduced-motion: reduce) {
  .main-nav a::before { transition: none; }
  .btn-primary:hover,
  .btn-light:hover { transform: none; }
  .service-more::after,
  .job-card-link::after { transition: none; }
  .service:hover .service-more::after,
  .job-card:hover .job-card-link::after { transform: none; }
  .ref-featured-media img,
  .page-hero-bild img { transition: none; }
  .ref-featured:hover .ref-featured-media img { transform: none; }
}

/* ============================================================
   NACHLESE DES UI-AUDITS, 25.08.2026
   Fuenf Linsen ueber Blatt und Markup, 35 Funde, davon hier die
   sichtbaren und die bedienungsrelevanten.
   ============================================================ */

/* ---------- Bewegung: eine Sperre statt sieben Positivlisten ----------
   Das Blatt hatte sieben getrennte reduced-motion-Bloecke, jeder mit einer
   eigenen Aufzaehlung. Vier bewegte Bausteine standen in keinem davon: der
   Bohrtiefen-Zaehler faehrt beim Scrollen ein, die Referenzkarte hebt sich
   um 4 px, die beiden Aufschlusspunkte an Leistungs- und Menue-Symbol
   skalieren um 35 Prozent, und der Punkt am Leistungen-Eintrag im mobilen
   Menue federt mit einem Ueberschwinger nach. Genau dieses Muster soll die
   Einstellung abstellen.

   Die Sperre steht am Blattende und wirkt auf alles. Die Bloecke darueber
   behalten ihre Zeilen, die einen Endzustand setzen: die brauchen wir weiter,
   sonst bliebe eine Einblendung auf Deckkraft null stehen. Geprueft: main.js
   wartet nirgends auf transitionend oder animationend, die einzige
   keyframes-Regel laeuft mit forwards und hat ihren Endzustand separat. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }

  /* Der Zaehler faehrt nicht mehr ein, er ist einfach da. */
  .depth-counter { transform: none; }
  .ref-card:hover { transform: none; }
  .service:hover .service-icon .dot,
  .mega:hover .mega-icon .dot { transform: none; }
}

/* ---------- Der Punkt im Ring skaliert mit ----------
   .marker ist 14 px aussen mit 2 px Rahmen, der Punkt kam aus inset: 3px.
   Wegen border-box ist der Bezug die Polsterbox, also 10 px, der Punkt also
   4 px. Zwei Stellen verkleinern den Ring auf 12 und 11 px, ohne inset
   nachzuziehen: dort blieben 2 px und 1 px uebrig, aus dem gefuellten Punkt
   wurde ein leerer Ring. Prozentual bezogen skaliert er mit. */


/* ---------- Zustaende, die fehlten ---------- */

/* Der gesperrte Absendeknopf sah aus wie der bedienbare: main.js setzt
   disabled, das Blatt hatte dafuer kein Gegenstueck. */
.btn:disabled,
.btn[aria-disabled="true"] {
  background: var(--grau);
  border-color: var(--grau);
  color: var(--papier);
  box-shadow: none;
  transform: none;
  cursor: not-allowed;
}

.btn:disabled:hover,
.btn[aria-disabled="true"]:hover {
  background: var(--grau);
  box-shadow: none;
  transform: none;
}

/* Auswahlfelder fielen aus der Fokusregel: input und textarea standen darin,
   select nicht. */
select:focus-visible {
  outline: 3px solid var(--rot);
  outline-offset: 2px;
}

/* Die Verweise im Fuss trugen weder einen Zeigezustand noch eine erkennbare
   Linie: der Unterstrich lag bei 1,46:1. */
.footer-social a:hover,
.footer-social a:focus-visible {
  color: var(--rot-hell);
  border-bottom-color: var(--rot-hell);
}

/* Die aktuelle Seite und das blosse Zeigen sahen in der Navigation gleich
   aus, beide trugen eine rote Linie. Die aktuelle Seite bekommt ein zweites
   Merkmal, so wie es das mobile Menue schon macht. */
.main-nav a[aria-current] { font-weight: 600; }

/* Der Fokusring auf den dunklen Referenzkacheln war rot. Das Blatt sieht
   dafuer den weissen Ring vor, weil Rot auf Anthrazit kaum steht. */
.ref-tile:has(a:focus-visible) {
  outline-color: var(--weiss);
  box-shadow: 0 0 0 6px rgba(var(--verlauf-grund), 0.9);
}

/* ---------- Tippziele ----------
   Der Hoerer im Kopf mass 38 x 38 px und lag damit unter der Schwelle. Das
   Symbol bleibt gleich gross, nur die Flaeche darum waechst. */
@media (max-width: 1180px) {
  .header-phone {
    min-width: 44px;
    min-height: 44px;
    display: grid;
    place-items: center;
  }
}

/* ---------- Schmale Geraete ----------
   Die Kontaktkarte liess bei 320 px nur 116 px fuer Name und Adresse. Erst
   unterhalb von 360 px stapeln, darueber traegt die Zeile alles. */
@media (max-width: 360px) {
  .contact-person {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding: 20px;
  }
}

/* ---------- Silbentrennung in Ueberschriften ----------
   Die Trennung stand nur in der 700-px-Abfrage. Ab 901 px brachen lange
   deutsche Woerter deshalb mitten im Wort um, ohne Trennstrich. Gemessen auf
   acht Seiten mit 101 Ueberschriften: bei 1280 px aendert die Regel keine
   einzige Zeilenzahl, sie setzt den Strich nur dort, wo ohnehin gebrochen
   wird. */
h1, h2, h3, h4,
.page-tagline {
  hyphens: auto;
  -webkit-hyphens: auto;
}

/* ---------- Aufzaehlungen in den Fachkarten ----------
   Die Absaetze der Karten waren gegen Ueberlauf gesichert, die Listen nicht.
   Bei 320 px ragte ein Eintrag aus dem Rahmen. */
.spec li,
.prose li {
  overflow-wrap: break-word;
  hyphens: auto;
  -webkit-hyphens: auto;
}

/* ---------- Kopfzeile auf sehr schmalen Schirmen ----------
   Bei 320 px war die Marke auf 7 px zusammengedrueckt und der Menueknopf auf
   26 px: beide standen mit flex-shrink 1 in einer Zeile, die 200 px an
   Hoerer und Knopf verlor. Marke und Menueknopf geben nichts mehr ab, dafuer
   verliert der Knopf unter 400 px sein erstes Wort. */
.brand,
.nav-toggle { flex: none; }

@media (max-width: 400px) {
  .site-header .nur-breit { display: none; }
  .header-actions { gap: 12px; }
}

/* ---------- Rufnummern brechen nicht ----------
   Bei 360 px lief "040 280 08 37 00" im Formularhinweis ueber zwei Zeilen.
   Eine Nummer, die man abtippt oder antippt, gehoert in eine Zeile. */
a[href^="tel:"] { white-space: nowrap; }


/* ---------- Standortband auf der Kontaktseite ----------
   Das Luftbild ist 1600 x 1067, das Band 494 px hoch. Mit dem mittigen
   Zuschnitt lag der sichtbare Streifen bei y 256 bis 810 des Originals: Baeume
   und Dachflaeche. Die Glasfassade beginnt erst bei y 650, der Eingang bei
   850. Der Ausschnitt wandert deshalb an den unteren Rand. */
.image-band-fassade img { object-position: center bottom; }

/* ---------- Ton am Kopffilm ----------
   Beschrifteter Knopf unten links auf dem Film. Ein reines Lautsprecher-
   symbol wird nicht als Schalter gelesen, deshalb steht der Zweck als Text
   daneben. Waehrend der Film mit Ton laeuft, uebernehmen die Bedienelemente
   des Browsers und der Knopf verschwindet. */
.video-sound {
  position: absolute;
  left: 14px;
  bottom: 14px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 10px 18px;
  border: none;
  border-radius: 999px;
  background: rgba(22, 24, 27, 0.78);
  color: var(--weiss);
  font-family: var(--font-sans);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: background 0.2s ease, transform 0.2s ease;
}

/* hidden ist ein Attribut, das der Browser mit display:none umsetzt. Die
   Regel oben setzt aber display:inline-flex und gewinnt, weil sie spezifischer
   ist als die eingebaute Regel des Browsers. Folge: main.js setzte den Knopf
   beim Start des Tonfilms auf hidden, sichtbar blieb er trotzdem, und er lag
   unten links genau auf der Bedienleiste des Browsers, also auf Abspielknopf
   und Zeitleiste. Gemessen am 28.08.: Knopf 150x35 bei 625,655, Leiste des
   Videos von 661 bis 706. Diese Zeile stellt hidden wieder her. */
.video-sound[hidden],
.video-toggle[hidden] { display: none; }

.video-sound span { font-size: 10px; line-height: 1; }

.video-sound:hover {
  background: var(--rot);
  transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
  .video-sound { transition: none; }
  .video-sound:hover { transform: none; }
}

/* ---------- Abstand zwischen Text und Knopf ----------
   Gemessen ueber neun Seiten: jeder Knopf, der direkt auf eine Liste oder
   einen Absatz folgt, stand mit Abstand NULL darunter. Er klebte damit an der
   letzten Zeile und las sich wie ein weiterer Listeneintrag statt wie die
   Handlung, zu der der Text hinfuehrt. Betroffen waren die Nachweisliste auf
   der Startseite, der Standortabsatz auf /historie/ und der Knopf im
   Leistungsmenue auf allen 30 Seiten.

   :where haelt das Gewicht bei null, damit jede eigene Regel weiter gewinnt. */
:where(p, ul, ol, dl) + :where(.btn) {
  margin-top: clamp(22px, 2.6vh, 34px);
}

/* ============================================================
   FUENF BEWEGUNGEN AUS DER BILDSPRACHE DER SEITE
   Keine Zierde: jede greift ein Motiv auf, das die Seite ohnehin
   fuehrt (Bohrprofil, Aufschlusspunkt, Tiefe) und beantwortet
   dabei eine Frage. Alle fuenf sind unter prefers-reduced-motion
   abgeschaltet.
   ============================================================ */

/* ---------- 1. Bohrsaeule im Tiefenzaehler ----------
   Der Zaehler nannte die Tiefe als Zahl. Eine Zahl allein sagt nicht, wie
   weit unten man ist. Die Saeule daneben fuellt sich mit dem Fortschritt und
   macht aus der Angabe eine Strecke, so wie ein Bohrprofil. */
.depth-counter {
  display: flex;
  /* Die Ursprungsregel weiter oben setzt column. Ohne diese Zeile stapelt
     sich die Saeule ueber den Text und hat dort keine Hoehe. */
  flex-direction: row;
  align-items: stretch;
  gap: 12px;
}

.depth-counter-text { display: block; }

.depth-saeule {
  position: relative;
  width: 4px;
  flex: none;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.18);
  overflow: hidden;
}

.depth-saeule i {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: var(--teufe, 0%);
  background: var(--rot-hell);
  transition: height 0.18s linear;
}

/* ---------- 2. Der Aufschlusspunkt setzt sich ----------
   Das Leitmotiv der Seite bekommt beim Erscheinen einen eigenen Moment: der
   Ring faehrt aus der Mitte auf, mit einem winzigen Ueberschwinger, wie ein
   Punkt, der im Profil gesetzt wird. Nur dort, wo er mit einem Reveal
   zusammen erscheint. */
@keyframes punkt-setzen {
  0%   { transform: scale(0.35); opacity: 0; }
  70%  { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

.js .reveal.in .marker,
.js .reveal.in.stat::before,
.js .reveal.in .ref-facts li::before,
.js .stat.reveal.in::before {
  animation: punkt-setzen 0.5s cubic-bezier(0.2, 0.7, 0.3, 1) both;
  animation-delay: calc(var(--reveal-i, 0) * 60ms + 120ms);
}

/* ---------- 3. Die Bohrung laeuft durch den Ablauf ----------
   Die vier Schritte tragen nummerierte Ringe. Die Linie dazwischen zeichnet
   sich von links nach rechts, sobald der Block ins Bild kommt: der Ablauf
   ist eine Strecke, keine Sammlung von vier Kaesten. */
@media (min-width: 861px) {
  .process { position: relative; }

  .process::before {
    content: "";
    position: absolute;
    left: 26px;
    right: 26px;
    top: 26px;
    height: 2px;
    background: var(--linie);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 1.2s cubic-bezier(0.22, 1, 0.36, 1) 0.2s;
  }

  .js .process:has(.process-step.in)::before { transform: scaleX(1); }

  /* Die Nummern stehen auf der Linie, nicht darunter. */
  .process-step::before { position: relative; z-index: 1; }
}

/* ---------- 4. Die Kopfzeile verdichtet sich ----------
   Ueber dem Hero nimmt der Kopf Platz, darunter macht er dem Inhalt Platz.
   80 auf 64 px, das Logo geht mit. */
.site-header {
  transition: box-shadow 0.3s ease;
}

.header-inner {
  transition: height 0.3s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.brand-logo {
  transition: width 0.3s cubic-bezier(0.2, 0.6, 0.2, 1),
              height 0.3s cubic-bezier(0.2, 0.6, 0.2, 1);
}

@media (min-width: 1181px) {
  .site-header.dicht .header-inner { height: 64px; }
  .site-header.dicht .brand-logo { width: 54px; height: 35px; }
  .site-header.dicht { box-shadow: 0 6px 24px rgba(22, 24, 27, 0.07); }
}

/* ---------- 5. Tiefe auf den Kacheln ----------
   Beim Zeigen hebt sich der Textblock leicht und die Faktenzeile klart auf.
   Zusammen mit dem Zoom des Motivs entsteht der Eindruck, dass die Kachel
   naeher kommt, statt nur die Farbe zu wechseln. */
.ref-tile-body {
  transition: transform 0.35s cubic-bezier(0.2, 0.6, 0.2, 1);
}

.ref-tile-fact {
  opacity: 0.82;
  transition: opacity 0.35s ease;
}

.ref-tile:hover .ref-tile-body { transform: translateY(-4px); }
.ref-tile:hover .ref-tile-fact { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .depth-saeule i { transition: none; }
  .js .reveal.in .marker,
  .js .reveal.in.stat::before,
  .js .reveal.in .ref-facts li::before,
  .js .stat.reveal.in::before { animation: none; }
  .process::before { transition: none; transform: scaleX(1); }
  .header-inner,
  .brand-logo,
  .site-header { transition: none; }
  .ref-tile-body { transition: none; }
  .ref-tile:hover .ref-tile-body { transform: none; }
  .ref-tile-fact { opacity: 1; transition: none; }
}
