/* ============================================================
   TerraTec Baugrunduntersuchung · Relaunch
   Collective Brain · Designsprache uebernommen von terra-ing.de (TIG),
   Volle Breite, Fira Sans + Noto Serif, Farben auf das TerraTec-Logo gezogen
   ============================================================ */

:root {
  /* Das Logo steht auf #EE3B34. Weisse Schrift darauf kommt nur auf 3,95:1,
     fuer Knoepfe und Textflaechen zu wenig. --rot ist deshalb eine Spur
     tiefer gezogen (5,06:1 gegen Weiss, 4,59:1 gegen --papier), die reine
     Logofarbe bleibt fuer Flaechen ohne Schrift und Zeichen. */
  --rot: #D42A22;
  --rot-marke: #EE3B34;
  --rot-dunkel: #B3231C;
  --rot-hell: #FF5A52; /* 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(212, 42, 34, 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;
}

/* Schmal: Film randlos direkt unter dem Kopf, darunter der Text. Ab 861 px
   wird .hero-grid zur Buehne, der Film fuellt sie ganz und der Text liegt
   links darauf (siehe "Hero-Buehne" weiter unten). */
.hero-grid {
  display: grid;
  gap: clamp(28px, 6vw, 44px);
  padding-bottom: clamp(36px, 6vw, 56px);
}

.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; }

/* Intro-Film im nativen Querformat. Schmal steht er randlos ueber der
   Ueberschrift: die negativen Raender holen ihn aus dem Seitenrand der .wrap
   heraus, order stellt ihn nach oben. Im Markup bleibt er hinter dem Text,
   damit Vorleseprogramme mit der H1 beginnen. Das Standbild wird auf jeder
   Breite vorgeladen (build.mjs, seitenPreload), oben steht es also sofort. */

.hero-media {
  position: relative;
  order: -1;
  aspect-ratio: 16 / 9;
  margin-inline: calc(-1 * var(--pad));
}

.hero-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: var(--anthrazit);
}

.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); }

/* ---------- Hero-Buehne ab 861 px ----------
   Der Film laeuft ueber die volle Breite, der Text steht links darauf. Damit
   er auf jedem Filmbild lesbar bleibt, liegt ein Verlauf von links ueber dem
   Film, unten ein zweiter fuer den Ton-Knopf. Rechts bleibt das Bild frei.

   Hoehe: 16:9 der Breite, aber hoechstens so hoch, dass unter dem Kopf noch
   der Anfang der Zahlenreihe zu sehen ist. Wird der Text hoeher (schmale
   Fenster, grosse Schrift), waechst die Buehne mit und der Film schneidet
   seitlich zu. */
@media (min-width: 861px) {
  .hero-grid {
    position: relative;
    isolation: isolate;
    display: flex;
    align-items: center;
    min-height: max(560px, min(56.25vw, 100vh - 160px));
    min-height: max(560px, min(56.25vw, 100svh - 160px));
    padding-block: clamp(48px, 7vh, 104px);
    background: var(--anthrazit);
  }

  .hero-media {
    position: absolute;
    inset: 0;
    margin: 0;
    aspect-ratio: auto;
  }

  .hero-media::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
      linear-gradient(90deg,
        rgba(var(--verlauf-grund), 0.86) 0%,
        rgba(var(--verlauf-grund), 0.72) 30%,
        rgba(var(--verlauf-grund), 0.3) 58%,
        rgba(var(--verlauf-grund), 0) 80%),
      linear-gradient(to top,
        rgba(var(--verlauf-grund), 0.45) 0%,
        rgba(var(--verlauf-grund), 0) 28%);
    transition: opacity 0.45s ease;
  }

  .hero-copy {
    position: relative;
    z-index: 1;
    max-width: clamp(480px, 46vw, 820px);
    transition: opacity 0.35s ease, visibility 0.35s;
  }

  .hero-copy .eyebrow { color: rgba(255, 255, 255, 0.72); }

  /* 8em haelt die Zeile bei drei Zeilen "Wir machen / Baugrund / planbar.",
     wie in der Spalte vorher. Ohne Grenze trennte sie bei 1024 und 1920 px
     "Bau-grund". */
  .hero-copy h1 {
    max-width: 8em;
    hyphens: manual;
    -webkit-hyphens: manual;
    color: var(--weiss);
    text-shadow: 0 2px 32px rgba(var(--verlauf-grund), 0.35);
  }

  .hero-copy h1 em { color: var(--rot-hell); }

  .hero-copy .hero-sub,
  .hero-copy .hero-trust { color: var(--grau-invert); }

  .hero-copy .hero-trust strong { color: var(--weiss); }

  .hero-copy .btn-ghost { color: var(--weiss); }

  .hero-copy .btn-ghost:hover {
    background: var(--weiss);
    border-color: var(--weiss);
    color: var(--anthrazit);
  }

  .video-toggle { top: 24px; right: var(--pad); }

  /* Die Zahlen stehen direkt unter dem Film, dessen Kante trennt schon. */
  .hero .stats { border-top: 0; margin-top: 0; }

  /* Laeuft der Film mit Ton, tritt der Text zur Seite: sonst laege er auf
     dem Film und auf der linken Haelfte der Bedienleiste. contain zeigt dann
     das ganze Bild statt des Zuschnitts. */
  .hero.ton-modus .hero-copy { opacity: 0; visibility: hidden; }
  .hero.ton-modus .hero-media::after { opacity: 0; }
  .hero.ton-modus .hero-video { object-fit: contain; }
}

