/* ==========================================================================
   Self-hosted fonts — previously loaded live from fonts.googleapis.com /
   fonts.gstatic.com, which sends every visitor's IP to Google before any
   consent choice is possible (the LG München 2022 ruling's exact scenario).
   These two files are the Google Fonts API's own variable-font woff2s
   (latin subset only — covers German incl. äöüß, which all sit in the
   base Latin-1 range), fetched once and committed here; nothing at
   runtime talks to Google for fonts anymore, on any page, regardless of
   the cookie-banner choice below (this isn't a consent-gated resource —
   self-hosting removes the third-party request entirely). font-weight is
   a range because each file is variable across its whole axis, not a
   single static weight. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/inter-latin-variable.woff2') format('woff2');
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 600 800;
  font-display: swap;
  src: url('fonts/montserrat-latin-variable.woff2') format('woff2');
}

/* ==========================================================================
   Maskos – Design System
   Structure merged from two Stitch drafts (startseite_autovermietung_region +
   startseite_variante_2_emotional_bildstark / "Teutonic Mobility").
   Color system: real MASKOS brand identity (sampled from the actual vehicle
   livery photos) — MASKOS red as the sole accent, anthracite typography,
   warm off-white surfaces. Blue/orange removed entirely.
   ========================================================================== */

:root {
  /* MASKOS red — sampled from the red logo boxes on the real fleet photos
     (avg. ~#b8262b across three independent images), tuned to a clean,
     accessible web value. This is the one and only accent color. */
  --color-red: #c4272c;
  --color-red-dark: #9e1f23;
  --color-red-darker: #7c181c;
  --color-red-soft: #f7e6e5;        /* ~6% tint — icon backgrounds */
  --color-red-soft-strong: #f0d4d3; /* stronger tint for hover states */

  --color-text-primary: #1c1c1a;    /* anthracite — headlines */
  --color-text-secondary: #5f5d58;  /* warm dark gray — body copy */
  --color-text-muted: #6f6c64;      /* meta text — darkened from #8a8781 for AA contrast */

  --color-bg-main: #fcfbf9;         /* warm off-white — page background */
  --color-bg-soft: #f5f3ef;         /* soft warm beige-gray — alt sections */
  --color-surface: #ffffff;         /* cards */

  --color-border: #e4e1db;          /* warm neutral border */
  --color-border-strong: #d3cfc6;

  --color-graphite: #201f1d;        /* footer / dark overlay base */
  --color-graphite-soft: #38362f;

  --font-head: 'Montserrat', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'Inter', 'Segoe UI', system-ui, sans-serif;

  --radius-sm: 0.5rem;
  --radius-md: 1rem;
  --radius-lg: 1.5rem;
  --radius-full: 999px;

  --container-max: 1280px;
  --gutter: 24px;
  --margin-desktop: 40px;
  --margin-mobile: 16px;

  --shadow-sm: 0 1px 3px rgba(28, 28, 26, 0.08), 0 1px 2px rgba(28, 28, 26, 0.06);
  --shadow-md: 0 8px 24px rgba(28, 28, 26, 0.10);
  --shadow-lg: 0 16px 40px rgba(28, 28, 26, 0.16);
}

/* -------------------------------------------------------------------------
   Reset
   ------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
/* overflow-x:hidden must NOT go on html: WebKit (Safari) treats any
   overflow value on the root element as reason to stop honoring
   position:sticky on descendants entirely — confirmed by testing the
   sticky header in real WebKit, where it silently degraded to normal
   in-flow positioning (scrolled clean off-screen instead of sticking to
   top:0) the moment this was added. body's own overflow-x:hidden below
   is what actually contains the reviews marquee's intentionally-oversized
   track; see the note there for the small residual case that didn't
   fully close, fixed instead via a max-width safety on .reviews-marquee. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}
body {
  font-family: var(--font-body);
  color: var(--color-text-primary);
  background: var(--color-bg-main);
  line-height: 1.5;
  min-height: 100vh;
  overflow-x: hidden;
}
img, picture { max-width: 100%; display: block; }
input, button, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; padding: 0; }
h1, h2, h3, h4 { font-family: var(--font-head); font-weight: 700; line-height: 1.15; }

.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--margin-mobile);
}
@media (min-width: 768px) {
  .container { padding-inline: var(--margin-desktop); }
}

/* Anchor targets for the nav (Leistungen dropdown, Über Maskos, Kontakt,
   FAQ) — without this, the sticky header (76px, floating pill above
   900px) covers the top of whatever section a jump lands on. 96px clears
   the header at every breakpoint/scroll state with a little breathing
   room to spare. */
#transporter-lkw, #sprinter, #busse, #anhaenger, #faq, #kontakt, #rechner, #fahrzeuge, #vertrauen, #geschichte, #standort {
  scroll-margin-top: 96px;
}

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

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

/* -------------------------------------------------------------------------
   Buttons
   ------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  padding: 0.95rem 1.75rem;
  border-radius: var(--radius-full);
  border: none;
  transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease, border-color 0.2s ease;
  white-space: nowrap;
}
.btn-primary {
  background: var(--color-red);
  color: #ffffff;
  box-shadow: var(--shadow-md);
}
.btn-primary:hover { background: var(--color-red-dark); box-shadow: var(--shadow-lg); transform: translateY(-2px); }
.btn-primary:active { background: var(--color-red-darker); transform: translateY(0) scale(0.98); }

.btn-ghost-light {
  background: rgba(255, 255, 255, 0.22);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.45);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}
.btn-ghost-light:hover { background: rgba(255, 255, 255, 0.32); transform: translateY(-2px); }

.btn-outline {
  background: transparent;
  color: var(--color-text-primary);
  border: 1.5px solid var(--color-border-strong);
}
.btn-outline:hover { border-color: var(--color-red); background: var(--color-red-soft); }

.btn-block { width: 100%; }

/* -------------------------------------------------------------------------
   Header
   ------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  width: 100%;
  background: rgba(252, 251, 249, 0.85);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid transparent;
  border-bottom: 1px solid rgba(228, 225, 219, 0.7);
  border-radius: 0;
  box-shadow: none;
  transition:
    top 380ms cubic-bezier(0.22, 1, 0.36, 1),
    width 380ms cubic-bezier(0.22, 1, 0.36, 1),
    margin 380ms cubic-bezier(0.22, 1, 0.36, 1),
    border-radius 380ms cubic-bezier(0.22, 1, 0.36, 1),
    background-color 380ms ease,
    border-color 380ms ease,
    box-shadow 380ms ease,
    backdrop-filter 380ms ease,
    -webkit-backdrop-filter 380ms ease;
}
/* Default (also mobile <900px, which keeps this simple treatment only —
   the floating pill below is scoped to >=900px and never touches mobile). */
.site-header.is-scrolled {
  background: rgba(252, 251, 249, 0.97);
  box-shadow: 0 2px 16px rgba(28, 28, 26, 0.08);
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 76px;
  gap: 1rem;
  transition: height 380ms cubic-bezier(0.22, 1, 0.36, 1), padding 380ms cubic-bezier(0.22, 1, 0.36, 1);
}
.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.35rem;
  color: var(--color-text-primary);
  /* Never let flexbox's default shrink squeeze the brand block below its
     own content width — that's what was wrapping "FAHRZEUGVERMIETUNG
     PEINE" onto two lines once the scrolled/pill header narrowed and
     tightened its gaps. Other flex siblings (nav links, actions) can
     absorb the space pressure instead. */
  flex-shrink: 0;
  white-space: nowrap;
}
.brand .mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--color-red);
  color: #fff;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.1rem;
}
.brand .place {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.68rem;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.055em;
  display: block;
  margin-top: -2px;
  white-space: nowrap;
}

/* Brand logo image: the full lockup in its light-background ink (dark
   wordmark) everywhere the header background is light — mobile always,
   and >=900px whenever it's not scrolled, since the rest-state header is
   light there too now. Once scrolled at >=900px the header goes dark/
   compact, and that dark-ink wordmark would go illegible against it — the
   same full lockup in its dark-background ink (.brand-logo--dark, white
   wordmark, red "MASKOS" stays red either way — same file used in the
   dark footer) takes over there instead, so the wordmark stays readable
   at every scroll position rather than shrinking to just the icon mark.
   Height is fixed per tier below to fit next to the call/menu controls
   without overflowing. */
.brand-logo { display: block; line-height: 0; }
.brand-logo img { display: block; height: 21px; width: auto; }
.brand-logo--dark { display: none; }

@media (min-width: 900px) {
  .brand-logo img { height: 32px; }
  .site-header.is-scrolled .brand-logo--light { display: none; }
  .site-header.is-scrolled .brand-logo--dark { display: block; }
  .site-header.is-scrolled .brand-logo--dark img { height: 30px; }
}

@media (min-width: 900px) and (max-width: 1099px) {
  /* Same narrow tablet/laptop tier the header already trims content for
     (see .brand .place further below) — logo stays smaller here so it
     doesn't compete with the nav for space. The call-chip swap that also
     used to live here has moved next to that other same-tier rule, since
     source order after the base >=900px call-chip rule is what makes it
     actually win. */
  .brand-logo img { height: 22px; }
  .site-header.is-scrolled .brand-logo--dark img { height: 22px; }
}

.nav-desktop {
  display: none;
  align-items: center;
  gap: 2rem;
}
.nav-desktop a {
  font-weight: 500;
  color: var(--color-text-secondary);
  padding: 0.5rem 0;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.nav-desktop a:hover { color: var(--color-red); }
/* Current-page indicator. Static (hardcoded in the markup) rather than
   route-driven, since this is one HTML file today — "Startseite" carries
   it now; when the four Leistungen categories become real subpages, each
   one's own nav link would carry this same class instead. */
.nav-desktop a.is-nav-active,
.nav-mobile a.is-nav-active {
  color: var(--color-text-primary);
  border-bottom-color: var(--color-red);
}
.site-header.is-scrolled .nav-desktop a.is-nav-active { color: #fff; }

/* ---- "Leistungen" dropdown ----
   A <button> trigger (not a link — it has no destination of its own) that
   toggles a menu via script.js. CSS alone would mean either hover-only
   (broken for touch/keyboard) or a :focus-within trick that closes the
   instant focus leaves the button before a menu link can be tapped; a
   plain JS toggle with an outside-click/Escape close is simpler and more
   reliable than either. */
.nav-dropdown { position: relative; }
.nav-dropdown-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: none;
  border: none;
  font: inherit;
  font-weight: 500;
  color: var(--color-text-secondary);
  padding: 0.5rem 0;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.nav-dropdown-trigger:hover { color: var(--color-red); }
.nav-caret { transition: transform 0.2s ease; flex-shrink: 0; }
.nav-dropdown.is-open .nav-caret { transform: rotate(180deg); }
/* Dark graphite, matching the header's own scrolled/floating-pill look —
   not a white card. Note this also fixes a real bug, not just a color
   choice: .site-header.is-scrolled .nav-desktop a sets color:#fff with
   higher specificity (0,3,1) than the old .nav-dropdown-menu a (0,1,1),
   and since the dropdown lives inside .nav-desktop, that rule silently
   made these links white-on-white (invisible) whenever the header was in
   its scrolled state. Using #navDropdownMenu (ID, effectively unbeatable
   specificity) for the text color below removes that failure mode for
   good, on top of now wanting white text here anyway by design. */
.nav-dropdown-menu {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  min-width: 230px;
  background: var(--color-graphite);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
  z-index: 10;
}
.nav-dropdown.is-open .nav-dropdown-menu {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
#navDropdownMenu a {
  display: block;
  padding: 0.7rem 0.9rem;
  border-radius: 0.6rem;
  font-weight: 500;
  font-size: 0.92rem;
  color: rgba(255, 255, 255, 0.85);
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease;
}
#navDropdownMenu a:hover,
#navDropdownMenu a:focus-visible {
  background: rgba(196, 39, 44, 0.22);
  color: #fff;
}
.site-header.is-scrolled .nav-dropdown-trigger { color: #fff; }
.site-header.is-scrolled .nav-dropdown-trigger:hover { color: var(--color-red-soft); }

.header-actions { display: flex; align-items: center; gap: 0.75rem; }
.call-chip {
  display: none;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--color-red);
  padding: 0.6rem 1rem;
  border-radius: var(--radius-full);
  border: 1.5px solid var(--color-border);
  white-space: nowrap;
  flex-shrink: 0;
  transition: border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}
.call-chip:hover { border-color: var(--color-red); background: var(--color-red-soft); }
.call-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 999px;
  color: var(--color-red);
  background: var(--color-red-soft);
}

.menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: transparent;
  border: none;
  color: var(--color-text-primary);
}
.menu-toggle:hover { background: var(--color-bg-soft); }

@media (min-width: 900px) {
  .nav-desktop { display: flex; }
  .call-chip { display: inline-flex; }
  .call-icon-btn { display: none; }
  .menu-toggle { display: none; }
  /* Pre-existing pinch point: right at 900px, nav links + phone chip + CTA
     button don't quite fit together. Tighten header-only spacing (not the
     shared --margin-desktop token used across the rest of the site) so
     nothing overflows right where the desktop nav first turns on. */
  .site-header .header-inner { padding-inline: 14px; gap: 0.65rem; }
  .nav-desktop { gap: 1rem; }
  .header-actions { gap: 0.5rem; }
}
@media (min-width: 1180px) {
  .site-header .header-inner { padding-inline: var(--margin-desktop); gap: 1rem; }
  .nav-desktop { gap: 2rem; }
  .header-actions { gap: 0.75rem; }
}

/* ---- Top/hero state (scroll position 0), >=900px: stays on the same
   warm-white glass as the base/mobile header (rgba(252,251,249,…) from the
   shared .site-header rule above) rather than a dark overlay — nav links,
   the dropdown trigger and the call chip all already default to dark,
   light-bg-friendly colors (see their base rules above), so nothing here
   needs to flip them. Only the scrolled pill below goes dark. */

/* -------------------------------------------------------------------------
   Floating glass pill navigation (scroll state, >=900px only)
   AVIO's interaction/shape logic, MASKOS's own colors: on scroll the header
   detaches from the top edge, narrows to a centered pill, and turns into a
   translucent anthracite glass bar. Mobile/tablet-portrait (<900px) keeps
   the plain full-width header from the block above — untouched.
   ------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .site-header.is-scrolled {
    top: 14px;
    /* Tablet/narrow-laptop tier: near-full width, small side margin (see
       the >=1180px tier below for the dramatic desktop shrink) — enough
       room for nav links + phone chip + CTA to sit on one line. */
    width: calc(100% - 28px);
    margin-inline: auto;
    background: rgba(32, 31, 29, 0.78);
    border-color: rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    box-shadow: 0 8px 30px rgba(20, 18, 16, 0.18);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
  }
  .site-header.is-scrolled .header-inner {
    height: 60px;
    padding-inline: 16px;
    gap: 0.75rem;
  }
  .site-header.is-scrolled .nav-desktop { gap: 0.75rem; }
  .site-header.is-scrolled .header-actions { gap: 0.4rem; }
  .site-header.is-scrolled .brand,
  .site-header.is-scrolled .nav-desktop a {
    color: #fff;
  }
  .site-header.is-scrolled .brand .place {
    color: rgba(255, 255, 255, 0.72);
  }
  .site-header.is-scrolled .nav-desktop a:hover {
    color: var(--color-red-soft);
  }
  .site-header.is-scrolled .call-chip {
    color: #fff;
    border-color: rgba(255, 255, 255, 0.28);
    background: rgba(255, 255, 255, 0.06);
  }
  .site-header.is-scrolled .call-chip:hover {
    border-color: rgba(255, 255, 255, 0.45);
    background: rgba(255, 255, 255, 0.14);
  }
}

