/* =========================================================
   KI-Büro 24 — Onepager
   Vanilla CSS, mobile-first, keine externen Abhängigkeiten.
   Systemschriften: schnell + kein Google-Fonts-Datenschutzproblem.
   ========================================================= */

:root {
  --ink: #1b2733; /* Anthrazit, Grundton */
  --ink-2: #2a3947;
  --ink-soft: #5a6b7b;
  --paper: #f7f5f2; /* warmes Off-White */
  --paper-2: #fffefc;
  --line: #e2ddd6;
  --brand: #e8730a; /* Handwerks-Orange */
  --brand-dk: #c65c00;
  --brand-soft: #fdf0e3;
  --wa: #25d366;
  --wa-dk: #128c4a;
  --ok: #1f7a44;
  --err: #b3261e;
  --r: 14px;
  --r-lg: 22px;
  --shadow: 0 1px 2px rgba(27, 39, 51, 0.06), 0 8px 24px rgba(27, 39, 51, 0.08);
  --shadow-lg: 0 2px 4px rgba(27, 39, 51, 0.06), 0 18px 50px rgba(27, 39, 51, 0.14);
  --wrap: 1180px;
  /* Seitenabstand des Inhalts. Slider ziehen sich um genau diesen Wert
     nach aussen, damit sie am Bildschirmrand anschneiden statt abzubrechen. */
  --gutter: clamp(16px, 4.4vw, 40px);
  --fs: clamp(1rem, 0.96rem + 0.2vw, 1.075rem);
  --sans: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 76px;
  /* Riegel gegen horizontales Scrollen. Bewusst `clip` und nicht `hidden`:
     `hidden` würde aus dem Element einen Scroll-Container machen — und ein
     Scroll-Container ist die Bezugsgrösse für `view()`. Die scroll-getriebenen
     Animationen weiter unten würden dann an einem Kasten hängen, der nie
     scrollt, und stünden still. `clip` klemmt nur ab. */
  overflow-x: clip;
}

body {
  margin: 0;
  font-family: var(--sans);
  font-size: var(--fs);
  line-height: 1.62;
  color: var(--ink);
  background: var(--paper);
  /* Der Riegel gegen Querscrollen sitzt jetzt oben an `html`. Hier stand
     `overflow-x: hidden` — das darf nicht bleiben: Sobald `html` nicht mehr
     `visible` ist, wird der Wert von `body` nicht mehr an den Viewport
     durchgereicht und `body` selbst wird zum Scroll-Container. Genau daran
     würden dann alle `view()`-Zeitleisten hängen — an einem Kasten, der nie
     scrollt. Die Bewegung stünde still, ohne dass irgendetwas fehlschlägt. */
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}
svg {
  display: block;
}

/* Eigene display-Regeln würden das [hidden]-Attribut sonst aushebeln. */
[hidden] {
  display: none !important;
}

h1,
h2,
h3 {
  line-height: 1.18;
  letter-spacing: -0.021em;
  margin: 0 0 0.5em;
  font-weight: 800;
  text-wrap: balance;
}
h1 {
  font-size: clamp(2rem, 1.35rem + 3.1vw, 3.55rem);
}
h2 {
  font-size: clamp(1.6rem, 1.2rem + 1.9vw, 2.5rem);
}
h3 {
  font-size: clamp(1.15rem, 1.02rem + 0.6vw, 1.42rem);
}
p {
  margin: 0 0 1em;
}
p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--brand-dk);
  text-underline-offset: 3px;
}

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

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Nur für Screenreader — sichtbarer Ersatz für animierte Textwechsel. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

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

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  padding: 1rem 1.6rem;
  border: 0;
  border-radius: var(--r);
  font: inherit;
  font-weight: 700;
  line-height: 1.25;
  text-decoration: none;
  cursor: pointer;
  transition:
    transform 0.16s ease,
    box-shadow 0.16s ease,
    background-color 0.16s ease;
  min-height: 52px;
  text-align: center;
}
.btn:hover {
  transform: translateY(-2px);
}
.btn:active {
  transform: translateY(0);
}
.btn-sm {
  padding: 0.72rem 1.1rem;
  min-height: 44px;
  font-size: 0.94rem;
}
.btn-block {
  width: 100%;
}

.btn-primary {
  background: var(--brand);
  color: #fff;
  box-shadow: 0 6px 18px rgba(232, 115, 10, 0.32);
}
.btn-primary:hover {
  background: var(--brand-dk);
  box-shadow: 0 10px 26px rgba(232, 115, 10, 0.4);
}

.btn-dark {
  background: var(--ink);
  color: #fff;
}
.btn-dark:hover {
  background: var(--ink-2);
}

.btn-ghost {
  background: transparent;
  color: #fff;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.35);
}
.btn-ghost:hover {
  background: rgba(255, 255, 255, 0.1);
}

.btn-wa {
  background: var(--wa);
  color: #04331a;
  box-shadow: 0 6px 20px rgba(37, 211, 102, 0.34);
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.12rem);
  padding: 1.1rem 1.7rem;
}
.btn-wa:hover {
  background: #1fbb5a;
}
.ico-wa {
  width: 1.45em;
  height: 1.45em;
  flex: 0 0 auto;
}

/* Dezentes Pulsieren, nur auf dem grünen Haupt-CTA */
.pulse {
  position: relative;
}
.pulse::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.55);
  animation: pulse 2.6s ease-out infinite;
  pointer-events: none;
}
@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.5);
  }
  70% {
    box-shadow: 0 0 0 18px rgba(37, 211, 102, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(37, 211, 102, 0);
  }
}

/* ---------- Scroll-Reveal ---------- */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 0.6s ease,
    transform 0.6s ease;
}
.reveal.in {
  opacity: 1;
  transform: none;
}

/* ---------- Kopfzeile ---------- */
.site-head {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(247, 245, 242, 0.9);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid transparent;
  transition:
    border-color 0.2s ease,
    box-shadow 0.2s ease;
}
.site-head.stuck {
  border-bottom-color: var(--line);
  box-shadow: 0 4px 20px rgba(27, 39, 51, 0.06);
}
.head-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 68px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--ink);
  font-weight: 800;
}
/* Wortmarke statt Bildlogo — kein Request, skaliert verlustfrei, in einer Zeile änderbar.
   Der Kontrast entsteht aus Schriftschnitt und Laufweite, nicht aus einer Grafik. */