@media (min-width: 861px) and (prefers-reduced-motion: reduce) {
  .hero-copy,
  .hero-media::after { transition: none; }
}

/* 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;
}

/* Personenmotive: der Helm steht oben im Bild. Auf breiten Schirmen schneidet
   das Band sonst genau dort. */
.image-band img[src*="stelle-geotechnik-ingenieur"] { object-position: 50% 30%; }

.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;
}

/* 132 px seit 13.10.2026 (Wunsch Arno, vorher 88). */
.contact-person img {
  width: 132px;
  height: 132px;
  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);
  /* 70em schliessen den Rand von .wrap ein. Waechst --pad ueber 88 px (ab
     rund 1956 px Fensterbreite), waechst die Grenze um denselben Betrag mit,
     sonst blieben bei 2557 px nur 207 px Zeilenbreite. Darunter gilt 70em. */
  max-width: calc(70em + 2 * max(0px, var(--pad) - 88px));
}

.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) {
  .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; }

/* Bilder in der Textspalte: zu schmal fuer ein Vollband (Diagramme) oder
   bewusst neben den Text gestellt. Nichts wird beschnitten. */
.prosa-bild { margin: 36px 0; }
/* data-format gibt Bildern sonst einen festen Kasten mit Beschnitt; hier
   gilt das eigene Seitenverhaeltnis, und nichts wird ueber die echte Breite
   hinaus vergroessert. */
.prosa-bild img,
.prosa-bild img[data-format] { display: block; width: auto; max-width: 100%; height: auto; aspect-ratio: auto; object-fit: contain; }
.prosa-bild figcaption { margin-top: 10px; font-size: var(--t-xs); color: var(--grau); }
/* Hochformate laufen rechts mit, sonst waere ein 360 px schmales Bild ein
   Bildschirm hoher Block mit Leerraum daneben. */
.prosa-bild-hoch { float: right; width: min(42%, 360px); margin: 6px 0 24px 36px; }
.prose h2 { clear: right; }
@media (max-width: 600px) {
  .prosa-bild-hoch { float: none; width: auto; max-width: 360px; margin: 28px 0; }
}

.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. 132 px seit 13.10.2026 (vorher 88), dieselbe Groesse wie in
   der Kontaktkarte (.contact-person) auf /karriere/, damit Margarita Huber
   ueberall 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: 132px;
  height: 132px;
  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; }

/* Feste Spaltenzahl statt Flexbox: --spalten setzt chipNav() je nach Anzahl.
   Unter 860 px zwei Spalten, unter 520 px eine. Acht Leistungen gehen damit
   in jeder Breite glatt auf (4 x 2, 2 x 4, 1 x 8). */
.chip-grid {
  display: grid;
  grid-template-columns: repeat(var(--spalten, 4), minmax(0, 1fr));
  gap: 1px;
  background: var(--linie);
  border: 1px solid var(--linie);
}
@media (max-width: 860px) {
  .chip-grid { grid-template-columns: repeat(min(var(--spalten, 4), 2), minmax(0, 1fr)); }
}
@media (max-width: 520px) {
  .chip-grid { grid-template-columns: 1fr; }
}

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

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