@media (min-width: 900px) and (max-width: 1099px) {
  /* Narrower tablet/laptop landscape: brand + 4 nav links + phone chip + CTA
     don't fit on one line with the subline included (measured ~912px of
     content alone at 900px viewport). Hide it in both rest and scrolled
     states here — it comes back from 1100px up where there's room. */
  .brand .place { display: none; }
  /* Logo lockup is wider than the old text block was, so this tier also
     swaps the phone-number chip for the existing compact round call
     button (already used on mobile) to keep everything on one line. Must
     come after the base >=900px .call-chip rule above to win. */
  .call-chip { display: none; }
  .call-icon-btn { display: inline-flex; }
}

@media (min-width: 1180px) {
  .site-header.is-scrolled {
    /* Desktop tier: the dramatic AVIO-style shrink into a capped pill. */
    width: min(calc(100% - 64px), 1100px);
  }
  .site-header.is-scrolled .header-inner {
    padding-inline: 32px;
    gap: 1rem;
  }
  .site-header.is-scrolled .nav-desktop { gap: 1.75rem; }
  .site-header.is-scrolled .header-actions { gap: 0.75rem; }
}

/* Mobile nav drawer */
.nav-mobile {
  position: fixed;
  inset: 76px 0 0 0;
  background: var(--color-surface);
  z-index: 99;
  transform: translateX(100%);
  transition: transform 0.3s ease;
  overflow-y: auto;
}
.nav-mobile.is-open { transform: translateX(0); }
.nav-mobile ul { display: flex; flex-direction: column; padding: 1.5rem var(--margin-mobile); gap: 0.25rem; }
.nav-mobile a {
  display: block;
  padding: 1rem 0.5rem;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--color-text-primary);
  border-bottom: 1px solid var(--color-bg-soft);
}
.nav-mobile .nav-mobile-cta { margin-top: 1rem; padding: 0 0.5rem; display: flex; flex-direction: column; gap: 0.75rem; }

/* "Leistungen" as an in-drawer accordion (not a link to nowhere) — the
   same 4 categories as the desktop dropdown, indented as sub-items. */
.nav-mobile-group-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  font: inherit;
  text-align: left;
  padding: 1rem 0.5rem;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--color-text-primary);
  border-bottom: 1px solid var(--color-bg-soft);
}
.nav-mobile-group-trigger .nav-caret { transition: transform 0.2s ease; }
.nav-mobile-group.is-open .nav-mobile-group-trigger .nav-caret { transform: rotate(180deg); }
/* Overrides the generic .nav-mobile ul rule above (display:flex + padding),
   which also matches this nested <ul> — that padding alone was ~48px, so
   max-height:0 never actually collapsed it (a flex column's implicit
   min-height:auto floors it at content size unless overridden here). Needs
   the two-class selector: .nav-mobile ul is (0,1,1) specificity, which
   beats a single .nav-mobile-subitems (0,1,0) regardless of source order. */
.nav-mobile-group .nav-mobile-subitems {
  display: block;
  padding: 0;
  gap: 0;
  max-height: 0;
  min-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}
/* Bumped from 320px: six group entries (was four) plus the Busse divider
   need more room to fully unfold, especially where labels wrap to two
   lines on narrow screens. */
.nav-mobile-group.is-open .nav-mobile-subitems { max-height: 480px; }
.nav-mobile-subitems a {
  padding: 0.85rem 0.5rem 0.85rem 1.5rem;
  font-size: 1rem;
  font-weight: 500;
  color: var(--color-text-secondary);
}
@media (min-width: 900px) { .nav-mobile { display: none; } }

/* -------------------------------------------------------------------------
   Hero
   ------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 640px;
  /* Fills the actual visible mobile screen so only the hero photo shows
     at rest — you have to scroll to reach the white content below,
     matching >=768px's own full-viewport treatment further down. 640px
     above is the fallback for browsers that don't support svh; 100svh
     (not 100vh) specifically because it's the SMALL viewport height —
     stable across the address bar showing/hiding as you scroll, unlike
     100vh, which would reintroduce exactly the reflow jump fixed above by
     making the hero's own height renegotiate mid-scroll. */
  min-height: 100svh;
  display: flex;
  /* Maskos' own request: text sits up in the photo's sky/empty area
     instead of vertically centered, so the fleet lower in the frame
     stays visible instead of getting text laid over it. Top padding
     (not 0) keeps it off the very top edge/header, still reads as
     "up near the top" without looking cramped. */
  align-items: flex-start;
  padding: 6.5rem 0 3.5rem;
  overflow: hidden;
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
/* The <picture> wrapping the hero <img> is a plain block box with no
   intrinsic height of its own — without an explicit height it sizes to
   the img's natural aspect ratio (about 810px tall on a 1440px-wide
   viewport) instead of filling this absolutely-positioned 100%-tall
   container. That left a few hundred px of empty space below the actual
   photo, still covered by the dark ::after gradient below, which is what
   read as a "grey bar" under the hero on every page. Stretching the
   picture to 100% lets the img's own height:100% + object-fit:cover
   below actually fill the hero and crop correctly, with zero gap. */
.hero-media picture {
  width: 100%;
  height: 100%;
}
.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 62%;
}
/* Small disclosure for the hero photo whenever it's an AI-touched-up shot
   (currently is again) — bottom-right corner, roughly where
   .trust-badge-float (fixed, viewport-relative) sits on initial load, but
   kept part of the hero itself so it scrolls away with the photo instead
   of floating over the rest of the page. Text-shadow (not just low
   opacity) keeps it readable regardless of what's directly behind it. */
.hero-ai-note {
  position: absolute;
  right: 18px;
  bottom: 14px;
  z-index: 1;
  font-size: 0.72rem;
  color: rgba(255, 255, 255, 0.8);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.75), 0 0 2px rgba(0, 0, 0, 0.6);
  letter-spacing: 0.02em;
  pointer-events: none;
}
@media (max-width: 699px) {
  .hero-ai-note { right: 12px; bottom: 10px; font-size: 0.64rem; }
}
/* The two full-height hero photos (.hero/.about-hero, both deliberately
   min-height:calc(100vh + 48px) at >=768px — see those rules — so
   scrolling into the arch transition starts soon rather than after a dead
   zone) need different handling than .about-fact-photo's plain in-flow
   card, the third place this class is reused:
   1. Positioned from the SECTION's bottom edge (like the base rule above),
      this note sat ~48px+header-height below the fold at rest on both
      heroes — invisible without scrolling first, on any real viewport
      height.
   2. The bottom-RIGHT corner (the base rule's side) is also where
      .trust-badge-float already lives — fixed, ~180px tall, always
      visible on desktop unlike its mobile-only hide-during-hero behaviour
      — so simply pulling this note up into view there would still overlap
      the badge.
   Fixed positioning (viewport-relative, like the badge) sidesteps the fold
   math entirely, and sitting just to the badge's left — still the same
   bottom-right corner, not the opposite side — sidesteps the collision
   (the hero's own CTA buttons live on the left, so that side isn't free
   either). .is-past-hero-fold (already toggled by the same small
   scroll-threshold that fades .hero-arch in) fades it back out once the
   photo starts scrolling away, preserving the original intent that it not
   float over the rest of the page. */
@media (min-width: 768px) {
  .hero-media .hero-ai-note, .about-hero-media .hero-ai-note {
    position: fixed;
    right: 245px;
    bottom: 24px;
    transition: opacity 280ms ease;
  }
  .is-past-hero-fold .hero-media .hero-ai-note,
  .is-past-hero-fold .about-hero-media .hero-ai-note {
    opacity: 0;
  }
}
/* .hero-content/.about-hero-content carry the .container class for their
   side padding, but NOT its centering: .container also caps at
   --container-max (1280px) and auto-centers, which on any wider viewport
   left a large empty gap between the true left edge of the (edge-to-edge)
   photo and the text — .about-hero-content lost this override in an
   earlier pass (only .hero-content kept it), which is exactly why the
   Über-Maskos/Propangas heroes sat ~80px further right than the
   homepage's at 1440px+ widths despite using the same --margin-desktop.
   Dropping the cap on both lets the flex column below start flush with
   the homepage's own left edge. */
.hero-content, .about-hero-content { max-width: none; margin-inline: 0; }
.hero-content {
  position: relative;
  z-index: 2;
  color: #fff;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}

/* Even veil over the full photo (replaces the old .hero-panel-shape
   "Halbbogen" — a dark curved backdrop that only covered the left half
   and hid the vehicles there). Just enough contrast to keep the
   centered text readable while the fleet stays clearly visible;
   matches .about-hero-veil on the Über-Maskos page. */
.hero-veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(10, 9, 8, 0.32);
  pointer-events: none;
}

.hero-panel {
  position: relative;
  z-index: 2;
  max-width: min(90%, 640px);
}

.hero-badge {
  /* flex (not inline-flex) + fit-content: block-level so the eyebrow right
     after it in the markup still starts on its own line, same as when a
     wrapper div forced that — but sized to its own content, not full width. */
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.38);
  padding: 0.4rem 0.9rem;
  border-radius: var(--radius-full);
  backdrop-filter: blur(6px);
  margin-bottom: 1.25rem;
}
/* Flyer-group badge: bridges the printed Maskos tariff flyer (Gruppe
   A/B/C/D-E) and this page — a customer holding the flyer should recognize
   their group instantly. Deliberately a solid red pill, not a translucent
   one like .hero-badge above, so it doesn't read as the same "location"
   chip; sits between .hero-badge and .hero-eyebrow in markup order. */
.hero-group-badge {
  display: flex;
  width: fit-content;
  align-items: center;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--color-red);
  color: #fff;
  padding: 0.35rem 0.85rem;
  border-radius: var(--radius-full);
  margin-bottom: 0.75rem;
}
.hero .hero-eyebrow {
  /* The base .eyebrow color (brand red) can land directly over the red
     MASKOS livery lettering in the photo, where it nearly disappears
     regardless of shadow strength. White (matching the rest of the hero
     text) keeps it legible over any part of the photo without a global
     darkening pass. */
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
}
.hero h1 {
  font-size: clamp(2rem, 5vw + 0.5rem, 3.5rem);
  letter-spacing: -0.02em;
  margin-bottom: 1.1rem;
  /* Back to left-aligned, sitting in the photo's sky area now (see
     .hero's own align-items:flex-start) — no longer needs the wider
     centered-balance box, just a cap that keeps it off the fleet lower
     in the frame. */
  max-width: 30ch;
  text-wrap: balance;
  text-shadow: 0 2px 20px rgba(0, 0, 0, 0.35);
}
.hero p {
  font-size: clamp(1.05rem, 1.2vw + 0.7rem, 1.25rem);
  max-width: 46ch;
  color: rgba(255, 255, 255, 0.95);
  margin-bottom: 2rem;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.3);
}
.hero-actions { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 0.9rem; }

@media (min-width: 768px) {
  /* Full viewport height plus a little extra clearance keeps the hero
     photo dominant at rest, on top of the 76px header above the hero —
     tight on purpose, so scrolling into the arch transition (see
     .hero-arch) happens soon rather than after a long dead zone. */
  .hero { min-height: calc(100vh + 48px); padding: 8.5rem 0 4.5rem; }
}

/* -------------------------------------------------------------------------
   Sections
   ------------------------------------------------------------------------- */
section { padding: 4rem 0; }
@media (min-width: 900px) { section { padding: 6rem 0; } }

.section-head { text-align: center; max-width: 640px; margin: 0 auto 3rem; }
.eyebrow {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-red);
  margin-bottom: 0.75rem;
}
.section-head h2 {
  font-size: clamp(1.6rem, 2.4vw + 0.8rem, 2.4rem);
  color: var(--color-text-primary);
  margin-bottom: 0.75rem;
}
.section-head p { color: var(--color-text-secondary); font-size: 1.05rem; }

.bg-alt { background: var(--color-bg-soft); }
.bg-white { background: var(--color-surface); }

/* Fade-in on scroll */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.is-visible { opacity: 1; transform: translateY(0); }

/* -------------------------------------------------------------------------
   Shared "Anfragen ->" link used inside each journey station's copy block
   ------------------------------------------------------------------------- */
.card-link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--color-red);
  transition: color 0.2s ease;
}
.card-link:hover { color: var(--color-red-dark); }
.card-link svg { width: 16px; height: 16px; transition: transform 0.2s ease; }
.card-link:hover svg { transform: translateX(3px); }

/* Station 05 (PKW-Anhänger) is the only station with two stacked
   card-links instead of one: a secondary "show sizes" trigger above the
   usual red "Unverbindlich anfragen". A plain flex column keeps them on
   their own lines without changing .card-link's own inline-flex sizing
   (which every other station still relies on as a single link). */
.card-link-group { display: flex; flex-direction: column; align-items: flex-start; gap: 0.6rem; }
/* .card-link is normally an <a> — a plain <button> sharing the class
   (the trailer-sizes trigger) needs its native chrome (background,
   border, padding) stripped explicitly, or Safari/Chrome's default
   button box shows through and it reads as a boxed pill sitting
   slightly off-line from the plain-text link below it. */
.card-link {
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
}
/* Muted vs. the primary red link, so it reads as the secondary,
   informational action (opens a table) rather than the main CTA. */
.card-link-secondary { color: var(--color-text-secondary); }
.card-link-secondary:hover { color: var(--color-text-primary); }

/* -------------------------------------------------------------------------
   Angebot — route journey (4 stations, each an image+copy pair, connected
   by a scroll-drawn route). Desktop/tablet: each station is a fixed-height
   row (own background SVG route, own path per tier — not one path scaled
   down) so the hand-tuned path coordinates below stay in sync with the
   real pin positions. Mobile: normal vertical flow, no SVG, a simple
   dashed CSS connector between stations.
   ------------------------------------------------------------------------- */
.journey-wide {
  max-width: 1500px;
  margin-inline: auto;
  padding-inline: var(--margin-mobile);
}
@media (min-width: 768px) { .journey-wide { padding-inline: var(--margin-desktop); } }

.journey-cta {
  margin-top: 3rem;
  background: var(--color-bg-soft);
  border-radius: var(--radius-lg);
  padding: 2rem 2.25rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}
.journey-cta-text h3 { font-size: 1.25rem; color: var(--color-text-primary); margin-bottom: 0.4rem; }
.journey-cta-text p { color: var(--color-text-secondary); font-size: 0.95rem; max-width: 42ch; }
.journey-cta-actions { display: flex; align-items: center; }
@media (max-width: 599px) {
  .journey-cta { padding: 1.75rem; }
  .journey-cta-actions { width: 100%; }
  .journey-cta-actions .btn { justify-content: center; width: 100%; }
}

.journey-track { position: relative; margin-top: 2.5rem; }
/* visibility, not display:none — keeps SVG geometry (getTotalLength) valid
   in script.js regardless of which tier is currently active; absolute
   positioning already means neither takes up layout space either way. */
.journey-route, .journey-route-tablet { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; visibility: hidden; }

/* z-index:0 gives each station its own stacking context, so the negatively
   z-indexed .journey-num below stays behind this station's own image/text
   without falling behind the section's white page background. */
.journey-station { position: relative; z-index: 0; margin-bottom: 3rem; }
.journey-station:last-child { margin-bottom: 0; }

.journey-media { position: relative; }
/* .journey-photo-frame is the sized, clipped card (radius/shadow/height) —
   split out from .journey-photo (the <picture>) so the hover zoom below can
   scale just the picture inside a fixed, non-scaling frame. */
.journey-photo-frame {
  position: relative;
  z-index: 1;
  width: 100%;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}
.journey-photo { position: relative; display: block; width: 100%; height: 100%; transform-origin: center; }
/* transform-origin only — script.js drives scale()+translateY() together
   for a subtle scroll-pan per photo; no motion at all until JS sets it
   (and it never does under prefers-reduced-motion). Left untouched by the
   hover effect below, which animates .journey-photo (the <picture>) instead
   of the img itself, so the two motions never fight over the same transform. */