.wordmark {
  display: inline-flex;
  align-items: baseline;
  font-size: clamp(1.24rem, 1.1rem + 0.6vw, 1.5rem);
  font-weight: 900;
  letter-spacing: -0.045em;
  line-height: 1;
  white-space: nowrap;
}
.wm-ki {
  /* Der Verlauf trägt die Marke — bei fehlender Unterstützung bleibt Orange stehen. */
  color: var(--brand);
  background: linear-gradient(100deg, var(--brand) 0%, #ff9d3c 55%, var(--brand-dk) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
@supports not (background-clip: text) {
  .wm-ki {
    -webkit-text-fill-color: currentColor;
  }
}
.wm-buero {
  color: var(--ink);
  font-weight: 800;
}
.wm-24 {
  margin-left: 0.14em;
  padding: 0.16em 0.34em;
  border-radius: 7px;
  background: var(--ink);
  color: var(--paper-2);
  font-size: 0.62em;
  font-weight: 800;
  letter-spacing: 0.01em;
  transform: translateY(-0.18em);
}
.brand:hover .wm-24 {
  background: var(--brand);
}

.head-nav {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2vw, 26px);
}
.head-nav a {
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.96rem;
}
.head-nav a:hover {
  color: var(--brand-dk);
}
.head-nav a.btn {
  color: #fff;
}
/* Textlinks auf schmalen Screens ausblenden, CTA bleibt */
@media (max-width: 820px) {
  .head-nav a:not(.btn) {
    display: none;
  }
}

/* ---------- Hero ---------- */
/* Bewegung im ersten Bildschirm, komplett in CSS:
   zwei langsam wandernde Farbschleier hinter dem Inhalt. Kein JS, kein Bild,
   keine Layout-Neuberechnung — animiert wird nur transform/opacity auf der
   Compositor-Ebene, das kostet auf schwachen Handys praktisch nichts. */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(38px, 6vw, 80px) 0 clamp(44px, 6vw, 86px);
}
.hero::before,
.hero::after {
  content: '';
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.5;
  pointer-events: none;
  will-change: transform;
}
.hero::before {
  top: -18%;
  left: -12%;
  width: min(62vw, 560px);
  aspect-ratio: 1;
  background: radial-gradient(circle, rgba(232, 115, 10, 0.5), transparent 68%);
  animation: drift-a 19s ease-in-out infinite alternate;
}
.hero::after {
  right: -16%;
  bottom: -22%;
  width: min(58vw, 520px);
  aspect-ratio: 1;
  background: radial-gradient(circle, rgba(37, 211, 102, 0.34), transparent 68%);
  animation: drift-b 24s ease-in-out infinite alternate;
}
@keyframes drift-a {
  from {
    transform: translate3d(0, 0, 0) scale(1);
  }
  to {
    transform: translate3d(11%, 16%, 0) scale(1.16);
  }
}
@keyframes drift-b {
  from {
    transform: translate3d(0, 0, 0) scale(1.1);
  }
  to {
    transform: translate3d(-13%, -12%, 0) scale(1);
  }
}

/* Wechselnde Pointe in der H1. Die sichtbare Variante ist per aria-hidden vom
   Screenreader ausgenommen, .sr-only liefert dort einen festen Satz. */
.h1-pre {
  display: block;
  font-size: 0.62em;
  font-weight: 700;
  color: var(--ink-soft);
  letter-spacing: -0.01em;
  margin-bottom: 0.18em;
}
.h1-main {
  display: block;
}
.rotator {
  display: inline-grid;
  overflow: hidden;
  vertical-align: bottom;
  /* Feste Höhe einer Zeile: verhindert, dass die Seite beim Wechsel springt. */
  height: 1.18em;
  color: var(--brand-dk);
}
/* Filmstreifen: die Pointen stehen untereinander, das Fenster darüber ist
   1,18 em hoch und clippt. Verschoben wird der Streifen, nicht der Text. */
.rotator-in {
  display: grid;
  grid-auto-rows: 1.18em;
  animation: rotate-words 15s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}
.rotator-in > span {
  height: 1.18em;
  white-space: nowrap;
}
/* Fünf Pointen, danach läuft die Schleife in den Klon des ersten Eintrags
   und beginnt unsichtbar von vorn. Jede Pointe steht 16 % der Laufzeit. */
@keyframes rotate-words {
  0%,
  16% {
    transform: translateY(0);
  }
  20%,
  36% {
    transform: translateY(-1.18em);
  }
  40%,
  56% {
    transform: translateY(-2.36em);
  }
  60%,
  76% {
    transform: translateY(-3.54em);
  }
  80%,
  96% {
    transform: translateY(-4.72em);
  }
  100% {
    transform: translateY(-5.9em);
  }
}
.hero-in {
  display: grid;
  gap: clamp(30px, 4vw, 56px);
  align-items: center;
}
@media (min-width: 960px) {
  .hero-in {
    grid-template-columns: 1.08fr 0.92fr;
  }
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  margin: 0 0 1rem;
  font-size: 0.83rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--brand-dk);
}
.eyebrow-light {
  color: #f6b16a;
}
.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  flex: 0 0 auto;
}

.hero-lead {
  font-size: clamp(1.04rem, 0.99rem + 0.34vw, 1.22rem);
  color: var(--ink-soft);
  max-width: 60ch;
}

.pricetag {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  margin: 1.7rem 0 1.6rem;
  padding: 1rem 1.4rem;
  background: var(--brand-soft);
  border: 1px solid #f4d3ac;
  border-left: 5px solid var(--brand);
  border-radius: var(--r);
}
.pricetag-lbl {
  font-size: 0.83rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brand-dk);
}
/* Zwei Preisteile: einmalig und monatlich stehen gleichwertig nebeneinander,
   damit die laufenden Kosten nicht wie Kleingedrucktes wirken. */
.pricetag-val {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.3em 0.55em;
  margin: 0.24rem 0 0.34rem;
  font-size: clamp(0.94rem, 0.88rem + 0.3vw, 1.06rem);
  font-weight: 700;
  color: var(--ink-soft);
  letter-spacing: -0.01em;
}
.pricetag-part {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3em;
  white-space: nowrap;
}
.pricetag-num {
  font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2.15rem);
  font-weight: 900;
  letter-spacing: -0.035em;
  color: var(--ink);
}
.pricetag-plus {
  font-size: 1.25rem;
  font-weight: 800;
  color: var(--brand);
}
.pricetag-sub {
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.pricetag-fineprint {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--ink-soft);
}
/* Pflichtangabe zur Umsatzsteuer — muss lesbar sein, darf den Preis aber nicht überstimmen. */
.pricetag-vat {
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--ink-soft);
  opacity: 0.85;
}

/* Spar-Badge über dem Preis: soll "krass" auffallen (Auftraggeber-Wunsch
   29.08.2026, 21:52 Uhr) -- deshalb eigene Signalfarbe statt Markenorange
   und ein dezentes Pulsieren wie beim WhatsApp-Button (.pulse), nur rot statt
   grün, damit beide Signale nicht verwechselt werden. Reduzierte Bewegung
   greift automatisch über die globale prefers-reduced-motion-Regel unten. */
.savings-badge {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  margin-bottom: 0.55rem;
  padding: 0.34rem 0.8rem;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.01em;
  color: #fff;
  background: linear-gradient(100deg, #e8730a, #ff3d3d);
  border-radius: 999px;
  box-shadow: 0 4px 14px rgba(232, 115, 10, 0.35);
}
.pulse-badge {
  animation: pulse-badge 1.8s ease-out infinite;
}
@keyframes pulse-badge {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 61, 61, 0.5);
  }
  70% {
    box-shadow: 0 0 0 12px rgba(255, 61, 61, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(255, 61, 61, 0);
  }
}

/* Button und QR-Karte stehen nebeneinander, sobald Platz ist —
   sonst rutscht die QR-Karte automatisch in die nächste Zeile. */
.cta-block {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: stretch;
}
.cta-block .btn-wa {
  flex: 1 1 290px;
}