/* Die eigene Seite steht mit im Raster, ist aber kein Link. */
.chip-aktuell { 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 Quellenangabe zu den Kartendaten. Sie steht im HTML und nicht nur in
   der Karte, damit sie auch dasteht, wenn die Karte ruht oder nicht kann.
   Deshalb leiser gesetzt als der Hinweis darueber: sie ist Pflichtangabe,
   nicht Ansprache. */
.standort-quelle {
  margin: 8px 0 0;
  font-size: var(--t-3xs);
  line-height: 1.5;
  color: var(--grau-hell);
}

.standort-quelle a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.standort-quelle a:hover,
.standort-quelle a:focus-visible { color: var(--rot); }

/* Lizenzliste im Impressum: dieselbe Bauart wie die Anfahrtsliste, damit die
   beiden Aufzaehlungen der Seite nicht zwei verschiedene Sprachen sprechen. */
.lizenzen { margin: 0 0 24px; }

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

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

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

/* MapLibre liefert seine Knoepfe mit 29 px aus. Der Rest dieser Seite haelt
   44 px ein (WCAG 2.5.5), dafuer wurde im August schon der Menueknopf
   nachgezogen. Eine Weltkarte, die man mit dem Daumen bedient, braucht das
   erst recht. */
.karte-rahmen .maplibregl-ctrl-group button {
  width: 44px;
  height: 44px;
}

.karte-rahmen .maplibregl-ctrl-group button + button {
  border-top: 1px solid var(--linie);
}

.karte-rahmen .maplibregl-ctrl-group button .maplibregl-ctrl-icon {
  /* Die Symbole sind Hintergrundbilder in fester Groesse und saessen sonst
     verloren in der groesseren Flaeche. */
  background-size: 20px 20px;
}

.karte-rahmen .maplibregl-ctrl-group button:focus-visible {
  outline: 2px solid var(--rot);
  outline-offset: -2px;
  box-shadow: none;
}

/* Die eigenen Zoomknoepfe. Sie ersetzen die von MapLibre, weil ein Klick hier
   Zoom und Neigung in einer Bewegung faehrt statt in zwei, die sich
   gegenseitig abwuergen. Gesetzt wird das Zeichen als Text, nicht als
   Hintergrundbild: so skaliert es mit der Schriftgroesse mit. */
.karte-rahmen .karte-zoom {
  display: grid;
  place-items: center;
  font-family: var(--font-sans);
  font-size: 22px;
  font-weight: 400;
  line-height: 1;
  color: var(--text);
  padding-bottom: 2px;
}

.karte-rahmen .karte-zoom:hover { color: var(--rot); }

/* Nach Norden. Der Knopf dreht sich mit der Karte, damit die Nadel immer
   dorthin zeigt, wo Norden wirklich liegt. */
.karte-rahmen .karte-nord {
  display: grid;
  place-items: center;
  transition: transform 120ms linear;
}

.karte-rahmen .karte-nadel-nord {
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 15px solid var(--rot);
  position: relative;
}

/* Der graue Gegenzeiger, damit die Nadel als Kompass lesbar ist und nicht als
   Pfeil nach oben. */
.karte-rahmen .karte-nadel-nord::after {
  content: "";
  position: absolute;
  left: -6px;
  top: 15px;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 15px solid var(--grau-hell);
}

.karte-rahmen .karte-nord-gruppe[hidden] { display: none; }

/* Der Weg zurueck zum eigenen Haus. Traegt den Aufschlusspunkt der Marke
   statt eines fremden Symbols. */
.karte-rahmen .karte-heim { display: grid; place-items: center; }

.karte-rahmen .karte-heim .marker {
  --marker-mass: 15px;
  --marker-farbe: var(--rot);
}

/* Der Hinweis, der erscheint, wenn jemand ohne Strg oder Cmd scrollt.
   MapLibre legt ihn ueber die ganze Karte, mit eigener Schrift und eigenem
   Grau. Beides auf das Haus gezogen. */
.karte-rahmen .maplibregl-cooperative-gesture-screen {
  font-family: var(--font-sans);
  font-size: var(--t-sm);
  font-weight: 400;
  background: rgba(22, 24, 27, 0.55);
  color: var(--weiss);
  padding: 0;
}

.karte-rahmen .maplibregl-cooperative-gesture-screen .maplibregl-desktop-message,
.karte-rahmen .maplibregl-cooperative-gesture-screen .maplibregl-mobile-message {
  background: var(--anthrazit);
  padding: 12px 20px;
  border-radius: var(--radius-klein, 4px);
}

/* Der Massstab: dieselbe Schrift wie die Bildunterschriften, kein Kasten. */
.karte-rahmen .maplibregl-ctrl-scale {
  font-family: var(--font-sans);
  font-size: var(--t-3xs);
  color: var(--grau);
  background: rgba(244, 244, 242, 0.82);
  border-color: var(--grau-hell);
  border-width: 0 1.5px 1.5px;
  padding: 2px 6px;
}

@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;
}

/* 96 px seit 13.10.2026 (Wunsch Arno: 70 Prozent groesser, vorher 56). */
.schiene-person img {
  width: 96px;
  height: 96px;
  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. Seit
   das Bild 132 statt 88 px hat, blieben bei 375 px nur noch 127 px, Name und
   Mailadresse brachen um. Deshalb unter 480 px stapeln: Bild oben, Text
   darunter in voller Breite. */
@media (max-width: 480px) {
  .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. */

/* ---------- Ton am Kopffilm ----------
   Beschrifteter Knopf unten 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. An seine Stelle tritt oben rechts
   "Film schliessen", gleich gebaut. */
.video-sound,
.video-schliessen {
  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],
.video-schliessen[hidden] { display: none; }

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

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

.video-schliessen {
  left: auto;
  bottom: auto;
  top: 14px;
  right: 14px;
}

/* Auf der breiten Buehne steht links der Text. Der Ton-Knopf rueckt deshalb
   nach rechts unten, beide Knoepfe halten den Seitenrand der Spalte ein. */
@media (min-width: 861px) {
  .video-sound { left: auto; right: var(--pad); bottom: 28px; }
  .video-schliessen { top: 24px; right: var(--pad); }

  /* Dunkle Pille auf dunklem Verlauf war als Knopf nicht mehr zu erkennen,
     nur noch als Schrift. Helle Glaskante statt dunkler Flaeche. */
  .video-sound,
  .video-schliessen,
  .video-toggle {
    background: rgba(255, 255, 255, 0.14);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.42);
    backdrop-filter: blur(8px);
  }

  .video-toggle:hover { background: rgba(255, 255, 255, 0.26); }
}

@media (prefers-reduced-motion: reduce) {
  .video-sound,
  .video-schliessen { transition: none; }
  .video-sound:hover,
  .video-schliessen: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; }
}