.journey-photo img { width: 100%; height: 100%; object-fit: cover; display: block; transform-origin: center; }

/* Soft "lift" + zoom + one-shot light sweep on hover — hover-capable
   pointers only, and only once motion is allowed. Deliberately touches
   .journey-photo-frame (lift/shadow) and .journey-photo (zoom) rather than
   .journey-photo img, which script.js drives continuously on scroll; a
   transition on that same property would fight the scroll-pan and make it
   lag behind the actual scroll position. */
@media (hover: hover) and (pointer: fine) {
  .journey-photo-frame {
    transition: transform 620ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow 620ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .journey-photo {
    transition: transform 620ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .journey-photo-frame::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(115deg, transparent 42%, rgba(196, 39, 44, 0.16) 50%, transparent 58%);
    opacity: 0;
  }
  .journey-photo-frame:hover {
    transform: translateY(-4px);
    box-shadow: 0 18px 40px rgba(28, 28, 26, 0.14), 0 10px 26px rgba(196, 39, 44, 0.16);
  }
  .journey-photo-frame:hover .journey-photo { transform: scale(1.016) translateX(-0.8%); }
  .journey-photo-frame:hover::after { animation: journey-photo-shine 620ms cubic-bezier(0.16, 1, 0.3, 1); }
}
@keyframes journey-photo-shine {
  0% { opacity: 0; transform: translateX(-40%); }
  12% { opacity: 1; }
  80% { opacity: 1; }
  100% { opacity: 0; transform: translateX(40%); }
}
@media (prefers-reduced-motion: reduce) {
  .journey-photo-frame, .journey-photo { transition: none !important; }
  .journey-photo-frame::after { display: none !important; }
  .journey-photo-frame:hover { transform: none; box-shadow: var(--shadow-md); }
  .journey-photo-frame:hover .journey-photo { transform: none; }
}

/* Same flyer-bridge idea as .hero-group-badge, sized down for the journey
   card next to the station's own big pale number. */
.journey-group-tag {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-red);
  background: var(--color-red-soft);
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius-full);
  margin-bottom: 0.5rem;
}
.journey-content h3 { font-family: var(--font-head); font-size: 1.5rem; color: var(--color-text-primary); margin-bottom: 0.6rem; }
.journey-content p { color: var(--color-text-secondary); font-size: 1rem; line-height: 1.6; max-width: 42ch; margin-bottom: 1.1rem; }

/* Pins are a plain teardrop (circle + rotated-square tail), not a rotated
   whole element, so the number inside stays upright with no counter-rotate
   trick needed. script.js reads this element's own getBoundingClientRect()
   for the scroll math — the tail is a pseudo-element and doesn't affect it. */
.journey-pin {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--color-red);
  color: #fff;
  font-family: var(--font-head);
  font-weight: 700;
  box-shadow: 0 6px 16px rgba(196, 39, 44, 0.35), 0 2px 4px rgba(28, 28, 26, 0.12);
  z-index: 4;
}
.journey-pin::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -7px;
  width: 15px;
  height: 15px;
  background: var(--color-red);
  border-radius: 0 0 5px 0;
  transform: translateX(-50%) rotate(45deg);
  z-index: -1;
}

/* Large pale station numbers — a direct child of .journey-station (not
   nested in .journey-media), sized and placed to sit boldly behind BOTH
   the image and the text of its own station (Massivhaus-style), never
   floated independently in the track. z-index:-1 relies on the station's
   own z-index:0 stacking context above — without that, a negative
   z-index here would fall behind the page background instead of just
   behind this station's content. */
.journey-num {
  position: absolute;
  font-family: var(--font-head);
  font-weight: 700;
  line-height: 1;
  color: var(--color-border);
  user-select: none;
  pointer-events: none;
  z-index: -1;
}

/* Presence is a continuous 0-1 value script.js sets per station every scroll
   tick from real pin positions — not a one-shot reveal, so scrolling back up
   just plays the same math backwards. --presence defaults to 1 so no-JS
   visitors (the custom property is simply never set) always see full
   opacity; JS-driven dimming only ever makes not-yet-reached stations
   *less* prominent (down to ~0.55/0.4), never invisible. */
.journey-station { --presence: 1; }
.journey-media, .journey-content {
  opacity: calc(0.65 + var(--presence) * 0.35);
  transition: opacity 150ms linear;
}
.journey-pin {
  opacity: calc(0.55 + var(--presence) * 0.45);
  transition: opacity 150ms linear, box-shadow 250ms ease;
}
.journey-station.is-reached .journey-pin {
  box-shadow: 0 6px 16px rgba(196, 39, 44, 0.5), 0 2px 4px rgba(28, 28, 26, 0.12);
}

.journey-route path,
.journey-route-tablet path {
  fill: none;
}
.route-base { stroke: var(--color-border); stroke-width: 3; stroke-dasharray: 2 10; stroke-linecap: round; }
.route-seg { stroke: var(--color-red); stroke-width: 3; stroke-linecap: round; }

/* ---- Mobile default: stacked image-over-copy, pin on the photo corner,
   no SVG route (a dashed CSS connector instead), numbers hidden — a giant
   number has no clean spot once everything else is single-column. ---- */
.journey-photo-frame { aspect-ratio: 1400 / 788; }
.journey-media { margin-bottom: 1.25rem; }
.journey-pin { width: 34px; height: 34px; font-size: 0.85rem; top: 14px; left: 14px; }
.journey-pin::after { width: 12px; height: 12px; bottom: -6px; }
.journey-num { display: none; }
@media (max-width: 699px) {
  .journey-station:not(:first-child)::before {
    content: "";
    display: block;
    width: 3px;
    height: 36px;
    margin: 0 auto 1.25rem;
    background-image: repeating-linear-gradient(to bottom, var(--color-red) 0 6px, transparent 6px 12px);
  }
}

/* ---- Tablet: stacked image-over-copy like mobile, but wider photos, a
   visible (smaller) number, and its own gently-curved SVG route down the
   left edge — compact, not the full desktop zigzag squeezed down. ---- */
@media (min-width: 700px) and (max-width: 1099px) {
  .journey-route-tablet { visibility: visible; }
  .journey-photo-frame { aspect-ratio: 1400 / 788; }
  .journey-pin { width: 40px; height: 40px; font-size: 0.95rem; top: 20px; left: 20px; }
  .journey-pin::after { width: 14px; height: 14px; bottom: -7px; }
  .journey-num {
    display: block;
    font-size: clamp(4rem, 14vw, 6rem);
    top: -0.35em;
    left: 0;
  }
}

/* ---- Desktop: compact zigzag — each station a 2-column grid (image | copy,
   alternating sides via the --img-left/--img-right modifier). The pin sits
   dead-center on the row (not offset toward either column) so it always
   lands in the gap between image and text, never overlapping the vehicle
   itself — with equal 1fr/1fr columns, the row's horizontal center IS the
   gap's center regardless of gap width. Number is tucked behind the outer
   edge of the image, coupled to that station's own media block. ---- */
@media (min-width: 1100px) {
  .journey-route { visibility: visible; }
  .journey-station {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 88px;
    align-items: center;
    min-height: 310px;
    margin-bottom: 30px;
  }
  .journey-media { grid-column: 1; grid-row: 1; }
  .journey-content { grid-column: 2; grid-row: 1; }
  .journey-station--img-right .journey-media { grid-column: 2; }
  .journey-station--img-right .journey-content { grid-column: 1; }

  .journey-photo-frame { aspect-ratio: 1400 / 788; }
  .journey-content h3 { font-size: 1.6rem; }
  .journey-content p { font-size: 1rem; }
  /* Text stays left-aligned for readability, but the block itself hugs the
     inner edge (toward the pin/route), flush against the gap — mirroring
     img-left stations, whose content starts exactly at the gap already
     because that's where column 2 begins. Without this, a short 42ch
     paragraph left-anchored in img-right's wide column1 would leave a
     dead gap before ever reaching the pin, breaking that symmetry. */
  .journey-station--img-right .journey-content { margin-left: auto; }

  /* Always centered — see comment above. */
  .journey-pin { width: 44px; height: 44px; font-size: 0.98rem; top: 50%; left: 50%; transform: translate(-50%, -50%); }
  .journey-pin::after { width: 16px; height: 16px; }

  /* Massivhaus-style: big and bold, rising up out of the whitespace above
     its own photo and dipping down behind just the photo's very top edge
     (image z-index:1 vs. this z-index:-1) — not centered fully behind it,
     which would hide the whole numeral with nothing left visible. top is
     a fixed px, not a %, so the poke-above amount is exact: the photo
     sits 30px below the row top (row min-height 360 − photo height 300,
     halved by align-items:center), so top:-50px clears the previous
     station's 40px margin-bottom with room to spare while dipping only
     ~40-70px into this station's own photo — more visible than hidden.
     Alternating offset per station (not one identical value ×4) so the
     four don't read as a mechanically repeated template. */
  .journey-num { display: block; font-size: clamp(7rem, 8.5vw, 10rem); top: -50px; }
  .journey-station--img-left .journey-num { left: 0; }
  .journey-station--img-right .journey-num { right: 0; }
  .journey-station-2 .journey-num, .journey-station-4 .journey-num { top: -40px; }
}

/* -------------------------------------------------------------------------
   Vertrauen — hero-to-content transition
   Organic curve rising out of the hero, two decorative line-art PNGs
   (real assets, not redrawn) flanking the trust cards.
   ------------------------------------------------------------------------- */
.trust-transition {
  position: relative;
  /* Override the generic section's 4rem/6rem top padding — the arch
     itself already creates separation from the hero, so the content
     underneath it should follow soon after, not float in empty space. */
  padding-top: clamp(1.25rem, 3vw, 2rem);
  /* No overflow:hidden here (deliberately): .hero-arch below pokes up
     above this section's own top edge into the hero photo, and clipping
     that — even just vertically via overflow-x/-y split — is what
     silently hid it before (overflow-y computes to "auto", which still
     clips, the moment overflow-x isn't "visible" too; there's no CSS way
     to clip one axis only without also clipping the other). The truck
     illustration's negative-left bleed (see .trust-illustration-truck)
     doesn't need clipping here either — body already has its own
     overflow-x:hidden for exactly this kind of horizontal bleed. */
}
.trust-transition > .container {
  position: relative;
  z-index: 2;
}
.trust-transition .section-head {
  margin-bottom: 2rem;
}

/* Large architectural arch marking the hero → content boundary. A single
   wide ellipse (border-radius 50%/100% draws one full dome across the top
   edge, not a wave) — much wider than the viewport so only a gentle, wide
   curve of it is ever on screen. Positioned with bottom:100% so it sits
   entirely above this section's own box, overlapping the last bit of the
   hero photo.
   Visibility is a plain two-state fade (see .has-js below), toggled by a
   class on <html> from a small fixed scroll threshold in script.js — NOT
   geometry (e.g. "make the hero tall enough that the arch starts below the
   viewport"). The header is position:sticky and takes real space in the
   document (not an overlay), so its height eats into the hero's assumed
   clearance and varies with viewport size — relying on hero height to hide
   the arch left a sliver of it visible at scrollY 0 on real screens. A
   scroll-triggered class is independent of all of that: 0% visible at rest,
   full stop, on any viewport. */
/* .hero-arch itself is deliberately much wider than any viewport (see
   below) so its curve reads as shallow rather than a full semicircle; that
   horizontal bleed only ever looked fine because it was assumed to be
   clipped by body's overflow-x:hidden. In real browsers a wide
   position:absolute box like this is NOT reliably contained by an
   ancestor's overflow-x:hidden the way box-generating in-flow content is —
   confirmed live: document.documentElement.scrollWidth measured the full
   unclipped width, making the whole page horizontally pannable on mobile.
   .hero-arch-clip is a tightly-sized wrapper (same footprint the arch used
   to occupy) that does the actual clipping locally, so the section below
   doesn't need overflow:hidden itself — that was tried before and instead
   cut the arch off vertically where it pokes up into the hero photo. */
.hero-arch-clip {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: clamp(60px, 8vw, 160px);
  overflow: hidden;
  z-index: 1;
  pointer-events: none;
}
@media (max-width: 767px) {
  .hero-arch-clip { height: clamp(64px, 18vw, 110px); }
}
.hero-arch {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: max(1400px, 180vw);
  max-width: 2800px;
  height: 100%;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  background: var(--color-surface);
}
/* Mobile gets a plain straight edge instead of the curve: the dome's
   elliptical border-radius is drawn from a box far wider than the
   viewport (so only a shallow slice of the curve ever shows), and on
   narrow screens the mobile browser's own address bar showing/hiding as
   you scroll repeatedly resizes the real viewport — which reflows that
   oversized ellipse each time and reads as the whole boundary "jumping".
   A flat rectangle has no curve to reflow, so it can't jitter the same
   way; simplified to 100% width too since the wide-bleed trick only ever
   existed to make the curve read as shallow. */
@media (max-width: 767px) {
  .hero-arch { width: 100%; border-radius: 0; }
}
/* Always fully visible, no scroll-triggered reveal: the fade-in +
   translateY(8px) used to run on a small scroll-position threshold, and
   on real (non-headless) mobile browsers that threshold reads differently
   as the address bar shows/hides and resizes the viewport mid-scroll —
   perceived as the whole boundary "jumping". A static, always-shown arch
   has no state to get out of sync, on any device. */

.trust-illustration {
  position: absolute;
  /* Anchored up by the curve/headline, framing the top of the section,
     rather than centered on the full section height next to the cards. */
  top: clamp(10px, 3vw, 50px);
  width: clamp(240px, 26vw, 460px);
  z-index: 0;
  pointer-events: none;
  user-select: none;
}
.trust-illustration img {
  width: 100%;
  height: auto;
  display: block;
}
.trust-illustration-truck {
  left: clamp(-60px, -3vw, 0px);
  opacity: 0.4;
}
.trust-illustration-route {
  /* Was a negative right offset (bled up to ~60px past the section's own
     edge, same idea as the truck illustration's negative-left bleed) —
     but unlike a leftward bleed, a rightward one genuinely extends
     document.documentElement.scrollWidth past the viewport (confirmed
     live), making the whole page horizontally pannable on desktop widths
     ≥1100px. Flush at 0 instead — matches what already happens below
     1100px via the override two rules down. */
  right: 0;
  opacity: 0.65;
}
@media (max-width: 1099px) {
  /* The 2-column card grid at this width leaves little clearance beside
     it, so keep the illustrations up by the (narrower, centered)
     headline. Smaller and fainter than the desktop tier so an incidental
     edge under the text never competes with it. */
  .trust-illustration { width: clamp(90px, 15vw, 190px); top: 20px; }
  .trust-illustration-truck { left: 0; opacity: 0.25; }
  .trust-illustration-route { right: 0; opacity: 0.4; }
}
@media (max-width: 639px) {
  /* Prioritize legibility on phones over squeezing both motifs in. */
  .trust-illustration { display: none; }
}

/* Scroll-triggered reveal: route "draws in" via a clip-path wipe (the
   asset is a flat PNG, not a vector path, so this stands in for a literal
   stroke-dashoffset draw), truck fades and lifts a few px. Progressive
   enhancement — .has-js is added by script.js, so this only ever hides
   content for JS users right before the observer reveals it; no-JS users
   see the final state immediately. Fires once via IntersectionObserver;
   reduced-motion collapses the transition to ~0ms globally (see reset). */
