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

:root {
  --bg: #141414;
  --bg-2: #1a1a1a;
  --bg-3: #1f1f1f;
  --white: #ffffff;
  --off-white: #c8c8c8;
  --muted: #666666;
  --line: rgba(255,255,255,0.08);
  --gold: #d4af37;
  --font: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

/* scrollbar-gutter keeps the scrollbar's space reserved even while the intro
   locks scrolling (overflow:hidden), so the centered hero text doesn't jump
   left when the scrollbar reappears on unlock. */
html { scroll-behavior: smooth; scrollbar-gutter: stable; }

/* Scroll anchoring is evaluated per potential-anchor element, not just on
   the scroller — disabling it only on html/body still leaves it free to
   anchor to a descendant. It needs to be off everywhere to stop the
   browser nudging scrollY on its own to compensate for the descent
   pin-spacer's height changing as the pin releases, which otherwise
   silently absorbs/delays our own gap-snap scrollTo writes there. */
* { overflow-anchor: none; }

body {
  background: var(--bg);
  color: var(--white);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ── ACCESSIBILITY TOGGLE STATES (global) ──
   Driven by the nav accessibility panel; persisted in localStorage and
   re-applied on every page by script.js. */

/* 1. High contrast — redefine the palette tokens on <body> so the whole
   token-based UI flips to pure black/white with much stronger hairlines
   (every border/divider that uses --line strengthens automatically).
   Decorative gradients (hero-bg, descent frames, .c1–.c9) stay as-is. */
body.a11y-contrast {
  --bg: #000000; --bg-2: #000000; --bg-3: #0a0a0a;
  --white: #ffffff; --off-white: #ffffff; --muted: #cfcfcf;
  --line: rgba(255,255,255,0.55);
}
body.a11y-contrast :is(a, button, input, textarea, select, [tabindex]):focus-visible {
  outline: 2px solid var(--gold); outline-offset: 2px;
}
/* Thicken the very thin display type in high-contrast with a hairline stroke
   instead of font-weight — text-stroke paints over the glyph and does NOT
   change its advance width, so nothing reflows. Scoped to the light-weight
   hero/closing headlines and their tracked eyebrow marks, not body copy. */
body.a11y-contrast .hero-statement-mark,
body.a11y-contrast .hero-statement-line,
body.a11y-contrast .descent-outro-mark,
body.a11y-contrast .descent-outro-line {
  -webkit-text-stroke: 0.4px currentColor;
}

/* 2. Font size — zoom scales the whole (px-based) layout uniformly. */
body.a11y-fs-1 { zoom: 1.12; }
body.a11y-fs-2 { zoom: 1.25; }

/* 3. Reduce motion (manual, beyond the OS media query) — near-instant durations
   kill CSS animations/transitions (grid, particles, fadeUp, all transitions).
   Canvas/WebGL rAF loops keep running (chosen scope A3). */
body.a11y-reduce-motion *,
body.a11y-reduce-motion *::before,
body.a11y-reduce-motion *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}

/* ── NAV ── */
nav {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  padding: 28px 60px;
  transition: background 0.4s, padding 0.4s, transform 0.7s cubic-bezier(.16,1,.3,1) 0.7s;
}
nav.scrolled {
  background: rgba(20,20,20,0.95);
  backdrop-filter: blur(12px);
  padding: 18px 60px;
  border-bottom: 1px solid var(--line);
}
.nav-logo {
  font-size: 22px; font-weight: 700;
  letter-spacing: 0.18em; color: var(--white);
  text-decoration: none; text-transform: uppercase;
  display: flex; align-items: center; flex-shrink: 0;
}
.nav-logo-img { height: 24px; width: auto; flex-shrink: 0; position: relative; left: 30px; }
.nav-links {
  display: flex; gap: 48px; list-style: none;
}
.nav-links a {
  color: var(--off-white); text-decoration: none;
  font-size: 12px; letter-spacing: 0.14em;
  text-transform: uppercase; font-weight: 500;
  position: relative; transition: color 0.2s;
}
.nav-links a::after {
  content: ''; position: absolute; bottom: -4px; left: 0;
  width: 0; height: 1px; background: var(--white);
  transition: width 0.3s ease;
}
.nav-links a:hover { color: var(--white); }
.nav-links a:hover::after { width: 100%; }
.nav-links.open {
  display: flex; flex-direction: column;
  position: absolute; top: 100%; left: 0; right: 0;
  background: rgba(20,20,20,0.98);
  padding: 24px 32px; gap: 20px;
  border-bottom: 1px solid var(--line);
}
.nav-cta {
  font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 500; color: var(--bg); background: var(--white);
  padding: 10px 24px; text-decoration: none;
  transition: background 0.2s;
}
.nav-cta:hover { background: var(--off-white); }
.nav-burger {
  display: none; flex-direction: column; gap: 5px;
  background: none; border: none; cursor: pointer; padding: 4px;
}
.nav-burger span {
  display: block; width: 24px; height: 1px;
  background: var(--white);
}

/* ── NAV ACCESSIBILITY BUTTON + PANEL ── */
.nav-a11y {
  position: absolute; right: 210px; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; flex-shrink: 0;
}
/* Option A: taken OUT of the nav flex flow so the logo, links and Kontakt keep
   their original space-between positions — the button only sits in the
   Blog↔Kontakt gap. The right offset is viewport-tuned (CSS-only), so it can
   drift slightly at extreme widths; adjust these three values to taste. */
@media (max-width: 1100px) { .nav-a11y { right: 130px; } }
@media (max-width: 1024px) { .nav-a11y { right: 64px; } }   /* beside the burger */

/* Tablet/iPad: use the mobile burger nav already below 1024px — the full
   desktop nav overcrowds here (links/Kontakt overlap) and the opaque Kontakt
   button hides the absolutely-positioned a11y button. Only the nav switches at
   this breakpoint; the rest of the tablet/mobile layout keeps its own
   breakpoints (1100px grids, 768px single-column) unchanged. */
@media (max-width: 1024px) {
  .nav-links { display: none; }
  .nav-links.open { display: flex; }
  .nav-cta { display: none; }
  .nav-burger { display: flex; }
}
.nav-a11y-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; padding: 0;
  background: none; border: 1px solid var(--line); border-radius: 50%;
  color: var(--off-white); cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.nav-a11y-btn:hover,
.nav-a11y-btn[aria-expanded="true"] { color: var(--white); border-color: rgba(255,255,255,0.4); }
.nav-a11y-btn:focus-visible { outline: 2px solid var(--white); outline-offset: 2px; }

.nav-a11y-panel {
  position: absolute; top: calc(100% + 14px); right: 0; z-index: 20;
  width: 260px; padding: 18px;
  background: rgba(20,20,20,0.98); border: 1px solid var(--line);
  backdrop-filter: blur(16px);
  display: flex; flex-direction: column; gap: 18px;
  opacity: 0; visibility: hidden; transform: translateY(-10px);
  transition: opacity 0.2s ease, visibility 0.2s, transform 0.2s ease;
}
.nav-a11y-panel.open { opacity: 1; visibility: visible; transform: translateY(0); }

.a11y-group { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.a11y-group--col { flex-direction: column; align-items: stretch; gap: 10px; }
.a11y-label {
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--off-white); font-weight: 500;
}

/* Switch toggle (Kontrast / Animationen) */
.a11y-toggle {
  flex-shrink: 0; width: 42px; height: 22px; padding: 0;
  background: none; border: none; cursor: pointer;
}
.a11y-toggle-track {
  display: block; width: 42px; height: 22px; border-radius: 22px;
  background: var(--bg-3); border: 1px solid var(--line);
  position: relative; transition: background 0.2s, border-color 0.2s;
}
.a11y-toggle-thumb {
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: var(--off-white);
  transition: transform 0.2s, background 0.2s;
}
.a11y-toggle[aria-checked="true"] .a11y-toggle-track { background: var(--white); border-color: var(--white); }
.a11y-toggle[aria-checked="true"] .a11y-toggle-thumb { transform: translateX(20px); background: var(--bg); }
.a11y-toggle:focus-visible { outline: 2px solid var(--white); outline-offset: 3px; border-radius: 22px; }

/* Segmented font-size control */
.a11y-seg { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.a11y-seg-btn {
  padding: 8px 6px; background: var(--bg-3); border: 1px solid var(--line);
  color: var(--off-white); font-family: var(--font);
  font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  cursor: pointer; transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.a11y-seg-btn:hover { color: var(--white); }
.a11y-seg-btn[aria-pressed="true"] { background: var(--white); color: var(--bg); border-color: var(--white); }
.a11y-seg-btn:focus-visible { outline: 2px solid var(--white); outline-offset: 2px; }

/* ── NAV DROPDOWN (Leistungen) ──
   Desktop/hover only — see the 1100px query below. The outer .nav-dropdown
   has no gap below the trigger (padding-top carries the visual gap
   instead), so the mouse never crosses dead space and drops the :hover. */
.nav-has-dropdown { position: relative; }
.nav-dropdown-trigger { display: inline-flex; align-items: center; gap: 6px; }
.nav-caret { opacity: 0.55; transition: transform 0.35s cubic-bezier(.16,1,.3,1), opacity 0.2s; }
.nav-has-dropdown:hover .nav-caret,
.nav-has-dropdown:focus-within .nav-caret { transform: rotate(180deg); opacity: 1; }
.nav-dropdown {
  position: absolute; top: 100%; left: 0; z-index: 10;
  padding-top: 18px;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.2s ease, visibility 0.2s;
}
.nav-has-dropdown:hover .nav-dropdown,
.nav-has-dropdown:focus-within .nav-dropdown {
  opacity: 1; visibility: visible; pointer-events: auto;
}
.nav-dropdown-panel {
  width: 252px; background: rgba(20,20,20,0.98);
  border: 1px solid var(--line); padding: 8px;
  backdrop-filter: blur(16px);
  transform: translateY(-10px) scale(0.96); transform-origin: top left;
  transition: transform 0.35s cubic-bezier(.16,1,.3,1);
}
.nav-has-dropdown:hover .nav-dropdown-panel,
.nav-has-dropdown:focus-within .nav-dropdown-panel {
  transform: translateY(0) scale(1);
}
.nav-dropdown-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; color: var(--off-white);
  opacity: 0; transform: translateY(6px);
  transition: background 0.2s, color 0.2s, opacity 0.3s ease, transform 0.3s ease;
}
.nav-dropdown-item::after { display: none; }
.nav-dropdown-item svg { opacity: 0.55; flex-shrink: 0; transition: opacity 0.2s, transform 0.2s; }
.nav-dropdown-item:hover { background: var(--bg-3); color: var(--white); }
.nav-dropdown-item:hover svg { opacity: 1; transform: translateX(2px); }
.nav-has-dropdown:hover .nav-dropdown-item,
.nav-has-dropdown:focus-within .nav-dropdown-item { opacity: 1; transform: translateY(0); }
.nav-dropdown-item:nth-child(1) { transition-delay: 0.03s; }
.nav-dropdown-item:nth-child(2) { transition-delay: 0.07s; }
.nav-dropdown-item:nth-child(3) { transition-delay: 0.11s; }
.nav-dropdown-item:nth-child(4) { transition-delay: 0.15s; }

/* ── BUTTONS ── */
.btn-primary {
  display: inline-block; padding: 14px 36px;
  background: var(--white); color: var(--bg);
  text-decoration: none; font-size: 12px;
  letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 600; transition: background 0.2s, transform 0.2s;
}
.btn-primary:hover { background: var(--off-white); transform: translateY(-1px); }
.btn-ghost {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--off-white); text-decoration: none; font-size: 12px;
  letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 500; transition: color 0.2s;
}
.btn-ghost:hover { color: var(--white); }
.btn-ghost svg { transition: transform 0.2s; }
.btn-ghost:hover svg { transform: translateX(4px); }
.btn-outline {
  display: inline-block; text-align: center; padding: 13px 28px;
  border: 1px solid var(--line); color: var(--white);
  text-decoration: none; font-size: 11px;
  letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500;
  transition: background 0.2s, border-color 0.2s;
}
.btn-outline:hover { background: var(--white); color: var(--bg); border-color: var(--white); }

/* ── SECTION DEFAULTS ── */
section { padding: 120px 60px; }
.section-label {
  font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 24px;
  display: flex; align-items: center; gap: 16px;
}
.section-label::before {
  content: ''; width: 32px; height: 1px; background: var(--muted);
}
.section-title {
  font-size: clamp(32px, 4vw, 54px); font-weight: 700;
  line-height: 1.05; letter-spacing: -0.025em; margin-bottom: 20px;
}
.section-desc {
  font-size: 15px; color: var(--off-white); max-width: 520px;
  line-height: 1.75; font-weight: 300; margin-bottom: 60px;
}

/* ── PAGE HERO (subpages) ── */
/* ── Portfolio intro: immersive 3D photo gallery (portfolio-gallery.js) ──
   Full-viewport WebGL canvas (mounted as an absolute child by the script) with
   a centered title overlay and a scroll hint. Scroll passes straight through it
   into the page-hero and the existing portfolio grid below. */
/* Tall scroll track: the visual itself stays pinned (the sticky stage below)
   while the user scrolls through this extra height, so they linger in the
   gallery longer before the page-hero and grid arrive. Tune the dwell time by
   changing this height (300vh ≈ two extra screens of pinned scrolling). */
.portfolio-gallery {
  position: relative; height: 300vh;
  width: 100%; background: var(--bg);
}
/* Pinned stage that actually holds the WebGL canvas + overlay at viewport size. */
.portfolio-gallery-stage {
  position: sticky; top: 0; height: 100vh; min-height: 600px;
  width: 100%; overflow: hidden;
}
/* Bottom fade so the gallery dissolves into the page background rather than
   ending on a hard edge above the page-hero. */
.portfolio-gallery-stage::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 220px;
  z-index: 2; pointer-events: none;
  background: linear-gradient(to bottom, transparent 0%, var(--bg) 100%);
}
.portfolio-gallery-overlay {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 18px;
  /* Reads cleanly over whatever photo drifts behind it. */
  mix-blend-mode: exclusion; color: var(--white);
}
.portfolio-gallery-eyebrow {
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  font-weight: 500; padding-left: 0.22em;
}
.portfolio-gallery-title {
  font-size: clamp(56px, 12vw, 160px); font-weight: 700;
  letter-spacing: -0.04em; line-height: 0.95; margin: 0;
}
.portfolio-gallery-hint {
  position: absolute; left: 0; right: 0; bottom: 38px; z-index: 3;
  pointer-events: none; text-align: center;
  font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  font-weight: 500; color: var(--off-white);
  display: flex; flex-direction: column; gap: 6px;
}
.portfolio-gallery-hint-sub { color: var(--muted); }