/* ============================================================
   Anfrage: Seitenkopf und Formular als ein Abschnitt
   ============================================================
   Der Kunde meldete am 11.09.2026, das Formular habe zu viele
   Moeglichkeiten und der Nutzer komme nicht above the fold zum Ziel.
   Nachgemessen bei 1440x900: das Formular begann bei 710 px, der
   Absendeknopf sass bei 2681 px, also im dritten Bildschirm. Allein die
   Leistungsauswahl war 538 px hoch.

   Jetzt teilen sich Ueberschrift und Formular den ersten Bildschirm. Die
   Reihenfolge im Quelltext ist die Lesereihenfolge, deshalb braucht das
   Raster keine order-Angaben und die Tabulatorfolge stimmt von selbst. */
.anfrage-kopf {
  background: var(--weiss);
  border-bottom: 1px solid var(--linie);
  /* Unten stand hier 32 px, damit die Ansprechpartner moeglichst frueh ins
     Bild kommen. Am Desktop klebte die Formularkarte damit fast am dunklen
     Abschnitt darunter (Wunsch Arno, 13.10.2026: mehr Abstand). Jetzt
     waechst der Abstand mit der Fensterhoehe, 72 px bei 900 px Hoehe. Das
     Handy behaelt seine 32 px aus der Regel unter 900 px Breite. */
  padding-block: 26px clamp(64px, 8vh, 112px);
}

.anfrage-raster {
  display: grid;
  /* 360 px Boden fuer die linke Spalte. Ohne ihn gibt sie als einzige nach:
     bei 1024 px Fenster schrumpfte sie auf 210 px, die H1 brach dreizeilig um
     und das Formular stand unveraendert auf 680 px daneben. Jetzt gibt die
     Karte nach, die das ohne Schaden kann. */
  grid-template-columns: minmax(360px, 1fr) minmax(0, 680px);
  /* Die erste Zeile nimmt nur, was die Ueberschrift braucht, die zweite den
     Rest. Ohne diese Angabe verteilt das Raster die Hoehe der Formularkarte
     auf beide Zeilen, und zwischen Vorspann und den direkten Wegen klafft ein
     Loch von rund 150 px. */
  grid-template-rows: min-content 1fr;

  /* Die Seite darf bis 1780 px breit werden. Ohne die Deckelung hier nimmt
     die linke Spalte den ganzen Rest: 1780 - 88 Spalt - 540 Formular = 1152 px
     fuer einen Text, der bei 500 px endet. Zwischen Ueberschrift und
     Formularkante standen damit ueber 700 px Leere, und die beiden Haelften
     lasen sich nicht mehr als ein Block, sondern als zwei Seiten.

     1080 px sind kein runder Zufallswert: 540 Formular + 44 Spalt lassen der
     linken Spalte 496 px, und genau so breit ist ihr Inhalt (H1 bei 46 px auf
     zwei Zeilen, Vorspann 28 em). Die Spalte traegt damit ihren Text und
     keinen Leerraum, und das Paar steht als Einheit unter der Brotkrume.
     Ueber 1080 px waechst nicht mehr das Loch in der Mitte, sondern der
     Rand rechts. */
  /* 1220 statt 1080 px, weil das Formular von 540 auf 680 px gewachsen ist:
     die linke Spalte behaelt ihre 496 px, und das ist genau die Breite ihres
     Inhalts (H1 bei 46 px auf zwei Zeilen, Vorspann 28 em). Ueber 1220 px
     waechst der Rand rechts, nicht das Loch in der Mitte. */
  max-width: 1220px;
  column-gap: clamp(24px, 2.6vw, 44px);
  row-gap: 26px;
  align-items: start;
}

.anfrage-text { grid-column: 1; grid-row: 1; }
.anfrage-karte { grid-column: 2; grid-row: 1 / span 2; }
.anfrage-wege { grid-column: 1; grid-row: 2; }

/* Die H1 traegt hier weniger Luft als auf den uebrigen Seiten: jeder
   Pixel oben kostet einen Pixel unter dem Absendeknopf. Der Kicker
   "Kontakt" faellt weg, die Brotkrume zwei Zeilen hoeher sagt dasselbe
   Wort und er kostete 41 px im knappsten Bereich der Seite. */
.anfrage-text h1 {
  font-size: clamp(32px, 3.2vw, 46px);
  line-height: 1.06;
  margin: 0;
}

.anfrage-vorspann {
  margin: 18px 0 0;
  font-size: 17px;
  font-weight: 300;
  line-height: 1.55;
  color: var(--grau);
  max-width: 28em;
}