.has-js .trust-illustration-truck {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 800ms ease 100ms, transform 800ms ease 100ms;
}
.has-js .trust-transition.is-visible .trust-illustration-truck {
  opacity: 0.4;
  transform: translateY(0);
}
.has-js .trust-illustration-route {
  opacity: 0;
  clip-path: inset(0 100% 0 0);
  transition: opacity 900ms ease 150ms, clip-path 1100ms cubic-bezier(0.4, 0, 0.2, 1) 150ms;
}
.has-js .trust-transition.is-visible .trust-illustration-route {
  opacity: 0.65;
  clip-path: inset(0 0% 0 0);
}
@media (max-width: 1099px) {
  .has-js .trust-transition.is-visible .trust-illustration-truck { opacity: 0.25; }
  .has-js .trust-transition.is-visible .trust-illustration-route { opacity: 0.4; }
}

.grid-trust {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gutter);
}
@media (min-width: 700px) { .grid-trust { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .grid-trust { grid-template-columns: repeat(4, 1fr); } }

.trust-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: 2rem 1.5rem;
  text-align: center;
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--color-border);
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.trust-card:hover {
  transform: translateY(-8px);
  box-shadow: var(--shadow-lg);
  border-color: var(--color-red-soft);
}
.trust-icon {
  width: 56px;
  height: 56px;
  border-radius: 999px;
  background: var(--color-red-soft);
  color: var(--color-red);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 1.25rem;
  transition: transform 0.25s ease, background-color 0.25s ease, color 0.25s ease;
}
.trust-card:hover .trust-icon {
  background: var(--color-red);
  color: #fff;
  transform: scale(1.08);
}
.trust-icon svg { width: 26px; height: 26px; }
.trust-card h3 { font-size: 1.05rem; margin-bottom: 0.5rem; color: var(--color-text-primary); }
.trust-card p { font-size: 0.92rem; color: var(--color-text-secondary); }

/* -------------------------------------------------------------------------
   Bewertungen — static review data (no API), auto-scrolling carousel.
   ------------------------------------------------------------------------- */
.reviews-summary {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
  font-size: 0.95rem;
  color: var(--color-text-secondary);
}
.reviews-stars { color: #f5a623; letter-spacing: 0.1em; }
.reviews-summary strong { color: var(--color-text-primary); }

/* Native scroll-snap carousel, auto-scrolled by rAF in
   js/include-testimonials.js (wireUpAutoScroll) rather than a CSS
   animation, so it stays the same real overflow:auto scroll container
   prev/next, native touch swipe/drag, and keyboard all rely on — the
   auto-scroll just nudges marquee.scrollLeft a fraction of a px per frame
   and pauses the moment anything else touches the container. The track
   holds two identical sets of cards (see partials/testimonials.html); once
   scrollLeft passes the first set's width the loop silently subtracts that
   same width back off, landing on the pixel-identical duplicate card — an
   invisible seam, no jump. Cards keep a fixed comfortable width so, on a
   normal desktop container, roughly three sit fully visible with a
   deliberate slice of the next one peeking at the edge. */
.reviews-carousel { position: relative; margin-top: 3rem; }
.reviews-marquee {
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  width: 100%;
  max-width: 100vw;
  scroll-snap-type: x proximity;
  scroll-padding-inline: 0.625rem;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
}
.reviews-marquee::-webkit-scrollbar { display: none; }
/* Snap has to stand down while the auto-scroll in include-testimonials.js
   owns scrollLeft — it fights the per-frame increments otherwise, snapping
   back to the current card each time and pinning the marquee in place.
   Restored the instant a user hovers/touches/tabs into the carousel. */
.reviews-marquee.is-auto-scrolling { scroll-snap-type: none; }
.reviews-track {
  display: flex;
  gap: 1.25rem;
  padding-inline: 0.625rem;
}
.review-card {
  flex-shrink: 0;
  width: min(340px, 80vw);
  scroll-snap-align: start;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.review-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }

.reviews-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-md);
  transition: transform 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.reviews-arrow:hover { color: var(--color-red); border-color: var(--color-red-soft); box-shadow: var(--shadow-lg); transform: translateY(-50%) scale(1.06); }
.reviews-arrow-prev { left: 0.5rem; }
.reviews-arrow-next { right: 0.5rem; }
@media (min-width: 900px) {
  .reviews-arrow-prev { left: 1.5rem; }
  .reviews-arrow-next { right: 1.5rem; }
  /* Room for the 44px arrows so they float over the faded mask edge
     instead of sitting on top of the first/last card's own text.
     scroll-padding-inline has to match, or the snap algorithm "corrects"
     the initial scroll position back to its own (stale) 0.625rem target
     the instant the page loads, silently scrolling the row under the
     padding and right back to the arrows again. */
  .reviews-marquee { padding-inline: 4.5rem; scroll-padding-inline: 4.5rem; }
  .reviews-track { padding-inline: 0; }
}
@media (max-width: 599px) {
  /* Native swipe already works great on touch; the buttons mostly add
     visual clutter at this width, so they step aside for the fade edges. */
  .reviews-arrow { display: none; }
}
.review-stars { color: #f5a623; letter-spacing: 0.15em; font-size: 0.95rem; }
.review-text { font-size: 0.92rem; line-height: 1.55; color: var(--color-text-secondary); flex-grow: 1; }
.review-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; font-size: 0.82rem; }
.review-name { font-weight: 700; color: var(--color-text-primary); }
.review-time { color: var(--color-text-muted); }

.reviews-cta { margin-top: 2.5rem; text-align: center; }
/* On the narrowest real phones (~320px, e.g. iPhone SE 1st-gen) this
   button's nowrap text ("Weitere Bewertungen ansehen" + icon) is a few px
   wider than the available content width, which was making the whole page
   horizontally scrollable — confirmed via document.documentElement.
   scrollWidth. Letting just this one long-label button wrap avoids
   loosening .btn's shared white-space:nowrap everywhere else. */
@media (max-width: 359px) {
  #googleReviewsLink { white-space: normal; text-align: center; }
}

/* -------------------------------------------------------------------------
   Visual break band
   ------------------------------------------------------------------------- */
.visual-band {
  position: relative;
  min-height: 380px;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.visual-band-window { position: absolute; inset: 0; overflow: hidden; }
.visual-band-window img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Biased down from center: the source photo's top half is mostly grey
     sky, bottom half is the fleet/building — this keeps the vehicles the
     dominant subject instead of cropping in from an even center. */
  object-position: center 78%;
  transform-origin: center;
  will-change: transform;
}
.visual-band::before {
  content: "";
  position: absolute; inset: 0;
  /* Lighter than before (was 0.88→0.15) — the photo itself should read
     bright now; a soft "glass" panel on .visual-band-content below does
     most of the actual contrast work for the text, so this base layer
     only needs to be a mild assist, not the main mechanism. Neutral
     warm-black, no blue cast, keeps the real red MASKOS lettering true. */
  background: linear-gradient(100deg, rgba(18,16,14,0.45) 0%, rgba(18,16,14,0.22) 45%, rgba(18,16,14,0.08) 75%);
}
/* Soft frosted-glass panel behind the headline/copy — not a hard box:
   generous radius, low-opacity tint, blurred backdrop. Keeps the photo
   itself bright while still guaranteeing contrast regardless of what's
   directly behind the text at any given scroll/pan position. */
.visual-band-content {
  position: relative;
  z-index: 1;
  color: #fff;
  max-width: 34rem;
  margin-inline: auto;
  padding: 1.75rem 2rem;
  border-radius: var(--radius-lg);
  background: rgba(18, 16, 14, 0.32);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  text-align: center;
}
.visual-band-content h2 { font-size: clamp(1.6rem, 2.5vw + 0.6rem, 2.3rem); margin-bottom: 1rem; text-shadow: 0 2px 16px rgba(0, 0, 0, 0.3); }
.visual-band-content p { font-size: 1.05rem; color: rgba(255,255,255,0.92); text-shadow: 0 1px 10px rgba(0, 0, 0, 0.25); }

/* -------------------------------------------------------------------------
   Ablauf (steps)
   ------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------
   Ablauf — "In drei Schritten zum passenden Mietfahrzeug"
   Two-column process section: large editorial text on the left, the three
   steps as an open (card-free) vertical process on the right, connected by
   a scroll-driven timeline echoing the Fahrzeuge journey route above —
   same "grow a red progress line as you scroll" idea, just a straight
   vertical line instead of an SVG path, since these three steps just stack.
   ------------------------------------------------------------------------- */
.process-section { overflow: hidden; }
/* Not a plain .container: this section deliberately bleeds edge-to-edge
   at desktop (the beige card's background reaches the true left edge,
   the step dividers reach the true right edge) rather than sitting in a
   centered, padded box like most sections — max-width caps it only on
   screens wider than 1560px, same ceiling this already had, just no
   longer overridden by an outer .container's own 1280px cap. Mobile
   keeps a small safe inset since there's no long text line here to keep
   content naturally clear of the screen edge the way desktop's short
   headings/short paragraph max-width do. */
.process-container {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  /* No max-width: this section bleeds fully edge-to-edge like the red
     panels elsewhere (Hero, Über Maskos, FAQ) — a cap here reintroduced
     the exact side gap the full-bleed rework was meant to remove, just
     later (on wide-but-not-huge monitors instead of narrow container
     widths). */
  padding-inline: var(--margin-mobile);
}
@media (min-width: 900px) {
  .process-container { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); gap: 4rem; align-items: stretch; padding-inline: 0; }
}

.process-left {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--color-bg-soft);
  padding: 2.5rem 1.75rem;
  display: flex;
  align-items: center;
}
@media (min-width: 900px) {
  .process-left {
    padding: 3rem 3rem 3rem clamp(2rem, 5vw, 4rem);
    /* Square on the left where it now bleeds to the true viewport edge,
       rounded on the right where it meets the steps column. */
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  }
}
.process-left-inner { position: relative; z-index: 1; }
.process-watermark {
  position: absolute;
  left: -0.4rem;
  bottom: -3rem;
  z-index: 0;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: clamp(9rem, 22vw, 15rem);
  line-height: 1;
  color: var(--color-red);
  opacity: 0.05;
  user-select: none;
  pointer-events: none;
}
.process-heading {
  font-size: clamp(2rem, 3.4vw + 0.8rem, 3rem);
  line-height: 1.12;
  margin: 0.75rem 0 1.25rem;
  color: var(--color-text-primary);
}
.process-intro { color: var(--color-text-secondary); font-size: 1.05rem; max-width: 42ch; margin-bottom: 1.75rem; }
.process-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 700;
  color: var(--color-text-primary);
  transition: gap 0.2s ease;
}
.process-cta:hover { gap: 0.85rem; color: var(--color-red); }
.process-cta-arrow {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  background: var(--color-red);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}

.process-right {
  --pi-size: 60px;
  position: relative;
  display: flex;
  flex-direction: column;
}
.process-line {
  position: absolute;
  top: calc(var(--pi-size) / 2);
  bottom: calc(var(--pi-size) / 2);
  left: calc(var(--pi-size) / 2);
  transform: translateX(-50%);
  width: 3px;
  border-radius: 999px;
  background: #e5e0da;
  z-index: 0;
}
.process-line-progress {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 0%;
  border-radius: 999px;
  background: var(--color-red);
}
.process-step {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  gap: 1.5rem;
  padding: 1.75rem 0;
}
.process-step:first-child { padding-top: 0; }
.process-step:last-child { padding-bottom: 0; }
.process-step + .process-step { border-top: 1px solid var(--color-border); }
@media (min-width: 900px) { .process-step { padding: 2.5rem 0; } }

.process-step-icon {
  position: relative;
  flex-shrink: 0;
  width: var(--pi-size);
  height: var(--pi-size);
  border-radius: 999px;
  background: var(--color-red-soft);
  color: var(--color-red);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.25s ease, color 0.25s ease, transform 0.25s ease;
}
.process-step-icon svg { width: 26px; height: 26px; }
.process-step-num {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  background: var(--color-red);
  color: #fff;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.78rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid var(--color-surface);
  transition: transform 0.25s ease;
}
.process-step-body h3 { font-size: 1.2rem; margin-bottom: 0.4rem; color: var(--color-text-primary); }
.process-step-body p { color: var(--color-text-secondary); font-size: 0.98rem; max-width: 46ch; }

/* Reached state, driven by script.js as the red progress line grows past
   each step — restrained on purpose: a small scale, a touch more contrast,
   nothing bouncy. */
.process-step.is-active .process-step-icon {
  background: var(--color-red);
  color: #fff;
  transform: scale(1.03);
}
.process-step.is-active .process-step-num { transform: scale(1.08); }

@media (max-width: 899px) {
  .process-right { --pi-size: 52px; }
  .process-heading br { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .process-step-icon, .process-step-num, .process-cta { transition: none; }
}

/* -------------------------------------------------------------------------
   "Warum Maskos" — was shared by the "Vertrauen" section on the four now-
   removed Leistungsseiten (sprinter/transporter-lkw/busse/anhaenger.html —
   see vercel.json for their redirects). No page uses this component
   anymore; left in place rather than hunted down class-by-class, same as
   the rest of that now-unreferenced page-specific CSS.
   ------------------------------------------------------------------------- */
.about-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  align-items: center;
}
@media (min-width: 900px) { .about-grid { grid-template-columns: 1fr 1fr; gap: 4rem; } }
.about-grid img { border-radius: var(--radius-lg); box-shadow: var(--shadow-md); width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4/3; }
.about-text .eyebrow { display: block; }
.about-text h2 { font-size: clamp(1.6rem, 2.4vw + 0.8rem, 2.2rem); color: var(--color-text-primary); margin-bottom: 1.1rem; }
.about-text p { color: var(--color-text-secondary); margin-bottom: 1rem; font-size: 1.02rem; }
.about-list { margin-top: 1.5rem; display: grid; gap: 0.75rem; }
.about-list li { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.95rem; color: var(--color-text-primary); }
.about-list svg { flex-shrink: 0; width: 20px; height: 20px; color: var(--color-red); margin-top: 2px; }

/* -------------------------------------------------------------------------
   Über Maskos — homepage only. Full-bleed two-column layout (breaks out of
   .container on purpose): a red "blob" panel that touches the true left
   viewport edge, an organic bulge on its right side via elliptical
   border-radius, and — as one visually joined unit — a large real map of
   the Maskos location plus a light info panel docked directly to its right
   edge (equal height, zero gap, so they read as a single card rather than
   the map floating alone). Reuses the truck line-art asset from the
   "Warum Maskos" trust-transition higher up the page.
   ------------------------------------------------------------------------- */
.about-feature-grid {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
}
@media (min-width: 900px) {
  .about-feature-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); align-items: stretch; }
}

.about-feature-panel {
  position: relative;
  overflow: hidden;
  background: linear-gradient(150deg, var(--color-red) 0%, var(--color-red-dark) 100%);
  display: flex;
  align-items: center;
  /* Touches the true left edge of the viewport (breaking out of the
     centered .container). Left padding is a fixed, modest value — NOT
     scaled to viewport width — so the text sits close to the panel's own
     edge at every screen size instead of drifting far to the right on
     ultra-wide monitors. */
  padding: 3rem var(--margin-mobile);
}
@media (min-width: 640px) {
  .about-feature-panel { padding-block: 3.5rem; }
}
@media (min-width: 900px) {
  .about-feature-panel {
    min-height: 620px;
    padding: 4rem 3.5rem 4rem clamp(2rem, 6vw, 5rem);
    /* Elliptical border-radius shorthand (horizontal-radii / vertical-radii):
       square on the left (flush with the viewport edge, no visible corner
       to round), a big semi-ellipse bulge on the right — the "Halbrund"
       shape from the reference, done in pure CSS. */
    border-radius: 0 55% 55% 0 / 0 50% 50% 0;
  }
}