.qr-card {
  flex: 1 1 290px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px 12px 12px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow);
}
.qr-box {
  width: 96px;
  height: 96px;
  flex: 0 0 auto;
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
  display: grid;
  place-items: center;
}
.qr-box img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.qr-ph {
  position: relative;
  width: 100%;
  height: 100%;
  background:
    repeating-linear-gradient(90deg, var(--ink) 0 5px, transparent 5px 10px),
    repeating-linear-gradient(0deg, var(--ink) 0 5px, transparent 5px 10px);
  background-size: 10px 10px;
  opacity: 0.16;
  display: grid;
  place-items: center;
  border-radius: 8px;
}
.qr-corner {
  position: absolute;
  width: 22px;
  height: 22px;
  border: 4px solid var(--ink);
  border-radius: 4px;
}
.qr-corner.tl {
  top: 5px;
  left: 5px;
}
.qr-corner.tr {
  top: 5px;
  right: 5px;
}
.qr-corner.bl {
  bottom: 5px;
  left: 5px;
}
.qr-ph-txt {
  font-size: 0.62rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background: #fff;
  padding: 2px 5px;
  border-radius: 3px;
}
.qr-txt {
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--ink-soft);
  max-width: 24ch;
}
.qr-txt strong {
  color: var(--ink);
}
/* QR ist auf dem Handy sinnlos — dort steht der Button direkt zur Verfügung */
@media (max-width: 599px) {
  .qr-card {
    display: none;
  }
}

.trust {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem 1.5rem;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.9rem;
  color: var(--ink-soft);
}
.trust li {
  display: flex;
  align-items: center;
  gap: 0.5em;
}
.trust li::before {
  content: '✓';
  color: var(--ok);
  font-weight: 800;
}

.hero-fig {
  margin: 0;
  position: relative;
}
.hero-cap {
  position: absolute;
  left: 16px;
  bottom: 16px;
  right: 16px;
  background: rgba(27, 39, 51, 0.92);
  color: #fff;
  padding: 0.8rem 1rem;
  border-radius: 12px;
  font-size: 0.92rem;
  line-height: 1.4;
  backdrop-filter: blur(4px);
}
.hero-cap strong {
  color: #ffb469;
}

/* Bildplatzhalter — wird ersetzt, sobald echte Fotos vorliegen */
.ph-img {
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--ink);
  box-shadow: var(--shadow-lg);
}
.ph-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ph-hero {
  aspect-ratio: 4/5;
}
.ph-side {
  aspect-ratio: 4/3;
  margin-top: 1.6rem;
  max-width: 460px;
}
.ph-note {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 24px;
  text-align: center;
  color: rgba(255, 255, 255, 0.5);
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.6;
  background:
    linear-gradient(135deg, #243342, #1b2733 60%, #2c3d4d),
    repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.03) 0 12px, transparent 12px 24px);
}
.ph-img:has(img:not([hidden])) .ph-note {
  display: none;
}

/* ---------- Team-Streifen ---------- */
.team-strip {
  background: var(--paper-2);
  border-block: 1px solid var(--line);
  padding: clamp(30px, 4vw, 48px) 0;
}
.team-in {
  display: grid;
  gap: 18px;
}
@media (min-width: 760px) {
  .team-in {
    grid-template-columns: repeat(3, 1fr);
  }
}
.team-footnote {
  margin: 20px 0 0;
  text-align: center;
  font-size: 0.86rem;
  font-style: italic;
  color: var(--ink-soft);
}
.team-card {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}
.team-card p {
  font-size: 0.94rem;
  color: var(--ink-soft);
  margin: 0;
}
.team-name {
  font-size: 1.06rem;
  margin: 0 0 0.25rem;
  font-weight: 800;
}
.team-role {
  color: var(--ink-soft);
  font-weight: 600;
  font-size: 0.92rem;
}
.team-ava {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  border-radius: 13px;
  font-weight: 800;
  font-size: 1.1rem;
  color: #fff;
  position: relative;
  overflow: hidden;
}
/* Portrait-Foto liegt über dem Buchstaben-Avatar. Solange die Datei fehlt
   (siehe assets/BILDER.md), bleibt sie per [hidden] unsichtbar und der
   Buchstabe zeigt weiter durch — kein kaputtes Layout ohne Foto. */
