/* Neckler & Koch Bau – Stylesheet
   Aufbau: 1 Tokens · 2 Grundlagen · 3 Kopf & Navigation · 4 Hero
   5 Leistungen · 6 Ueber uns · 7 Ablauf · 8 Anfrage · 9 Anfahrt
   10 Fuss & Werkzeuge · 11 3D-Ebene · 12 Bewegung & Responsive */

/* ---------- 0. Schrift (lokal, keine Verbindung zu Google) ---------- */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- 1. Tokens ---------- */
:root {
  --ink: #17191f;
  --charcoal: #25272c;
  --muted: #667085;
  --paper: #f7f7f5;
  --white: #ffffff;
  --line: #e7e2dc;
  --red: #ba1f32;
  --red-dark: #8f1726;
  --shadow-sm: 0 2px 10px rgba(23, 25, 31, .06);
  --shadow: 0 24px 70px rgba(23, 25, 31, .14);
  --radius: 14px;
  --font: "Inter", "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* ---------- 2. Grundlagen ---------- */
* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  min-width: 320px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }
img, svg { max-width: 100%; }

h1, h2, h3 { line-height: 1.1; letter-spacing: -.02em; font-weight: 800; }
h1 { font-size: clamp(2.4rem, 6vw, 4.3rem); }
h2 { font-size: clamp(1.75rem, 3.6vw, 2.75rem); }
h3 { font-size: 1.2rem; letter-spacing: -.01em; }

.section-inner,
.topbar-inner,
.nav-inner,
.footer-inner { width: min(1200px, calc(100% - 40px)); margin: 0 auto; }

section { padding: clamp(72px, 10vw, 128px) 0; position: relative; }

.eyebrow {
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .78rem;
  font-weight: 700;
  color: var(--red);
  margin-bottom: 14px;
}

.section-head { max-width: 780px; margin-bottom: clamp(40px, 6vw, 64px); }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head h2 + .lead { margin-top: 18px; color: var(--muted); font-size: 1.08rem; }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: #fff;
  padding: 12px 18px;
}
.skip-link:focus { left: 12px; top: 12px; }

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

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 15px 28px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
  font: inherit;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: transform .25s var(--ease), background-color .25s var(--ease), box-shadow .25s var(--ease);
}
.button:hover { background: var(--red-dark); transform: translateY(-2px); box-shadow: 0 14px 30px rgba(186, 31, 50, .28); }
.button.secondary { background: transparent; border-color: currentColor; color: inherit; }
.button.secondary:hover { background: rgba(255, 255, 255, .1); box-shadow: none; }
.button.full { width: 100%; }

/* ---------- 3. Kopf & Navigation ---------- */
.topbar {
  /* Positioniert, damit der Hintergrund-Canvas (fixiert, z-index 0) die
     Leiste nicht ueberdeckt. Ohne diese Zeilen verschwinden Telefonnummer
     und E-Mail hinter der Planzeichnung. */
  position: relative;
  z-index: 1;
  background: var(--charcoal);
  color: rgba(255, 255, 255, .86);
  font-size: .92rem;
}
.topbar-inner { display: flex; justify-content: space-between; gap: 18px; padding: 9px 0; flex-wrap: wrap; }
.topbar a { text-decoration: none; }
.topbar a:hover { color: #fff; text-decoration: underline; }

header {
  position: sticky;
  top: 0;
  z-index: 40;
  /* Bewusst deckend statt mit backdrop-filter: Ein unscharfer Hintergrund
     legt die Kopfzeile in eine eigene Compositing-Ebene, wodurch der
     WebGL-Canvas das aufgeklappte Menue ueberdecken kann. */
  background: rgba(255, 255, 255, .97);
  border-bottom: 1px solid rgba(23, 25, 31, .08);
  transition: box-shadow .3s var(--ease);
}
header.is-compact { box-shadow: var(--shadow-sm); }

/* Die Hoehe der Kopfzeile bleibt beim Scrollen konstant. Wuerde sie sich
   aendern, verschoebe sich der gesamte Inhalt darunter -- die Kopfzeile
   klebt zwar oben, steht aber weiterhin im Textfluss. Firefox hat dieses
   Rucken als wiederholte Scroll-Korrektur gemeldet. Das Zusammenschieben
   passiert deshalb nur noch optisch ueber transform. */
.nav-inner { display: flex; align-items: center; justify-content: space-between; gap: 28px; padding: 14px 0; }

.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; min-width: 0; font-weight: 800; }
.brand img {
  width: 118px; height: 54px; object-fit: contain;
  transform-origin: left center;
  transition: transform .3s var(--ease);
}
/* Skalieren statt Groesse aendern: veraendert nur das Bild, nicht das Layout. */
header.is-compact .brand img { transform: scale(.84); }
.brand span { font-size: .95rem; line-height: 1.2; }