.page-hero {
  padding: 180px 60px 100px;
  border-bottom: 1px solid var(--line);
  position: relative; overflow: hidden;
}
.page-hero::before {
  content: attr(data-title);
  position: absolute; right: 60px; bottom: -20px;
  font-size: clamp(80px, 14vw, 200px);
  font-weight: 700; letter-spacing: -0.05em;
  color: rgba(255,255,255,0.03);
  line-height: 1; white-space: nowrap; pointer-events: none;
}
.page-hero-eyebrow {
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 20px;
}
.page-hero h1 {
  font-size: clamp(42px, 6vw, 88px); font-weight: 700;
  line-height: 0.95; letter-spacing: -0.03em; margin-bottom: 28px;
}
.page-hero p {
  font-size: 16px; color: var(--off-white); max-width: 500px;
  line-height: 1.75; font-weight: 300;
}

/* ── Liquid-metal hero variant ──
   A WebGL chrome backdrop (liquid-metal.js) renders into .page-hero-canvas,
   a left-to-right scrim keeps the headline readable, and a decorative frosted
   glass panel sits upper-right and lets the metal shimmer through it. */
.page-hero--shader {
  background: var(--bg);
  min-height: 100vh;
  min-height: 100dvh;   /* fills the viewport on mobile despite browser chrome */
  display: flex; flex-direction: column; justify-content: center;
}
/* Kill the giant data-title watermark for this variant (the "TECHNIK" word). */
.page-hero--shader::before { content: none; }