/* Die Formularkarte steht auf Papier statt auf Weiss, damit die Eingaben
   sich als weisse Flaechen davon abheben. Der rote Balken oben ist kein
   neues Motiv: die Mailvorlagen des Anfragedienstes setzen unter ihren
   anthrazitfarbenen Kopf denselben Streifen. Formular und Bestaetigung
   sprechen damit dieselbe Sprache. */
.anfrage-karte.contact-form {
  background: var(--papier);
  border: 1px solid var(--linie);
  border-top: 4px solid var(--rot);
  border-radius: var(--radius);
  padding: clamp(18px, 1.6vw, 20px);
  gap: 14px;
  /* Die Karte lag flach auf dem weissen Abschnitt und unterschied sich von ihm
     nur um zwei Helligkeitsstufen. Ein knapper Schatten macht aus der Flaeche
     ein Objekt, ohne dass die Seite nach Material aussieht: die erste Zeile
     ist die Kante, die zweite der Abstand zum Grund. */
  box-shadow: 0 1px 2px rgba(22, 24, 27, 0.05), 0 14px 34px -18px rgba(22, 24, 27, 0.18);
  align-content: start;
}

/* Titel und Dauerzeile auf einer Grundlinie. flex-wrap, damit die Dauerzeile
   unter den Titel rutscht, sobald die Karte schmal wird. */
.anfrage-formularkopf {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 16px;
  flex-wrap: wrap;
}

.anfrage-formularkopf .anfrage-dauer { margin: 0; }

/* Der Feldblock bringt 22 px Abstand aus dem dunklen Abschnitt mit, wo das
   Formular frueher stand und Platz im Ueberfluss hatte. Hier zaehlt jeder
   Pixel gegen die Falzkante. */
.anfrage-karte .feld-block { row-gap: 14px; }

/* ---------- Querformat ----------
   Die vier Felder standen untereinander: 449 px von 697 px Kartenhoehe, und
   der Ansprechpartner-Abschnitt begann dadurch bei 911 px, elf Pixel unter der
   Falzkante eines 1440x900-Schirms.

   Jetzt stehen die drei kurzen Angaben in einer Spalte und das Textfeld
   daneben ueber ihre volle Hoehe. Das spart nicht nur rund 150 px, es gibt
   auch dem einen Feld Platz, in dem der eigentliche Sachverhalt steht: aus
   zwei Zeilen werden gut acht. Wer eine Trasse beschreibt, sieht endlich, was
   er geschrieben hat.

   Angesprochen wird das Textfeld ueber data-feld und nicht ueber :nth-child:
   wer in dienst/felder.mjs ein Feld einschiebt, verschoebe sonst stumm das
   Raster. Die uebrigen drei ordnen sich von selbst in die erste Spalte, weil
   die zweite ueber alle drei Zeilen belegt ist.

   Die Bedingung fragt die Karte und nicht das Fenster. Das ist hier der
   Unterschied zwischen richtig und ungefaehr: die Karte ist mal 680, mal 437
   px breit, je nachdem was die linke Spalte uebrig laesst. Eine Fensterregel
   traf deshalb regelmaessig daneben - bei 1150 px Fenster passten zwei
   Spalten, bei 1150 px Fenster mit laengerer Ueberschrift nicht. Unter 600 px
   Kartenbreite bleiben die Felder untereinander: zwei Spalten waeren dort
   keine 280 px breit, und der Hilfetext unter "Standort" braucht allein drei
   Zeilen. */
.anfrage-karte.contact-form {
  container-type: inline-size;
  container-name: anfrage;
}

@container anfrage (min-width: 600px) {
  .anfrage-karte .feld-block {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 18px;
  }

  .anfrage-karte .feld[data-feld="projekt"] {
    grid-column: 2;
    grid-row: 1 / span 3;
    /* Label, Hilfetext, und der Rest gehoert dem Textfeld. */
    grid-template-rows: auto auto 1fr;
  }

  /* height statt min-height, damit das Feld genau die Hoehe der drei Angaben
     daneben bekommt. resize bleibt: wer einen langen Sachverhalt schreibt,
     zieht es groesser, und die Karte waechst mit. Nur nach unten, seitlich
     wuerde es aus dem Raster laufen. */
  .anfrage-karte .feld[data-feld="projekt"] textarea {
    height: 100%;
    resize: vertical;
  }
}

.anfrage-karte .feld input,
.anfrage-karte .feld textarea,
.anfrage-karte .feld select { background: var(--weiss); }

.anfrage-karte .form-note {
  margin: 0;
  font-size: var(--t-3xs);
  line-height: 1.5;
  color: var(--grau-hell);
}

/* Die direkten Wege. Sie stehen NEBEN dem Formular, nicht dahinter: wer
   lieber anruft, soll nicht erst an einem Formular vorbeiscrollen. */
.anfrage-wege {
  display: grid;
  gap: 18px;
  align-content: start;
  max-width: 30em;
}

.anfrage-weg {
  margin: 0;
  font-size: var(--t-sm);
  font-weight: 300;
  line-height: 1.6;
  color: var(--grau);
}