nav { display: flex; align-items: center; gap: 26px; font-weight: 600; }
nav a { text-decoration: none; position: relative; padding: 6px 0; }
nav a:not(.nav-cta)::after {
  content: "";
  position: absolute;
  left: 0; right: 100%; bottom: 0;
  height: 2px;
  background: var(--red);
  transition: right .3s var(--ease);
}
nav a:not(.nav-cta):hover::after { right: 0; }
.nav-cta { background: var(--ink); color: #fff; padding: 11px 20px; border-radius: 999px; }
.nav-cta:hover { background: var(--red); }

.nav-toggle {
  display: none;
  width: 46px; height: 46px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #fff;
  cursor: pointer;
  position: relative;
}
.nav-toggle span,
.nav-toggle::before,
.nav-toggle::after {
  content: "";
  position: absolute;
  left: 13px; right: 13px;
  height: 2px;
  background: var(--ink);
  transition: transform .3s var(--ease), opacity .2s var(--ease);
}
.nav-toggle span { top: 22px; }
.nav-toggle::before { top: 15px; }
.nav-toggle::after { top: 29px; }
.nav-toggle[aria-expanded="true"] span { opacity: 0; }
.nav-toggle[aria-expanded="true"]::before { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"]::after { transform: translateY(-7px) rotate(-45deg); }

/* ---------- 4. Hero ---------- */
.hero {
  background: radial-gradient(120% 90% at 78% 12%, #32353d 0%, #1d1f25 48%, #15171c 100%);
  color: #fff;
  overflow: hidden;
  padding-top: clamp(56px, 8vw, 96px);
  padding-bottom: clamp(56px, 8vw, 96px);
}
.hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 140px;
  background: linear-gradient(to bottom, rgba(247, 247, 245, 0), var(--paper));
  pointer-events: none;
}
.hero .eyebrow { color: #e2606f; }
.hero-grid {
  --hero-gap: clamp(32px, 5vw, 64px);
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: var(--hero-gap);
  align-items: center;
}
.hero-copy p.hero-text { margin-top: 20px; font-size: 1.1rem; color: rgba(255, 255, 255, .78); max-width: 52ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }

.hero-stage {
  position: relative;
  width: 100%;
  max-width: 340px;
  /* Zentriert in der eigenen Spalte reicht nicht: Der Zwischenraum
     zwischen den Grid-Spalten zaehlt nur zur linken Seite mit, nicht zur
     rechten. Ohne diesen Ausgleich haengt die Box sichtbar zu weit rechts.
     Bewusst ueber die Raender statt per transform ausgeglichen: Dieselbe
     Box traegt auch die "reveal"-Klasse fuer die Einblendanimation, die
     ebenfalls transform setzt und mit hoeherer Spezifitaet gewonnen haette. */
  margin-left: calc(50% - 170px - (var(--hero-gap, 0px) / 2));
  margin-right: calc(50% - 170px + (var(--hero-gap, 0px) / 2));
  aspect-ratio: 1 / 1;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, .12);
  background: linear-gradient(160deg, rgba(255, 255, 255, .07), rgba(255, 255, 255, .01));
  overflow: hidden;
  /* Ueber den WebGL-Canvas (z-index 2) heben, damit die Eckwinkel unten
     nicht von der 3D-Ebene uebermalt werden. Der Canvas bleibt trotzdem
     sichtbar: Er zeichnet in genau diesen Ausschnitt hinein, und die Box
     selbst hat ausser dem Rahmen keinen deckenden Inhalt. */
  z-index: 3;
}
/* Die runden Ecken der Animation entstehen nicht hier, sondern in der Szene
   selbst (assets/js/scenes/hero.js): Der gemeinsame WebGL-Canvas zeichnet
   jeden Ausschnitt rechteckig, deshalb radiert die Szene ihre eigenen vier
   Ecken zum Schluss durchsichtig. Ein Nachmalen an dieser Stelle waere zum
   Scheitern verurteilt -- der Hero liegt auf einem Verlauf, die vier Ecken
   braeuchten vier verschiedene Farben, und die verschieben sich mit jeder
   Fenstergroesse. */

/* Vier Eckwinkel wie bei einer Werkzeichnung -- derselbe rote Akzent wie
   die Massketten im Hintergrundplan, aber direkt an der Box selbst statt
   im fest zum Bildschirm positionierten Plan. So wandert der Rahmen immer
   exakt mit der Box mit, auch beim Scrollen. Nach innen statt ueber den
   Rand hinaus gesetzt, damit "overflow: hidden" oben sie nicht abschneidet. */
.hero-stage::before {
  content: "";
  position: absolute;
  inset: 10px;
  pointer-events: none;
  /* Der WebGL-Canvas liegt fest ueber der ganzen Seite (z-index 2) und
     wuerde die Eckwinkel sonst uebermalen. Ein eigener Stapelkontext auf
     der Box hebt sie darueber. */
  z-index: 3;
  background-image:
    linear-gradient(to right, rgba(226, 96, 111, .65) 2px, transparent 2px),
    linear-gradient(to bottom, rgba(226, 96, 111, .65) 2px, transparent 2px),
    linear-gradient(to left, rgba(226, 96, 111, .65) 2px, transparent 2px),
    linear-gradient(to bottom, rgba(226, 96, 111, .65) 2px, transparent 2px),
    linear-gradient(to right, rgba(226, 96, 111, .65) 2px, transparent 2px),
    linear-gradient(to top, rgba(226, 96, 111, .65) 2px, transparent 2px),
    linear-gradient(to left, rgba(226, 96, 111, .65) 2px, transparent 2px),
    linear-gradient(to top, rgba(226, 96, 111, .65) 2px, transparent 2px);
  background-repeat: no-repeat;
  background-size: 22px 22px;
  background-position: top left, top left, top right, top right, bottom left, bottom left, bottom right, bottom right;
}
.hero-stage .stage-fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 12%;
}
/* Kein Filter mehr: Das Fallback-Bild ist das echte, farbige Firmenlogo
   (undurchsichtiges PNG). Der alte Filter war fuer ein weisses Linien-Icon
   gedacht und machte aus dem Logo ohne WebGL nur noch eine einfarbige
   Flaeche. */
.hero-stage .stage-fallback img { background: #fff; border-radius: 8px; padding: 6%; }

.facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin-top: clamp(40px, 6vw, 64px);
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 16px;
  overflow: hidden;
}
.facts p {
  background: rgba(23, 25, 31, .55);
  padding: 22px 24px;
  margin: 0;
  font-size: .98rem;
  color: rgba(255, 255, 255, .82);
}
.facts strong {
  display: block;
  font-size: .74rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #e2606f;
  margin-bottom: 6px;
}
.facts a { text-decoration: none; }
.facts a:hover { text-decoration: underline; }

/* ---------- 5. Leistungen ---------- */
.services-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 24px;
}
.service {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
}
.service:hover { transform: translateY(-6px); box-shadow: var(--shadow); border-color: rgba(186, 31, 50, .3); }
.service-media {
  order: -1;
  position: relative;
  aspect-ratio: 16 / 10;
  background: linear-gradient(150deg, #eceae6, #f7f7f5);
  border-bottom: 1px solid var(--line);
}
.service-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; padding: 8%; }
.service-media img.is-missing { display: none; }
.service-body { padding: 24px 26px 28px; }
.service-body p { margin-top: 10px; color: var(--muted); }