.about-feature-panel-inner {
  position: relative;
  z-index: 2;
  max-width: 46ch;
  /* .about-feature-panel is a flex container with this as its only child —
     without min-width:0, a flex item won't shrink below its own content's
     intrinsic width, so around the ~900-1100px tablet range (where the
     panel itself is narrower than the text's natural width) the text
     overflowed straight through the map/info card next to it instead of
     wrapping. */
  min-width: 0;
}
.about-feature-panel .eyebrow { color: rgba(255, 255, 255, 0.85); display: block; }
.about-feature-panel h2 { color: #fff; font-size: clamp(1.9rem, 2.8vw + 0.9rem, 2.6rem); line-height: 1.15; margin: 0.85rem 0 1.25rem; }
.about-feature-panel p { color: rgba(255, 255, 255, 0.9); margin-bottom: 1.1rem; font-size: 1.08rem; line-height: 1.6; }

.about-feature-list { margin-top: 1.75rem; display: grid; gap: 1rem; }
.about-feature-list li { display: flex; align-items: center; gap: 0.85rem; font-size: 1.05rem; font-weight: 600; color: #fff; }
.about-feature-check {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  background: #fff;
  color: var(--color-red);
  display: flex;
  align-items: center;
  justify-content: center;
}
.about-feature-check svg { width: 14px; height: 14px; }

.about-feature-illustration { position: absolute; pointer-events: none; user-select: none; }
.about-feature-illustration img { width: 100%; height: auto; display: block; }
.about-feature-illustration-bus {
  z-index: 1;
  width: clamp(260px, 36vw, 460px);
  left: 2%;
  bottom: -4%;
  opacity: 0.16;
  /* Source art is a dusty-rose line drawing on transparent — brightness(0)
     + invert turns it into a flat white silhouette so it reads as a quiet
     background shadow on this red panel instead of clashing with it. */
  filter: brightness(0) invert(1);
}

/* Map + info panel, docked together as one unit. On desktop this whole
   unit is pulled left (negative margin, width compensated to match) so it
   visually overlaps the red panel's bulge and reads as a foreground layer
   floating above the background shape, not tucked behind/below it — with
   its own shadow/rounding/clipping living on this wrapper rather than on
   each child, so the map and info panel read as ONE card, not two. It's
   also shorter than the red panel and vertically centered, so red is
   visible peeking out above, below and to the left — the "layering" cue.
   The right edge is left unpadded so the info panel reaches the true
   viewport edge, mirroring how the red panel bleeds to the left edge. */
.about-feature-right {
  display: flex;
  flex-direction: column;
  position: relative;
}
@media (min-width: 900px) {
  .about-feature-right {
    flex-direction: row;
    align-self: center;
    /* Shortening the About text (see .about-feature-panel-inner p) meant
       the grid row's height — previously set by that text being the
       tallest content, not by this map/info side — would otherwise drop
       well below the FAQ panel's fixed height. This floor keeps both
       halves of the pair at roughly their previous presence; raising it
       just grows the map (a real functional element), not empty space. */
    min-height: 780px;
    z-index: 3;
    margin-left: -4.5rem;
    width: calc(100% + 4.5rem);
    border-radius: var(--radius-lg) 0 0 var(--radius-lg);
    overflow: hidden;
    box-shadow: 0 24px 56px rgba(28, 28, 26, 0.22), 0 4px 14px rgba(28, 28, 26, 0.1);
  }
}

.about-feature-map-wrap { position: relative; min-height: 340px; flex: 1 1 auto; }
.home-about-cta { margin-top: 0.5rem; }
.about-feature-map {
  width: 100%;
  height: 100%;
  min-height: 340px;
  border: 0;
  display: block;
  filter: saturate(0.85) contrast(1.02);
}

/* Warm cream/beige — deliberately a step warmer than --color-bg-soft
   (#f5f3ef), which read too cool/grey next to the map's own colors here.
   Kept local to this panel rather than promoted to a variable since
   nothing else on the site needs quite this warm a tone. */
.about-feature-info-panel {
  flex-shrink: 0;
  background: #f8f0e2;
  border: 1px solid var(--color-border);
  border-top: 0;
  padding: 1.75rem 1.5rem 2rem;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
@media (min-width: 900px) {
  .about-feature-info-panel {
    width: 300px;
    border: 0;
    border-left: 1px solid rgba(28, 28, 26, 0.08);
    padding: 2.5rem 2.25rem;
    justify-content: center;
    gap: 1.25rem;
  }
}

/* Single shared left axis: the pin is absolutely positioned into the
   reserved indent rather than sitting in a flex row with the name, so
   every line below (name, address, divider, rating, phone, note) starts
   at exactly the same x — nothing "jumps" left/right between lines. */
.about-feature-info-content {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding-left: calc(40px + 0.85rem);
  text-align: left;
}
.about-feature-map-pin {
  position: absolute;
  top: 1px;
  left: 0;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  background: var(--color-red-soft);
  color: var(--color-red);
  display: flex;
  align-items: center;
  justify-content: center;
}
.about-feature-map-pin svg { width: 20px; height: 20px; }

.about-feature-info-name { display: block; color: var(--color-text-primary); font-size: 1.08rem; line-height: 1.32; }

.about-feature-info-address {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.94rem;
  color: var(--color-text-secondary);
}

.about-feature-info-divider { height: 1px; background: rgba(28, 28, 26, 0.1); }

.about-feature-info-rating { display: flex; flex-direction: column; align-items: flex-start; gap: 0.35rem; }
.about-feature-info-rating-text { font-size: 0.92rem; color: var(--color-text-secondary); }
.about-feature-info-rating-text strong { color: var(--color-text-primary); font-size: 1rem; }
.about-feature-info-rating .reviews-stars { font-size: 0.9rem; letter-spacing: 0.06em; }

.about-feature-info-phone {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--color-red);
  font-weight: 700;
  font-size: 1.1rem;
}

.about-feature-info-note {
  font-size: 0.88rem;
  color: var(--color-text-muted);
  font-style: italic;
}

.about-feature-route-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-red);
  width: fit-content;
  transition: gap 0.2s ease, color 0.2s ease;
}
.about-feature-route-link:hover { color: var(--color-red-dark); gap: 0.55rem; text-decoration: underline; }

@media (max-width: 899px) {
  .about-feature-panel { border-radius: 0; }
}

/* Tablet/narrow-laptop tier: the panel's fixed height (matched to the
   map+info card next to it) is tightest here relative to the amount of
   text — full desktop padding/spacing pushed the checklist past the
   panel's own overflow:hidden edge. Tighten padding and list spacing
   just in this range; text size/content stay the same. */
@media (min-width: 900px) and (max-width: 1199px) {
  .about-feature-panel { padding-top: 2.25rem; padding-bottom: 2.25rem; }
  .about-feature-list { margin-top: 1rem; gap: 0.65rem; }
  .faq-feature-panel {
    padding-top: 2.25rem;
    padding-bottom: 2.25rem;
    /* The extra paragraph (added to balance this panel against "Über
       Maskos") wraps to several lines at this narrower width — with the
       default vertical centering that pushed the phone CTA down far
       enough to collide with the floating badge's fixed corner. Anchor
       the block to the top instead so it grows downward from a fixed
       start point, keeping the CTA's position predictable regardless of
       how many lines the paragraph wraps to. */
    align-items: flex-start;
  }
  /* The extra paragraph itself (not just the support line/illustration)
     has to go in this narrow band too — even top-anchored, its wrapped
     height alone is enough to push the CTA button down into the
     floating badge's fixed corner. */
  .faq-feature-extra { display: none; }
  /* The actual cause of the "missing" white text low in the panel at this
     width isn't a width overflow (the text column itself fits fine) — the
     50%-tall elliptical bulge curves in hardest right at the panel's own
     top and bottom edges, and the checklist/support text sits exactly in
     that bottom zone with almost no vertical slack to spare, so its last
     lines run past the curve and get clipped by the rounded overflow box.
     Easing off just the bottom (About) / bottom-left (FAQ) corner's own
     radius — the one nearest that content — keeps full width available
     right where it's needed, without touching the shape's top corner or
     the desktop tier's more generous "Halbrund". */
  .about-feature-panel { border-radius: 0 55% 30% 0 / 0 50% 22% 0; }
  .faq-feature-panel { border-radius: 55% 0 0 30% / 50% 0 0 22%; }
}

/* Reduce the generic section top/bottom padding right where "Über Maskos"
   meets FAQ — both halves of one designed pair, so the gap between them
   should read as a short deliberate breath, not a full generic section
   gap on both sides (4rem/6rem + 4rem/6rem). Mobile keeps the normal
   rhythm, since the two sections stack into a longer, simpler flow there. */
@media (min-width: 900px) {
  .about-feature-section { padding-bottom: 2.5rem; }
  .faq-feature-section { padding-top: 2.5rem; }
}

/* -------------------------------------------------------------------------
   FAQ — homepage only. Mirrors the "Über Maskos" red-panel layout: same
   full-bleed technique and elliptical bulge, but flipped — the red panel
   sits on the RIGHT this time (bulge on its left edge), and the FAQ list
   sits on the LEFT, pulled right via negative margin so its cards overlap
   the panel's bulge the same way the map+info-panel overlapped the red
   shape in "Über Maskos". Panel comes first in the DOM (heading before
   the list, for a sane reading/tab order) and is only reordered visually
   via `order` at the desktop breakpoint; on mobile both just stack in
   natural document order. Reuses .faq-list/.faq-item/.faq-answer as-is —
   those stay untouched so the FAQ sections on all four Leistungsseiten
   keep looking exactly as they do now. ------------------------------------------------------------------------- */
.faq-feature-grid {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
}
@media (min-width: 900px) {
  /* gap:0 here (overriding the mobile-only 2.5rem stacking gap above) so
     the red panel's fr-share of the grid computes to the exact same
     pixel width as .about-feature-panel's — a real gap value here would
     shave a few dozen px off just this side's red shape and break the
     "exact mirror" requirement. */
  .faq-feature-grid { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); align-items: stretch; gap: 0; }
}

.faq-feature-panel {
  position: relative;
  z-index: 1;
  overflow: hidden;
  background: linear-gradient(150deg, var(--color-red) 0%, var(--color-red-dark) 100%);
  display: flex;
  align-items: center;
  padding: 3rem var(--margin-mobile);
}
@media (min-width: 640px) { .faq-feature-panel { padding-block: 3.5rem; } }
@media (min-width: 900px) {
  .faq-feature-panel {
    order: 2;
    /* Fixed to the same height as .about-feature-panel and pinned to the
       top of the grid row via align-self (NOT the grid's default
       align-items:stretch) — otherwise this stretched to match the FAQ
       list's height, which grows/shrinks as <details> elements open and
       close, making the red shape visibly resize on every click. It's
       now a static layout element, same as its "Über Maskos" sibling. */
    align-self: start;
    /* Matches .about-feature-panel's actual rendered height (measured at
       780px, stable across 1024–1920px) so both red shapes are really the
       same size, not just visually close. */
    min-height: 780px;
    padding: 4rem clamp(2rem, 6vw, 5rem) 4rem 3.5rem;
    justify-content: flex-end;
    /* Mirror of .about-feature-panel's bulge: rounded on the left edge
       this time, square on the right where it bleeds to the viewport edge. */
    border-radius: 55% 0 0 55% / 50% 0 0 50%;
  }
}
@media (max-width: 899px) {
  .faq-feature-panel { border-radius: var(--radius-lg); }
}

.faq-feature-panel-inner { position: relative; z-index: 2; max-width: 42ch; min-width: 0; }
@media (min-width: 900px) {
  /* Mirrors .about-feature-panel's text: that one sits left-aligned near
     the viewport's true left edge, so this sits right-aligned near the
     true right edge — same inset, opposite side. */
  .faq-feature-panel-inner { text-align: right; }
}
.faq-feature-panel .eyebrow { color: rgba(255, 255, 255, 0.85); display: block; }
.faq-feature-panel h2 { color: #fff; font-size: clamp(1.7rem, 2.4vw + 0.8rem, 2.3rem); margin: 1.1rem 0 1.3rem; }
.faq-feature-panel p { color: rgba(255, 255, 255, 0.9); font-size: 1.02rem; line-height: 1.6; margin-bottom: 1.9rem; }
.faq-feature-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  background: #fff;
  color: var(--color-red);
  font-weight: 700;
  font-size: 0.98rem;
  padding: 0.85rem 1.6rem;
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-md);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.faq-feature-cta:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }

.faq-feature-support {
  margin-top: 1.5rem;
  margin-bottom: 0 !important;
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.75);
}

/* FAQ's own motif — the real trailer illustration, not the bus used in
   "Über Maskos" (that one stays exclusive to the About panel), so the two
   sections read as individually designed rather than copy-pasted. Same
   image-based treatment as the About panel's bus: brightness(0)+invert
   turns the source art into a flat white silhouette, low opacity, quiet
   background layer. Sits low, clear of the text/CTA stack above and the
   floating badge's corner. */
.faq-feature-illustration-trailer {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  user-select: none;
  width: clamp(320px, 40vw, 520px);
  right: 4%;
  bottom: -2%;
  opacity: 0.22;
  filter: brightness(0) invert(1);
}
.faq-feature-illustration-trailer img { width: 100%; height: auto; display: block; }
@media (min-width: 900px) and (max-width: 1359px) {
  /* Between ~900-1359px the panel is too narrow for this to sit visibly:
     any position that clears the floating badge on the right lands under
     the FAQ cards' own overlap on the left instead (they sit on top,
     z-index 3). Rather than show a mostly-hidden sliver, skip it in this
     band — the panel still reads fine on eyebrow/headline/CTA alone,
     same as it did before this illustration existed. */
  .faq-feature-illustration-trailer { display: none; }
  /* The second, longer paragraph (added to balance this panel's length
     against "Über Maskos") pushes the vertically-centered content block
     tall enough at this width that the last line — the support text —
     now reaches the floating badge's fixed corner. The phone CTA above
     it already clears the badge on its own; drop just this trailing
     one-liner here rather than fight the spacing further. */
  .faq-feature-support { display: none; }
}
@media (max-width: 639px) {
  .faq-feature-illustration-trailer { display: none; }
}

.faq-feature-list-wrap { position: relative; z-index: 3; }
@media (min-width: 900px) {
  .faq-feature-list-wrap {
    order: 1;
    align-self: start;
    margin-right: -4.5rem;
    width: calc(100% + 4.5rem);
    padding-left: clamp(2rem, 6vw, 5rem);
  }
}
.faq-feature-list-wrap .faq-list { max-width: none; margin: 0; width: 100%; }

/* Scoped to the homepage FAQ pair only (.faq-feature-list-wrap) so the
   four Leistungsseiten's own plain .faq-item rows keep their existing,
   simpler look untouched. Hover nudges toward the red circle on the
   right; open state gets a light rosé fill so the active question is
   unmistakable among the rest. */
@media (min-width: 900px) {
  .faq-feature-list-wrap .faq-item:hover {
    transform: translateX(4px);
    border-color: var(--color-red-soft);
    box-shadow: var(--shadow-md);
  }
}
.faq-feature-list-wrap .faq-item {
  transition: box-shadow 0.2s ease, border-color 0.2s ease, transform 0.2s ease, background-color 0.2s ease;
}
.faq-feature-list-wrap .faq-item:hover summary::after {
  border-color: var(--color-red-dark);
}
.faq-feature-list-wrap .faq-item[open] {
  background: var(--color-red-soft);
  border-color: var(--color-red-soft);
}

/* -------------------------------------------------------------------------
   Über Maskos (ueber-maskos.html) — editorial layout adapted from the
   Stitch "Über Uns" draft (see /Über Uns Seite/code.html + DESIGN.md):
   split hero, giant pale year watermark behind a circular history photo,
   and an asymmetric "bento" facts grid. Structure and composition carried
   over 1:1; every color/font/radius/shadow value below is a MASKOS token,
   not Stitch's own (`#e11d48` red, Material Symbols, 0.25rem radius etc.
   never appear here). The Standort section further down reuses
   .about-feature-* verbatim (moved from index.html, not redesigned).
   ------------------------------------------------------------------------- */