.team-ava img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.team-ava:has(img:not([hidden])) .ava-letter {
  display: none;
}
.team-photo-note {
  margin: 0.3rem 0 0;
  font-size: 0.78rem;
  color: var(--ink-soft);
  font-style: italic;
}
.ava-m {
  background: linear-gradient(150deg, #2f9e5c, #128c4a);
}
.ava-s {
  background: linear-gradient(150deg, #3a6ea8, #2a5183);
}
.ava-t {
  background: linear-gradient(150deg, var(--brand), var(--brand-dk));
}

/* ---------- Simulator ---------- */
.sim {
  background: var(--ink);
  color: #fff;
  padding: clamp(48px, 7vw, 92px) 0;
  position: relative;
}
.sim h2 {
  color: #fff;
}
.sec-head {
  max-width: 44rem;
  margin-bottom: clamp(28px, 4vw, 44px);
}
.sec-sub {
  color: var(--ink-soft);
  font-size: 1.03rem;
}
.sim .sec-sub {
  color: #a9bacb;
}

.sim-grid {
  display: grid;
  gap: clamp(26px, 4vw, 44px);
  align-items: start;
}
@media (min-width: 960px) {
  .sim-grid {
    grid-template-columns: 1fr minmax(300px, 380px);
  }
}

.sim-tabs {
  display: grid;
  gap: 12px;
  align-content: start;
}
.sim-tab {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  width: 100%;
  padding: 1rem 1.15rem;
  text-align: left;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-left: 4px solid transparent;
  border-radius: var(--r);
  color: #fff;
  font: inherit;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    transform 0.2s ease;
}
.sim-tab:hover {
  background: rgba(255, 255, 255, 0.09);
  transform: translateX(3px);
}
.sim-tab.is-on {
  background: rgba(232, 115, 10, 0.14);
  border-color: rgba(232, 115, 10, 0.42);
  border-left-color: var(--brand);
}
.sim-tab-ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: 11px;
  font-size: 1.15rem;
  background: rgba(255, 255, 255, 0.08);
}
.sim-tab.is-on .sim-tab-ico {
  background: rgba(232, 115, 10, 0.24);
}
.sim-tab-txt {
  display: block;
  min-width: 0;
}
.sim-tab-txt strong {
  display: block;
  font-size: 1rem;
  line-height: 1.3;
}
.sim-tab-txt small {
  display: block;
  color: #9fb2c4;
  font-size: 0.86rem;
  line-height: 1.4;
  margin-top: 2px;
}

.sim-hint {
  margin-top: 4px;
}
.lnk-replay {
  background: none;
  border: 0;
  padding: 0.5rem 0;
  color: #9fb2c4;
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.lnk-replay:hover {
  color: #fff;
}

/* Smartphone */
.sim-stage {
  display: grid;
  justify-items: center;
}
.phone {
  width: 100%;
  max-width: 340px;
}
.phone-frame {
  position: relative;
  border-radius: 34px;
  background: #0d151d;
  padding: 10px;
  box-shadow:
    0 0 0 2px #38495a,
    var(--shadow-lg);
  overflow: hidden;
}
.phone-notch {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  width: 104px;
  height: 20px;
  background: #0d151d;
  border-radius: 0 0 12px 12px;
  z-index: 3;
}
.phone-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 26px 12px 10px;
  background: #128c4a;
  color: #fff;
  border-radius: 26px 26px 0 0;
}
.phone-ava {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
  font-weight: 800;
  font-size: 0.9rem;
  flex: 0 0 auto;
}
.phone-meta {
  display: block;
  min-width: 0;
  flex: 1;
}
.phone-meta strong {
  display: block;
  font-size: 0.88rem;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.phone-meta small {
  display: block;
  font-size: 0.74rem;
  opacity: 0.85;
}
.phone-icons {
  opacity: 0.8;
}

.phone-screen {
  height: min(64vh, 430px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 14px 12px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: #ece5dd
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60'%3E%3Cg fill='%23d9d0c6' fill-opacity='.5'%3E%3Ccircle cx='12' cy='14' r='1.4'/%3E%3Ccircle cx='44' cy='36' r='1.4'/%3E%3Ccircle cx='28' cy='52' r='1.4'/%3E%3C/g%3E%3C/svg%3E");
  border-radius: 0 0 26px 26px;
  scrollbar-width: thin;
}

.msg {
  max-width: 86%;
  padding: 0.55rem 0.75rem;
  border-radius: 12px;
  font-size: 0.9rem;
  line-height: 1.48;
  color: #111b21;
  background: #fff;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.13);
  position: relative;
  overflow-wrap: anywhere; /* nie über den Rand hinaus */
  animation: pop 0.28s ease both;
}
.msg.me {
  align-self: flex-end;
  background: #d9fdd3;
}
.msg.them {
  align-self: flex-start;
}
.msg .t {
  display: block;
  text-align: right;
  font-size: 0.66rem;
  color: #667781;
  margin-top: 2px;
}
@keyframes pop {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.msg.sys {
  align-self: center;
  max-width: 94%;
  text-align: center;
  background: #fff5d6;
  color: #6b5310;
  font-size: 0.78rem;
  font-weight: 600;
  border-radius: 8px;
}
.msg.alert {
  background: #ffe0dd;
  color: #8f2018;
}

.typing {
  align-self: flex-start;
  display: inline-flex;
  gap: 4px;
  padding: 0.7rem 0.8rem;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.13);
  animation: pop 0.2s ease both;
}
.typing i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #8fa0ab;
  animation: blink 1.3s infinite;
}
.typing i:nth-child(2) {
  animation-delay: 0.18s;
}
.typing i:nth-child(3) {
  animation-delay: 0.36s;
}
@keyframes blink {
  0%,
  60%,
  100% {
    opacity: 0.3;
    transform: translateY(0);
  }
  30% {
    opacity: 1;
    transform: translateY(-3px);
  }
}

/* Nur für Screenreader — sichtbar ist das Label im Chat nicht nötig,
   vorlesbar aber schon. */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Eingabezeile im Live-Chat — sitzt unter dem Display wie bei WhatsApp.
   Wird nur eingeblendet, wenn chat.php erreichbar ist. */
.phone-compose {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  background: #f0f2f5;
  border-radius: 0 0 26px 26px;
}
/* Sobald die Zeile da ist, endet das Display eckig — sonst klafft eine Lücke. */
.phone-screen.has-compose {
  border-radius: 0;
}

.phone-compose input {
  flex: 1;
  min-width: 0;
  padding: 0.6rem 0.9rem;
  border: 0;
  border-radius: 20px;
  background: #fff;
  font: inherit;
  font-size: 0.9rem;
  color: #111b21;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.08);
}

.phone-compose button {
  flex: none;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 50%;
  background: var(--wa-dk);
  color: #fff;
  cursor: pointer;
  transition:
    transform 0.15s ease,
    opacity 0.15s ease;
}
.phone-compose button svg {
  width: 19px;
  height: 19px;
  margin-left: 2px;
}
.phone-compose button:hover:not(:disabled) {
  transform: scale(1.06);
}
.phone-compose button:disabled {
  opacity: 0.45;
  cursor: default;
}

/* Der Live-Reiter bekommt einen dezenten Hinweis, dass hier etwas anderes
   passiert als in den drei Beispielen darüber. */
.sim-tab-live {
  border-style: dashed;
}

/* Anruf-Auslöser */
.callout {
  margin-top: 18px;
  text-align: center;
  animation: pop 0.4s ease both;
}
.call-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 0.85rem 1.4rem;
  background: #fff;
  color: var(--ink);
  border: 0;
  border-radius: var(--r);
  cursor: pointer;
  font: inherit;
  box-shadow: var(--shadow);
  animation: shake 3s ease-in-out infinite;
}
.call-btn:hover {
  transform: translateY(-2px);
}
.ico-tel {
  width: 26px;
  height: 26px;
  color: var(--wa-dk);
  flex: 0 0 auto;
}
.call-txt {
  text-align: left;
  line-height: 1.25;
}
.call-txt strong {
  display: block;
  font-size: 0.98rem;
}
.call-txt small {
  color: var(--ink-soft);
  font-size: 0.84rem;
}
.call-ring {
  position: absolute;
  inset: -4px;
  border-radius: 18px;
  border: 2px solid rgba(37, 211, 102, 0.5);
  animation: pulse 2.4s ease-out infinite;
  pointer-events: none;
}
@keyframes shake {
  0%,
  88%,
  100% {
    transform: rotate(0);
  }
  90% {
    transform: rotate(-1.6deg);
  }
  93% {
    transform: rotate(1.6deg);
  }
  96% {
    transform: rotate(-1deg);
  }
}
.callout-hint {
  margin: 0.7rem 0 0;
  font-size: 0.86rem;
  color: #9fb2c4;
}

/* Anruf-Overlay */
.modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(13, 21, 29, 0.82);
  backdrop-filter: blur(5px);
  animation: fade 0.25s ease both;
}
/* Klassenregel schlägt sonst das [hidden]-Attribut des Browsers */
.modal[hidden],
.callout[hidden] {
  display: none;
}
@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.modal-box {
  position: relative;
  width: 100%;
  max-width: 390px;
  padding: 2.2rem 1.6rem 1.5rem;
  text-align: center;
  background: linear-gradient(165deg, #2a3947, #1b2733);
  color: #fff;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  animation: pop 0.3s ease both;
}
.modal-x {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.modal-x:hover {
  background: rgba(255, 255, 255, 0.2);
}
.call-ava {
  display: grid;
  place-items: center;
  width: 82px;
  height: 82px;
  margin: 0 auto 1rem;
  border-radius: 50%;
  background: linear-gradient(150deg, #3a6ea8, #2a5183);
  font-size: 2rem;
  font-weight: 800;
}
.call-status {
  margin: 0 0 0.2rem;
  font-size: 0.84rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #8fd6a8;
  font-weight: 700;
}
.call-name {
  margin: 0 0 0.1rem;
  font-size: 1.25rem;
  color: #fff;
}
.call-num {
  margin: 0 0 1.1rem;
  color: #9fb2c4;
  font-size: 0.94rem;
}

.call-wave {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 38px;
  margin-bottom: 1rem;
  opacity: 0.35;
}
.call-wave.on {
  opacity: 1;
}
.call-wave i {
  width: 4px;
  height: 8px;
  border-radius: 2px;
  background: #8fd6a8;
}
.call-wave.on i {
  animation: wave 1s ease-in-out infinite;
}
.call-wave i:nth-child(2n) {
  animation-delay: 0.12s;
}
.call-wave i:nth-child(3n) {
  animation-delay: 0.26s;
}
.call-wave i:nth-child(4n) {
  animation-delay: 0.4s;
}
@keyframes wave {
  0%,
  100% {
    height: 8px;
  }
  50% {
    height: 30px;
  }
}

.call-sub {
  min-height: 4.6em;
  margin: 0 0 1rem;
  font-size: 1rem;
  line-height: 1.5;
  color: #e8eef4;
}
.call-sub .cur {
  border-right: 2px solid #8fd6a8;
  animation: caret 0.8s steps(1) infinite;
}
@keyframes caret {
  50% {
    border-color: transparent;
  }
}
.call-foot {
  margin: 0;
  font-size: 0.78rem;
  color: #8598a9;
  line-height: 1.5;
}

/* ---------- Gewerke-Kacheln ---------- */
.trades {
  padding: clamp(48px, 7vw, 92px) 0;
  background: var(--paper);
}
/* Mobil ein seitlicher Slider statt acht gestapelter Kacheln:
   spart auf 360 px rund 1500 px Scrollhöhe und gibt der Seite die Querbewegung.
   Ab 760 px wird daraus wieder ein normales Raster — dort ist Platz genug. */
/* Zwei Kästen statt einem, seit das Band beim Scrollen seitlich fährt:
   `.tile-rail` ist das Fenster (scrollt, wischbar, schneidet ab),
   `.tile-grid` ist die Reihe darin (fährt). Das muss getrennt sein — ein
   Element kann nicht gleichzeitig der Scrollcontainer und der verschobene
   Inhalt sein, sonst schiebt sich sein eigenes Sichtfenster mit weg. */
.tile-rail {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--gutter, 16px);
  /* Der Slider zieht sich über den Wrap hinaus bis an den Bildschirmrand,
     damit die nächste Kachel angeschnitten sichtbar ist ("es geht weiter"). */
  margin-inline: calc(-1 * var(--gutter, 16px));
  scrollbar-width: none;
  /* Bezugsgrösse für `cqw` weiter unten: die sichtbare Breite des Fensters.
     Nur so kennt die Reihe im Keyframe ihren eigenen Überstand, ohne dass
     eine einzige Zeile JavaScript irgendetwas ausmessen muss. */
  container-type: inline-size;
}
.tile-rail::-webkit-scrollbar {
  display: none;
}
.tile-grid {
  display: grid;
  gap: 14px;
  grid-auto-flow: column;
  grid-auto-columns: 82cqw;
  width: max-content;
  /* Innenabstand bewusst an der Reihe, nicht am Fenster: nur so zählt der
     Abstand hinter der letzten Kachel zur Scrollbreite und die achte Kachel
     klebt am Ende nicht am Bildschirmrand. */
  padding-inline: var(--gutter, 16px);
  padding-block: 4px 18px;
}
.tile-grid > .tile {
  scroll-snap-align: center;
}

@media (min-width: 760px) {
  .tile-rail {
    overflow-x: visible;
    margin-inline: 0;
    scroll-snap-type: none;
  }
  .tile-grid {
    grid-auto-flow: row;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
    grid-auto-columns: auto;
    width: auto;
    padding-inline: 0;
  }
}

/* Hinweis "Wisch zur Seite" nur zeigen, solange es wirklich ein Slider ist. */
.sec-sub-hint {
  display: inline-block;
  margin-left: 0.4em;
  color: var(--brand-dk);
  font-weight: 700;
  white-space: nowrap;
}
@media (min-width: 760px) {
  .sec-sub-hint {
    display: none;
  }
}

.tile {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  perspective: 1200px;
  min-height: 230px;
  text-align: left;
}
.tile-in {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  min-height: 230px;
  transition: transform 0.6s cubic-bezier(0.3, 0.8, 0.4, 1);
  transform-style: preserve-3d;
}
/* Hover-Vorschau nur für echte Zeigegeräte (Maus). Auf Touch-Geräten bleibt
   ":hover" nach dem Antippen oft "kleben" — kombiniert mit dem Klick-Handler
   in app.js (der [aria-expanded] umschaltet) sah es dann so aus, als ließe
   sich die Kachel nicht zurückklappen: der zweite Tap setzte aria-expanded
   korrekt auf false, aber :hover allein hielt die Drehung trotzdem aufrecht.
   Per (hover: hover) bekommen nur Maus-Nutzer die Vorschau; Touch verlässt
   sich ausschließlich auf aria-expanded, das app.js zuverlässig umschaltet. */
@media (hover: hover) {
  .tile:hover .tile-in {
    transform: rotateY(180deg);
  }
}
.tile[aria-expanded='true'] .tile-in {
  transform: rotateY(180deg);
}

.tile-face {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: 1.4rem;
  border-radius: var(--r-lg);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  overflow: hidden;
}
.tile-front {
  background: var(--paper-2);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  justify-content: flex-end;
  gap: 0.15rem;
}
.tile-front strong {
  font-size: 1.14rem;
  letter-spacing: -0.015em;
}
.tile-front small {
  color: var(--ink-soft);
  font-size: 0.9rem;
  line-height: 1.45;
}
.tile-ico {
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
  margin-bottom: auto;
  border-radius: 13px;
  background: var(--brand-soft);
  font-size: 1.5rem;
}
.tile-flip {
  margin-top: 0.7rem;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--brand-dk);
}
.tile-flip::after {
  content: ' ↻';
}

.tile-back {
  transform: rotateY(180deg);
  background: linear-gradient(158deg, var(--ink-2), var(--ink));
  color: #fff;
  box-shadow: var(--shadow-lg);
}
.tile-back strong {
  font-size: 0.78rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #f6b16a;
  margin-bottom: 0.7rem;
  display: block;
}
.tile-back ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.55rem;
}
.tile-back li {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.9rem;
  line-height: 1.45;
  color: #dbe4ec;
}
.tile-back li::before {
  content: '✓';
  position: absolute;
  left: 0;
  top: -1px;
  color: #7fd4a0;
  font-weight: 800;
}