/* ---------- 6. Ueber uns ---------- */
.about-band { background: var(--ink); color: #fff; }
.about-layout {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: clamp(32px, 5vw, 64px);
  align-items: center;
}
.about-panel {
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--radius);
  padding: clamp(28px, 4vw, 44px);
  text-align: center;
}
.about-panel img { width: 200px; height: auto; margin-bottom: 20px; }
.about-panel strong { display: block; font-size: 1.15rem; line-height: 1.4; color: rgba(255, 255, 255, .9); }
.about-copy p { margin-top: 16px; color: rgba(255, 255, 255, .78); }
.about-copy .eyebrow { color: #e2606f; }
.stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin-top: 36px; }
.stat strong { display: block; font-size: 2.4rem; font-weight: 800; color: #fff; line-height: 1; }
.stat span { color: rgba(255, 255, 255, .66); font-size: .92rem; }

/* ---------- 7. Ablauf ---------- */
.process-stage {
  position: relative;
  height: clamp(180px, 24vw, 280px);
  margin-bottom: 32px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: linear-gradient(150deg, #eceae6, #f7f7f5);
  overflow: hidden;
}
.process-stage .stage-fallback { position: absolute; inset: 0; display: grid; place-items: center; opacity: .55; color: var(--muted); }

/* Beschriftung ueber den Pfeilern der Ablauf-Szene. Position und Deckkraft
   setzt process.js pro Bild; hier steht nur das Aussehen. Bewusst wie eine
   Anmerkung in einer Werkzeichnung: gesperrte Versalien mit feinem
   Anschlussstrich nach unten zum Pfeiler. */
.stage-label {
  position: absolute;
  top: 0;
  left: 0;
  padding-bottom: 13px;
  pointer-events: none;
  white-space: nowrap;
  font-size: .66rem;
  font-weight: 800;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--text, var(--ink));
  opacity: 0;
  transition: opacity .35s var(--ease);
  will-change: transform;
}
.stage-label::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 1px;
  height: 11px;
  background: currentColor;
  opacity: .45;
}
@media (max-width: 700px) {
  /* Auf schmalen Buehnen wuerden vier Schilder uebereinanderfallen -- die
     Ueberschriften stehen ohnehin gleich darunter in den Kaesten. */
  .stage-label { display: none; }
}
.process { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 24px; counter-reset: step; }
.step {
  counter-increment: step;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px 24px;
  position: relative;
}
.step::before {
  content: counter(step);
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--red);
  color: #fff;
  font-weight: 800;
  margin-bottom: 16px;
}
.step p { margin-top: 8px; color: var(--muted); }