/* Full-bleed photo hero — deliberately the same pattern as index.html's
   .hero (own classes below so nothing on the homepage can regress, but
   position/overflow/gradient/typography values are copied 1:1): the real
   company photo IS the hero now, headline + single CTA overlaid on top,
   no separate card/text section above it. */
.about-hero {
  position: relative;
  min-height: 520px;
  /* Same full-mobile-screen treatment as .hero — see its own comment. */
  min-height: 100svh;
  display: flex;
  /* Same Maskos request as .hero: text up in the photo's sky area
     instead of vertically centered, so the Geschäftsführer/fleet lower
     in the frame stay visible. */
  align-items: flex-start;
  padding: 6.5rem 0 3.5rem;
  overflow: hidden;
}
.about-hero-media { position: absolute; inset: 0; z-index: 0; }
.about-hero-media picture { width: 100%; height: 100%; }
.about-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Biased down from center, same idea as .hero-media img's 62%: keeps
     the fleet + Geschäftsführer (lower two-thirds of the source photo) in
     frame and crops sky first as the box gets taller than the photo. */
  object-position: center 60%;
}
/* A light, even veil over the full photo — just enough contrast to keep
   the centered headline readable while the car/building stay clearly
   visible. Same pattern as .hero-veil on the homepage; both pages
   replaced the old .hero-panel-shape "Halbbogen" (a dark curved panel
   that covered only the left half and hid the vehicles there). */
.about-hero-veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(10, 9, 8, 0.32);
  pointer-events: none;
}
.about-hero-content {
  position: relative;
  z-index: 2;
  color: #fff;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}
.about-hero-panel { max-width: min(90%, 640px); }
.about-hero-title {
  /* font-family/weight/line-height come from the base h1 rule now
     (700, same as .hero h1) — this used to override to 800, which read
     visibly bigger/heavier than the homepage's h1 at the identical
     clamp() size and broke the "look like the same page family" match
     Maskos asked for. */
  font-size: clamp(2rem, 5vw + 0.5rem, 3.5rem);
  letter-spacing: -0.02em;
  /* Left-aligned again, sitting in the photo's sky area now (see
     .about-hero's own align-items:flex-start) instead of centered. */
  max-width: 34ch;
  text-wrap: balance;
  text-shadow: 0 2px 20px rgba(0, 0, 0, 0.35);
  margin-bottom: 1.1rem;
}
/* Eyebrow above and paragraph below the title, plus a second ghost
   button — same shape as .hero's own badge/eyebrow/h1/p/actions
   structure on the homepage, so the two heroes read as one family
   instead of one looking sparser than the other. */
.about-hero .hero-eyebrow {
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
}
.about-hero-text {
  font-size: clamp(1.05rem, 1.2vw + 0.7rem, 1.25rem);
  max-width: 46ch;
  color: rgba(255, 255, 255, 0.95);
  margin-bottom: 2rem;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.3);
}
@media (min-width: 768px) {
  /* Same full-viewport-height treatment as index.html's .hero, so the two
     pages open with matching drama instead of this one looking smaller. */
  .about-hero { min-height: calc(100vh + 48px); padding: 8.5rem 0 4.5rem; }
}

/* Propangas page: reuses .about-hero's photo/veil/text pattern AND now
   its full-viewport height too (the .gas-hero class used to override
   this shorter — 640px — since the page itself is short overall, but
   that made the hero look visibly smaller than the homepage/Über-Maskos
   ones and dropped the arch transition below it; Maskos asked for all
   three to match). No .gas-hero-specific rule needed anymore — it just
   falls through to .about-hero's own rules above. */
/* position:relative so .hero-arch-clip (position:absolute, bottom:100%)
   anchors to this section's own top edge and pokes up into the hero
   above — same mechanic as .trust-transition/.about-story. Reduced top
   padding for the same reason as those two: the arch itself already
   supplies visual separation from the hero. */
.gas-options-section { position: relative; padding-top: clamp(1.25rem, 3vw, 2rem); }
.gas-hero-text {
  color: rgba(255, 255, 255, 0.92);
  font-size: clamp(1.05rem, 1.2vw + 0.7rem, 1.2rem);
  max-width: 46ch;
  /* Was "0 auto 1.75rem" — a leftover from this hero's old centered
     layout. Auto side-margins center a block within a flex column even
     when the column itself is align-items:flex-start, which pulled just
     this paragraph off the left edge the h1/button both sit on. */
  margin: 0 0 1.75rem;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.3);
}

.gas-options-grid { display: grid; grid-template-columns: 1fr; gap: 1.25rem; max-width: 860px; margin: 0 auto; }
@media (min-width: 700px) {
  .gas-options-grid { grid-template-columns: 1fr 1fr; }
}
.gas-option-card { text-align: left; }

/* Honest stand-in for a fixed price list the business itself doesn't use
   (LPG tracks the daily fuel price) — a plain callout instead of
   inventing numbers. */
.gas-price-note {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  max-width: 860px;
  margin: 2rem auto 0;
  padding: 1.1rem 1.4rem;
  background: var(--color-red-soft);
  border: 1px solid var(--color-red-soft-strong);
  border-radius: var(--radius-lg);
  color: var(--color-text-primary);
}
.gas-price-note-icon { color: var(--color-red); flex-shrink: 0; margin-top: 0.1rem; }
.gas-price-note-icon svg { width: 22px; height: 22px; }
.gas-price-note p { margin: 0; font-size: 0.95rem; line-height: 1.55; }

.about-story { position: relative; padding: clamp(3rem, 6vw, 6rem) 0; }
.about-story > .container { position: relative; z-index: 2; }

/* Same line-art motif as .trust-illustration on the homepage's "Verlässlich
   auf jeder Etappe" section head, mirrored left/right (route left, truck
   right here) so the two pages read as one family without being identical. */
.about-story-illustration {
  position: absolute;
  top: clamp(10px, 3vw, 50px);
  width: clamp(240px, 26vw, 460px);
  z-index: 0;
  pointer-events: none;
  user-select: none;
}
.about-story-illustration img { width: 100%; height: auto; display: block; }
.about-story-illustration-route { left: clamp(-60px, -3vw, 0px); opacity: 0.65; }
/* Was a negative right offset — same fix as .trust-illustration-route on
   the homepage: a rightward bleed genuinely extends scrollWidth past the
   viewport (confirmed live) at desktop widths, unlike the leftward bleed
   on .about-story-illustration-route just above, which browsers don't let
   you scroll to anyway. Flush at 0 instead. */
.about-story-illustration-truck { right: 0; opacity: 0.4; }
@media (max-width: 1099px) {
  .about-story-illustration { width: clamp(90px, 15vw, 190px); top: 20px; }
  .about-story-illustration-route { left: 0; opacity: 0.4; }
  .about-story-illustration-truck { right: 0; opacity: 0.25; }
}
@media (max-width: 639px) {
  .about-story-illustration { display: none; }
}
/* #unsere-geschichte anchor target: offsets the jump so the heading clears
   the sticky header instead of landing underneath it (76px rest-state
   height on mobile/tablet and the >=900px rest state, plus headroom). */
#unsere-geschichte { scroll-margin-top: 100px; }
.about-story-outro {
  max-width: 720px;
  /* Bottom spacing lives on .about-story's own padding-bottom now, not
     here: a margin on the last child of a section with no bottom
     padding/border collapses straight through it, so it rendered as a
     sliver of the page's own background (--color-bg-main) between this
     white section and the beige .about-facts one below — a visible third
     color where only two were meant to meet. */
  margin: 3.5rem auto 0;
  padding: clamp(2rem, 5vw, 3rem) clamp(1.5rem, 5vw, 3rem);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  text-align: center;
}
.about-story-outro p { color: var(--color-text-secondary); font-size: 1.1rem; margin-bottom: 1.75rem; }
/* Same fix as #googleReviewsLink on the homepage: on the narrowest real
   phones (~320px) this button's nowrap label + icon was a few px wider
   than the available space, which alone was enough to make the whole page
   horizontally scrollable. */
@media (max-width: 359px) {
  .about-story-outro .btn { white-space: normal; text-align: center; }
}

/* -------------------------------------------------------------------------
   Über-Maskos: horizontale Zeitreise
   Deliberately its own component, not the homepage journey reused: same red
   pin language, its own left-to-right layout. Base (mobile/tablet, <1100px):
   a plain scroll-snap strip, every card already visible — no JS-dependent
   reveal at this size, since making a progressive reveal play nicely with
   touch scrolling too isn't worth the fragility. >=1100px only: the pins
   sit on a real horizontal line, cards alternate above/below it, and both
   the line's fill and each card's reveal are tied to actual scroll position
   via script.js (a --history-progress custom property + .is-active toggles,
   not a fixed-duration animation).
   ------------------------------------------------------------------------- */
.history-timeline { margin-top: clamp(2.5rem, 6vw, 4rem); }
.history-line { display: none; }
.history-bg-illustration { display: none; }

.history-stations {
  list-style: none;
  margin: 0;
  padding: 0.25rem 0 0.75rem;
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.history-stations::-webkit-scrollbar { display: none; }
.history-stations:focus-visible { outline: 2px solid var(--color-red); outline-offset: 4px; border-radius: var(--radius-lg); }

.history-station {
  flex: 0 0 82%;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.9rem;
}

.history-pin {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-red);
  color: #fff;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.98rem;
  box-shadow: 0 6px 16px rgba(196, 39, 44, 0.35), 0 2px 4px rgba(28, 28, 26, 0.12);
}
.history-pin::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -7px;
  width: 15px;
  height: 15px;
  background: inherit;
  border-radius: 0 0 5px 0;
  transform: translateX(-50%) rotate(45deg);
  z-index: -1;
}

.history-card {
  width: 100%;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 1.25rem 1.4rem;
}
.history-date {
  display: block;
  color: var(--color-red);
  font-weight: 700;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.4rem;
}
.history-card h3 { font-family: var(--font-head); font-size: 1.15rem; color: var(--color-text-primary); margin-bottom: 0.5rem; line-height: 1.3; }
.history-card p { color: var(--color-text-secondary); font-size: 0.94rem; line-height: 1.6; }

@media (min-width: 700px) and (max-width: 1099px) {
  .history-station { flex-basis: 42%; }
}

/* ---- Desktop (>=1100px): pins on a real line, cards alternating above/
   below, scroll-tied reveal. Matches the homepage journey's own desktop
   cutoff so both timelines switch layout language at the same breakpoint. */