/* Das unangenehme-Sachen-Feature */
.awkward {
  display: grid;
  gap: 18px;
  align-items: start;
  margin-top: clamp(24px, 3vw, 36px);
  padding: clamp(22px, 3.4vw, 34px);
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-top: 4px solid var(--brand);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}
@media (min-width: 720px) {
  .awkward {
    grid-template-columns: auto 1fr;
    gap: 24px;
  }
}
.awkward h3 {
  margin-bottom: 0.4rem;
}
.awkward p {
  color: var(--ink-soft);
  margin: 0;
}
.awkward strong {
  color: var(--ink);
}
.awkward-ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 58px;
  height: 58px;
  border-radius: 16px;
  background: var(--brand);
  color: #fff;
}
.awkward-ico svg {
  width: 30px;
  height: 30px;
}

/* ---------- Garantie / Preis ---------- */
.promise {
  padding: clamp(48px, 7vw, 92px) 0;
  background: var(--paper);
}
.promise-box {
  position: relative;
  max-width: 800px;
  margin-inline: auto;
  padding: clamp(34px, 5vw, 58px) clamp(22px, 4vw, 52px) clamp(30px, 4vw, 48px);
  text-align: center;
  background: linear-gradient(163deg, #2a3947, #1b2733);
  color: #fff;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.promise-box::before {
  content: '';
  position: absolute;
  top: -70px;
  right: -70px;
  width: 230px;
  height: 230px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(232, 115, 10, 0.28), transparent 68%);
  pointer-events: none;
}
.promise-box h2 {
  color: #fff;
  margin-bottom: 1rem;
}
.promise-seal {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  margin: 0 auto 1.1rem;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  box-shadow: 0 8px 26px rgba(232, 115, 10, 0.42);
}
.promise-seal svg {
  width: 34px;
  height: 34px;
}
.promise-slogan {
  font-size: clamp(1.1rem, 1rem + 0.7vw, 1.42rem);
  font-weight: 700;
  color: #ffb469;
  max-width: 32ch;
  margin-inline: auto;
  margin-bottom: 1rem;
}
/* CRM-Box (Immobilienmakler/Vertrieb, KIB-14-Kommentar 29.08.2026, 21:52 Uhr):
   erbt fast alles von .promise-box, nur der Akzent ist Indigo statt Orange --
   sonst wäre nicht auf den ersten Blick klar, dass das ein anderes Angebot
   ist als das Kombi-Angebot direkt darüber. */