.page-hero-canvas {
  position: absolute; inset: 0; z-index: 0;
  pointer-events: none;
}
.page-hero-canvas canvas { display: block; width: 100%; height: 100%; }

/* Readability scrim: solid background on the left where the text lives, fading
   to fully transparent on the right so the metal and glass stay visible. */
.page-hero--shader::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(90deg,
    var(--bg) 0%,
    rgba(20,20,20,0.88) 28%,
    rgba(20,20,20,0.35) 58%,
    rgba(20,20,20,0) 82%);
}

/* The lens refraction (the "glass") is drawn inside the WebGL shader
   (liquid-metal.js) so it can truly refract the metal, not just blur it. */

.page-hero--shader .page-hero-content { position: relative; z-index: 3; }

/* Small camera artwork floating over the animation. Its PNG background is
   transparent, so it hovers on the metal; a slow bob makes it "schweben". */
.page-hero-camera {
  position: absolute; z-index: 2; pointer-events: none;
  right: calc(clamp(16px, 6vw, 96px) - 2vw); top: 48%;
  /* Sized so the camera's transparent lens hole (≈0.240·artwork width) equals
     the shader glass circle (diameter 2·0.145 = 0.29·hero height):
     width = 0.29 / 0.240 ≈ 1.209 → 120.9vh. */
  width: 120.9vh;
  aspect-ratio: 1376 / 768; height: auto;
  transform: translateY(-50%);
  filter: drop-shadow(0 26px 52px rgba(0,0,0,0.6));
  animation: heroCameraFloat 6s ease-in-out infinite;
}
@keyframes heroCameraFloat {
  0%, 100% { transform: translateY(calc(-50% + 9px)); }
  50%      { transform: translateY(calc(-50% - 9px)); }
}
@keyframes heroCameraFloatMobile {
  0%, 100% { transform: translateX(50%) translateY(7px); }
  50%      { transform: translateX(50%) translateY(-7px); }
}
@media (prefers-reduced-motion: reduce) {
  .page-hero-camera { animation: none; }
}

/* On narrow viewports the text column gets wide, so retire the glass panel and
   darken the scrim across the full width to keep the headline crisp. */
@media (max-width: 900px) {
  .page-hero--shader { min-height: 88vh; min-height: 88dvh; }
  /* Centre the floating camera near the bottom so it clears the full-width text. */
  .page-hero-camera {
    right: 50%; top: auto; bottom: 7%;
    width: clamp(200px, 56vw, 320px);
    transform: translateX(50%);
    animation-name: heroCameraFloatMobile;
  }
  .page-hero--shader::after {
    background: linear-gradient(90deg,
      var(--bg) 0%,
      rgba(20,20,20,0.92) 45%,
      rgba(20,20,20,0.6) 100%);
  }
}