.anfrage-weg .label {
  display: block;
  font-size: var(--t-3xs);
  font-weight: 600;
  letter-spacing: var(--versal);
  text-transform: uppercase;
  color: var(--grau);
  margin-bottom: 4px;
}

/* Telefon und Mail sind die Hauptsache dieser Zeilen, deshalb tragen sie
   Textgroesse und Gewicht. Als Tippziel am Handy mindestens 44 px hoch. */
.anfrage-weg > a {
  font-size: 19px;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid var(--linie);
  display: inline-block;
  min-height: 30px;
}

.anfrage-weg > a:hover,
.anfrage-weg > a:focus-visible { color: var(--rot); border-bottom-color: currentColor; }

.anfrage-weg-terratec { font-size: var(--t-2xs); }
.anfrage-weg-terratec a { font-size: inherit; font-weight: 400; border-bottom-color: var(--linie); min-height: 0; }

@media (max-width: 900px) {
  .anfrage-kopf { padding-block: 20px 32px; }

  /* Eine Spalte, in der Reihenfolge des Quelltexts: Text, Formular, Wege.
     Die Wege rutschen damit unter das Formular, weil der Daumen sie dort
     sucht, nachdem er das Formular gesehen hat. */
  .anfrage-raster { grid-template-columns: minmax(0, 1fr); row-gap: 22px; }
  .anfrage-text,
  .anfrage-karte,
  .anfrage-wege { grid-column: 1; grid-row: auto; }

  .anfrage-vorspann { margin-top: 14px; font-size: 16px; }
  .anfrage-karte.contact-form { gap: 18px; }
  .anfrage-weg > a { min-height: 44px; line-height: 44px; }
}

/* Die vier Fachfragen auf der Dankeseite. Sie tragen, was frueher vier
   Formularfelder waren, deshalb duerfen sie Luft haben. */
.danke-liste { margin: 0 0 26px; padding-left: 1.2em; }
.danke-liste li { margin-bottom: 12px; line-height: 1.6; }
.danke-liste strong { font-weight: 600; }

/* ============================================================
   Ansprechpartner auf der Kontaktseite
   ============================================================
   Ueberschrift und Anschrift links, die beiden Personen rechts
   nebeneinander. Vorher trug das Raster zwei gleich breite Spalten aus
   der Zeit, als rechts das Formular stand: seit dessen Umzug in den
   Seitenkopf war die rechte Haelfte leer und die Karten standen schmal
   untereinander. */
.personen-vorspann {
  margin: 14px 0 0;
  font-size: 17px;
  font-weight: 300;
  line-height: 1.55;
  max-width: 24em;
}

.personen-raster {
  display: grid;
  grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
  gap: clamp(40px, 6vw, 96px);
  align-items: start;
}

/* Kein fester Umbruch in der Ueberschrift: die Spalte ist schmaler als der
   dunkle Abschnitt frueher, ein <br> nach "bei" haette daraus drei Zeilen
   gemacht. text-wrap: balance verteilt sie gleichmaessig, egal wie breit
   die Spalte am Ende ist. */
.personen-text h2 {
  margin: 14px 0 0;
  text-wrap: balance;
  max-width: 9em;
}

.personen-adresse {
  margin-top: 28px;
  font-style: normal;
  font-size: var(--t-sm);
  font-weight: 300;
  line-height: 1.7;
  color: var(--grau-hell);
}

.personen-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 24px;
}

/* Achtung, Klassenname geteilt: .person heisst auch die Teamkarte der
   Startseite (.people .person). Sie erbt Grund, Rahmen und Foto von hier,
   ihre Schriftfarben stehen weiter unten bei .people .person. */
/* Die Karte steht als Block, nicht als Zeile mit Bild daneben: so tragen
   beide Personen dieselbe Hoehe, egal wie lang ihre Rolle heisst, und das
   Bild bekommt Platz genug, um ein Gesicht zu sein statt eines Symbols. */
.person {
  background: var(--anthrazit-2);
  border: 1px solid var(--linie-dunkel);
  border-top: 3px solid var(--rot);
  border-radius: var(--radius);
  padding: 28px 26px 26px;
  display: grid;
  align-content: start;
  gap: 0;
}

/* 168 px seit 13.10.2026 (Wunsch Arno, vorher 112): dieselbe Groesse wie im
   Team auf der Startseite, das schon so gross war. Mobil 138 statt 92. */
.person img {
  width: 168px;
  height: 168px;
  object-fit: cover;
  border-radius: 50%;
  margin-bottom: 20px;
}

.person-name {
  margin: 0;
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--text-invert);
}

.person-rolle {
  margin: 2px 0 0;
  font-size: var(--t-2xs);
  color: var(--grau-hell);
}

/* Wofuer die Person zustaendig ist. Stand vorher nirgends: wer eine
   Bewerbung schicken will, musste raten, welche der beiden Adressen die
   richtige ist. */
.person-fach {
  margin: 14px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--linie-dunkel);
  font-size: var(--t-2xs);
  font-weight: 300;
  line-height: 1.55;
  color: var(--grau-hell);
}

.person-wege {
  margin: 16px 0 0;
  display: grid;
  gap: 6px;
}