@media (min-width: 1100px) {
  /* margin-block is a no-JS/pre-measurement fallback only — script.js
     overwrites it with the real measured card heights (they vary a lot:
     one line of text vs. two paragraphs) via inline styles once it runs. */
  .history-timeline { position: relative; margin-block: 420px; }

  /* Quiet background texture only — the empty white space above/below the
     line (between the 01/03 and 02/04 card pairs) otherwise reads as bare.
     Same source art as .trust-illustration-truck/-route, at a similar
     opacity — it's already a very pale dusty-rose line drawing on its own
     (by design, for exactly this kind of watermark use), so 0.05-0.1 here
     compounded into genuinely invisible; 0.3 is roughly where it actually
     registers, matching what .trust-illustration already uses with the
     same source file. */
  .history-bg-illustration {
    display: block;
    position: absolute;
    /* No negative z-index: .history-timeline doesn't establish its own
       stacking context (position:relative alone doesn't), so a -1 here
       escaped to the nearest ancestor that does — rendering it behind
       .about-story's own opaque white background and making it invisible
       regardless of opacity. Being the first children in the markup, with
       the default stacking order (z-index left at auto) they already
       paint behind the line/cards that follow, no z-index needed at all. */
    opacity: 0.3;
    pointer-events: none;
    user-select: none;
  }
  .history-bg-illustration img { display: block; width: 100%; height: auto; }
  /* Parked in the two corners that no card ever reaches: station-1's card
     is above-left and station-3's is above-center, leaving above-right
     permanently empty; station-2's card is below-center and station-4's
     is below-right, leaving below-left permanently empty. Placing the
     illustrations there (instead of the gaps between cards) keeps them
     clear regardless of each card's actual measured width/height. */
  .history-bg-illustration-truck { width: clamp(200px, 18vw, 300px); right: 2%; bottom: calc(100% + 40px); }
  .history-bg-illustration-trailer { width: clamp(220px, 20vw, 320px); left: 2%; top: calc(100% + 60px); }

  .history-line {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 4px;
    transform: translateY(-50%);
    z-index: 0;
  }
  .history-line-base {
    position: absolute;
    inset: 0;
    border-radius: 999px;
    background-image: repeating-linear-gradient(to right, var(--color-border-strong) 0 8px, transparent 8px 16px);
  }
  .history-line-progress {
    position: absolute;
    inset: 0;
    width: calc(var(--history-progress, 0) * 100%);
    border-radius: 999px;
    background: var(--color-red);
    /* --history-progress now flips 0/1 in one step (IntersectionObserver,
       not a continuous scroll formula — see script.js) rather than
       creeping up with scroll position, so the fill itself needs its own
       transition to still read as growing smoothly left to right. */
    transition: width 700ms cubic-bezier(0.22, 1, 0.36, 1);
  }

  .history-stations {
    position: relative;
    z-index: 1;
    overflow: visible;
    padding: 0;
    gap: 0;
    justify-content: space-between;
    align-items: center;
    scroll-snap-type: none;
  }
  .history-station {
    flex: 0 1 auto;
    align-items: center;
    position: relative;
    scroll-snap-align: none;
  }

  .history-pin {
    background: var(--color-border-strong);
    box-shadow: none;
    transition: background-color 250ms ease, box-shadow 250ms ease, transform 250ms ease;
  }
  .history-station.is-active .history-pin {
    background: var(--color-red);
    box-shadow: 0 6px 16px rgba(196, 39, 44, 0.4), 0 2px 4px rgba(28, 28, 26, 0.12);
    transform: scale(1.04);
  }

  .history-card {
    position: absolute;
    left: 50%;
    /* Capped by geometry, not taste: at the narrowest supported desktop
       width (1100px, 4 evenly-spaced pins) anything wider risks the
       edge-aligned first/last card overlapping its neighbor's centered
       one. Actual vertical clearance for these absolutely-positioned
       cards is sized dynamically in script.js from their real measured
       height instead of a guessed fixed margin. */
    width: 220px;
    opacity: 0;
    transition: opacity 320ms cubic-bezier(0.22, 1, 0.36, 1), transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .history-station--above .history-card { bottom: calc(100% + 30px); transform: translate(-50%, 18px); }
  .history-station--below .history-card { top: calc(100% + 30px); transform: translate(-50%, -18px); }
  .history-station.is-active .history-card { opacity: 1; transform: translate(-50%, 0); }
  /* All four stations activate together (see script.js's HISTORY_THRESHOLDS
     comment on why) — this is purely a cosmetic ripple across that single
     moment, not a scroll-driven stagger. */
  .history-station-2.is-active .history-card { transition-delay: 70ms; }
  .history-station-3.is-active .history-card { transition-delay: 140ms; }
  .history-station-4.is-active .history-card { transition-delay: 210ms; }

  /* First/last station: centering the card on an edge pin would run it past
     the timeline's own left/right bound, so these two anchor to the pin's
     inner edge instead of its center. Comes after the above/below rules
     above (same specificity) to win. */
  .history-station-1 .history-card { left: 0; transform: translate(0, 18px); }
  .history-station-1.is-active .history-card { transform: translate(0, 0); }
  .history-station-4 .history-card { left: auto; right: 0; transform: translate(0, -18px); }
  .history-station-4.is-active .history-card { transform: translate(0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .history-pin, .history-card, .history-line-progress { transition: none !important; }
}

.about-facts { padding: clamp(3rem, 6vw, 6rem) 0; }
.about-facts-grid { display: grid; grid-template-columns: 1fr; gap: 1.25rem; }
@media (min-width: 900px) {
  /* 120px (was 140px) auto-rows + .about-fact-large's own lower min-height
     below: the 2x2 card's short heading+paragraph don't need 260-300px to
     breathe, and the old combination of that min-height with
     justify-content:space-between visibly stretched a gap between the
     icon and the text instead of just letting the card be shorter. */
  .about-facts-grid { grid-template-columns: repeat(4, 1fr); grid-auto-rows: minmax(120px, auto); gap: 1.5rem; }
  .about-fact-large { grid-column: span 2; grid-row: span 2; }
  .about-fact-accent { grid-column: span 2; }
}
.about-fact {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 2rem;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.5rem;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
  /* Grid items default to min-width:auto, i.e. their content's min-content
     size — a single unbreakable word in the h3 (see overflow-wrap above)
     was forcing this card's 1fr track wider than the container at ~320px,
     which pushed the whole page's scrollWidth past the viewport even
     though the h3 text itself no longer overflowed. Standard fix for this
     class of CSS Grid bug. */
  min-width: 0;
}
.about-fact:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--color-red-soft-strong); }
.about-fact-large { min-height: 200px; }
/* Photo variant of the bento card (currently just the "Seit 1988"
   large tile): drops the base card's padding/centered-text layout in
   favor of a full-bleed image, clipped to the card's own rounded corners
   via overflow:hidden rather than the image carrying its own radius. */
.about-fact-photo {
  position: relative;
  padding: 0;
  overflow: hidden;
  align-items: stretch;
  min-height: 280px;
}
.about-fact-photo picture { display: block; width: 100%; height: 100%; }
.about-fact-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.about-fact-accent { background: var(--color-red); border-color: var(--color-red); color: #fff; justify-content: center; }
.about-fact-icon { color: var(--color-red); }
.about-fact-accent .about-fact-icon { color: #fff; }
.about-fact-icon svg { width: 32px; height: 32px; }
/* overflow-wrap: a single long unbreakable German compound word
   ("Familienunternehmen") was a few px wider than the card's available
   width on the narrowest real phones (~320px), which — with nothing else
   on the page to blame — was enough on its own to make the whole page
   horizontally scrollable (confirmed via document.documentElement.
   scrollWidth). Only kicks in when a word truly doesn't fit; normal
   wrapping between words is unaffected. */
.about-fact h3 { font-family: var(--font-head); font-size: 1.3rem; font-weight: 700; color: var(--color-text-primary); overflow-wrap: break-word; }
.about-fact-accent h3 { color: #fff; }
.about-fact p { color: var(--color-text-secondary); font-size: 0.98rem; line-height: 1.55; }
.about-fact-accent p { color: rgba(255, 255, 255, 0.9); }

/* -------------------------------------------------------------------------
   FAQ — native <details>/<summary>: accessible and toggleable with zero JS.
   ------------------------------------------------------------------------- */
.faq-list { max-width: 760px; margin: 0 auto; display: grid; gap: 0.85rem; }
.faq-item {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 0.4rem 1.5rem;
  transition: box-shadow 0.2s ease, border-color 0.2s ease;
}
.faq-item:hover { border-color: var(--color-red-soft); box-shadow: var(--shadow-sm); }
.faq-item summary {
  list-style: none;
  cursor: pointer;
  padding: 1.1rem 2rem 1.1rem 0;
  position: relative;
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--color-text-primary);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0.15rem;
  width: 11px;
  height: 11px;
  border-right: 2px solid var(--color-red);
  border-bottom: 2px solid var(--color-red);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.25s ease;
}
.faq-item[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq-answer { padding: 0 0 1.35rem; }
.faq-answer p { color: var(--color-text-secondary); font-size: 0.95rem; line-height: 1.6; }
.faq-answer a { color: var(--color-red); font-weight: 600; }
.faq-answer a:hover { text-decoration: underline; }

/* -------------------------------------------------------------------------
   Kontakt
   ------------------------------------------------------------------------- */
.contact-panel {
  background: var(--color-surface);
  border-radius: 2rem;
  box-shadow: var(--shadow-lg);
  border: 1px solid var(--color-border);
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr;
}
@media (min-width: 950px) { .contact-panel { grid-template-columns: 0.85fr 1.15fr; } }

/* Dark anthracite instead of solid red — red stays the accent (phone
   number, icons) rather than covering the whole panel, calmer next to
   the light/warm-white look of the rest of the site. */
.contact-info {
  background: var(--color-graphite);
  color: #fff;
  padding: 2.5rem 2rem;
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}
.contact-info h2 { font-size: 1.5rem; margin-bottom: 0.25rem; }
.contact-info > p.lead { color: rgba(255,255,255,0.72); font-size: 0.98rem; }
.contact-phone-link {
  display: inline-flex;
  flex-direction: column;
  gap: 0.3rem;
}
.contact-phone-link .num {
  font-family: var(--font-head);
  font-size: clamp(1.6rem, 2.5vw + 0.8rem, 2.1rem);
  font-weight: 700;
  color: #fff;
  transition: color 0.2s ease;
}
.contact-phone-link:hover .num { color: var(--color-red-soft); }
.contact-phone-link .cta-label {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--color-red-soft);
}
.contact-fact { display: flex; gap: 0.85rem; align-items: flex-start; }
.contact-fact svg { width: 22px; height: 22px; flex-shrink: 0; color: var(--color-red-soft); margin-top: 2px; }
.contact-fact h3 { font-size: 0.95rem; margin-bottom: 0.25rem; }
.contact-fact p { font-size: 0.9rem; color: rgba(255,255,255,0.72); line-height: 1.5; }
.contact-fact a { color: #fff; }
.contact-fact a:hover { text-decoration: underline; }

.contact-form-wrap { padding: 2.5rem 2rem; }
.contact-form-wrap h3 { font-size: 1.2rem; margin-bottom: 0.4rem; color: var(--color-text-primary); }
.contact-form-wrap > p { color: var(--color-text-secondary); font-size: 0.92rem; margin-bottom: 1.75rem; }

.form-grid { display: grid; grid-template-columns: 1fr; gap: 1.1rem; }
@media (min-width: 560px) { .form-grid.cols-2 { grid-template-columns: 1fr 1fr; } }

.field { display: flex; flex-direction: column; gap: 0.4rem; }
.field label { font-size: 0.85rem; font-weight: 600; color: var(--color-text-primary); }
.field .optional { font-weight: 400; color: var(--color-text-secondary); }
.field input, .field select, .field textarea {
  border: 1.5px solid var(--color-border);
  border-radius: 0.7rem;
  padding: 0.75rem 0.9rem;
  background: var(--color-bg-main);
  color: var(--color-text-primary);
  font-size: 0.95rem;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
  width: 100%;
}
.field input::placeholder, .field textarea::placeholder { color: var(--color-text-muted); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--color-red);
  box-shadow: 0 0 0 3px rgba(196, 39, 44, 0.14);
}
.field textarea { resize: vertical; min-height: 100px; }
/* "Welche Anhängergröße?" stays in the layout at all times (no
   hide/show jump) but is greyed out and inert until "PKW-Anhänger" is
   picked as the main category — script.js toggles both this class and
   the select's own `disabled` together. */
.field.is-disabled label { color: var(--color-text-secondary); }
.field.is-disabled select { background: var(--color-border); color: var(--color-text-secondary); cursor: not-allowed; }
.form-footer { margin-top: 1.5rem; display: flex; flex-direction: column; gap: 0.75rem; }
.form-note { font-size: 0.82rem; color: var(--color-text-secondary); }
.form-privacy-note { font-size: 0.78rem; color: var(--color-text-secondary); opacity: 0.85; margin-top: -0.3rem; }
.form-privacy-note a { color: inherit; text-decoration: underline; }
/* DSGVO consent checkbox, directly above the submit button. Plain native
   checkbox (not a fake toggle graphic), same reasoning as
   .cookie-settings-row's: stays exactly as accessible/keyboard-operable as
   any other form control here. */
.form-consent {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: 0.85rem;
  color: var(--color-text-secondary);
  line-height: 1.45;
  cursor: pointer;
}
.form-consent input[type="checkbox"] {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 0.15em;
  accent-color: var(--color-red);
}
.form-consent a { color: var(--color-text-primary); font-weight: 600; text-decoration: underline; }
.form-status { font-size: 0.88rem; font-weight: 600; min-height: 1.2em; }
.form-status.success { color: #146c2e; }
.form-status.error { color: #ba1a1a; }

/* -------------------------------------------------------------------------
   Kontakt-Modal — same overlay pattern as .badge-lightbox (fixed, centered,
   backdrop + close button), wrapping the exact same .contact-panel markup
   used inline in #kontakt on index.html, so the dark-info/white-form look
   is identical wherever it appears. Injected async by
   js/include-contact-modal.js; see script.js for the open/close wiring.
   ------------------------------------------------------------------------- */
.contact-modal {
  position: fixed;
  inset: 0;
  z-index: 200; /* above header (100) and mobile drawer (99), matches .badge-lightbox */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.contact-modal[hidden] { display: none; }
.contact-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(18, 16, 14, 0.72);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  border: 0;
  padding: 0;
  cursor: pointer;
}
.contact-modal-dialog {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 900px;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  border-radius: 2rem;
  animation: badge-lightbox-in 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.contact-modal-dialog .contact-panel { border: 0; box-shadow: none; }
.contact-modal-close {
  position: absolute;
  z-index: 2;
  top: 14px;
  right: 14px;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: 0;
  background: rgba(255, 255, 255, 0.92);
  color: var(--color-text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.2s ease;
}
.contact-modal-close:hover { background: #fff; }

/* Anhänger-Größentabelle: reuses .contact-modal/.contact-modal-dialog for
   the overlay shell (fixed, centered, backdrop, close button) but its own
   plain white card layout — no dark two-column .contact-panel here, just
   a heading, intro line and the size table. */
.trailer-sizes-dialog { max-width: 640px; background: #fff; padding: clamp(1.5rem, 4vw, 2.5rem); }
.trailer-sizes-panel h2 {
  font-family: var(--font-head);
  font-size: clamp(1.35rem, 1.6vw + 0.9rem, 1.7rem);
  color: var(--color-text-primary);
  margin-bottom: 0.5rem;
  padding-right: 2rem;
}
.trailer-sizes-intro { color: var(--color-text-secondary); font-size: 0.95rem; margin-bottom: 1.5rem; }
.trailer-size-table-wrap { overflow-x: auto; }
.trailer-size-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.trailer-size-table th, .trailer-size-table td {
  padding: 0.7rem 0.85rem;
  text-align: left;
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}
.trailer-size-table th {
  font-size: 0.76rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-secondary);
}
.trailer-size-table td:first-child, .trailer-size-table th:first-child { padding-left: 0; }
.trailer-size-table td:first-child { font-weight: 700; color: var(--color-red); }
/* The merged "Typ / Maße" column carries the longest strings (e.g.
   "Auto-Transporter mit Winde") — letting only this one wrap keeps the
   short weight/payload columns tidy while still fitting the whole table
   in the dialog's width without a horizontal scrollbar. */
.trailer-size-table td:nth-child(2), .trailer-size-table th:nth-child(2) { white-space: normal; }
@media (max-width: 560px) {
  .trailer-size-table { font-size: 0.82rem; }
  .trailer-size-table th, .trailer-size-table td { padding: 0.55rem 0.6rem; }
}

/* Config recap (calculator pages "Fahrzeug unverbindlich anfragen" →
   opens this modal with the already-computed price breakdown carried
   over): reuses .result-card's own dark styling as-is — .contact-info is
   the very same --color-graphite, so the nested card just drops its own
   background/shadow/padding rather than doubling up, while still picking
   up .result-card h3 / .result-vehicle / .result-lines / .result-total
   etc. for identical typography to the calculator sidebar. */
.contact-modal-recap.result-card {
  background: transparent;
  box-shadow: none;
  padding: 0 0 1.75rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
}
.contact-modal-trust {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.75);
}
.contact-modal-trust strong { color: #fff; }
.contact-modal-trust .reviews-stars { font-size: 0.95rem; }
@media (max-width: 949px) {
  /* Stacked layout (.contact-panel goes single-column below 950px): the
     dark info panel sits on top, so the close button needs to stay legible
     against it too — same translucent-white treatment works on both. */
  .contact-modal-close { top: 10px; right: 10px; }
}

/* -------------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------------- */
.site-footer { background: var(--color-graphite); color: rgba(255,255,255,0.85); }
.footer-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  padding: 4rem 0 2.5rem;
}
@media (min-width: 700px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
.footer-col p { font-size: 0.93rem; line-height: 1.6; }
.footer-brand { display: flex; align-items: center; gap: 0.6rem; font-family: var(--font-head); font-weight: 700; font-size: 1.25rem; color: #fff; margin-bottom: 1rem; }
.footer-brand .mark { width: 34px; height: 34px; border-radius: 9px; background: var(--color-red); display: flex; align-items: center; justify-content: center; font-size: 1rem; }
.footer-brand picture { display: block; line-height: 0; }
.footer-brand img { display: block; height: 32px; width: auto; }
.footer-col h3 { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.08em; color: rgba(255,255,255,0.55); margin-bottom: 1rem; font-family: var(--font-body); font-weight: 700; }
.footer-col ul { display: grid; gap: 0.65rem; }
.footer-col a { font-size: 0.93rem; }
.footer-col a:hover { color: var(--color-red-soft); text-decoration: underline; }
/* Resets a <button> (needed since it opens the cookie panel via JS rather
   than navigating) back to reading like the plain-text links around it —
   in .footer-col's <ul> on index/ueber-maskos, and standalone next to the
   copyright <span> in .footer-bottom on impressum/datenschutz. */
.footer-cookie-link {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 0.93rem;
  color: inherit;
  cursor: pointer;
  text-align: left;
}
.footer-cookie-link:hover { color: var(--color-red-soft); text-decoration: underline; }
.footer-desc { font-size: 0.92rem; max-width: 32ch; color: rgba(255,255,255,0.65); }
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,0.12);
  padding: 1.5rem 0;
  font-size: 0.82rem;
  color: rgba(255,255,255,0.55);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
}
/* Own row below .footer-bottom (not squeezed onto its flex line) so it
   reads as a quiet sign-off, not another nav item competing with
   Impressum/Datenschutz/the phone number. Same border-top treatment,
   deliberately smaller and dimmer than .footer-bottom's own text. */
.footer-credit {
  border-top: 1px solid rgba(255,255,255,0.12);
  padding: 1rem 0;
  text-align: center;
  font-size: 0.76rem;
  color: rgba(255,255,255,0.4);
}
.footer-credit a { color: rgba(255,255,255,0.65); font-weight: 600; }
.footer-credit a:hover { color: var(--color-red-soft); text-decoration: underline; }

/* -------------------------------------------------------------------------
   Utility page (Impressum / Datenschutz)
   ------------------------------------------------------------------------- */
.legal-page main { padding: 5rem 0 6rem; min-height: 60vh; }
/* overflow-wrap: "Datenschutzerklärung" as an h1 is one long unbreakable
   word that was a few px wider than the viewport at ~320px — same class
   of bug as .about-fact h3 elsewhere, same fix. */
.legal-page h1 { color: var(--color-text-primary); font-size: 2rem; margin-bottom: 1.5rem; overflow-wrap: break-word; }
.legal-page h2 { color: var(--color-text-primary); font-size: 1.3rem; margin: 2rem 0 0.75rem; overflow-wrap: break-word; }
.legal-page h3 { color: var(--color-text-primary); font-size: 1.05rem; margin: 1.5rem 0 0.5rem; overflow-wrap: break-word; }
.legal-page p { color: var(--color-text-secondary); margin-bottom: 1rem; max-width: 60ch; }
.legal-page ul { list-style: disc; padding-left: 1.4rem; margin-bottom: 1rem; max-width: 60ch; }
.legal-page li { color: var(--color-text-secondary); margin-bottom: 0.4rem; line-height: 1.55; }
.legal-page code { background: var(--color-bg-soft); padding: 0.1em 0.4em; border-radius: 0.3em; font-size: 0.9em; }
/* Marks a fact Maskos still has to supply/confirm — deliberately loud
   (not just italic) so it can't be mistaken for finished copy and is easy
   to scan for before going live. */
.legal-todo {
  overflow-wrap: break-word;
  background: var(--color-red-soft);
  border-left: 3px solid var(--color-red);
  color: var(--color-text-primary) !important;
  padding: 0.75rem 1rem;
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  font-size: 0.92rem;
  font-weight: 600;
}
/* Preview-phase-only notice — see js/cookie-consent.js's footer link
   comment for the parallel "remove before launch" pattern. Deliberately
   quieter than .legal-todo (this isn't a missing fact, just a status
   note) but still legible, not buried. */
.legal-draft-notice {
  margin-top: 2.5rem;
  padding: 1rem 1.25rem;
  background: var(--color-bg-soft);
  border-radius: var(--radius-md);
  max-width: 70ch;
}
.legal-draft-notice p { color: var(--color-text-secondary); font-size: 0.85rem; margin-bottom: 0; max-width: none; }
.legal-page .back-link { display: inline-flex; align-items: center; gap: 0.4rem; margin-top: 1.5rem; font-weight: 600; color: var(--color-red); }

/* -------------------------------------------------------------------------
   Floating trust badge — fixed to the viewport (not nested in any section),
   a real designed asset used as-is. z-index sits below the header (100)
   and mobile drawer (99) so the drawer covers it while open; script.js
   fades it out once the footer scrolls into view so it never sits on top
   of footer links/text.
   ------------------------------------------------------------------------- */
.trust-badge-float {
  /* Now a <button> (it opens the lightbox below instead of navigating),
     so the browser's default button chrome — background, border, padding,
     font, text-align — needs resetting before position:fixed takes over. */
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  text-align: left;
  position: fixed;
  right: 28px;
  bottom: 28px;
  z-index: 90;
  width: 195px; /* was 156px — ~25% larger again, same aspect ratio (height:auto) */
  filter: drop-shadow(0 10px 24px rgba(20, 18, 16, 0.28));
  transition: transform 0.25s ease, opacity 0.3s ease, visibility 0.3s;
}
.trust-badge-float:hover { transform: scale(1.05); }
.trust-badge-float img { width: 100%; height: auto; display: block; }
.trust-badge-float.is-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(10px);
}
@media (max-width: 699px) {
  /* Smaller bump than desktop (~20% vs ~25%) so it stays out of the way
     on small screens — was 92px. */
  .trust-badge-float { width: 110px; right: 14px; bottom: 14px; }
}
@media (prefers-reduced-motion: reduce) {
  .trust-badge-float:hover { transform: none; }
}

/* -------------------------------------------------------------------------
   Trust badge lightbox — click the floating badge to see the same asset
   large. Built once in script.js and shared across every page (same
   pattern as the badge itself); no separate per-page markup or a second
   badge design, just the existing picture cloned into an overlay.
   ------------------------------------------------------------------------- */
.badge-lightbox {
  position: fixed;
  inset: 0;
  z-index: 200; /* above header (100) and mobile drawer (99) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.badge-lightbox[hidden] { display: none; }
.badge-lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(18, 16, 14, 0.72);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  border: 0;
  padding: 0;
  cursor: pointer;
}
.badge-lightbox-panel {
  position: relative;
  z-index: 1;
  width: min(78vw, 420px);
  animation: badge-lightbox-in 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.badge-lightbox-panel picture,
.badge-lightbox-panel img {
  width: 100%;
  height: auto;
  display: block;
  filter: drop-shadow(0 20px 48px rgba(0, 0, 0, 0.45));
}
.badge-lightbox-close {
  position: absolute;
  z-index: 2;
  top: -14px;
  right: -14px;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  border: none;
  background: var(--color-surface);
  color: var(--color-text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-md);
  cursor: pointer;
  transition: transform 0.15s ease, background-color 0.15s ease;
}
.badge-lightbox-close:hover { background: var(--color-red-soft); transform: scale(1.06); }
.badge-lightbox-close svg { width: 18px; height: 18px; }
@keyframes badge-lightbox-in {
  from { opacity: 0; transform: scale(0.92); }
  to { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .badge-lightbox-panel { animation: none; }
}
@media (max-width: 480px) {
  .badge-lightbox-panel { width: min(82vw, 320px); }
  .badge-lightbox-close { top: -10px; right: -10px; width: 36px; height: 36px; }
}

/* -------------------------------------------------------------------------
   Ehemalige Leistungsseiten — gemeinsame Rechner-Bausteine
   Die sechs Fahrzeug-Unterseiten (sprinter/transporter-.../lkw-mieten/
   busse/anhaenger.html) und ihre Mietpreisrechner sind auf Kundenwunsch
   entfernt worden (siehe Redirects in vercel.json). Die meisten Klassen
   hier sind seitdem ungenutzt — .result-card und seine Kindklassen
   (.result-vehicle, .result-tariff, .result-lines, .result-total, …)
   bleiben jedoch aktiv: sie stecken jetzt in .contact-modal-recap, der
   Preisübersicht im Kontakt-Modal (siehe partials/contact-modal.html).
   ------------------------------------------------------------------------- */

/* Kompakte Kennzahl-/USP-Reihe unterhalb des Hero (reuse von .trust-card) */
.usp-row .trust-card { text-align: left; }
.usp-row .trust-icon { margin: 0 0 1.25rem; }

.calc-section { }
.calc-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  align-items: start;
}
@media (min-width: 1024px) {
  .calc-grid { grid-template-columns: 1.5fr 1fr; gap: 2.5rem; }
}

.calc-main {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 1.75rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
@media (min-width: 768px) { .calc-main { padding: 2.5rem; } }

.calc-step-title {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 1.15rem;
  margin-bottom: 1.1rem;
  color: var(--color-text-primary);
}
.calc-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: var(--color-red);
  color: #fff;
  font-size: 0.9rem;
  font-weight: 700;
  flex-shrink: 0;
}
.calc-step-group-label {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 1.4rem 0 0.6rem;
}
.calc-step-group-label:first-child { margin-top: 0; }

/* Auswahlkarten (Fahrzeuggruppe / Tarif) — echte <input type="radio">,
   visuell versteckt statt entfernt, damit Tastatur- und Screenreader-
   Bedienung erhalten bleibt. Aktiver Zustand wird nie nur über Farbe
   vermittelt: roter Rahmen + roter Tint-Hintergrund + sichtbares Häkchen. */
.choice-cards { display: grid; grid-template-columns: 1fr; gap: 0.9rem; }
@media (min-width: 560px) { .choice-cards-2col { grid-template-columns: 1fr 1fr; } }
@media (min-width: 700px) { .choice-cards-3col { grid-template-columns: repeat(3, 1fr); } }

.choice-card {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1.1rem 1.2rem;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
  min-height: 44px;
}
.choice-card:hover { border-color: var(--color-border-strong); }
.choice-card input {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.choice-card.is-selected {
  border-color: var(--color-red);
  background: var(--color-red-soft);
  box-shadow: 0 0 0 1px var(--color-red);
}
.choice-card input:focus-visible ~ .choice-card-check,
.choice-card:focus-within { outline: 2px solid var(--color-red); outline-offset: 2px; }

.choice-card-body { flex: 1; min-width: 0; }
.choice-card-title { font-weight: 700; color: var(--color-text-primary); font-size: 0.98rem; }
.choice-card-meta { display: block; font-size: 0.85rem; color: var(--color-text-secondary); margin-top: 0.2rem; }
.choice-card-price { display: block; font-size: 0.82rem; color: var(--color-red); font-weight: 600; margin-top: 0.4rem; }
.choice-card-note { display: block; font-size: 0.78rem; color: var(--color-text-muted); margin-top: 0.3rem; }

.choice-card-check {
  flex-shrink: 0;
  width: 22px; height: 22px;
  border-radius: 999px;
  border: 1.5px solid var(--color-border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}
.choice-card-check svg { width: 13px; height: 13px; }
.choice-card.is-selected .choice-card-check {
  background: var(--color-red);
  border-color: var(--color-red);
  color: #fff;
}

/* Mietdauer / Kilometer-Eingaben */
.calc-fields { display: grid; grid-template-columns: 1fr; gap: 1.1rem; }
@media (min-width: 560px) { .calc-fields { grid-template-columns: 1fr 1fr; } }
.calc-field label { display: block; font-size: 0.85rem; font-weight: 600; color: var(--color-text-primary); margin-bottom: 0.4rem; }
.calc-field input {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-size: 1rem;
  min-height: 44px;
}
.calc-field input:focus { outline: none; border-color: var(--color-red); box-shadow: 0 0 0 3px var(--color-red-soft); }
.calc-field-hint { font-size: 0.8rem; color: var(--color-text-muted); margin-top: 0.35rem; }

/* Ergebnis-Card — sticky auf Desktop, direkt unter der Eingabe auf Mobile */
.calc-aside { position: static; }
@media (min-width: 1024px) { .calc-aside { position: sticky; top: 110px; } }

.result-card {
  background: var(--color-graphite);
  color: #fff;
  border-radius: var(--radius-lg);
  padding: 1.75rem 1.5rem;
  box-shadow: var(--shadow-lg);
}
.result-card h3 {
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.6);
  margin-bottom: 1.25rem;
}
.result-vehicle { font-weight: 700; font-size: 1.05rem; }
.result-tariff { font-size: 0.9rem; color: rgba(255,255,255,0.75); margin-top: 0.2rem; margin-bottom: 1.1rem; }
.result-lines { display: flex; flex-direction: column; gap: 0.6rem; margin: 1rem 0; }
.result-lines > div { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.9rem; color: rgba(255,255,255,0.85); }
.result-lines dt { font-weight: 400; }
.result-lines dd { font-weight: 600; white-space: nowrap; }
.result-note { font-size: 0.82rem; color: rgba(255,255,255,0.6); margin-bottom: 1rem; }
.result-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1.1rem;
  border-top: 1px solid rgba(255,255,255,0.18);
  margin-top: 0.5rem;
}
.result-total span { font-size: 0.92rem; color: rgba(255,255,255,0.85); }
.result-total strong { font-size: 1.7rem; font-family: var(--font-head); color: #fff; }
.result-disclaimer { font-size: 0.78rem; color: rgba(255,255,255,0.55); margin-top: 1rem; }

.result-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.35rem 0.8rem;
  border-radius: var(--radius-full);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  margin-bottom: 0.9rem;
}
.result-badge-quote { background: rgba(196, 39, 44, 0.25); color: #ffb3b0; }
.result-badge-incomplete { background: rgba(255,255,255,0.12); color: rgba(255,255,255,0.75); }
.result-card p { font-size: 0.92rem; color: rgba(255,255,255,0.8); }

.result-cta { margin-top: 1.5rem; }
.result-cta .btn { width: 100%; }
.result-deposit-note { font-size: 0.78rem; color: rgba(255,255,255,0.55); margin-top: 0.8rem; }

/* Einsatzbereiche-Icons (Umzug, Möbeltransport, ...) */
.use-case-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; }
@media (min-width: 700px) { .use-case-grid { grid-template-columns: repeat(4, 1fr); } }
.use-case-card { text-align: center; }
.use-case-icon {
  width: 56px; height: 56px;
  border-radius: 999px;
  background: var(--color-red-soft);
  color: var(--color-red);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 0.9rem;
}
.use-case-icon svg { width: 26px; height: 26px; }
.use-case-card h3 { font-size: 0.95rem; margin-bottom: 0.3rem; }
.use-case-card p { font-size: 0.85rem; color: var(--color-text-secondary); }

/* -------------------------------------------------------------------------
   Cookie consent banner — dark/red, matches .site-footer's own palette.
   Built and shown by js/cookie-consent.js on every page; reopenable any
   time via the "Cookie-Einstellungen" footer link. Two states in the same
   panel (.is-settings toggles between them) rather than two components, so
   there's only ever one banner in the DOM. z-index sits above the contact
   modal / badge lightbox (200) — a consent choice shouldn't be blockable
   by something opened on top of it.
   ------------------------------------------------------------------------- */
.cookie-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 300;
  background: var(--color-graphite);
  color: rgba(255, 255, 255, 0.92);
  box-shadow: 0 -12px 32px rgba(0, 0, 0, 0.28);
  max-height: 100vh;
  overflow-y: auto;
}
.cookie-banner[hidden] { display: none; }
.cookie-banner-inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1.5rem var(--margin-mobile) 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
@media (min-width: 768px) { .cookie-banner-inner { padding: 1.75rem var(--margin-desktop) 2rem; } }
.cookie-banner-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.cookie-banner-title { font-family: var(--font-head); font-weight: 700; font-size: 1.05rem; color: #fff; }
.cookie-banner-close[hidden],
.cookie-banner-actions[hidden],
.cookie-settings[hidden] { display: none; }
.cookie-banner-close {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  border: 0;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.cookie-banner-close:hover { background: rgba(255, 255, 255, 0.18); }
.cookie-banner-text { font-size: 0.9rem; line-height: 1.6; color: rgba(255, 255, 255, 0.78); max-width: 68ch; }
.cookie-banner-text a { color: #fff; text-decoration: underline; text-underline-offset: 2px; }

/* Three actions, deliberately the same visual weight (size, padding, row
   position) — "Alle akzeptieren" isn't styled larger or brighter than
   "Nur notwendige" the way a lot of consent banners do. Only the fill
   (red vs outline) differs, matching how .btn-primary/.btn-outline are
   used as equals everywhere else on the site. */
.cookie-banner-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.cookie-banner-actions .btn { flex: 1 1 200px; justify-content: center; white-space: nowrap; }
.btn-outline-light {
  background: transparent;
  color: #fff;
  border: 1.5px solid rgba(255, 255, 255, 0.4);
}
.btn-outline-light:hover { border-color: #fff; background: rgba(255, 255, 255, 0.08); }

/* Settings sub-view */
.cookie-settings { display: flex; flex-direction: column; gap: 0.9rem; }
.cookie-settings-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.95rem 1.1rem;
  background: rgba(255, 255, 255, 0.06);
  border-radius: var(--radius-md);
}
.cookie-settings-row-text h4 { font-size: 0.92rem; font-weight: 700; color: #fff; margin-bottom: 0.25rem; }
.cookie-settings-row-text p { font-size: 0.84rem; line-height: 1.5; color: rgba(255, 255, 255, 0.68); }
/* Plain checkbox, not a fake toggle-switch graphic — keeps the on/off
   state exactly as native and screen-reader-legible as any other form
   control on the site (see input[type=checkbox] usage elsewhere), just
   sized up since it's the whole control here. */
.cookie-settings-row input[type="checkbox"] {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  accent-color: var(--color-red);
}
.cookie-settings-row input[type="checkbox"]:disabled { opacity: 0.6; }

/* Maps consent placeholder — replaces the live Google Maps iframe until
   .cookie-consent-maps is granted (see js/cookie-consent.js). Sized to
   fill the same .about-feature-map-wrap box the iframe would. */
.maps-consent-placeholder[hidden] { display: none; }
.maps-consent-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.9rem;
  padding: 1.75rem;
  background: var(--color-bg-soft);
  border-radius: inherit;
}
.maps-consent-icon {
  width: 52px;
  height: 52px;
  border-radius: 999px;
  background: var(--color-red-soft);
  color: var(--color-red);
  display: flex;
  align-items: center;
  justify-content: center;
}
.maps-consent-icon svg { width: 26px; height: 26px; }
.maps-consent-placeholder p { font-size: 0.92rem; color: var(--color-text-secondary); max-width: 34ch; }