/* ── HERO (homepage) ── */
.hero {
  position: relative; height: 100vh; min-height: 700px;
  display: flex; align-items: center; justify-content: center;
  text-align: center; overflow: hidden;
}
.hero-bg {
  position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, rgba(20,20,20,0.15) 0%, rgba(20,20,20,0.7) 60%, rgba(20,20,20,1) 100%),
    linear-gradient(135deg, #1a1a1a 0%, #0a0a0a 100%);
}
.hero-grid { position: absolute; inset: 0; overflow: hidden; }
.hero-grid::before {
  content: ''; position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
  background-size: 80px 80px;
  transform: perspective(600px) rotateX(30deg) scale(2);
  transform-origin: bottom center;
  animation: gridMove 8s linear infinite;
}
@keyframes gridMove {
  from { background-position: 0 0; }
  to   { background-position: 0 80px; }
}
.particle {
  position: absolute; width: 2px; height: 2px;
  background: rgba(255,255,255,0.5); border-radius: 50%;
  animation: floatUp linear infinite;
}
@keyframes floatUp {
  from { transform: translateY(100vh); opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  to   { transform: translateY(-10vh); opacity: 0; }
}
.hero-content {
  position: relative; z-index: 2;
  padding: 0 60px; max-width: 1000px;
}
/* Centered hero statement — mirrors the closing grid statement styling
   (.descent-outro-mark / .descent-outro-line) so hero and grid read as a pair.
   Fades in on load (during the intro) BEFORE nav and buttons appear. */
.hero-statement-mark {
  display: block;
  font-size: 11px; letter-spacing: 0.42em; text-transform: uppercase;
  color: var(--muted); font-weight: 500; padding-left: 0.42em;
  margin-bottom: 18px;
  animation: fadeUp 1s ease 0.3s both;
}
.hero-statement-line {
  font-size: clamp(30px, 4.5vw, 60px); font-weight: 300; letter-spacing: -0.02em;
  line-height: 1.1; color: var(--white); max-width: 18ch;
  margin: 0 auto 44px;
  animation: fadeUp 1s ease 0.5s both;
}
.hero-eyebrow {
  font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 7px;
  transition: opacity 0.8s ease, transform 0.8s ease;
}
.hero-title {
  font-size: clamp(47px, 7.2vw, 99px); font-weight: 700;
  line-height: 0.92; letter-spacing: -0.03em; margin-bottom: 32px;
  transition: opacity 0.8s ease 0.12s, transform 0.8s ease 0.12s;
}
.hero-title em { font-style: normal; color: var(--muted); }
.hero-sub {
  font-size: 13.5px; color: var(--off-white); max-width: 414px;
  line-height: 1.7; margin-bottom: 47px;
  transition: opacity 0.8s ease 0.24s, transform 0.8s ease 0.24s; font-weight: 300;
}
.hero-actions {
  display: flex; gap: 20px; align-items: center; justify-content: center;
  margin-top: 14px;
  transition: opacity 0.8s ease 0.1s, transform 0.8s ease 0.1s;
}
/* Hero buttons a touch smaller than the site-wide CTA size (scoped to the hero
   so other CTAs are unaffected). */
.hero-actions .btn-primary { padding: 12px 30px; font-size: 11px; }
/* Counterweight the arrow (gap 10 + icon 16 = 26px) on the left so the label
   "Projekt starten" sits centered in the button box, mirroring the filled
   button whose symmetric padding already centers its text. */
.hero-actions .btn-ghost { font-size: 11px; padding-left: 26px; }
.hero-scroll {
  position: absolute; bottom: 40px; right: 60px;
  display: flex; align-items: center; justify-content: center;
  transition: opacity 0.8s ease 0.35s, transform 0.8s ease 0.35s;
}

/* Rotating "scroll to explore" cue — pure CSS/SVG, no JS */
.scroll-cue {
  --size: 84px;            /* Durchmesser des Buttons        */
  --speed: 16s;           /* Dauer einer Umdrehung           */
  --color: var(--muted);  /* Text- und Punktfarbe            */
  --track-size: 9px;      /* Schriftgröße des Rings          */
  --track-spacing: 0.18em;/* Laufweite (Buchstabenabstand)   */
  --dot-size: 5px;        /* Größe des Mittelpunkts          */
  display: inline-grid;
  place-items: center;
  width: var(--size);
  height: var(--size);
  color: var(--color);
  cursor: pointer;
  transition: color 0.3s ease;
}
.scroll-cue:hover { --color: #fff; }
.scroll-cue__ring {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  animation: scroll-cue-spin var(--speed) linear infinite;
}
.scroll-cue text {
  font-family: ui-sans-serif, system-ui, sans-serif;
  font-size: var(--track-size);
  letter-spacing: var(--track-spacing);
  text-transform: uppercase;
  fill: var(--color);
}
.scroll-cue__dot {
  grid-area: 1 / 1;
  align-self: center;
  justify-self: center;
  width: var(--dot-size);
  height: var(--dot-size);
  border-radius: 50%;
  background: var(--color);
}
@keyframes scroll-cue-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .scroll-cue__ring { animation: none; }
}
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── HERO CANVAS (hills backdrop) + INTRO ──
   The GLSL hills (descent-hills.js) mount into .hero-canvas and run
   immediately as the hero background. On first load the chrome (nav + hero
   text) is hidden and the page is scroll-locked via .intro on <html>;
   script.js removes .intro after the intro dwell, and the staggered
   transitions on nav / hero text (above) then reveal them. */
.hero-canvas { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.hero-canvas canvas { display: block; width: 100%; height: 100%; }
/* Absolute in both of its homes (originally the hero, now the descent-outro
   slot) so the floating particles fill the container and stay out of the
   slot's flex layout. */
#particles { position: absolute; inset: 0; pointer-events: none; }

html.intro, html.intro body { overflow: hidden; height: 100%; }
/* The centered hero statement stays visible during the intro; only the nav,
   buttons and scroll-cue are held back and revealed after it.
   NOTE: the nav is hidden via transform (slide up), NOT opacity — descent.js
   owns the nav's opacity via GSAP (autoAlpha), and hiding it here with opacity
   would collide with that and leave the nav stamped invisible after the intro. */
html.intro #nav { transform: translateY(-120%); }
html.intro .hero-actions,
html.intro .hero-scroll { opacity: 0; transform: translateY(24px); }

/* ── DESCENT (Immersive Scroll Sequence) ──
   Placeholder frames until real footage lands. To swap in real material,
   add an <img> or <video> inside the matching .descent-frame-bg--* element
   (it already sits behind the scrim and content layers); the gradient
   rules below are reused 1:1 from the Portfolio grid's placeholder tints
   further down this file, so visual continuity holds either way.
   Horizon Gold (--gold) is rationed to this section only — see DESIGN.md
   "The Achromatic Shell Rule". */
.descent { position: relative; background: var(--bg); padding: 0; }
.descent-pin { position: relative; height: 100vh; min-height: 600px; overflow: hidden; }
/* Soft handoff from the hero's flat background into the frame imagery —
   without this, the pin's top edge cuts straight into the frame's own
   gradient, reading as a hard line at the hero/descent boundary. */
.descent-pin::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 220px;
  z-index: 2; pointer-events: none;
  background: linear-gradient(to bottom, var(--bg) 0%, transparent 100%);
}
/* pointer-events: none here, re-enabled on .descent-frame-content below —
   otherwise the stacked (but invisible) frames on top in DOM order would
   block clicks/hover on the active frame's link sitting underneath them. */
.descent-frame { position: absolute; inset: 0; display: flex; align-items: flex-end; pointer-events: none; }
.descent-frame-bg { position: absolute; inset: 0; background-size: cover; background-position: center; }
/* A looping video overlays the gradient placeholder inside each frame-bg. As a
   child of .descent-frame-bg it inherits the GSAP crossfade (autoAlpha + scale
   animate the parent), so the existing fade/zoom is unchanged. Shown at all
   widths — the mobile/tablet fallback plays the videos too. */
.descent-frame-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.descent-frame-bg--werbung { background: linear-gradient(135deg, #1e2a1e 0%, #0d1a0d 100%); }
.descent-frame-bg--fpv { background: linear-gradient(135deg, #1a1e2a 0%, #0d1018 100%); }
.descent-frame-bg--immobilien { background: linear-gradient(135deg, #2a1a1e 0%, #180d10 100%); }
.descent-frame-bg--events { background: linear-gradient(135deg, #1a2a2a 0%, #0d1818 100%); }
.descent-frame-bg::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(20,20,20,0.9) 0%, rgba(20,20,20,0.2) 55%, rgba(20,20,20,0.55) 100%);
}
.descent-frame-content { position: relative; z-index: 2; padding: 0 60px 100px; max-width: 720px; pointer-events: auto; }
.descent-frame-num { font-size: 11px; letter-spacing: 0.18em; color: var(--muted); margin-bottom: 16px; font-weight: 500; }
.descent-frame-title { font-size: clamp(32px, 4vw, 54px); font-weight: 700; letter-spacing: -0.025em; line-height: 1.05; margin: 14px 0 12px; }
.descent-frame-title a, .descent-frame-title a:hover { color: inherit; text-decoration: none; }
.descent-frame-tagline { font-size: 15px; color: var(--off-white); font-weight: 300; line-height: 1.6; max-width: 60ch; }

.descent-glow {
  /* Disabled (same as .descent-horizon): the soft gold radial glow suited the
     gradient placeholders but competes with the real video footage. Kept in the
     DOM so descent.js can still target it harmlessly; just not rendered. */
  display: none;
  position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0;
  background: radial-gradient(ellipse 70% 50% at 50% 30%, rgba(212,175,55,0.18), transparent 70%);
}
.descent-horizon {
  /* Disabled: the gold horizon stripe read well over the gradient placeholders
     but competes with the real video footage now. Kept in the DOM so descent.js
     can still target it harmlessly; just not rendered. */
  display: none;
  position: absolute; left: 50%; bottom: 38%; z-index: 3; pointer-events: none;
  width: 70%; height: 1px; transform: translateX(-50%) scaleX(0); opacity: 0;
  background: linear-gradient(90deg, transparent, var(--gold) 50%, transparent);
  box-shadow: 0 0 24px 1px rgba(212,175,55,0.35);
}
.descent-exit { position: absolute; inset: 0; z-index: 4; pointer-events: none; background: var(--bg); opacity: 0; }

/* Closing interstitial that fills the dark hand-off between the animation and
   the stats bar. Sits above the exit overlay; its opacity is driven entirely
   by the scroll timeline (starts at 0), so it fades in only once the screen is
   already var(--bg) dark and fades back out natively when scrubbing upward. */
.descent-outro {
  position: absolute; inset: 0; z-index: 5; opacity: 0; pointer-events: none;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 0 40px; gap: 18px;
}
/* Flowing GLSL ridgelines mounted by descent-hills.js sit at z-index 0 inside
   .descent-outro; lift the closing text above them so it stays fully legible. */
.descent-outro-canvas { display: block; }
.descent-outro-mark {
  position: relative; z-index: 1;
  font-size: 11px; letter-spacing: 0.42em; text-transform: uppercase;
  color: var(--muted); font-weight: 500; padding-left: 0.42em;
}
.descent-outro-line {
  position: relative; z-index: 1;
  font-size: clamp(30px, 4.5vw, 60px); font-weight: 300; letter-spacing: -0.02em;
  line-height: 1.1; color: var(--white); max-width: 18ch;
}
.descent-outro-sub {
  position: relative; z-index: 1;
  font-size: 14px; color: var(--off-white); font-weight: 300;
  line-height: 1.7; max-width: 46ch; margin-top: 4px;
}
.descent:not(.descent--pinned) .descent-outro { display: none; }
/* Fix: in the non-pinned fallback (≤1023px) the outro now flows as its own
   section AFTER frame 4 (see below), so it shows the grid + particle backdrop
   AND its text — mirroring the desktop closing. Children can't render under a
   display:none (and opacity:0) parent, so re-show the container here — the
   higher-specificity .descent-pin ancestor wins over the rule above regardless
   of source order — and restore the opacity the base rule zeroes for the pinned
   timeline. The original rule above is left untouched. */
.descent:not(.descent--pinned) .descent-pin .descent-outro {
  display: flex; opacity: 1;
  position: relative;   /* in-flow ⇒ follows AFTER frame 4 instead of overlaying it */
  inset: auto;          /* cancel the absolute inset:0 anchoring */
  height: 100vh; min-height: 600px;   /* own section, matching the frame height */
  overflow: hidden;     /* keep the particles within the section */
}

.descent-progress { position: absolute; right: 60px; top: 50%; z-index: 5; transform: translateY(-50%); display: flex; flex-direction: column; gap: 14px; }
.descent-progress-tick {
  /* Higher contrast than --line: this sits on varied imagery, not the flat
     carbon background the standard hairline value is tuned for. */
  width: 2px; height: 20px; background: rgba(255,255,255,0.3);
  transform: scaleY(1); transform-origin: center;
  transition: background 0.3s, transform 0.3s;
}
.descent-progress-tick.is-active { background: var(--white); transform: scaleY(1.4); }

.descent--pinned .descent-frame-bg,
.descent--pinned .descent-frame { will-change: opacity, transform; }

/* Default state: no JS enhancement, reduced motion, or narrow viewport.
   Frames render as plain stacked sections — the calm fallback this
   sequence enhances, never the other way around. */
.descent:not(.descent--pinned) .descent-pin { height: auto; min-height: 0; display: block; }
.descent:not(.descent--pinned) .descent-frame { position: relative; height: 100vh; min-height: 600px; }
.descent:not(.descent--pinned) .descent-frame + .descent-frame { border-top: 1px solid var(--line); }
.descent:not(.descent--pinned) .descent-glow,
.descent:not(.descent--pinned) .descent-horizon,
.descent:not(.descent--pinned) .descent-exit,
.descent:not(.descent--pinned) .descent-progress { display: none; }
.descent:not(.descent--pinned) .descent-frame-content {
  opacity: 0; transform: translateY(24px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.descent:not(.descent--pinned) .descent-frame-content.is-visible { opacity: 1; transform: translateY(0); }

@media (max-width: 1100px) {
  .descent-frame-content { padding: 0 32px 64px; }
}
@media (max-width: 768px) {
  .descent-frame-content { padding: 0 24px 48px; }
}

/* ── STATS ── */
.stats {
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  display: grid; grid-template-columns: repeat(4, 1fr);
}
.stat { padding: 48px 60px; border-right: 1px solid var(--line); }
.stat:last-child { border-right: none; }
.stat-num { font-size: 42px; font-weight: 700; letter-spacing: -0.03em; line-height: 1; margin-bottom: 8px; }
.stat-label { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }

/* ── MEDIA (hover-to-play video, Leistungen + Portfolio) ──
   Placeholder: <video> elements point at assets/video/<slot>.{webm,mp4}
   and a same-named poster .jpg. Until those files exist, loadeddata never
   fires (see media-hover.js), so the video stays invisible and the
   existing gradient tile underneath remains the only visible thing —
   drop the real exports in to activate, no markup changes needed. */
.media-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; pointer-events: none;
  transition: opacity 0.4s ease;
}
.media-video.is-playing { opacity: 1; }

/* ── LEISTUNGEN GRID ── */
.leistungen { background: var(--bg); }
.leistungen-header {
  display: flex; justify-content: space-between; align-items: flex-end;
  margin-bottom: 64px; flex-wrap: wrap; gap: 32px;
}
.leistungen-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; background: var(--line); border: 1px solid var(--line);
}
.leistung-card {
  background: var(--bg); padding: 48px 36px;
  position: relative; overflow: hidden;
  transition: background 0.35s; text-decoration: none;
  color: inherit; display: block;
}
.leistung-card::after {
  content: ''; position: absolute; bottom: 0; left: 0;
  width: 0; height: 2px; background: var(--white);
  transition: width 0.4s ease;
}
.leistung-card:hover { background: var(--bg-3); }
.leistung-card:hover::after { width: 100%; }
.leistung-num { font-size: 11px; letter-spacing: 0.16em; color: var(--muted); margin-bottom: 40px; font-weight: 500; }
.leistung-icon { margin-bottom: 28px; opacity: 0.7; }
.leistung-card h3 { font-size: 18px; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 14px; }
.leistung-card p { font-size: 13px; color: var(--muted); line-height: 1.7; font-weight: 300; }
.leistung-arrow { position: absolute; bottom: 36px; right: 36px; opacity: 0; transition: opacity 0.3s, transform 0.3s; }
.leistung-card:hover .leistung-arrow { opacity: 1; transform: translate(4px, -4px); }

/* Leistungen subpage only: a 4:3 video tile above the text. Bleeds edge to
   edge via negative margins instead of touching .leistung-card's own
   padding, so the homepage's icon-only cards stay exactly as they are. */
.leistung-card.has-media { padding-top: 0; }
.leistung-card.has-media .leistung-num { margin-top: 24px; margin-bottom: 12px; }
.leistung-media {
  position: relative; aspect-ratio: 4/3; overflow: hidden;
  margin: 0 -36px 0; background: var(--bg-3);
}
.leistung-media-bg { position: absolute; inset: 0; transition: transform 0.6s ease; }
.leistung-card:hover .leistung-media-bg { transform: scale(1.05); }
.leistung-media-bg--werbung { background: linear-gradient(135deg, #1e2a1e 0%, #0d1a0d 100%); }
.leistung-media-bg--fpv { background: linear-gradient(135deg, #1a1e2a 0%, #0d1018 100%); }
.leistung-media-bg--immobilien { background: linear-gradient(135deg, #2a1a1e 0%, #180d10 100%); }
.leistung-media-bg--events { background: linear-gradient(135deg, #1a2a2a 0%, #0d1818 100%); }

/* ── PORTFOLIO GRID (homepage) ── */
.portfolio { background: var(--bg); }
.portfolio-grid {
  display: grid; grid-template-columns: 2fr 1fr 1fr;
  grid-template-rows: 320px 320px; gap: 2px;
}
.portfolio-item { position: relative; overflow: hidden; background: var(--bg-3); }
.portfolio-item:first-child { grid-row: 1 / 3; }
.portfolio-item-bg { position: absolute; inset: 0; transition: transform 0.6s ease; }
.portfolio-item:hover .portfolio-item-bg { transform: scale(1.04); }
.pi-1 .portfolio-item-bg { background: linear-gradient(135deg, #1e2a1e 0%, #0d1a0d 100%); }
.pi-2 .portfolio-item-bg { background: linear-gradient(135deg, #1a1e2a 0%, #0d1018 100%); }
.pi-3 .portfolio-item-bg { background: linear-gradient(135deg, #2a1a1e 0%, #180d10 100%); }
.pi-4 .portfolio-item-bg { background: linear-gradient(135deg, #1a2a2a 0%, #0d1818 100%); }
.pi-5 .portfolio-item-bg { background: linear-gradient(135deg, #2a2a1a 0%, #181800 100%); }
.portfolio-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(20,20,20,0.85) 0%, transparent 50%);
  opacity: 0; transition: opacity 0.4s;
  display: flex; align-items: flex-end; padding: 28px;
}
.portfolio-item:hover .portfolio-overlay { opacity: 1; }
.portfolio-meta-cat { font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--off-white); margin-bottom: 4px; }
.portfolio-meta-title { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
.portfolio-placeholder-label {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
}
.placeholder-tag {
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted); border: 1px solid var(--line); padding: 6px 14px;
}

/* ── PROCESS ── */
.process { background: var(--bg-2); }
.process-steps {
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 64px;
}
.process-step { background: var(--bg-2); padding: 40px 28px; }
/* At the 3-column tablet layout (769–1100px) the 5 steps leave the 6th grid
   cell empty, exposing the container's --line background. Fill just that cell
   with a matching dark tile via a pseudo grid item, scoped to this range so it
   never adds an extra cell in the 5-col desktop or 1-col mobile layouts. */
@media (min-width: 769px) and (max-width: 1100px) {
  .process-steps::after { content: ''; background: var(--bg-2); }
}
.step-num { font-size: 10px; letter-spacing: 0.18em; color: var(--muted); margin-bottom: 24px; }
.step-title { font-size: 14px; font-weight: 600; letter-spacing: 0.02em; margin-bottom: 12px; }
.step-desc { font-size: 12px; color: var(--muted); line-height: 1.65; font-weight: 300; }

/* ── PREISE ── */
.preise { background: var(--bg); }
.preise-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 1px; background: var(--line); border: 1px solid var(--line);
}
.preis-card { background: var(--bg); padding: 52px 40px; position: relative; }
.preis-card.featured { background: var(--bg-3); }
.preis-badge {
  position: absolute; top: -1px; left: 40px;
  background: var(--white); color: var(--bg);
  font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 600; padding: 5px 12px;
}
.preis-name { font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); margin-bottom: 24px; }
.preis-num { font-size: 52px; font-weight: 700; letter-spacing: -0.04em; line-height: 1; margin-bottom: 4px; }
.preis-from { font-size: 11px; color: var(--muted); letter-spacing: 0.08em; margin-bottom: 36px; }
.preis-features { list-style: none; margin-bottom: 44px; }
.preis-features li {
  font-size: 13px; color: var(--off-white); padding: 10px 0;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 10px; font-weight: 300;
}
.preis-features li::before { content: '—'; color: var(--muted); flex-shrink: 0; }
.preis-card.featured .btn-outline { background: var(--white); color: var(--bg); border-color: var(--white); }
.preis-card.featured .btn-outline:hover { background: var(--off-white); border-color: var(--off-white); }

/* ── CTA BANNER ── */
.cta-banner {
  padding: 120px 60px; text-align: center;
  position: relative; overflow: hidden; border-top: 1px solid var(--line);
}
.cta-banner::before {
  content: attr(data-word);
  position: absolute; font-size: 320px; font-weight: 700;
  letter-spacing: -0.05em; color: rgba(255,255,255,0.02);
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  white-space: nowrap; pointer-events: none;
}
.cta-banner h2 { font-size: clamp(36px, 5vw, 72px); font-weight: 700; letter-spacing: -0.015em; margin-bottom: 20px; position: relative; }
.cta-banner p { font-size: 15px; color: var(--off-white); font-weight: 300; margin-bottom: 48px; position: relative; }
.cta-banner .btn-primary { position: relative; }

/* ── FOOTER ── */
footer { background: var(--bg-2); border-top: 1px solid var(--line); padding: 60px; }
.footer-top { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 60px; margin-bottom: 60px; }
.footer-brand h3 { font-size: 18px; font-weight: 700; letter-spacing: 0.14em; margin-bottom: 14px; }
.footer-logo-img { height: 22px; width: auto; }
.footer-brand p { font-size: 13px; color: var(--muted); line-height: 1.7; font-weight: 300; max-width: 260px; }
.footer-col h4 { font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); margin-bottom: 20px; font-weight: 500; }
.footer-col ul { list-style: none; }
.footer-col ul li { margin-bottom: 10px; }
.footer-col ul li a { font-size: 13px; color: var(--off-white); text-decoration: none; font-weight: 300; transition: color 0.2s; }
.footer-col ul li a:hover { color: var(--white); }
.footer-bottom { border-top: 1px solid var(--line); padding-top: 32px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px; }
.footer-bottom p { font-size: 12px; color: var(--muted); font-weight: 300; }
.footer-legal { display: flex; gap: 32px; }
.footer-legal a { font-size: 12px; color: var(--muted); text-decoration: none; transition: color 0.2s; }
.footer-legal a:hover { color: var(--white); }

/* ── PORTFOLIO PAGE ── */
.filter-bar { display: flex; gap: 2px; margin-bottom: 48px; flex-wrap: wrap; }
.filter-btn {
  padding: 10px 22px; background: transparent;
  border: 1px solid var(--line); color: var(--muted);
  font-family: var(--font); font-size: 11px;
  letter-spacing: 0.14em; text-transform: uppercase;
  cursor: pointer; transition: all 0.2s;
}
.filter-btn:hover { color: var(--white); border-color: rgba(255,255,255,0.3); }
.filter-btn.active { background: var(--white); color: var(--bg); border-color: var(--white); }
.portfolio-full-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px;
}
.p-item {
  position: relative; overflow: hidden; background: var(--bg-3);
  aspect-ratio: 4/3; transition: opacity 0.4s;
}
.p-item-bg { position: absolute; inset: 0; transition: transform 0.6s ease; }
.p-item:hover .p-item-bg { transform: scale(1.05); }
.p-item-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(20,20,20,0.9) 0%, transparent 55%);
  opacity: 0; transition: opacity 0.4s;
  display: flex; align-items: flex-end; padding: 24px;
}
.p-item:hover .p-item-overlay { opacity: 1; }
.p-item-cat { font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--off-white); margin-bottom: 4px; }
.p-item-title { font-size: 15px; font-weight: 600; }
.p-item-label {
  position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center;
}
.p-item-label span {
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--muted); border: 1px solid var(--line); padding: 6px 14px;
}

/* Placeholder colors for portfolio items */
.c1 { background: linear-gradient(135deg, #1e2a1e, #0d1a0d); }
.c2 { background: linear-gradient(135deg, #1a1e2a, #0d1018); }
.c3 { background: linear-gradient(135deg, #2a1a1e, #180d10); }
.c4 { background: linear-gradient(135deg, #1a2a2a, #0d1818); }
.c5 { background: linear-gradient(135deg, #2a2a1a, #181800); }
.c6 { background: linear-gradient(135deg, #201a2a, #100d18); }
.c7 { background: linear-gradient(135deg, #2a1e1a, #18100d); }
.c8 { background: linear-gradient(135deg, #1a2a1e, #0d1812); }
.c9 { background: linear-gradient(135deg, #221a2a, #120d18); }

/* ── TEAM PAGE ── */
.team-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; background: var(--line); border: 1px solid var(--line); }
.team-card { background: var(--bg); padding: 0; overflow: hidden; }
.team-photo {
  width: 100%; aspect-ratio: 3/4; position: relative;
  background: var(--bg-3); overflow: hidden;
}
.team-photo-placeholder {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
}
.team-photo-placeholder svg { opacity: 0.08; }
.team-info { padding: 28px 28px 36px; }
.team-name { font-size: 20px; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 6px; }
.team-role { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); margin-bottom: 16px; }
.team-bio { font-size: 13px; color: var(--off-white); line-height: 1.7; font-weight: 300; }
.team-photo-bg { width: 100%; height: 100%; object-fit: cover; }

/* ── TECHNIK PAGE ── */
.tech-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 64px; }
.tech-card { background: var(--bg); padding: 48px 36px; }
.tech-cat { font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); margin-bottom: 32px; }
.tech-card h3 { font-size: 20px; font-weight: 600; margin-bottom: 12px; }
.tech-card p { font-size: 13px; color: var(--muted); line-height: 1.7; font-weight: 300; margin-bottom: 28px; }
.tech-specs { list-style: none; }
.tech-specs li { font-size: 12px; color: var(--off-white); padding: 8px 0; border-bottom: 1px solid var(--line); display: flex; justify-content: space-between; font-weight: 300; }
.tech-specs li span { color: var(--muted); }
.tech-visual {
  width: 100%; aspect-ratio: 16/9; background: var(--bg-3);
  margin-bottom: 32px; position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.tech-visual svg { opacity: 0.12; }

/* ── BLOG PAGE ── */
.blog-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; background: var(--line); border: 1px solid var(--line); }
.blog-card { background: var(--bg); text-decoration: none; color: inherit; display: block; transition: background 0.3s; }
.blog-card:hover { background: var(--bg-3); }
.blog-thumb { width: 100%; aspect-ratio: 16/9; background: var(--bg-3); position: relative; overflow: hidden; }
.blog-thumb-bg { position: absolute; inset: 0; transition: transform 0.5s; }
.blog-card:hover .blog-thumb-bg { transform: scale(1.04); }
.blog-body { padding: 28px; }
.blog-meta { display: flex; gap: 16px; margin-bottom: 12px; }
.blog-tag { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.blog-date { font-size: 10px; color: var(--muted); }
.blog-card h3 { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 10px; line-height: 1.3; }
.blog-card p { font-size: 12px; color: var(--muted); line-height: 1.65; font-weight: 300; }

/* ── KONTAKT PAGE ── */
.kontakt-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 80px; align-items: start; }
.kontakt-info h2 { font-size: clamp(28px, 3vw, 44px); font-weight: 700; letter-spacing: -0.025em; margin-bottom: 20px; }
.kontakt-info p { font-size: 15px; color: var(--off-white); line-height: 1.75; font-weight: 300; margin-bottom: 48px; }
.kontakt-details { display: flex; flex-direction: column; gap: 24px; }
.kontakt-detail-label { font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted); margin-bottom: 4px; }
.kontakt-detail-value { font-size: 14px; color: var(--white); }
.kontakt-form { display: flex; flex-direction: column; gap: 10px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.form-field { display: flex; flex-direction: column; }
.form-field label { font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); padding: 14px 20px 10px; background: var(--bg-2); }
.form-field input,
.form-field textarea,
.form-field select {
  background: var(--bg-2); border: none; outline: none;
  color: var(--white); font-family: var(--font); font-size: 14px;
  padding: 10px 20px 16px; resize: none; font-weight: 300;
  border-bottom: 1px solid transparent; transition: border-color 0.2s;
}
.form-field input:focus,
.form-field textarea:focus,
.form-field select:focus { border-bottom-color: rgba(255,255,255,0.3); }
.form-field select option { background: var(--bg-2); }
.form-field textarea { min-height: 160px; }
.form-checkbox { display: flex; align-items: flex-start; gap: 14px; padding: 20px; background: var(--bg-2); }
.form-checkbox input { width: 16px; height: 16px; margin-top: 2px; accent-color: var(--white); flex-shrink: 0; }
.form-checkbox label { font-size: 12px; color: var(--muted); line-height: 1.6; font-weight: 300; }
.form-checkbox a { color: var(--off-white); }
.form-submit { background: var(--white); color: var(--bg); border: none; padding: 18px 36px; font-family: var(--font); font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 600; cursor: pointer; transition: background 0.2s; text-align: left; }
.form-submit:hover { background: var(--off-white); }

/* ── LEISTUNG DETAIL PAGE ── */
.leistung-detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; margin-bottom: 2px; }
.leistung-visual {
  aspect-ratio: 16/9; background: var(--bg-3);
  position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.leistung-visual svg { opacity: 0.1; }
/* Subpage detail videos fill their 16:9 .leistung-visual field (same treatment
   as the mainpage descent frames); the inline gradient stays as the underlay. */
.leistung-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* The subpage video/text sections carry an inline `padding:80px 60px 0`, which
   (being inline) overrides the mobile `section` padding and leaves side bars on
   phones. Reclaim full width by trimming only the horizontal padding ≤768px;
   top/bottom and all desktop/tablet spacing stay untouched. */
@media (max-width: 768px) {
  section[style*="padding:80px 60px 0"] { padding-left: 24px !important; padding-right: 24px !important; }
}
/* The fpv "FPV & Regularien" grid is forced to 3 columns via an inline
   grid-template-columns, which overrides the mobile 1-column rule and overflows
   the container on phones. Collapse just that inline-3-col variant to 1 column
   ≤768px; desktop/tablet keep their intended 3 columns. */
@media (max-width: 768px) {
  .process-steps[style*="grid-template-columns:repeat(3,1fr)"] { grid-template-columns: 1fr !important; }
}
/* leistungen.html: the cards section carries an inline `padding:120px 60px`,
   which overrides the mobile section padding and leaves side bars on phones.
   Trim only the horizontal padding ≤768px so the 4 cards reach full width. */
@media (max-width: 768px) {
  .leistungen[style*="padding:120px 60px"] { padding-left: 24px !important; padding-right: 24px !important; }
}
.leistung-detail-text { background: var(--bg-2); padding: 60px; display: flex; flex-direction: column; justify-content: center; }
.leistung-detail-text h2 { font-size: clamp(24px, 3vw, 38px); font-weight: 700; letter-spacing: -0.02em; margin-bottom: 20px; }
.leistung-detail-text p { font-size: 14px; color: var(--off-white); line-height: 1.8; font-weight: 300; margin-bottom: 32px; }
.leistung-list { list-style: none; }
.leistung-list li { font-size: 13px; color: var(--off-white); padding: 10px 0; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 12px; font-weight: 300; }
.leistung-list li::before { content: '→'; color: var(--muted); }

/* ── DATENSCHUTZ / IMPRESSUM ── */
.legal-content { max-width: 720px; }
.legal-content h2 { font-size: 22px; font-weight: 600; margin: 48px 0 16px; letter-spacing: -0.01em; }
.legal-content h2:first-child { margin-top: 0; }
.legal-content p { font-size: 14px; color: var(--off-white); line-height: 1.8; font-weight: 300; margin-bottom: 16px; }
.legal-content a { color: var(--white); }

/* ── RESPONSIVE ── */
@media (max-width: 1100px) {
  nav, nav.scrolled { padding: 24px 32px; }
  section { padding: 80px 32px; }
  .page-hero { padding: 160px 32px 80px; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stat { padding: 36px 32px; }
  .leistungen-grid { grid-template-columns: repeat(2, 1fr); }
  .portfolio-grid { grid-template-columns: 1fr 1fr; grid-template-rows: auto; }
  .portfolio-item:first-child { grid-row: auto; }
  .portfolio-full-grid { grid-template-columns: repeat(2, 1fr); }
  .process-steps { grid-template-columns: repeat(3, 1fr); }
  .preise-grid { grid-template-columns: 1fr; }
  .footer-top { grid-template-columns: 1fr 1fr; gap: 40px; }
  .kontakt-grid { grid-template-columns: 1fr; gap: 48px; }
  .leistung-detail-grid { grid-template-columns: 1fr; }
  .tech-grid { grid-template-columns: repeat(2, 1fr); }
  .team-grid { grid-template-columns: repeat(2, 1fr); }
  .blog-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  nav, nav.scrolled { padding: 33px 24px 20px; }
  /* Align with the burger's centre: the asymmetric nav padding (33 top / 20
     bottom) puts the flex-centred burger 6.5px below the a11y button's top:50%
     (measured against the full padding box), so nudge it down to match. */
  .nav-a11y { transform: translateY(calc(-50% + 6.5px)); }
  section { padding: 64px 24px; }
  .page-hero { padding: 140px 24px 64px; }
  .hero-content { padding: 0 24px 80px; }
  .hero-scroll { display: none; }
  .stats { grid-template-columns: 1fr 1fr; }
  .stat { padding: 28px 24px; border-right: none; border-bottom: 1px solid var(--line); }
  .stat-num { font-size: 32px; }
  .leistungen-grid { grid-template-columns: 1fr; }
  .portfolio-grid { grid-template-columns: 1fr; }
  .portfolio-item { height: 240px; }
  .portfolio-full-grid { grid-template-columns: 1fr; }
  .process-steps { grid-template-columns: 1fr; }
  .cta-banner { padding: 80px 24px; }
  footer { padding: 40px 24px; }
  .footer-top { grid-template-columns: 1fr; gap: 32px; }
  .footer-bottom { flex-direction: column; align-items: flex-start; }
  .team-grid { grid-template-columns: 1fr; }
  .tech-grid { grid-template-columns: 1fr; }
  .blog-grid { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr; }
  .leistung-detail-text { padding: 36px 24px; }
}

/* ── PRINT ──
   Ziel: Die Druckversion soll erkennbar nach der Website aussehen (Bilder,
   Gradient-Kacheln und Grundlayout bleiben), aber ohne bewegte Deko,
   interaktive Steuerelemente oder Vollbild-Stages, die Leerseiten erzeugen.
   Nav und Footer bleiben sichtbar, werden aber aus dem fixed/sticky-Flow
   gelöst, damit sie nicht auf jeder Seite überlappen. */
@media print {
  /* Hintergründe & Gradient-Platzhalter mitdrucken, statt sie zu strippen —
     sonst kippt das erkennbare Erscheinungsbild in leere weiße Flächen. */
  body {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    overflow: visible;
  }

  /* Nav aus dem fixierten Flow lösen: bleibt sichtbar, klebt aber nicht mehr
     auf jeder gedruckten Seite. Backdrop-Filter/Blur druckt ohnehin nicht. */
  nav, nav.scrolled {
    position: static;
    backdrop-filter: none;
    padding: 20px 60px;
  }

  /* Vollbild-Stages (100vh / sticky / 300vh Scroll-Track) auf natürliche Höhe
     bringen, damit kein leeres Blatt oder abgeschnittener Inhalt entsteht. */
  .hero,
  .page-hero--shader,
  .portfolio-gallery,
  .portfolio-gallery-stage,
  .descent-pin,
  .descent-frame {
    position: static;
    height: auto;
    min-height: 0;
    overflow: visible;
  }

  /* Descent-Sequenz als ruhig gestapelte Abschnitte darstellen (Bilder + Text
     bleiben), unabhängig davon ob das JS-Pinning aktiv war. */
  .descent-frame {
    position: relative;
    opacity: 1;
  }
  .descent-frame-content {
    opacity: 1 !important;
    transform: none !important;
  }

  /* Reine Deko / WebGL / Animationen — drucken leer oder als Artefakte. */
  canvas,
  .page-hero-canvas,
  .hero-grid,
  .particle,
  .scroll-cue,
  .hero-scroll,
  .page-hero-camera,
  .descent-glow,
  .descent-horizon,
  .descent-exit,
  .descent-progress,
  .descent-outro-canvas,
  .portfolio-gallery-hint,
  .nav-caret,
  .media-video {
    display: none !important;
  }

  /* Interaktive Steuerelemente — auf Papier ohne Funktion. */
  .nav-burger,
  .nav-cta,
  .nav-dropdown,
  .btn-primary,
  .btn-ghost,
  .btn-outline,
  .form-submit,
  .kontakt-form,
  .filter-bar,
  .leistung-arrow,
  .portfolio-overlay,
  .p-item-overlay {
    display: none !important;
  }
}