/* ---------- 7b. FAQ ---------- */
/* <details>/<summary> statt eigenem Auf-und-zu-Skript: funktioniert ohne
   JavaScript, ist von Haus aus per Tastatur bedienbar und Screenreader
   kuendigen den Zustand "geoeffnet/geschlossen" von selbst an. */
.faq-list { display: grid; gap: 14px; max-width: 780px; margin: 0 auto; }
.faq-item {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 4px 24px;
}
.faq-item summary {
  list-style: none;
  cursor: pointer;
  padding: 20px 32px 20px 0;
  position: relative;
  font-weight: 700;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  position: absolute;
  right: 0; top: 50%;
  transform: translateY(-50%);
  font-size: 1.3rem;
  font-weight: 400;
  color: var(--red);
  transition: transform .25s var(--ease);
}
.faq-item[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.faq-item p { margin: -4px 0 20px; color: var(--muted); }

/* ---------- 8. Anfrage ---------- */
.contact-section { background: var(--charcoal); color: #fff; }
.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}
.contact-card .eyebrow { color: #e2606f; }
.contact-card > p { margin-top: 14px; color: rgba(255, 255, 255, .78); }
.contact-list { margin-top: 30px; display: grid; gap: 18px; }
.contact-list p { display: grid; gap: 4px; }
.contact-list strong { font-size: .74rem; letter-spacing: .16em; text-transform: uppercase; color: rgba(255, 255, 255, .55); }
.contact-list a { text-decoration: none; }
.contact-list a:hover { text-decoration: underline; }

form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  background: var(--white);
  color: var(--ink);
  border-radius: var(--radius);
  padding: clamp(24px, 4vw, 40px);
  box-shadow: var(--shadow);
  position: relative;
}
form label { display: grid; gap: 8px; font-weight: 600; font-size: .95rem; }
form .full { grid-column: 1 / -1; }
input, select, textarea {
  font: inherit;
  color: inherit;
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
  width: 100%;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
input:focus, select:focus, textarea:focus {
  border-color: var(--red);
  box-shadow: 0 0 0 3px rgba(186, 31, 50, .14);
  outline: none;
}
input[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--red); background: #fdf4f5; }
textarea { min-height: 150px; resize: vertical; }
.field-error { color: var(--red-dark); font-size: .85rem; font-weight: 600; }
.form-note { font-size: .85rem; color: var(--muted); line-height: 1.55; }
.form-status { padding: 14px 16px; border-radius: 10px; font-weight: 600; }
.form-status.success { background: #edf7ee; color: #1c6b2c; border: 1px solid #bfe3c5; }
.form-status.error { background: #fdf1f2; color: var(--red-dark); border: 1px solid #f0c7cc; }
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------- 9. Anfahrt ----------
   Untereinander statt nebeneinander: Der Standort laeuft ueber die volle
   Breite, darunter stehen die drei Kontaktangaben in einer Reihe auf
   gleicher Grundlinie, zuletzt die Karten-Freigabe. Nebeneinander gestellt
   waren Karte und Angaben unterschiedlich hoch und wirkten unsortiert. */
.map-stage {
  position: relative;
  aspect-ratio: 21 / 9;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: linear-gradient(150deg, #ecebe7, #f9f9f7);
  overflow: hidden;
}
.map-stage .stage-fallback { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; padding: 24px; color: var(--muted); }

.map-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 40px);
  margin-top: 32px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}
.address-card { display: grid; gap: 6px; align-content: start; }
.address-card strong { font-size: .74rem; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }

/* Die Freigabe liegt ueber der 3D-Szene statt einen eigenen Block
   darunter zu belegen – die grosse Standortflaeche bleibt dadurch gross.
   Der Rahmen selbst blockiert keine Klicks (pointer-events: none), nur
   die Karte darin ist bedienbar. Nach dem Laden ersetzt das Skript den
   Inhalt durch das iframe, das dann die ganze Flaeche ausfuellt. */
.map-box {
  position: absolute;
  inset: 0;
  z-index: 3;
  padding: clamp(16px, 3vw, 28px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  pointer-events: none;
}
.map-box > * { pointer-events: auto; }
.map-box iframe { width: 100%; height: 100%; border: 0; display: block; }
.map-consent {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  width: min(620px, 100%);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px 22px;
  box-shadow: var(--shadow);
}
.map-consent p { color: var(--muted); font-size: .92rem; margin: 0; max-width: 62ch; }
.map-consent .button { flex-shrink: 0; }

/* ---------- 10. Fuss & Werkzeuge ---------- */
footer { background: var(--ink); color: rgba(255, 255, 255, .72); padding: 34px 0; position: relative; z-index: 3; }
.footer-inner { display: flex; justify-content: space-between; gap: 18px; flex-wrap: wrap; font-size: .92rem; }
footer a { text-decoration: none; }
footer a:hover { color: #fff; text-decoration: underline; }

.tools-float {
  position: fixed;
  right: 18px; bottom: 18px;
  z-index: 45;
  display: grid;
  gap: 10px;
  justify-items: end;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}
/* Ausgeblendet statt nur verschoben, sobald der Fuss sichtbar wird –
   sonst liegen die Schaltflaechen weiterhin ueber Widerruf/Cookies und
   lassen sich auf Tablets nicht mehr antippen. pointer-events:none nimmt
   sie zusaetzlich ganz aus der Klickreihenfolge. */
.tools-float.footer-visible {
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
}
.tool-button {
  font: inherit;
  font-weight: 600;
  font-size: .9rem;
  padding: 10px 16px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .96);
  color: var(--ink);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.tool-button:hover { border-color: var(--red); color: var(--red); }
#back-to-top { display: none; }
.translate-panel {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px;
  display: grid;
  gap: 8px;
  box-shadow: var(--shadow);
  width: 230px;
}
.translate-panel small { color: var(--muted); }

.mobile-cta {
  display: none;
  position: fixed;
  left: 12px; right: 12px; bottom: 12px;
  z-index: 44;
  gap: 10px;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}
.mobile-cta .button { flex: 1; padding: 14px 12px; font-size: .95rem; }
.mobile-cta .button.secondary { background: var(--white); color: var(--ink); border-color: var(--line); }
/* Dieselbe Regel wie bei .tools-float: am Seitenende verschwindet die
   Leiste komplett, sonst liegt sie ueber den Fusszeilen-Links. */
.mobile-cta.footer-visible {
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
}

/* ---------- 11. 3D-Ebene ---------- */
#gl-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
}
/* Sobald WebGL laeuft, weichen die statischen Platzhalter der 3D-Ebene. */
.webgl .stage-fallback,
.webgl .service-media img { opacity: 0; transition: opacity .6s var(--ease); }
.webgl .hero-stage,
.webgl .process-stage,
.webgl .map-stage { background-image: none; }
.webgl .service-media { background: linear-gradient(150deg, #f2f1ee, #fafaf9); }

/* ---------- 12. Bewegung & Responsive ---------- */
.reveal { opacity: 0; transform: translateY(26px); }
.js .reveal { transition: opacity .7s var(--ease), transform .7s var(--ease); }
.reveal.is-visible { opacity: 1; transform: none; }
.reveal-delay-1 { transition-delay: .08s; }
.reveal-delay-2 { transition-delay: .16s; }
.reveal-delay-3 { transition-delay: .24s; }

@media (max-width: 980px) {
  .hero-grid, .about-layout, .contact-layout { grid-template-columns: minmax(0, 1fr); }
  .map-stage { aspect-ratio: 16 / 10; }
  /* Im gestapelten Layout gibt es keine Nachbarspalte mehr, deren
     Zwischenraum auszugleichen waere. */
  .hero-stage { aspect-ratio: 4 / 3; order: -1; width: 100%; max-width: 380px; margin: 0 auto; transform: none; }
  .about-panel { order: -1; }
}

@media (max-width: 860px) {
  .nav-toggle { display: block; }
  nav {
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: #fff;
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow);
    padding: 8px 20px 20px;
    display: none;
  }
  nav.is-open { display: flex; }
  nav a { padding: 14px 0; border-bottom: 1px solid var(--line); }
  nav a:not(.nav-cta)::after { display: none; }
  .nav-cta { border-bottom: 0; margin-top: 14px; text-align: center; }
  .facts { grid-template-columns: minmax(0, 1fr); }
  .mobile-cta { display: flex; }
  .tools-float { bottom: 82px; }
  body { padding-bottom: 76px; }
  form { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 700px) {
  .map-facts { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .map-stage { aspect-ratio: 4 / 3; }
}

@media (max-width: 560px) {
  .topbar-inner { font-size: .84rem; }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .brand span { display: none; }
}

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

/* [hidden] muss staerker sein als die Layout-Regeln oben. */
[hidden] { display: none !important; }

/* ---------- 13. Werkstatt hinter der ganzen Seite ----------
   Das Panorama liegt fest hinter allen Abschnitten. Damit Text darauf
   lesbar bleibt, dreht das Farbschema auf dunkel: helle Schrift, und die
   weissen Karten werden zu durchscheinenden Paneelen. Bewusst als ein
   zusammenhaengender Block am Ende – wer den hellen Zustand zurueck will,
   loescht genau diesen Abschnitt.
   Kein backdrop-filter: Der legt Elemente in eigene Compositing-Ebenen,
   wodurch der WebGL-Canvas sie ueberdecken kann (siehe Kopfzeile oben). */
:root {
  --panel: rgba(20, 22, 27, .74);
  --panel-solid: rgba(20, 22, 27, .94);
  --panel-line: rgba(255, 255, 255, .13);
  --text: #eceef2;
  --text-muted: #a7b0bd;
  --accent: #e2606f;
}

body {
  /* Der Hintergrund ist ein Canvas, das backdrop.js zeichnet. Ohne
     JavaScript bleibt dieser Verlauf stehen -- nie eine leere Flaeche. */
  background: linear-gradient(#12151c, #0d0f14 55%, #08090c);
  color: var(--text);
}

#backdrop {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

h1, h2, h3 { color: var(--text); }
.eyebrow, .hero .eyebrow, .about-copy .eyebrow, .contact-card .eyebrow { color: var(--accent); }
.section-head .lead,
.service-body p,
.step p,
.faq-item p,
.form-note,
.map-consent p,
.address-card p,
.address-card strong { color: var(--text-muted); }

/* Kopfzeile und Fusszeile */
/* Deckend, nicht durchscheinend: Die Kopfzeile bleibt beim Scrollen
   stehen, und bei 90 % Deckkraft lief der Seiteninhalt sichtbar durch sie
   hindurch. Ein Weichzeichner ist keine Option -- der legt die Kopfzeile
   in eine eigene Compositing-Ebene, wodurch der WebGL-Canvas das
   aufgeklappte Menue ueberdeckt (siehe Kommentar weiter oben). */
.topbar { background: #0c0e12; }
header { background: #0f1116; border-bottom-color: var(--panel-line); }
nav a { color: var(--text); }
.nav-toggle { background: var(--panel-solid); border-color: var(--panel-line); }
.nav-toggle span,
.nav-toggle::before,
.nav-toggle::after { background: var(--text); }
footer { background: rgba(10, 11, 14, .9); }

/* Abschnitte: alle nur noch angedunkelt, nie deckend */
.hero {
  background: radial-gradient(120% 90% at 78% 12%,
    rgba(52, 56, 66, .68) 0%, rgba(22, 24, 30, .76) 48%, rgba(14, 16, 21, .84) 100%);
}
.hero::after { display: none; }
.about-band { background: rgba(14, 16, 20, .8); }
.contact-section { background: rgba(19, 21, 26, .8); }

/* Karten und Paneele */
.service,
.step,
.faq-item,
.map-consent,
.translate-panel,
form {
  background: var(--panel);
  border-color: var(--panel-line);
  color: var(--text);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
}
.service:hover { border-color: rgba(226, 96, 111, .45); }
.service-media,
.webgl .service-media { background: rgba(255, 255, 255, .04); border-bottom-color: var(--panel-line); }
.process-stage,
.map-stage { background: rgba(255, 255, 255, .04); border-color: var(--panel-line); }
.process-stage .stage-fallback,
.map-stage .stage-fallback { color: var(--text-muted); }

/* Formular */
input, select, textarea {
  background: rgba(255, 255, 255, .06);
  border-color: var(--panel-line);
  color: var(--text);
}
input::placeholder, textarea::placeholder { color: rgba(236, 238, 242, .42); }
/* Die Auswahlliste zeichnet das Betriebssystem – dort gilt wieder dunkel auf hell. */
select option { color: #17191f; }
input[aria-invalid="true"], textarea[aria-invalid="true"] { background: rgba(186, 31, 50, .14); }
.field-error { color: #ff8f9d; }

/* Schwebende Schaltflaechen */
.tool-button { background: var(--panel-solid); color: var(--text); border-color: var(--panel-line); }
.tool-button:hover { border-color: var(--accent); color: var(--accent); }
.mobile-cta .button.secondary { background: var(--panel-solid); color: var(--text); border-color: var(--panel-line); }

@media (max-width: 860px) {
  /* Feststehende Hintergruende ruckeln auf Mobilgeraeten, deshalb dort mitscrollen. */
  nav { background: #0f1116; border-bottom-color: var(--panel-line); }
  nav a { border-bottom-color: var(--panel-line); }
}