.person-wege a {
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--text-invert);
  text-decoration: none;
  border-bottom: 1px solid var(--linie-dunkel);
  justify-self: start;
  padding-block: 3px;
}

.person-wege a:hover,
.person-wege a:focus-visible { color: var(--rot-hell); border-bottom-color: currentColor; }

@media (max-width: 900px) {
  .personen-raster { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .personen-liste { gap: 18px; }
  .person { padding: 24px 22px; }
  .person img { width: 138px; height: 138px; margin-bottom: 16px; }
  /* Am Handy sind Telefon und Mail Tippziele, nicht nur Links. */
  .person-wege a { padding-block: 10px; }
}

/* Team auf der Startseite (.people). Seit dem 11.09. heisst der
   Ansprechpartner-Baustein der Kontaktseite ebenfalls .person, er steht hier
   darueber und hat der Startseite dunkle Karten und runde Fotos vererbt. Die
   Schrift kam aber weiter aus den alten, hellen Startseiten-Regeln: dunkel auf
   dunkel, gemessen Name 1,0:1, Rolle 2,6:1, also unsichtbar.

   Deshalb hier helle Schrift, mit denselben Farben wie die Kontaktkarten. Der
   Grund steht ausdruecklich mit dabei: Wird der Kontaktbaustein einmal
   umbenannt, stuende sonst weisse Schrift auf hellem Grund. Kontraste auf
   --anthrazit-2: Name 13,4:1, Rolle 4,87:1. Die Rolle bekommt Gewicht 400
   statt 300, feine Striche verlieren auf dunklem Grund zuerst. */
.people .person { background: var(--anthrazit-2); }
.people .person strong { color: var(--text-invert); }
.people .person span { color: var(--grau-hell); font-weight: 400; }
.people .person span a { color: var(--text-invert); }
.people .person span a:hover,
.people .person span a:focus-visible { color: var(--rot-hell); }

/* Kopf der Formularkarte. Er sagt, wohin das Formular fuehrt, und benennt
   es fuer Vorleseprogramme (aria-labelledby). */
.anfrage-titel {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 21px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--text);
}

.anfrage-dauer {
  margin: 4px 0 2px;
  font-size: var(--t-2xs);
  font-weight: 300;
  color: var(--grau);
}

/* Die Eingaben stehen auf Weiss im Papier der Karte. Der Rahmen war fuer
   den dunklen Abschnitt gedacht, in dem das Formular frueher sass: auf
   Papier wirkt 1,5 px Grau wie ein Kasten um jedes Feld. Jetzt traegt die
   Flaeche den Unterschied und der Rahmen nur noch die Kante. */
.anfrage-karte .feld input,
.anfrage-karte .feld textarea {
  border-color: var(--linie);
  padding: 13px 14px;
}

.anfrage-karte .feld input:hover,
.anfrage-karte .feld textarea:hover { border-color: var(--grau-hell); }

/* Der Fokus ist zwei Dinge zugleich: der rote Rahmen zeigt, wo man tippt,
   der Schein hebt das Feld aus der Karte. Ohne den Schein verschwindet der
   Rahmen auf Papier fast. */
.anfrage-karte .feld input:focus,
.anfrage-karte .feld textarea:focus {
  border-color: var(--rot);
  box-shadow: 0 0 0 3px rgba(212, 42, 34, 0.12);
  outline: none;
}

.anfrage-karte .feld label {
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* Der Knopf traegt die Farbe des Hauses und die volle Breite der Karte:
   er ist das Ziel dieser Seite, nicht eine Schaltflaeche unter anderen. */
.anfrage-karte .btn {
  width: 100%;
  padding-block: 15px;
  font-size: var(--t-sm);
  letter-spacing: 0.01em;
}

/* Das Textfeld trug eine Mindesthoehe von 140 px aus der Zeit, als es sechs
   Zeilen hatte und im dunklen Abschnitt stand. Mit rows="2" wirkt sie wie
   eine leere Flaeche, die zum langen Schreiben auffordert, und schiebt den
   Absendeknopf unter die Falzkante. Wer mehr schreiben will, zieht auf:
   resize bleibt. */
.anfrage-karte .feld textarea { min-height: 0; }

/* ============================================================
   Recruitingfilm auf /karriere/
   ============================================================
   Anders als der Kopffilm auf der Startseite laeuft dieser Film nicht von
   selbst: er hat Ton und eine Aussage, und niemand soll ihn ungefragt
   serviert bekommen. Deshalb die Bedienleiste des Browsers statt eigener
   Knoepfe, und deshalb laedt vor dem ersten Druck nur das Standbild. */

.film-grid {
  display: grid;
  /* 1,5 zu 1: der Film fuehrt, der Text bleibt aber lesbar. Bei 1,4 zu 0,6
     stand die Textspalte auf 326 px, das sind rund 40 Zeichen je Zeile und
     damit unter dem Band, in dem sich Fliesstext bequem liest. Gemessen
     bei 1440 px am 10.09.2026. */
  grid-template-columns: minmax(0, 1.5fr) minmax(280px, 1fr);
  gap: clamp(32px, 4.5vw, 76px);
  align-items: center;
  /* 1780 px wie der Rahmen der Seite. Bis 13.10.2026 stand hier 1280, damit
     blieben dem Film bei 1920 bis 2000 px Fensterbreite rund 620 px, Arno
     wollte ihn 50 Prozent groesser: jetzt rund 920 px. Unter 1440 px greift
     der Deckel nicht, dort fuellt das Raster ohnehin die Breite.
     Die 1780 px schliessen den Rand von .wrap ein, und --pad waechst ab
     rund 1956 px Fensterbreite mit. Ohne die Grenze unten blieben bei 2557 px
     kaum 1600 px fuer Film und Text. Hier endet der Rand bei 88 px. */
  max-width: 1780px;
  margin-inline: auto;
  padding-inline: min(var(--pad), 88px);
}

/* Die Buehne haelt das Seitenverhaeltnis frei, bevor Standbild oder Film da
   sind. Ohne sie springt das Layout beim Laden, und genau dieser Sprung
   zaehlt in den Core Web Vitals als Layout Shift. */
.film-buehne {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--anthrazit-tief);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.32);
}