.crm-seal {
  background: #5b5bd6;
  box-shadow: 0 8px 26px rgba(91, 91, 214, 0.42);
}
.crm-slogan {
  color: #b3aeff;
}
.promise-txt {
  color: #c3d0dc;
  max-width: 56ch;
  margin-inline: auto;
  margin-bottom: 1.7rem;
}
.promise-vat {
  font-size: 0.78rem;
  line-height: 1.4;
  color: #93a4b4;
  max-width: 56ch;
  margin: -1rem auto 1.7rem;
}

.promise-list {
  display: grid;
  gap: 0.6rem;
  max-width: 30rem;
  margin: 0 auto 2rem;
  padding: 0;
  list-style: none;
  text-align: left;
}
@media (min-width: 640px) {
  .promise-list {
    grid-template-columns: 1fr 1fr;
  }
}
.promise-fineprint {
  font-size: 0.78rem;
  line-height: 1.4;
  color: #93a4b4;
  max-width: 56ch;
  margin: -1rem auto 1.7rem;
}
.promise-list li {
  display: flex;
  gap: 0.6em;
  align-items: flex-start;
  font-size: 0.94rem;
  color: #dbe4ec;
}
.promise-list span {
  color: #7fd4a0;
  font-weight: 800;
}

.promise-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
}

/* Preis-Menü: die drei Alternativen zum Kombi-Angebot oben in .promise-list.
   Bewusst zurückhaltend gestaltet (kleiner, gedeckter als die Hauptbox) --
   das Kombi-Angebot soll die naheliegende Wahl bleiben, das Menü ist für
   Betriebe mit Sonderfall (schon eine Seite, nur eine KI gewünscht usw.). */
.price-menu {
  margin: 0 auto 1.6rem;
  max-width: 34rem;
  padding: 1.1rem 1.3rem;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r-md, 14px);
  background: rgba(255, 255, 255, 0.04);
  text-align: left;
}
.price-menu-lbl {
  margin: 0 0 0.7rem;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #93a4b4;
  text-transform: uppercase;
}
.price-menu-list {
  display: grid;
  gap: 0.55rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.price-menu-list li {
  font-size: 0.88rem;
  line-height: 1.45;
  color: #dbe4ec;
}
.price-menu-list strong {
  color: #fff;
}

/* Retainer-Kasten: 199 EUR/Monat ohne Einrichtungsgebühr, Zusage manuell durch
   die Geschäftsführung -- deshalb optisch abgesetzt (Akzentrahmen) von den
   automatisch bepreisten Optionen im .price-menu direkt darüber. */
.retainer-box {
  margin: 0 auto 1.6rem;
  max-width: 34rem;
  padding: 1.1rem 1.3rem;
  border: 1px solid rgba(232, 115, 10, 0.4);
  border-radius: var(--r-md, 14px);
  background: rgba(232, 115, 10, 0.08);
  text-align: left;
}
.retainer-lbl {
  margin: 0 0 0.4rem;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #ffb469;
  text-transform: uppercase;
}
.retainer-txt {
  margin: 0 0 0.8rem;
  font-size: 0.9rem;
  line-height: 1.5;
  color: #dbe4ec;
}
.retainer-txt strong {
  color: #fff;
}

/* ---------- Formular ---------- */
.lead {
  padding: clamp(48px, 7vw, 92px) 0;
  background: var(--paper-2);
  border-top: 1px solid var(--line);
}
.lead-in {
  display: grid;
  gap: clamp(28px, 4vw, 52px);
  align-items: start;
}
@media (min-width: 900px) {
  .lead-in {
    grid-template-columns: 1fr 1fr;
  }
}

.lead-note {
  padding: 1rem 1.2rem;
  margin-bottom: 1.2rem;
  background: #eaf7ee;
  border-left: 4px solid var(--wa-dk);
  border-radius: 0 var(--r) var(--r) 0;
  font-size: 0.97rem;
  color: #215c39;
}

.lead-form {
  display: grid;
  gap: 1rem;
  padding: clamp(22px, 3.4vw, 34px);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}
.field {
  display: grid;
  gap: 0.35rem;
}
.field label {
  font-weight: 700;
  font-size: 0.94rem;
}
.field .opt {
  font-weight: 500;
  color: var(--ink-soft);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  font: inherit;
  color: var(--ink);
  background: var(--paper-2);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  min-height: 50px;
  transition:
    border-color 0.16s ease,
    box-shadow 0.16s ease;
}
.field textarea {
  min-height: 96px;
  resize: vertical;
  line-height: 1.5;
}
/* Eigener Pfeil statt System-Look — sonst wirkt das Feld auf iOS wie deaktiviert. */
.field select {
  appearance: none;
  padding-right: 2.6rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%235b6b7c' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 12px 8px;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 0;
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(232, 115, 10, 0.15);
}
.field input[aria-invalid='true'],
.field select[aria-invalid='true'],
.field textarea[aria-invalid='true'] {
  border-color: var(--err);
  background: #fdf3f2;
}

.err {
  margin: 0;
  font-size: 0.85rem;
  color: var(--err);
  font-weight: 600;
  min-height: 0;
}
.err:empty {
  display: none;
}

.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.consent {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.consent input {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  margin-top: 2px;
  accent-color: var(--brand);
}

.form-msg {
  margin: 0;
  font-size: 0.94rem;
  font-weight: 600;
  line-height: 1.5;
}
.form-msg:empty {
  display: none;
}
.form-msg.ok {
  color: var(--ok);
}
.form-msg.bad {
  color: var(--err);
}
.form-fine {
  margin: 0;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

/* Schlichte Seiten ohne JavaScript: Danke-Seite und Fehlerausgabe aus anfrage.php */
.minimal-page {
  max-width: 640px;
  padding: clamp(40px, 7vw, 84px) 0;
}
.minimal-page h1 {
  font-size: clamp(1.6rem, 1.2rem + 1.8vw, 2.2rem);
  margin: 0 0 1rem;
}
.minimal-page p {
  margin: 0 0 1rem;
  color: var(--ink-soft);
  line-height: 1.6;
}
.err-list {
  margin: 0 0 1.4rem;
  padding-left: 1.2rem;
  color: var(--err);
  font-weight: 600;
  line-height: 1.7;
}

/* ---------- Fußzeile ---------- */
.site-foot {
  background: var(--ink);
  color: #a9bacb;
  padding: clamp(34px, 4vw, 52px) 0 1.5rem;
}
.foot-in {
  display: grid;
  gap: 22px;
  align-items: start;
}
@media (min-width: 720px) {
  .foot-in {
    grid-template-columns: 1fr auto;
    align-items: center;
  }
}
.foot-brand {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}
.foot-brand strong {
  color: #fff;
  display: block;
  font-size: 1.05rem;
}
.foot-brand p {
  margin: 0.2rem 0 0;
  font-size: 0.9rem;
  max-width: 42ch;
}
.foot-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2rem;
}
.foot-nav a {
  color: #a9bacb;
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 600;
}
.foot-nav a:hover {
  color: #fff;
  text-decoration: underline;
}
.foot-nav button.foot-nav-btn {
  background: none;
  border: 0;
  padding: 0;
  color: #a9bacb;
  text-decoration: none;
  font: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  cursor: pointer;
}
.foot-nav button.foot-nav-btn:hover {
  color: #fff;
  text-decoration: underline;
}
.foot-copy {
  max-width: var(--wrap);
  margin: 1.8rem auto 0;
  padding: 1.2rem clamp(16px, 4.4vw, 40px) 0;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 0.84rem;
  color: #7f93a5;
}

/* ---------- Mobiler Dauer-CTA ---------- */
.sticky-cta {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: 12px;
  z-index: 55;
  display: none;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  padding: 0.95rem;
  background: var(--wa);
  color: #04331a;
  border-radius: var(--r);
  text-decoration: none;
  font-weight: 800;
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.26);
  transform: translateY(140%);
  transition: transform 0.32s ease;
}
.sticky-cta.on {
  transform: none;
}
@media (max-width: 599px) {
  .sticky-cta {
    display: flex;
  }
  body {
    padding-bottom: 78px;
  }
}

/* ============================================================
   Seitwaerts — scroll-getriebene Bewegung
   ============================================================
   Der Scrollbalken ist die Zeitleiste: `animation-timeline: view()` koppelt den
   Fortschritt einer Animation an die Position des Elements im Viewport. Der
   Besucher scrollt nach unten, die Flaeche faehrt seitlich — synchron zum
   Finger, nicht als abgehacktes "Element blendet ein". Kein JavaScript, keine
   Bibliothek, 0 kB zusaetzliche Ladelast.

   Drei Regeln, die hier nicht verhandelbar sind:

   1. Alles steckt in `@supports (animation-timeline: view())`. Wo der Browser
      das nicht kann, greift der Block nicht: Das Element steht still, ist aber
      vollstaendig sichtbar. Kein Polyfill, kein JS-Fallback, nichts bricht.
   2. Nur `transform` und `opacity`. Beides laeuft im Compositor — kein Layout,
      kein Repaint, keine Ruckler auf dem Baustellen-Handy.
   3. Jede seitwaerts fahrende Flaeche sitzt in einem Container mit
      `overflow-x: clip`. Sonst waechst das Dokument nach rechts und das Handy
      scrollt quer — das ist die klassische Falle bei genau dieser Technik.
      `clip` statt `hidden`, weil `hidden` auf einer Achse die andere Achse zum
      Scrollcontainer macht und damit `position: sticky` im Dokument zerlegt.

   Bei "Bewegung reduzieren" laeuft nichts: Der ganze Block haengt zusaetzlich
   in `prefers-reduced-motion: no-preference`. Die Animationen starten dann gar
   nicht erst, statt nachtraeglich abgeschaltet zu werden. */

/* --- 1. Gewerke-Band ------------------------------------------------------
   Das Band faehrt beim Runterscrollen seitlich durchs Bild: acht Gewerke
   ziehen vorbei, ohne dass jemand wischen muss. Wer wischen will, wischt
   trotzdem — die Fahrt liegt als `transform` auf der Reihe, die Wischgeste
   bewegt das Fenster darum herum. Beide addieren sich, keine setzt die
   andere zurueck. Genau deshalb sind Fenster und Reihe getrennte Kaesten.

   Warum eine *benannte* Zeitleiste und nicht schlicht `view()`:
   `view()` sucht sich den naechsten Scroll-Container — und das waere hier
   `.tile-rail`, der zwar quer scrollt, aber nie hoch und runter. Eine
   Zeitleiste ohne Scrollweg ist "inaktiv", die Animation stuende still. Die
   Zeitleiste wird deshalb am Fenster benannt (`view-timeline`), per
   `timeline-scope` an die Sektion gehaengt und von der Reihe darin abgerufen.

   Der Weg steckt komplett in einer Zeile Rechnung: `-100%` ist die Breite der
   Reihe, `100cqw` die Breite des Fensters. Die Differenz ist der Ueberstand —
   also genau der Weg, nach dem die letzte Kachel rechts buendig steht. Kein
   ausgemessener Pixelwert, der bei anderer Kachelzahl oder Schriftgroesse
   falsch waere. */
@supports (animation-timeline: view()) and (timeline-scope: --kib) {
  @media (prefers-reduced-motion: no-preference) {
    .trades {
      /* Haelt die Fahrt im Rahmen. `clip` statt `hidden`, sonst wuerde die
         Sektion zum Scroll-Container und die Zeitleiste darunter unbrauchbar. */
      overflow-x: clip;
      timeline-scope: --gewerke-band;
    }
    /* Ab 760 px wird aus dem Raster wieder eine einzige Reihe, UND erst dort
       faehrt sie automatisch beim Scrollen durchs Bild. Beides gehoert in
       denselben Media-Block — sonst laeuft die Fahrt schon unterhalb von
       760 px auf der Kachelreihe mit, die da bereits ihr eigenes,
       manuelles Wisch-und-Antipp-Fenster ist (`.tile-rail` mit
       `overflow-x: auto`, siehe oben). Genau das war der Bug: Auf dem Handy
       addierte sich die automatische Fahrt zur manuellen Wischgeste, beide
       setzen sich nie zurueck — irgendwann liess sich per Wischen nur noch
       nach rechts kommen, die ersten Kacheln links waren nicht mehr
       erreichbar. Ohne Bewegungsunterstuetzung bleibt es unterhalb von
       760 px beim ruhigen, rein manuellen Wisch-Karussell. */
    @media (min-width: 760px) {
      .tile-rail {
        view-timeline: --gewerke-band block;
        margin-inline: calc(-1 * var(--gutter, 16px));
        scroll-snap-type: x proximity;
        overflow-x: auto;
      }
      .tile-grid {
        animation: gewerke-band linear both;
        animation-timeline: --gewerke-band;
        /* Von "Band taucht unten auf" bis "Band ist oben raus" — die Fahrt
           verteilt sich ueber den gesamten Weg durch den Viewport. */
        animation-range: cover 0% cover 100%;
        grid-auto-flow: column;
        grid-template-columns: none;
        grid-auto-columns: 300px;
        width: max-content;
        padding-inline: var(--gutter, 16px);
      }
    }
  }
}

@keyframes gewerke-band {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(calc(-100% + 100cqw));
  }
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* --- 2. Manni & Sabine -------------------------------------------------
       Die beiden kommen aus gegenueberliegenden Seiten herein und treffen sich
       mittig — passend zur Geschichte: der eine schreibt, die andere
       telefoniert. Die Fahrt ist mit `cover 40%` frueh zu Ende, damit die
       Karten lesbar stehen, solange der Besucher sie tatsaechlich liest. */
    .team-strip {
      overflow-x: clip;
    }
    .team-card-l,
    .team-card-r {
      animation: linear both;
      animation-timeline: view();
      /* Bis `cover 50%`: Die Karten stehen, sobald der Streifen mittig im Bild
         ist — also genau dann, wenn man anfaengt sie zu lesen. */
      animation-range: entry 0% cover 50%;
      will-change: transform, opacity;
    }
    .team-card-l {
      animation-name: come-from-left;
    }
    .team-card-r {
      animation-name: come-from-right;
    }

    /* --- 3. Zahlenband vor dem Preis --------------------------------------
       Zwei Zeilen, die gegenlaeufig durchziehen, direkt bevor der Preis
       gelesen wird. Setzt die Zahl in Bewegung, statt sie nur hinzuschreiben. */
    .numberband-row {
      animation: linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
      will-change: transform;
    }
    .nb-a {
      animation-name: band-left;
    }
    .nb-b {
      animation-name: band-right;
    }
  }
}