.film-video {
  width: 100%;
  height: 100%;
  /* contain statt cover: Film und Buehne sind beide 16:9, aber bei krummen
     Fensterbreiten rundet der Browser die Buehne auf einen halben Pixel.
     cover schnitte dann eine Zeile ab, contain laesst sie stehen. */
  object-fit: contain;
  background: var(--anthrazit-tief);
}

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

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

/* Laufzeit und Ton vor dem Druck: wer im Grossraum sitzt oder im Zug, will
   das vorher wissen und nicht erst, wenn es aus dem Lautsprecher kommt. */
.film-daten {
  margin-top: 14px;
  font-size: var(--t-2xs);
  letter-spacing: var(--versal-eng);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--grau-invert);
}

.film-ohne-video {
  padding: 24px;
  color: var(--text-invert);
  font-size: var(--t-sm);
}

.film-ohne-video a { color: var(--rot-hell); }

/* Unter 900 px steht der Film ueber dem Text, wie bei der Feldnotiz. */
@media (max-width: 900px) {
  .film-grid {
    grid-template-columns: 1fr;
    gap: 28px;
    max-width: 620px;
  }
}

/* ---------- Bildreihe auf den Stellenseiten ----------
   Drei Fotos nebeneinander ueber die volle Breite, alle im selben Format.
   Vorher stand hier ein einzelnes Standbild als Vollbreitenband (seit
   13.10.2026 ersetzt, Wunsch Arno). Die doppelte Klasse schlaegt die
   Formatregeln img[data-format=...], die sonst das Seitenverhaeltnis setzen. */
.bild-reihe {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(4px, 0.5vw, 8px);
}

.bild-reihe .bild-reihe-item { margin: 0; overflow: hidden; background: var(--anthrazit); }

.bild-reihe .bild-reihe-item img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Auf dem Handy waeren drei Querformate je 125 x 94 px gross. Hochkant
   zugeschnitten bleiben die Personen erkennbar, die Reihe bleibt eine Reihe. */
@media (max-width: 700px) {
  .bild-reihe .bild-reihe-item img { aspect-ratio: 3 / 4; }
}

/* ---------- Projekte auf den Leistungsseiten ----------
   Fotokarten statt Linkzeile (seit 13.10.2026). Dieselben Karten wie in der
   Referenzuebersicht, das Raster aber nach Anzahl: drei Spalten ab drei
   Projekten, zwei nebeneinander, ein einzelnes als breite Karte mit Bild
   links. Die Linie oben trennt den Abschnitt vom weissen Fliesstext davor.
   Die doppelten Klassen schlagen die Spaltenregeln von .ref-grid-wide, auch
   in deren Medienabfragen. */
.leistung-projekte { border-top: 1px solid var(--linie); }

.ref-grid-wide.projekt-raster-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ref-grid-wide.projekt-raster-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ref-grid-wide.projekt-raster-1 { grid-template-columns: minmax(0, 1fr); }

.projekt-raster-1 .ref-card { flex-direction: row; }

.projekt-raster-1 .ref-card-media {
  flex: 0 0 56%;
  border-bottom: 0;
  border-right: 1px solid var(--linie);
}

.projekt-raster-1 .ref-card-body {
  justify-content: center;
  padding: clamp(28px, 3.5vw, 56px);
}

.projekt-raster-1 .ref-card h3 { font-size: clamp(24px, 2vw, 32px); }

@media (max-width: 860px) {
  .ref-grid-wide.projekt-raster-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .projekt-raster-1 .ref-card { flex-direction: column; }
  .projekt-raster-1 .ref-card-media {
    flex: none;
    border-right: 0;
    border-bottom: 1px solid var(--linie);
  }
}

@media (max-width: 600px) {
  .ref-grid-wide.projekt-raster-3,
  .ref-grid-wide.projekt-raster-2 { grid-template-columns: minmax(0, 1fr); }
}