/* Die Keyframes stehen ausserhalb von `@supports`: Ungenutzte Keyframes kosten
   nichts, und so bleiben Bewegung und Bedingung sauber getrennt lesbar.
   Die Prozentwerte beim Zahlenband beziehen sich auf die Breite der Zeile
   selbst. 20 % von fuenf Wiederholungen ist rund eine Wiederholung Weg — weit
   genug, dass die Bewegung auffaellt, kurz genug, dass an keinem Ende eine
   Luecke aufreisst. Die Rechnung dazu steht bei `.numberband-row`. */
/* Der Weg ist bewusst in `%` der Kartenbreite, nicht in Pixeln: Auf dem Handy
   ist eine Karte breit und der Einflug entsprechend weit, am Desktop steht sie
   in einer von drei Spalten und der Weg schrumpft mit. Ein fester Pixelwert
   waere auf 1440 px kaum zu sehen und auf 360 px zu viel. */
@keyframes come-from-left {
  from {
    transform: translateX(-48%);
    opacity: 0.15;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}
@keyframes come-from-right {
  from {
    transform: translateX(48%);
    opacity: 0.15;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}
@keyframes band-left {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-20%);
  }
}
@keyframes band-right {
  from {
    transform: translateX(-20%);
  }
  to {
    transform: translateX(0);
  }
}

/* ---------- Zahlenband: Grundgestalt ----------
   Steht auch ohne Bewegung: Wo der Browser `animation-timeline` nicht kennt,
   ist es schlicht ein ruhiges, zweizeiliges Band. `clip` haelt die ueberlangen
   Zeilen im Rahmen — sie sind absichtlich breiter als der Bildschirm, damit
   beim Durchziehen an beiden Enden nie eine Luecke entsteht. */
.numberband {
  overflow-x: clip;
  padding-block: 4px 22px;
  user-select: none;
}
.numberband-row {
  display: flex;
  align-items: center;
  gap: 0.55em;
  width: max-content;
  /* Startversatz nach links, damit auch die nach rechts laufende Zeile
     jederzeit den Bildschirm fuellt.

     Damit rechts nie eine Luecke entsteht, muss gelten:
       Zeilenbreite  >  Startversatz + Fahrweg + Bildschirmbreite
     Die Zeile besteht aus fuenf gleichen Wiederholungen, der Fahrweg ist
     20 % davon (eine Wiederholung), der Versatz 12 % der Bildschirmbreite.
     Bei 1440 px: 5 x ~640 px = 3200 px Zeile gegen 173 + 640 + 1440 = 2253 px
     Bedarf. Wer den Fahrweg vergroessert, legt Wiederholungen nach. */
  margin-left: -12%;
  white-space: nowrap;
  font-weight: 800;
  font-size: clamp(1.05rem, 4.5vw, 1.7rem);
  letter-spacing: -0.02em;
  line-height: 1.5;
  color: var(--ink-soft);
  opacity: 0.5;
}
.nb-b {
  font-size: clamp(0.9rem, 3.4vw, 1.25rem);
  opacity: 0.34;
}
/* Der Abstand haengt am Trennpunkt, nicht am Flex-Gap: Die Zeile besteht aus
   fuenf Gruppen, innerhalb einer Gruppe steht der Text ohne Leerzeichen. */
.nb-dot {
  color: var(--brand);
  opacity: 0.75;
  margin-inline: 0.5em;
}
.nb-hl {
  color: var(--brand);
  opacity: 0.95;
}

/* ---------- Reduzierte Bewegung respektieren ---------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal {
    opacity: 1;
    transform: none;
  }
  .tile:hover .tile-in,
  .tile[aria-expanded='true'] .tile-in {
    transition: none;
  }
  /* Farbschleier im Hero stehen lassen statt wandern — die Optik bleibt,
     die Bewegung ist weg. */
  .hero::before,
  .hero::after {
    animation: none;
  }
  /* Ohne Laufanimation muss die erste Pointe fest sichtbar bleiben,
     sonst zeigt der Rotator einen leeren Kasten. */
  .rotator-in {
    animation: none;
    transform: translateY(0);
  }
  .tile-grid {
    scroll-behavior: auto;
  }
}

/* ---------- Consent-Panel (KIB-5) ---------- */
/* Kein Banner beim ersten Aufruf: Diese Seite lädt beim Laden nachweislich
   keine Drittanbieter-Inhalte und setzt keine Cookies (siehe
   scripts/check-privacy.mjs sowie Datenschutzerklärung Ziffer 3). Das Panel
   ist deshalb erst über den dauerhaften Footer-Link erreichbar, nicht als
   erzwungenes Pop-up — und schon jetzt vollständig bedienbar, damit KIB-7
   (Analytics) es ohne Umbau nachnutzen kann. */
.consent-overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(27, 39, 51, 0.55);
}
.consent-overlay[hidden] {
  display: none;
}
.consent-panel {
  position: relative;
  max-width: 460px;
  width: 100%;
  background: var(--paper-2);
  color: var(--ink);
  border-radius: var(--r);
  padding: clamp(22px, 4vw, 32px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
}
.consent-panel h2 {
  margin: 0 0 0.7rem;
  font-size: 1.25rem;
}
.consent-panel p {
  color: var(--ink-soft);
  margin: 0 0 1.3rem;
  font-size: 0.96rem;
  line-height: 1.55;
}
.consent-panel .consent-status {
  margin: -0.4rem 0 1.1rem;
  font-size: 0.86rem;
  color: var(--ink-soft);
}
.consent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
}
.consent-actions .btn {
  flex: 1 1 160px;
  padding: 0.85rem 1.1rem;
  min-height: 48px;
  font-size: 0.95rem;
}
.btn-outline {
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 2px var(--line);
}
.btn-outline:hover {
  background: var(--paper);
  box-shadow: inset 0 0 0 2px var(--ink-soft);
}
.consent-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-soft);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}
.consent-close:hover {
  background: var(--paper);
  color: var(--ink);
}
