/* =========================================================
   RAGETTLI CREATION — About page styles
   =========================================================
   All colors, fonts and spacing live in :root below.
   Values were measured directly from the live Framer site
   (ragettli-creation.ch/about) with browser DevTools.
   ========================================================= */

/* The two brand typefaces, both self-hosted from assets/.
   NIKEA is caps-only and carries the big headings; Lato does everything else.
   See the licensing note in README.md. */
@font-face {
  font-family: "NIKEA Regular";
  src: url("assets/NIKEA.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: optional;
}

@font-face {
  font-family: "Lato";
  src: url("assets/Lato-Light.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: optional;
}

@font-face {
  font-family: "Lato";
  src: url("assets/Lato-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: optional;
}

@font-face {
  font-family: "Lato";
  src: url("assets/Lato-Italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: optional;
}

@font-face {
  font-family: "Lato";
  src: url("assets/Lato-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: optional;
}

@font-face {
  font-family: "Lato";
  src: url("assets/Lato-BoldItalic.woff2") format("woff2");
  font-weight: 700;
  font-style: italic;
  font-display: optional;
}

/* Die Schriften laden mit font-display: optional statt swap. Mit swap
   zeichnete der Browser beim Seitenwechsel erst die Systemschrift und tauschte
   sie eine Zehntelsekunde später aus — die Navigation sprang sichtbar um.
   Zusammen mit dem <link rel="preload"> in jedem <head> ist die Datei fast
   immer schon da, und wenn nicht, bleibt es bei der Ersatzschrift, ohne Sprung.
   Outfit stands in for Action Sans, which the brandbook wants on titles and
   subtitles but which we have no licence for. Same geometric skeleton — round
   bowls, horizontal terminals, two-storey a. One variable file covers 100-900,
   so asking for any weight costs no extra request. */
@font-face {
  font-family: "Outfit";
  src: url("assets/Outfit.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: optional;
}

:root {
  /* --- Palette (measured from the original) --- */
  --bg: #0e0f11;            /* page + footer background */
  --ink: #ffffff;           /* headings, names, nav */
  --ink-soft: #8a8f8d;      /* paragraph text (original: #666, lifted slightly for AA contrast) */
  --accent: #89b8ae;        /* sage green — eyebrow text, logo triangle */
  --accent-light: #a8dacf;  /* lighter sage — hero highlight word, primary buttons */
  --pill-bg: rgba(0, 0, 0, 0.3);   /* nav + language pills */
  --card-bg: rgba(0, 0, 0, 0.2);   /* vision/mission cards */
  --line: rgba(255, 255, 255, 0.12);
  --btn-bg: #ffffff;        /* primary button */
  --btn-ink: #0e0f11;

  /* --- Typography (the brand typefaces, per the brandbook) --- */
  --font-display: "NIKEA Regular", sans-serif;   /* big caps headings */
  --font-title: "Outfit", system-ui, sans-serif; /* card + team titles, testimonials */
  --font-body: "Lato", system-ui, sans-serif;    /* body copy — 16px on the live site */
  /* Outfit, not Lato, for the interface. The original ran Geist here — a
     geometric grotesque — and Lato is humanist, which is why the nav and the
     buttons kept reading as "some other site" whatever size they were set at. */
  --font-ui: "Outfit", system-ui, sans-serif;    /* nav, buttons, small labels */

  /* --- Layout --- */
  /* 1280 outer minus the 30px gutters below = 1220px of content, which is
     what the live site lays out against (measured at 1280px viewport). */
  --container: 1280px;
  --radius: 24px;
  --header-h: 114px;
  --section-pad: 96px;
}

/* ---------- Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* Zieht man im Opener nach unten, schob das Gummiband einen schwarzen
   Streifen über das Video. Die Seite endet jetzt am Rand. */
html { overscroll-behavior-y: none; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;          /* live site: Inter 16px */
  line-height: 1.6;         /* 25.6px */
  letter-spacing: -0.4px;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 30px; }

/* Heading scale measured off the live site at 960 / 1280 / 1600px:
   h1 = 48 / 56 / 64px  ->  24px + 2.5vw
   h2 = 36 / 42 / 48px  ->  18px + 1.875vw
   Both track the viewport linearly; the clamps only guard the extremes. */
h1, h2 {
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 1.2;
  letter-spacing: normal;
  margin: 0 0 0.6em;
  color: var(--ink);
}
h3, h4 { font-family: var(--font-title); font-weight: 600; margin: 0 0 0.4em; color: var(--ink); }
.h2 { font-size: clamp(30px, calc(18px + 1.875vw), 60px); line-height: 1.2; }
p { margin: 0 0 1em; color: var(--ink-soft); }
p:last-child { margin-bottom: 0; }

.eyebrow {
  font-size: 13px;
  color: var(--accent);
  margin-bottom: 10px;
}

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

/* ---------- Header / nav ----------
   Measured from the live site (Aug 2026): the dark blur is a FULL-BLEED
   strip across the viewport (no rounding, no max-width). The only rounded
   element is the frosted pill around the menu itself — see .main-nav. */
/* The header bar itself stays transparent so the hero video reaches the top of
   the viewport. The glass is a floating panel inside it, set to the same 1220px
   the page content uses, so its edges line up with the three testimonial cards
   and the case-study grid rather than running to the window edge. */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  padding-bottom: 15px;
}
.nav-inner {
  position: relative;
  width: min(1220px, 100% - 32px);
  margin: 14px auto 0;
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  padding: 19px 16px;
  /* Darker and blurrier than the pill it contains. Two layers of backdrop
     blur is what gives the stacked-glass look: the panel frosts the page,
     the pill frosts the panel again. */
  background: rgba(10, 11, 12, 0.42);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 18px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.28);
}
/* object-fit: cover is load-bearing, not decoration. The logo SVG's viewBox
   is 340x156 (aspect 2.18) but this box is 150x38 (aspect 3.95), and the
   wordmark ink sits in the middle band of that tall canvas. Without `cover`
   the SVG letterboxes to fit the height and the wordmark draws only ~83px
   wide — a 45% smaller logo. `cover` scales to the width and crops the
   empty margin, which is what the live site does. */
.logo img { width: 150px; height: 38px; object-fit: cover; }

/* Frosted "glass pill" — measured from the Framer original:
   1px white border, blur(10px), and an inset 81px white glow
   instead of a dark background. */
.main-nav {
  display: flex; gap: 8px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.035) 100%);
  border: 1px solid rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 0 14px 0 rgba(255, 255, 255, 0.06), inset 0 0 42px 0 rgba(255, 255, 255, 0.10);
  border-radius: 12px;
  padding: 5px;
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
}
.main-nav a {
  /* The original runs Geist at 13px, but Lato sets smaller at any given size
     and the pill has room to spare, so the nav is deliberately a touch larger
     than the measurement rather than faithful to it. */
  font-family: var(--font-ui);
  font-size: 17.5px; color: var(--ink);
  line-height: 1.5em; letter-spacing: normal;
  padding: 10px 19px; border-radius: 10px;
  transition: background .2s;
}
.main-nav a:hover { background: rgba(255, 255, 255, 0.08); }

.nav-right { display: flex; align-items: center; gap: 12px; }
.lang-select {
  display: flex; align-items: center; gap: 5px;
  height: 53px; box-sizing: border-box;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.035) 100%);
  border: 1px solid rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 0 14px 0 rgba(255, 255, 255, 0.06), inset 0 0 42px 0 rgba(255, 255, 255, 0.10);
  border-radius: 12px;
  padding: 0 15px;
}
.lang-select svg { color: var(--ink); }
.lang-select select {
  font-family: var(--font-body);
  font-size: 16px; line-height: 1.5em; color: var(--ink);
  background: transparent; border: 0; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  padding-right: 2px;
}
.lang-select select option { color: #000; }

.nav-toggle { display: none; background: var(--pill-bg); border: 0; border-radius: 12px; cursor: pointer; padding: 12px 10px; }
.nav-toggle span {
  display: block; width: 22px; height: 2px; background: var(--ink);
  margin: 5px 0; transition: transform .2s, opacity .2s;
}

/* ---------- Story (hero) ---------- */
.story { padding-top: calc(var(--header-h) + 86px); }
.story-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(48px, 9vw, 127px);
  align-items: start;
}
.story-portrait { margin: 0; border-radius: 12px; overflow: hidden; }
.story-portrait img { width: 100%; aspect-ratio: 549 / 582; object-fit: cover; object-position: 50% 14%; }
.story-text a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.story-text a:hover { color: var(--accent); }
.story-stats { margin-top: 28px; width: 171px; }

/* ---------- Vision & mission ---------- */
.vision-mission { padding: var(--section-pad) 0; }
.vm-grid {
  display: grid; grid-template-columns: 1.1fr 1fr;
  gap: clamp(32px, 5vw, 61px);
  align-items: center;
}
/* Left: portrait sitting on a photographic card with a soft sage wash */
.vm-media {
  margin: 0; position: relative;
  border-radius: 30px; overflow: hidden;
  aspect-ratio: 610 / 602;
  display: grid; place-items: center;
}
.vm-media-bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}
/* Das Bild hinter dem Porträt ist ein fast schwarzer Verlauf. Farbmischungen
   greifen darauf nicht — multiplizieren lässt Schwarz schwarz. Deshalb liegt
   hier ein Salbei-Verlauf direkt darüber: oben satt, nach unten auslaufend,
   damit das Porträt sauber davor steht. */
.vm-media::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(155deg,
      rgba(137, 184, 174, .62) 0%,
      rgba(137, 184, 174, .34) 48%,
      rgba(137, 184, 174, .12) 76%,
      rgba(14, 15, 17, .42) 100%);
}
.vm-portrait { z-index: 2; }
.vm-portrait {
  position: relative; z-index: 1;
  width: 76%; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: var(--radius);
}
/* Right: two stacked cards */
.vm-cards { display: flex; flex-direction: column; gap: 24px; }
.vm-card {
  background: var(--card-bg);
  border-radius: var(--radius);
  padding: 24px;
  display: flex; flex-direction: column; gap: 16px;
}
.vm-card p, .vm-card h3 { margin: 0; }
.vm-icon { width: 40px; height: 40px; }
.vm-card h3 { font-size: 26px; }

/* ---------- Team carousel ---------- */
.team { padding-bottom: var(--section-pad); }
.team-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; margin-bottom: 40px;
}
.team-head .h2 { margin-bottom: 0; }
.team-track {
  display: flex; gap: 24px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-bottom: 8px;
  scrollbar-width: none;
}
.team-track::-webkit-scrollbar { display: none; }
.team-card {
  flex: 0 0 287px;
  scroll-snap-align: start;
}
.team-card img {
  width: 100%; aspect-ratio: 2702 / 3384; object-fit: cover;
  border-radius: 16px;
  margin-bottom: 16px;
}
.team-card h3 { font-size: 26px; margin-bottom: 2px; }
.team-card p { font-size: 13px; color: var(--ink); }

.carousel-nav { display: flex; gap: 10px; }
.carousel-btn {
  width: 48px; height: 48px; padding: 0;
  border: 0; background: transparent; cursor: pointer;
  opacity: .9; transition: opacity .2s, transform .2s;
}
.carousel-btn img { width: 48px; height: 48px; }
.carousel-btn:hover { opacity: 1; transform: scale(1.04); }

/* ---------- CTA ---------- */
.cta { padding: var(--section-pad) 0 0; }
.cta-card {
  border-radius: var(--radius);
  padding: 112px 30px;
  text-align: center;
}
.cta-content { max-width: 646px; margin: 0 auto; }
.cta-content p { margin-bottom: 28px; }

.btn {
  display: inline-block;
  background: var(--btn-bg); color: var(--btn-ink);
  font-family: var(--font-ui);
  font-size: 16.5px; letter-spacing: normal;
  padding: 15px 37px; border-radius: 10px;
  transition: transform .2s ease, opacity .2s ease;
}
.btn:hover { transform: translateY(-2px); opacity: .92; }

/* ---------- Footer ---------- */
.site-footer {
  margin-top: var(--section-pad);
  background: var(--bg);
  overflow: hidden;
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 40px;
  padding-top: 24px;
}
.footer-brand .logo img { width: 150px; height: 37px; }
.footer-brand p { font-size: 13px; color: var(--ink); margin-top: 16px; max-width: 280px; }

.footer-col { display: flex; flex-direction: column; gap: 10px; }
.footer-col h4 { font-size: 13px; font-weight: 500; margin-bottom: 6px; }
.footer-col a { font-size: 13px; color: var(--ink); opacity: .8; transition: opacity .2s, color .2s; }
.footer-col a:hover { opacity: 1; color: var(--accent); }

.footer-bottom {
  margin-top: 48px; padding-top: 20px; padding-bottom: 20px;
  border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.socials { display: flex; gap: 20px; }
.socials img { width: 20px; height: 20px; }
.socials a { opacity: .85; transition: opacity .2s; }
.socials a:hover { opacity: 1; }
.footer-bottom p { font-size: 11px; color: var(--ink); margin: 0; }

.footer-wordmark { width: 100%; display: block; }

/* ---------- Placeholder pages (not yet rebuilt) ---------- */
.placeholder {
  padding-top: calc(var(--header-h) + 86px);
  min-height: 55vh;
}
.placeholder p { max-width: 480px; margin-bottom: 24px; }

/* ---------- Scroll reveal ---------- */
.reveal {
  opacity: 0; transform: translateY(24px);
  transition: opacity .7s ease, transform .7s ease;
}
/* Die Karten in einem Raster kommen einzeln und leicht kleiner herein —
   das Raster selbst trägt .reveal, die Karten staffeln sich darunter. */
.case-grid .case-card,
.package-grid .package-card,
.tier .svc {
  opacity: 0; transform: translateY(20px) scale(.955);
  transition: opacity .75s cubic-bezier(.16,1,.3,1), transform .75s cubic-bezier(.16,1,.3,1);
}
.case-grid.is-visible .case-card,
.package-grid.is-visible .package-card,
.tier .svc.is-visible {
  opacity: 1; transform: none;
}
.case-grid.is-visible .case-card:nth-child(2), .package-grid.is-visible .package-card:nth-child(2) { transition-delay: .09s; }
.case-grid.is-visible .case-card:nth-child(3), .package-grid.is-visible .package-card:nth-child(3) { transition-delay: .18s; }
.case-grid.is-visible .case-card:nth-child(4) { transition-delay: .27s; }
.tier-2 .svc:nth-child(2), .tier-3 .svc:nth-child(2) { transition-delay: .09s; }
.tier-2 .svc:nth-child(3), .tier-3 .svc:nth-child(3) { transition-delay: .18s; }

/* 3) Tiefe: die Medien wandern beim Scrollen minimal gegen die Karte.
   Verschoben wird der Bildausschnitt, nicht das Element — so bleibt der
   Rahmen stehen und nichts läuft über die Kante. */
.case-card img, .case-card video, .svc-media video {
  object-position: 50% calc(50% + var(--py, 0%));
}
.tier-1 .svc-media video { object-position: calc(28% ) calc(50% + var(--py, 0%)); }
.mix video:nth-child(2) { object-position: 26% calc(50% + var(--py, 0%)); }
.reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .case-grid .case-card, .package-grid .package-card, .tier .svc { opacity: 1; transform: none; }
  .hero-media { transform: none; border-radius: 0; }
  .team-track { scroll-behavior: auto; }
}

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .story-grid { grid-template-columns: 1fr; }
  .vm-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .team-head { flex-direction: column; align-items: flex-start; }
}

/* Die Pille sitzt absolut in der Mitte; mit der grösseren Schrift stösst sie
   auf mittleren Breiten ans Logo. Dort etwas enger setzen. */
@media (max-width: 1150px) and (min-width: 721px) {
  .main-nav a { font-size: 15.5px; padding: 8px 13px; }
}

@media (max-width: 720px) {
  .main-nav {
    position: fixed; inset: var(--header-h) 16px auto 16px;
    transform: none; left: auto;
    background: rgba(14, 15, 17, 0.96);
    border: 1px solid var(--line);
    box-shadow: none;
    flex-direction: column; gap: 0;
    padding: 8px;
    display: none;
  }
  .main-nav.open { display: flex; }
  .main-nav a { padding: 12px 16px; font-size: 15px; }
  .nav-toggle { display: block; }
  .footer-grid { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; align-items: flex-start; }
}

/* ---------- Focus visibility ---------- */
a:focus-visible, button:focus-visible, select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

/* =========================================================
   Components for the full site (home, services, cases, contact, terms)
   ========================================================= */

/* ---------- Button variants ---------- */
.btn-accent { background: var(--accent-light); color: #0e0f11; }
.btn-ghost {
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: var(--ink);
}

/* ---------- Hero (video background) ---------- */
.hero {
  position: relative;
  background: var(--bg);
  min-height: clamp(560px, 92vh, 860px);
  /* Siehe .hero:has(+ .ticker) weiter unten: auf der Startseite endet der
     Opener früher, damit das Markenband nicht unter die Fensterkante rutscht. */
  display: flex; align-items: center;
  padding-top: var(--header-h);
  overflow: hidden;
}
.hero-media, .hero-media video, .hero-media img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
/* Der Film sitzt etwas tiefer im Rahmen als in der Mitte — es war oben zu viel
   Luft. Weil `cover` den Rahmen immer voll ausfüllt, kann dabei nie eine Kante
   auftauchen, egal welcher Wert hier steht: verschoben wird nur, welcher
   Ausschnitt weggeschnitten wird. Kleinerer Y-Wert = Bild rutscht nach unten. */
.hero-media video, .hero-media img { object-position: 50% 20%; }
.hero-media::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(rgba(10, 11, 12, 0.22), rgba(14, 15, 17, 0.34) 62%, rgba(14, 15, 17, .82) 88%, var(--bg));
}
/* Beim Scrollen zieht sich der Opener zurück: das Bild verkleinert sich und
   seine Ränder laufen ins Seitenschwarz, statt an einer sichtbaren Kante zu
   enden — ein verkleinerter heller Kasten auf dunklem Grund sah billig aus.
   Die Werte setzt das Skript als --hero-scale / --hero-edge. */
/* Nicht der Rahmen schrumpft, sondern das Video darin.
   Vorher trug die geclippte Box selbst die Skalierung: ihre Kante bewegte
   sich mit, wurde bei jedem Frame neu gerastert und blendete gegen nichts —
   daher der helle Saum, der nur beim Scrollen auftrat. Jetzt steht die Box
   still und deckt die volle Breite, in Seitenfarbe hinterlegt; einzig das
   Video darin wird kleiner. Was aussen frei wird, ist gemalter Hintergrund,
   keine offene Kante. */
.hero-media {
  overflow: hidden;
  background: var(--bg);
  border-radius: 0;
}
.hero-media video, .hero-media img {
  transform: scale(var(--hero-scale, 1));
  transform-origin: 50% 0;
  backface-visibility: hidden;
  will-change: transform;
}
/* Der Saum: vier Verläufe, die mit dem Scrollen aufziehen und alle vier
   Kanten in die Seitenfarbe legen. Bei --hero-edge: 1 ist der Rand des
   Films nicht mehr zu sehen, er löst sich einfach in die Seite auf. */
.hero-media::before {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  /* Der Saum liegt von Anfang an über dem Bild, nicht erst beim Scrollen —
     sonst blitzt beim ersten Radklick die helle Bildkante auf. */
  opacity: var(--hero-edge, .85);
  background:
    linear-gradient(90deg,  var(--bg) 0%, rgba(14, 15, 17, 0) 11%),
    linear-gradient(270deg, var(--bg) 0%, rgba(14, 15, 17, 0) 11%),
    linear-gradient(0deg,   var(--bg) 0%, rgba(14, 15, 17, 0) 14%),
    linear-gradient(180deg, var(--bg) 0%, rgba(14, 15, 17, 0) 10%);
}
.hero-content { will-change: transform, opacity; }
.hero-content { position: relative; z-index: 1; width: 100%; }
.hero h1 {
  font-size: clamp(40px, calc(24px + 2.5vw), 84px);
  line-height: 1.1;
  letter-spacing: -1.07px;
  margin-bottom: 18px;
  max-width: 15ch;
}
/* The German headline is 76 characters against the English 47, and NIKEA is a
   caps-only face, so the same size stacks it six lines deep and pushes the
   buttons off the fold. Slightly smaller type over a wider measure brings it
   back to three lines without touching the English page. */
html[lang="de"] .hero h1 {
  font-size: clamp(32px, calc(16px + 2vw), 58px);
  max-width: 26ch;
}
.hero-center { text-align: center; }
.hero-center h1 { margin-inline: auto; }
.hero .hl { color: var(--accent-light); }
/* Outfit rather than the body face, and grey rather than white: the original
   sets this line back from the headline instead of competing with it. */
.hero-sub {
  max-width: 600px;
  font-family: var(--font-title);
  font-size: 18px; line-height: 1.55;
  color: var(--ink-soft);
  margin-bottom: 32px;
}
.hero-center .hero-sub { margin-inline: auto; }
.hero-cta { display: flex; gap: 14px; flex-wrap: wrap; }
.hero-center .hero-cta { justify-content: center; }

/* chips above the services hero title */
.chip-row { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; margin-bottom: 28px; }
.chip {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(0, 0, 0, 0.35);
  border-radius: 999px; padding: 10px 16px;
  font-size: 13px; color: var(--ink);
}
.chip img { width: 20px; height: 20px; }

/* ---------- Brand logo ticker ----------
   On the live site each logo sits in its own translucent rounded tile:
   tile 204x56 (164x40 image + 8px/20px padding), #73737329, radius 12px,
   10px apart. content-box keeps the padding outside the 164x40 image box. */
.ticker { overflow: hidden; padding: 28px 0 40px; }
/* Nur die Startseite trägt das Markenband. Ihr Opener endet deshalb früher als
   der auf den Unterseiten: in einem Browserfenster ohne Vollbild — und so
   sitzen die meisten davor — begann das Band sonst genau an der Fensterkante
   und war schlicht nicht zu sehen. Jetzt ragt es rund hundert Pixel herein. */
.hero:has(+ .ticker) { min-height: clamp(520px, 78vh, 760px); }
.ticker-row { display: flex; align-items: center; gap: 10px; width: max-content; animation: ticker 55s linear infinite; }
/* Partner logos arrive as dark artwork on transparency, each sitting in a
   differently proportioned canvas — content filled anywhere from 20% to 74%
   of the file's height. The PNGs are now trimmed to their artwork, so
   `contain` gives every logo the same height instead of the same crop, and
   the filter flattens twelve different inks to one light grey. Together
   that is what makes the strip read as one row rather than a jumble. */
.ticker-row img {
  /* Tile stays 204px wide and grows to 62px tall; the logo inside gains 5%.
     Vertical padding carries the extra height, horizontal padding gives it
     back, so the row keeps its rhythm. */
  width: 172px; height: 42px;
  object-fit: contain;
  box-sizing: content-box;
  padding: 10px 16px;
  background: rgba(115, 115, 115, 0.16);
  border-radius: 12px;
  filter: brightness(0) invert(1) opacity(0.65);
}
/* Der Apfel ist ein Vollflächen-Glyph. Statt die Kachel zu skalieren (dann
   schrumpft die Kachel mit), trägt hier das Polster die Differenz: Kachel
   bleibt 204x62, das Zeichen sitzt kleiner darin. */
.ticker-row img[src$="apple.svg"] { height: 33px; padding: 14.5px 16px; }
/* Flims ist als einziges eine zweizeilige Marke und liegt jetzt eng
   beschnitten vor. Etwas weniger Höhe als die Kachel hergibt, damit die
   Schreibschrift nicht grösser wirkt als die Wortmarken daneben. */
.ticker-row img[src$="flims.png"] { height: 34px; padding: 14px 16px; }
@keyframes ticker { to { transform: translateX(-50%); } }

/* Die zweite Reihe gibt es nur auf dem Telefon. Dort ist das Band so schmal,
   dass in einer einzigen Reihe kaum eine Marke vorbeikommt, während man
   scrollt — zwei gegenläufige Reihen zeigen in derselben Zeit das Vierfache.
   Sie läuft rückwärts durch dieselben Keyframes, nicht durch eigene. */
.ticker-row-back { display: none; }
@media (max-width: 700px) {
  .ticker-row { animation-duration: 26s; }
  .ticker-row-back {
    display: flex; margin-top: 10px;
    animation-direction: reverse;
  }
}

/* ---------- Testimonial marquee ---------- */
.testi-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; margin-bottom: 40px;
}
.testi-head .h2 { margin-bottom: 0; }
/* Three cards, then it steps. The viewport is held to the page's own 1220px
   instead of running full-bleed, so exactly three fit and the fourth is the
   thing the carousel scrolls to. */
.testi-viewport {
  overflow: hidden;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 30px;
}
/* A stepping carousel, not a marquee: quotes need to hold still long enough
   to be read, and the arrows need something discrete to step through. */
.testi-track {
  display: flex; gap: 24px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-bottom: 8px;
  scrollbar-width: none;
}
.testi-track::-webkit-scrollbar { display: none; }
.testi-card {
  position: relative; overflow: hidden;
  flex: 0 0 calc((100% - 48px) / 3); scroll-snap-align: start;
  height: 560px;
  border-radius: 16px;
  display: flex; flex-direction: column; justify-content: space-between;
}
.testi-card > .bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.testi-card::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(rgba(8, 9, 10, 0.25), rgba(8, 9, 10, 0.72));
}
.testi-quote, .testi-person { position: relative; z-index: 1; padding: 26px; }
.testi-quote { font-family: var(--font-title); font-size: 23px; line-height: 1.35; color: var(--ink); }
.testi-person { display: flex; align-items: center; gap: 12px; }
.testi-person img { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; }
.testi-person strong { display: block; font-family: var(--font-title); font-weight: 600; font-size: 16px; color: var(--ink); }
.testi-person span { font-size: 11px; color: rgba(255, 255, 255, 0.75); }

/* ---------- Growth package teaser cards (home) ---------- */
.package-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.package-card {
  position: relative; overflow: hidden;
  border-radius: 16px; aspect-ratio: 368 / 465;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 28px;
}
.package-card > .bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.package-card::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8, 9, 10, 0.25) 0%, rgba(8, 9, 10, 0.78) 100%);
}
.package-card .icon, .package-card .pack-text { position: relative; z-index: 2; }
/* Der Lichtschein folgt dem Cursor. Er sitzt auf den Teasern, nicht auf der
   Leistungsseite: diese drei Karten sind Links, der Schein zeigt also auf
   etwas, das man anklicken kann. Die Position setzt das Skript. */
.package-card::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  opacity: 0; transition: opacity .4s ease;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 50%), rgba(137, 184, 174, 0.22), transparent 62%);
}
.package-card:hover::before { opacity: 1; }
.package-card .icon { width: 38px; height: 42px; }
.package-card h3 { font-size: 28px; margin-bottom: 8px; }
.package-card p { font-size: 13px; color: rgba(255, 255, 255, 0.8); }

/* ---------- Package detail cards (services) ---------- */
.package-detail {
  position: relative; overflow: hidden;
  border-radius: var(--radius);
  padding: clamp(28px, 4vw, 44px);
}
.package-detail > .bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.package-detail::after { content: ""; position: absolute; inset: 0; background: rgba(10, 11, 12, 0.82); }
.package-detail > div { position: relative; z-index: 1; }
.package-detail h3 {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(26px, 2.6vw, 34px); line-height: 1.2; margin-bottom: 20px;
}
.package-detail p { font-size: 14px; }
.package-detail .package-cta { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 28px; }
.package-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-bottom: 24px; }
.price-pill {
  display: inline-block; font-size: 13px; padding: 11px 32px;
  border-radius: 10px; border: 1px solid rgba(255, 255, 255, 0.14);
  color: var(--ink); background: rgba(255, 255, 255, 0.04);
}

/* ---------- Case study cards ---------- */
.case-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.case-card {
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.02);
  border-radius: 16px; padding: 20px;
}
.case-card img, .case-card video {
  width: 100%; aspect-ratio: 5 / 3; object-fit: cover;
  border-radius: 10px; margin-bottom: 20px;
  display: block; background: rgba(255, 255, 255, 0.04);
}
.case-card h3 {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: 22px; letter-spacing: 0.02em; margin-bottom: 4px;
}
.case-card p { font-size: 15px; }
.center-btn { text-align: center; margin-top: 36px; }

/* ---------- FAQ accordion ---------- */
.faq-grid { display: grid; grid-template-columns: 1fr 1.2fr; gap: clamp(32px, 5vw, 72px); align-items: start; }
.faq-intro p { margin-bottom: 24px; }
.faq-item { border-bottom: 1px solid var(--line); }
.faq-item summary {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 20px 0; cursor: pointer; list-style: none;
  font-size: 15px; color: var(--ink);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+"; flex: 0 0 28px; height: 28px;
  display: grid; place-items: center;
  background: var(--accent); color: #0e0f11;
  border-radius: 6px; font-size: 16px;
}
.faq-item[open] summary::after { content: "\2212"; }
.faq-item p { padding-bottom: 20px; max-width: 60ch; }

/* ---------- Stats ---------- */
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(24px, 3vw, 40px); }
/* ---------- Das gezeichnete Smiley ----------
   Aus dem getippten :) in der Überschrift ist eine Zeichnung geworden, die
   sich selbst zieht, sobald der Abschnitt erscheint: erst der Kreis — der am
   Ende ein Stück über den Anfang hinausläuft, wie ein Stift, der noch einmal
   nachfasst —, dann die zwei Augen, dann der Mund. Zusammen knapp drei
   Sekunden. `pathLength="1"` im SVG macht jede Linie gleich lang, egal wie
   lang sie wirklich ist; darum genügt hier ein einziger Strichwert. */
.smiley {
  width: .92em; height: .92em; vertical-align: -.1em;
  margin-left: .12em; overflow: visible;
}
.smiley path {
  fill: none; stroke: var(--accent);
  stroke-width: 4; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 1;
}
@keyframes smiley-draw { to { stroke-dashoffset: 0; } }
.section-head.is-visible .smiley-face  { animation: smiley-draw 1.5s cubic-bezier(.45,.05,.3,1) .15s forwards; }
.section-head.is-visible .smiley-eye-l { animation: smiley-draw .2s ease-out 1.75s forwards; }
.section-head.is-visible .smiley-eye-r { animation: smiley-draw .2s ease-out 1.98s forwards; }
.section-head.is-visible .smiley-mouth { animation: smiley-draw .9s ease-out 2.2s forwards; }
@media (prefers-reduced-motion: reduce) {
  .smiley path { stroke-dashoffset: 0; animation: none !important; }
}

.stat-num { font-family: var(--font-title); font-size: 56px; color: var(--ink); line-height: 1.1; }
.stat-num sup { font-size: 28px; }
.stat h4 { font-size: 16px; margin: 6px 0; }
.stat p { font-size: 13px; }

/* ---------- CTA background image ---------- */
.cta-card { position: relative; overflow: hidden; }
.cta-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cta-card::after { content: ""; position: absolute; inset: 0; background: rgba(10, 11, 12, 0.55); }
.cta-content { position: relative; z-index: 1; }
.cta-content p { color: rgba(255, 255, 255, 0.85); }

/* ---------- Forms ---------- */
/* Fields carry no border on the live site — the panel is a subtle vertical
   gradient with a 12px radius and 20px of padding, giving 67px-tall text
   fields and a 179px textarea. */
.contact-form { display: flex; flex-direction: column; gap: 12px; max-width: 100%; }
.contact-form input, .contact-form textarea {
  width: 100%; font: inherit; font-size: 16px; color: var(--ink);
  background: linear-gradient(rgb(15, 17, 18) 0%, rgba(103, 103, 103, 0.2) 100%);
  border: 0; border-radius: 12px; padding: 20px;
  line-height: 27px;
}
.contact-form input { height: 67px; }
.contact-form ::placeholder { color: rgba(255, 255, 255, 0.5); }
.contact-form textarea { min-height: 179px; resize: vertical; }
.contact-form .btn {
  align-self: flex-start; border: 0; cursor: pointer;
  font-size: 12px; line-height: 20px; padding: 10px 16px; margin-top: 21px;
}
.contact-form .btn:disabled { cursor: default; opacity: .65; transform: none; }

/* Honeypot: off-screen rather than display:none, because some bots skip
   hidden fields. Real visitors never reach it — it is out of the tab order
   and hidden from screen readers. */
.hp-field {
  position: absolute !important;
  left: -9999px; width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}

.form-status { font-size: 14px; margin: 0; }
.form-status:empty { display: none; }
.form-status.is-error { color: #ff9b8a; }

/* Replaces the form once the message is away. */
.form-done {
  border: 1px solid var(--accent);
  background: rgba(137, 184, 174, 0.08);
  border-radius: 12px; padding: 28px 24px;
}
.form-done h3 {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: 24px; letter-spacing: normal; color: var(--accent-light);
  margin: 0 0 8px;
}
.form-done p { margin: 0; }

/* ---------- Contact page ----------
   Measured from the live site at 1280px: a centred 59px title, then two
   columns — map (590x274) with the address details beneath it on the
   left, form (537 wide) on the right, 77px apart. */
.page-title {
  font-size: clamp(40px, calc(27px + 2.5vw), 88px);
  line-height: 1.1;
  text-align: center; margin-bottom: 44px;
}
.contact-layout {
  display: grid;
  grid-template-columns: 622fr 537fr;
  gap: 61px;
  align-items: start;
  margin-bottom: 48px;
}
/* The map and details sit in a bordered card, 622px wide with 16px of
   padding — which is what puts the 590px map at x=46. On the live site the
   border is drawn by an ::after pseudo-element rather than on the box. */
.contact-info {
  /* outline rather than border: it draws in the same place but takes no
     layout space, so the map stays a full 590px like the live site's
     pseudo-element border. */
  outline: 1px solid rgba(255, 255, 255, 0.1);
  outline-offset: -1px;
  border-radius: 16px;
  padding: 16px;
}
.map-img {
  width: 100%; aspect-ratio: 590 / 274; object-fit: cover;
  border-radius: 8px; margin-bottom: 10px;
}
/* Uneven on the live site: a 242px address block, then a 142px gap, then a
   207px contact block — not two equal halves. */
.contact-cols { display: grid; grid-template-columns: 242fr 207fr; gap: 142px; }
.contact-cols h3 { font-size: 26px; margin-bottom: 12px; }
.contact-cols a { display: block; color: var(--ink-soft); margin-bottom: 4px; }
.contact-cols a:hover { color: var(--accent); }

/* ---------- Legal / terms ---------- */
.legal-intro { max-width: 62ch; margin-bottom: 48px; }
.legal-section { border-top: 1px solid var(--line); padding: 28px 0; }
.legal-section h3 { font-size: 22px; margin-bottom: 12px; }
.legal-section p { max-width: 75ch; }

/* ---------- Section rhythm ---------- */
.section { padding-top: var(--section-pad); }
.section-head { margin-bottom: 40px; }

/* ---------- Responsive for new components ---------- */
@media (max-width: 900px) {
  .package-grid { grid-template-columns: 1fr; }
  .package-grid .package-card { aspect-ratio: auto; min-height: 320px; }
  .package-2col { grid-template-columns: 1fr; }
  .case-grid { grid-template-columns: 1fr; }
  .faq-grid { grid-template-columns: 1fr; }
  .stats-grid { grid-template-columns: 1fr 1fr; }
  .contact-cols { grid-template-columns: 1fr; }
  .contact-layout { grid-template-columns: 1fr; gap: 40px; }
}
@media (max-width: 900px) {
  /* Three across needs the desktop measure; below it, two, then one. */
  .testi-card { flex-basis: calc((100% - 24px) / 2); }
}
@media (max-width: 640px) {
  .testi-card { flex-basis: 100%; }
}
@media (max-width: 560px) {
  .stats-grid { grid-template-columns: 1fr; }
  .testi-card { height: 480px; }
}


/* =========================================================
   CASE-STUDY DETAIL PAGES (case-studies/<slug>/)
   ========================================================= */
a.case-card { display: block; color: inherit; text-decoration: none; }
.cs-breadcrumb { text-align: center; margin: 0 0 8px; }
.cs-breadcrumb a { color: var(--text-muted, #9ab29b); text-decoration: none; font-size: 14px; }
.cs-breadcrumb a:hover { text-decoration: underline; }
.cs-watch { text-align: center; letter-spacing: .02em; margin: 24px 0 12px; }
.cs-links { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-bottom: 32px; }
.cs-hero { margin: 0 auto 40px; max-width: 860px; }
.cs-hero video { width: 100%; border-radius: 16px; display: block; }
.cs-body { max-width: 760px; margin: 0 auto; }
.cs-body .h2 { margin: 40px 0 16px; }
.cs-body p { margin: 0 0 16px; line-height: 1.7; }
.cs-lede { margin: 24px 0 16px; font-size: 1.35rem; line-height: 1.45; }
.case-card-text { aspect-ratio: 16/10; display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.06); border-radius: 12px; }
.case-card-text span { font-family: var(--font-title); font-size: 1.3rem; opacity: .85; }

/* =========================================================
   SERVICES — Leistungen, nach Wichtigkeit gestaffelt
   Die Kartengrösse trägt die Rangfolge: eine grosse Karte für das,
   womit die meisten starten, dann zwei, dann drei kleinere.
   ========================================================= */

/* Laufband unter dem Opener */
.svc-ticker {
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: 18px 0; overflow: hidden; white-space: nowrap;
  background: rgba(255, 255, 255, 0.02);
}
.svc-ticker-track { display: inline-flex; gap: 46px; animation: svc-slide 42s linear infinite; will-change: transform; }
.svc-ticker span {
  font-family: var(--font-ui); font-size: 13px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-soft);
}
.svc-ticker span::before { content: "\25C6"; color: var(--accent); margin-right: 46px; font-size: 9px; vertical-align: middle; }
@keyframes svc-slide { to { transform: translateX(-50%); } }

.tier { display: grid; gap: 20px; margin-bottom: 20px; }
.tier-1 { grid-template-columns: 1fr; }
.tier-2 { grid-template-columns: repeat(3, 1fr); }
/* Sieben Leistungen: die kleinste Reihe trägt vier Karten. */
.tier-3 { grid-template-columns: repeat(3, 1fr); }

.svc {
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--line); border-radius: var(--radius);
  transition: border-color .4s ease, transform .5s cubic-bezier(.16,1,.3,1), background .4s ease;
}
.svc:hover { transform: translateY(-6px); border-color: rgba(137, 184, 174, 0.42); background: rgba(255, 255, 255, 0.055); }

.svc-media { position: relative; overflow: hidden; background: #000; }
.svc-media video, .svc-media img {
  width: 100%; height: 100%; object-fit: cover; transform: scale(1.02);
  transition: transform 1s cubic-bezier(.16,1,.3,1); filter: saturate(.92) contrast(1.05);
}
.svc:hover .svc-media video, .svc:hover .svc-media img { transform: scale(1.07); }
/* Zwei Clips in einem Rahmen: der erste läuft zu Ende, dann übernimmt der
   zweite — dieselbe Reihenfolge, in der an dem Tag gefilmt wurde. Beide liegen
   übereinander, sichtbar ist immer nur der laufende. Die Transform-Überblendung
   muss hier mitgeschrieben werden, sonst fiele die Hover-Fahrt weg. */
[data-sequence] video {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity .5s ease, transform 1s cubic-bezier(.16,1,.3,1);
}
[data-sequence] video.is-playing { opacity: 1; }
.svc-media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(14, 15, 17, 0.1) 0%, rgba(14, 15, 17, 0.72) 100%);
}

/* ---------- Der Mix ----------
   Drei Streifen nebeneinander, in jedem zwei Clips, die im Sekundentakt
   umschneiden: sechs Aufnahmen aus einem Drehalltag, die nie stillstehen.
   Jeder Schnitt kommt mit einem kurzen Aufblitzen in Mint und einer Unschärfe,
   die sofort aufklart — der Effekt, der die Farbe der Marke ins Bild trägt,
   ohne dass ein Filter dauerhaft darüberliegt.

   Die Takte: 3s Schnittzyklus (1.5s pro Clip), 1.5s Blitz- und Unschärfezyklus
   — sie passen ineinander, darum sitzt jeder Blitz auf einem Schnitt. Die drei
   Streifen laufen um eine halbe Sekunde versetzt (negative Verzögerung, damit
   sie nicht erst warten), so schneidet irgendwo auf der Karte alle 0.5s etwas. */
.mix { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px; background: #000; }
.mix-cell {
  position: relative; overflow: hidden; min-width: 0;
  animation: mix-blur 1.5s cubic-bezier(.2,.8,.3,1) infinite;
}
.mix-cell:nth-child(2) { animation-delay: -.5s; }
.mix-cell:nth-child(3) { animation-delay: -1s; }
.mix-cell video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  animation: mix-cut-a 3s steps(1, end) infinite;
}
.mix-cell video:nth-child(2) { animation-name: mix-cut-b; }
.mix-cell:nth-child(2) video { animation-delay: -.5s; }
.mix-cell:nth-child(3) video { animation-delay: -1s; }
@keyframes mix-cut-a { 0% { opacity: 1; } 50% { opacity: 0; } }
@keyframes mix-cut-b { 0% { opacity: 0; } 50% { opacity: 1; } }
/* Die Unschärfe sitzt auf dem Streifen, nicht auf dem Video: so wird das
   Aufblitzen gleich mitgeweicht und wirkt als Schein, nicht als Rechteck. */
@keyframes mix-blur {
  0%       { filter: blur(9px) saturate(1.6) brightness(1.18); }
  16%      { filter: blur(1px) saturate(1.05) brightness(1.02); }
  30%, 100% { filter: blur(0) saturate(1) brightness(1); }
}
/* Der Schein selbst: ein Mintfeld, das im Schnitt aufleuchtet und weggeht. */
.mix-cell::after {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background:
    radial-gradient(130% 70% at 50% 50%, rgba(168, 218, 207, .55), rgba(168, 218, 207, 0) 72%),
    linear-gradient(180deg, rgba(168, 218, 207, .3), rgba(168, 218, 207, 0) 55%);
  mix-blend-mode: screen; opacity: 0;
  animation: mix-flash 1.5s ease-out infinite;
  animation-delay: inherit;
}
@keyframes mix-flash { 0% { opacity: .9; } 10% { opacity: .35; } 26%, 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .mix-cell, .mix-cell video, .mix-cell::after { animation: none; }
  .mix-cell { filter: none; }
  .mix-cell::after { opacity: 0; }
  .mix-cell video { opacity: 0; }
  .mix-cell video:first-child { opacity: 1; }
}

.svc-body { position: relative; z-index: 2; padding: 32px; display: flex; flex-direction: column; flex: 1; }
/* Statt einer Nummer trägt jede Leistung eine Etappe des Aufstiegs. Als
   grosses Umrisswort stand sie dem Titel im Weg — zwei Zeilen in derselben
   Schrift, fast gleich gross, ohne erkennbare Rangfolge. Jetzt ist die Etappe
   eine leise Marke über dem Titel: klein, gesperrt, in Akzentfarbe, mit einem
   kurzen Strich als Ausklang. So ist der Titel wieder der Titel. */
.svc .svc-label {
  font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.22em; line-height: 1;
  color: var(--accent); margin-bottom: 12px;
  display: flex; align-items: center; gap: 12px;
  transition: color .4s ease;
}
.svc .svc-label::after {
  content: ""; flex: 0 0 auto; width: 34px; height: 1px;
  background: currentColor; opacity: .5;
}
.svc:hover .svc-label { color: var(--accent-light); }
.svc h3 {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  line-height: 1.02; letter-spacing: 0.01em; overflow-wrap: break-word; margin: 0;
}
.svc .kicker {
  font-family: var(--font-ui); font-size: 11.5px; font-weight: 600; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 12px;
}
.svc ul { list-style: none; margin: 20px 0 0; padding: 0; }
.svc li { position: relative; padding-left: 20px; color: #c7cbc9; font-size: 15px; margin-bottom: 8px; line-height: 1.5; }
.svc li:last-child { margin-bottom: 0; }
.svc li::before { content: ""; position: absolute; left: 0; top: 11px; width: 9px; height: 1px; background: var(--accent); }

.tier-1 .svc { flex-direction: row; min-height: 620px; align-items: stretch; }
.tier-1 .svc-media { flex: 0 0 42%; }
.tier-1 .svc-media video { object-position: 28% center; }
.tier-1 .svc-media::after { background: linear-gradient(90deg, rgba(14, 15, 17, 0) 40%, rgba(14, 15, 17, 0.85) 100%); }
.tier-1 .svc-body { flex: 1 1 auto; min-width: 0; padding: 52px 48px; justify-content: center; }
.tier-1 .svc-label { font-size: 16px; }
.tier-1 h3 { font-size: clamp(26px, 2.9vw, 42px); }
.tier-1 li { font-size: 16px; }

/* Feste Höhe hiess: 16:9-Material verliert links und rechts etwas. Ein festes
   Seitenverhältnis statt einer festen Höhe lässt einen Brandfilm ganz stehen —
   samt eingebrannter Bauchbinde, die sonst angeschnitten würde. */
.tier-2 .svc-media { aspect-ratio: 16 / 9; height: auto; }
.tier-2 .svc-label { font-size: 14px; }
.tier-2 h3 { font-size: clamp(21px, 1.8vw, 26px); }

.tier-3 .svc-media { height: 160px; }
.tier-3 .svc-body { padding: 26px; }
.tier-3 .svc-label { font-size: 13px; }
.tier-3 h3 { font-size: 21px; }
.tier-3 li { font-size: 14px; }

/* ---------- Ads & Paid Social ----------
   Für diese Leistung gibt es kein Filmmaterial, und gestelltes wäre gelogen.
   Die Karte zeigt stattdessen die Arbeit selbst, in drei Szenen à 2.5s, hart
   geschnitten wie das Durchklicken auf der Websites-Karte:
     1. die Reichweite läuft hoch, die Balken wachsen nach,
     2. die Kampagnenzeilen im Werbekonto, eine wird scharf geschaltet,
     3. was danach hereinkommt — ein Verkauf, ein Like, neue Follower.
   Alles CSS, 7.5s pro Runde. Alle Innenanimationen hängen an derselben
   7.5s-Schlaufe und wählen ihr Zeitfenster über Prozente, damit sie zur
   sichtbaren Szene passen; die Rückstellung fällt jeweils in eine Phase, in
   der die Szene ohnehin verdeckt ist. Die Zahlen sind Anschauung, keine
   Kennzahl dieses Hauses; Meta und Instagram stehen als Namen der Kanäle da,
   ohne Logo. */
@property --reach {
  syntax: "<integer>";
  initial-value: 128;
  inherits: true;
}
.ads { background: #0b0c0d; }
.ads::after { display: none; }
/* Bei jedem Schnitt fährt ein Lichtstreifen über die Fläche — der Kitt
   zwischen den drei Szenen, damit der Wechsel nicht nur ein Umschalten ist. */
.ads::before {
  content: ""; position: absolute; z-index: 4; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 42%, rgba(168, 218, 207, .16) 50%, transparent 58%);
  background-size: 260% 100%;
  animation: ads-sweep 2.5s cubic-bezier(.5,0,.2,1) infinite;
}
@keyframes ads-sweep { 0% { background-position: 130% 0; } 34%, 100% { background-position: -130% 0; } }
.ads-grid {
  position: absolute; inset: 0; opacity: .5;
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: 100% 26px, 32px 100%;
}
/* Jede Szene fährt langsam heran oder weg, während sie steht — derselbe
   Ken-Burns-Kniff wie auf der Websites-Karte. Der Ausschlag ist klein: es ist
   eine Oberfläche mit Text, die darf atmen, aber nicht wackeln. */
.ads-scene {
  position: absolute; inset: 0; z-index: 2; opacity: 0;
  animation: ads-scene 7.5s linear infinite, ads-zoom-in 7.5s ease-out infinite;
}
.ads-scene-1 { animation-delay: 0s; }
.ads-scene-2 { animation-delay: 2.5s; animation-name: ads-scene, ads-zoom-out; }
.ads-scene-3 { animation-delay: 5s; }
@keyframes ads-scene { 0%, 31% { opacity: 1; } 33%, 100% { opacity: 0; } }
@keyframes ads-zoom-in  { 0% { transform: scale(1); }    31%, 100% { transform: scale(1.06); } }
@keyframes ads-zoom-out { 0% { transform: scale(1.06); } 31%, 100% { transform: scale(1); } }

/* Szene 1 — Reichweite */
.ads-key {
  position: absolute; left: 18px; top: 20px;
  font-family: var(--font-ui); font-size: 9px; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase; color: var(--ink-soft);
}
.ads-count {
  position: absolute; left: 18px; top: 34px;
  font-family: var(--font-title); font-size: 30px; line-height: 1; color: var(--ink);
  animation: ads-count 7.5s cubic-bezier(.25,.85,.35,1) infinite;
}
/* counter() liest die animierte Zahl — deshalb erbt --reach (inherits: true),
   sonst sähe das Pseudoelement nur den Startwert. */
.ads-count::after { counter-reset: reach var(--reach); content: counter(reach) "K"; }
@keyframes ads-count { 0% { --reach: 42; } 17%, 100% { --reach: 128; } }
.ads-bars {
  position: absolute; left: 45%; right: 16px; bottom: 16px;
  height: 62px; display: flex; align-items: flex-end; gap: 5px;
}
.ads-bars i {
  flex: 1; border-radius: 2px 2px 0 0; transform-origin: bottom; transform: scaleY(.1);
  background: linear-gradient(180deg, var(--accent-light), rgba(137, 184, 174, .22));
  animation: ads-bar 7.5s cubic-bezier(.2,.85,.3,1) infinite;
}
.ads-bars i:nth-child(1) { --h: .26; animation-delay: .02s; }
.ads-bars i:nth-child(2) { --h: .4;  animation-delay: .07s; }
.ads-bars i:nth-child(3) { --h: .34; animation-delay: .12s; }
.ads-bars i:nth-child(4) { --h: .58; animation-delay: .17s; }
.ads-bars i:nth-child(5) { --h: .7;  animation-delay: .22s; }
.ads-bars i:nth-child(6) { --h: .86; animation-delay: .27s; }
.ads-bars i:nth-child(7) { --h: 1;   animation-delay: .32s; }
@keyframes ads-bar { 0% { transform: scaleY(.1); } 16%, 90% { transform: scaleY(var(--h, 1)); } 100% { transform: scaleY(.1); } }
/* Auf der Oberkante jedes Balkens sitzt ein Lichtpunkt, der kurz aufglüht,
   sobald der Balken steht. */
.ads-bars i::after {
  content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 2px;
  border-radius: 2px; background: var(--accent-light);
  box-shadow: 0 0 8px rgba(168, 218, 207, .9);
  opacity: 0; animation: ads-spark 7.5s ease-out infinite;
}
.ads-bars i { position: relative; }
@keyframes ads-spark { 0%, 12% { opacity: 0; } 18% { opacity: 1; } 30%, 100% { opacity: 0; } }

/* Szene 2 — das Werbekonto */
.ads-row {
  position: absolute; left: 14px; right: 14px;
  display: grid; grid-template-columns: 1fr auto auto; gap: 10px; align-items: center;
  font-family: var(--font-ui); font-size: 9.5px; color: var(--ink);
  padding: 7px 10px; border-radius: 7px;
  background: rgba(255, 255, 255, .045); border: 1px solid var(--line);
  opacity: 0; animation: ads-row 7.5s cubic-bezier(.16,1,.3,1) infinite;
}
.ads-row span:nth-child(2) { color: var(--ink-soft); }
.ads-row span:nth-child(3) { color: var(--accent-light); font-weight: 600; }
.ads-row-head {
  background: none; border: none; padding: 0 10px;
  font-size: 8px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft);
}
.ads-row-head span { color: inherit !important; font-weight: 400 !important; }
.ads-scene-2 .ads-row:nth-child(1) { top: 18px; animation-delay: 0s; }
.ads-scene-2 .ads-row:nth-child(2) { top: 40px; animation-delay: .1s; }
.ads-scene-2 .ads-row:nth-child(3) { top: 78px; animation-delay: .2s; }
@keyframes ads-row {
  0% { opacity: 0; transform: translateY(7px); }
  9%, 90% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translateY(7px); }
}
.ads-live {
  display: inline-block; width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); margin-right: 6px; vertical-align: 1px;
  animation: ads-live 1.6s ease-in-out infinite;
}
@keyframes ads-live { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
/* Der Schalter geht in der Szene an: der Knopf fährt hinüber, die Bahn färbt. */
.ads-switch {
  position: absolute; right: 16px; bottom: 16px; width: 30px; height: 16px;
  border-radius: 999px; background: rgba(255, 255, 255, .12);
  animation: ads-switch-track 7.5s ease infinite;
}
.ads-switch i {
  position: absolute; top: 2px; left: 2px; width: 12px; height: 12px;
  border-radius: 50%; background: var(--ink);
  animation: ads-switch-knob 7.5s cubic-bezier(.34,1.56,.64,1) infinite;
}
@keyframes ads-switch-track { 0%, 12% { background: rgba(255, 255, 255, .12); } 18%, 100% { background: rgba(137, 184, 174, .55); } }
@keyframes ads-switch-knob { 0%, 12% { transform: none; } 18%, 100% { transform: translateX(14px); } }
/* Derselbe Play-Knopf, den die Seite unter den Cursor legt, drückt hier den
   Schalter — die Karte klickt sich selbst scharf. */
.ads-switch::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 26px; height: 26px;
  margin: -13px 0 0 -13px; border-radius: 50%;
  border: 1.5px solid var(--accent-light); background: rgba(168, 218, 207, .18);
  opacity: 0; animation: ads-tap 7.5s cubic-bezier(.16,1,.3,1) infinite;
}
@keyframes ads-tap {
  0%, 9% { opacity: 0; transform: scale(.5); }
  13%    { opacity: 1; transform: scale(1.05); }
  17%    { opacity: .9; transform: scale(.88); }
  24%, 100% { opacity: 0; transform: scale(1.35); }
}

/* Szene 3 — was hereinkommt */
.ads-pop {
  position: absolute; opacity: 0;
  font-family: var(--font-ui); font-size: 9.5px; font-weight: 600; letter-spacing: .04em;
  color: var(--accent-light); background: rgba(137, 184, 174, .13);
  border: 1px solid rgba(137, 184, 174, .32); border-radius: 999px;
  padding: 3px 9px; white-space: nowrap;
  animation: ads-pop 7.5s ease-out infinite;
}
.ads-pop-1 { left: 18px; bottom: 26px; animation-delay: 0s; }
.ads-pop-2 { right: 26px; top: 22px; animation-delay: .3s; }
.ads-pop-3 { left: 38%; top: 52px; animation-delay: .6s; }
.ads-pop-4 { right: 20px; bottom: 20px; animation-delay: .9s; }
.ads-pop-1::before, .ads-pop-4::before {
  content: ""; position: absolute; inset: -7px; border-radius: 999px;
  border: 1px solid rgba(168, 218, 207, .5);
  opacity: 0; animation: ads-ring 7.5s ease-out infinite; animation-delay: inherit;
}
@keyframes ads-ring {
  0%, 3% { opacity: 0; transform: scale(.6); }
  6%     { opacity: .8; }
  18%, 100% { opacity: 0; transform: scale(1.9); }
}
@keyframes ads-pop {
  0% { opacity: 0; transform: translateY(10px) scale(.92); }
  4% { opacity: 1; transform: none; }
  16% { opacity: 1; transform: translateY(-3px); }
  22%, 100% { opacity: 0; transform: translateY(-14px); }
}

@media (prefers-reduced-motion: reduce) {
  .ads::before, .ads-scene, .ads-count, .ads-bars i, .ads-bars i::after,
  .ads-row, .ads-live, .ads-switch, .ads-switch::after, .ads-switch i,
  .ads-pop, .ads-pop::before { animation: none; transform: none; }
  .ads-scene-1 { opacity: 1; }
  .ads-scene-2, .ads-scene-3 { opacity: 0; }
  .ads-bars i { transform: scaleY(var(--h, 1)); }
}

/* ---------- Strategy & Audit ----------
   Auch hier gab es nur einen schwachen Clip. Die Karte heisst Compass, also
   zeigt sie einen: die Nadel sucht, schwingt über das Ziel hinaus und kommt
   zur Ruhe — und während sie steht, hakt sich die Liste ab, Punkt für Punkt.
   6 Sekunden pro Runde. */
.plan { background: #0b0c0d; }
.plan::after { display: none; }
.plan-compass {
  position: absolute; left: 26px; top: 50%; width: 74px; height: 74px; margin-top: -37px;
  border-radius: 50%; border: 1px solid rgba(168, 218, 207, .35);
  box-shadow: inset 0 0 22px rgba(168, 218, 207, .1);
}
/* Die Teilstriche der Rose: vier Linien, aus zwei Verläufen gezeichnet. */
.plan-compass::before {
  content: ""; position: absolute; inset: 9px; border-radius: 50%;
  background:
    linear-gradient(var(--line) 1px, transparent 1px) center / 100% 50% no-repeat,
    linear-gradient(90deg, var(--line) 1px, transparent 1px) center / 50% 100% no-repeat;
  opacity: .8;
}
/* Die Nadel: ein Dreieck, das sich um die Mitte dreht. */
.plan-compass i {
  position: absolute; left: 50%; top: 50%; width: 0; height: 0; margin: -26px 0 0 -5px;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-bottom: 26px solid var(--accent-light);
  transform-origin: 50% 100%;
  animation: plan-needle 6s cubic-bezier(.34,1.4,.5,1) infinite;
}
.plan-compass::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 6px; height: 6px;
  margin: -3px 0 0 -3px; border-radius: 50%; background: var(--ink);
}
@keyframes plan-needle {
  0%   { transform: rotate(-128deg); }
  22%  { transform: rotate(24deg); }
  32%  { transform: rotate(-9deg); }
  40%, 88% { transform: rotate(0deg); }
  100% { transform: rotate(-128deg); }
}
.plan-north {
  position: absolute; left: 26px; top: 50%; width: 74px; margin-top: -58px;
  text-align: center; font-family: var(--font-ui); font-size: 8px; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--accent);
  opacity: 0; animation: plan-north 6s ease-out infinite;
}
@keyframes plan-north { 0%, 38% { opacity: 0; } 46%, 88% { opacity: 1; } 100% { opacity: 0; } }

.plan-list {
  position: absolute; left: 120px; right: 18px; top: 50%; margin: 0; transform: translateY(-50%);
  padding: 0; list-style: none;
}
.plan-list li {
  position: relative; padding-left: 20px; margin-bottom: 9px;
  font-family: var(--font-ui); font-size: 10.5px; color: var(--ink);
  opacity: 0; animation: plan-item 6s cubic-bezier(.16,1,.3,1) infinite;
}
.plan-list li:last-child { margin-bottom: 0; }
.plan-list li:nth-child(1) { animation-delay: .1s; }
.plan-list li:nth-child(2) { animation-delay: .5s; }
.plan-list li:nth-child(3) { animation-delay: .9s; }
/* Der Haken wird gezeichnet, nicht eingeblendet — zwei Striche, die aus dem
   Nichts wachsen. */
.plan-list li::before {
  content: ""; position: absolute; left: 1px; top: 3px; width: 9px; height: 5px;
  border-left: 1.5px solid var(--accent-light); border-bottom: 1.5px solid var(--accent-light);
  transform-origin: left bottom; transform: rotate(-45deg) scaleX(0);
  animation: plan-tick 6s cubic-bezier(.16,1,.3,1) infinite;
  animation-delay: inherit;
}
@keyframes plan-item { 0%, 40% { opacity: 0; transform: translateX(-6px); } 50%, 90% { opacity: 1; transform: none; } 100% { opacity: 0; } }
@keyframes plan-tick { 0%, 52% { transform: rotate(-45deg) scaleX(0); } 62%, 90% { transform: rotate(-45deg) scaleX(1); } 100% { transform: rotate(-45deg) scaleX(0); } }

@media (prefers-reduced-motion: reduce) {
  .plan-compass i, .plan-north, .plan-list li, .plan-list li::before { animation: none; }
  .plan-compass i { transform: rotate(0deg); }
  .plan-north, .plan-list li { opacity: 1; transform: none; }
  .plan-list li::before { transform: rotate(-45deg) scaleX(1); }
}

/* ---------- Websites ----------
   Die Karte erzählt eine kleine Geschichte in 7.5 Sekunden: erst das Zeichen
   der Marke, das angetippt wird und zwei Wellen schlägt — der Tropfen —, dann
   fährt die Kamera hindurch in die Seite hinein, und dort wird geklickt und
   gescrollt, sieben echte Aufnahmen lang. Bei jedem Klick blitzt derselbe
   Play-Knopf auf, den die Seite auch sonst unter den Cursor legt.

   Aufteilung der Runde: 0–2.25s Intro, 2.25–7.5s Seite, sieben Bilder à 0.75s.
   Alles hängt an derselben 7.5s-Schlaufe; wo etwas erst später beginnen soll,
   steht eine Verzögerung — ohne `backwards`, damit vorher der Grundzustand
   gilt und nicht der erste Keyframe. */
.web { background: #0b0c0d; }
.web::after { display: none; }

/* --- Intro: das Zeichen und der Tropfen --- */
.web-intro {
  position: absolute; inset: 0; z-index: 4; display: block;
  background: #0b0c0d;
  animation: web-intro 7.5s cubic-bezier(.5,0,.75,0) infinite;
}
@keyframes web-intro {
  0%, 24% { opacity: 1; transform: scale(1); }
  32%     { opacity: 0; transform: scale(2.6); }
  100%    { opacity: 0; transform: scale(2.6); }
}
.web-logo {
  position: absolute; left: 50%; top: 50%; width: 116px; height: 29px;
  margin: -14px 0 0 -58px;
  background: url("/assets/jjYNzZh33ZNnyKcyIrePLkX9HJ8.svg") center / contain no-repeat;
  opacity: 0; animation: web-logo 7.5s cubic-bezier(.16,1,.3,1) infinite;
}
@keyframes web-logo {
  0%      { opacity: 0; transform: scale(.86); }
  6%      { opacity: 1; transform: scale(1); }
  10%     { transform: scale(.94); }   /* der Druck */
  14%, 24% { transform: scale(1); }
  100%    { opacity: 1; transform: scale(1); }
}
/* Zwei Wellen vom Druckpunkt aus — das Zeichen sitzt links im Wortbild. */
.web-wave {
  position: absolute; left: 50%; top: 50%; width: 22px; height: 22px;
  margin: -11px 0 0 -28px; border-radius: 50%;
  border: 1px solid rgba(168, 218, 207, .55);
  opacity: 0; animation: web-wave 7.5s cubic-bezier(.2,.7,.3,1) infinite;
}
.web-wave-2 { animation-delay: .16s; border-color: rgba(255, 255, 255, .3); }
@keyframes web-wave {
  0%, 9%  { opacity: 0; transform: scale(.4); }
  12%     { opacity: .9; }
  22%,100%{ opacity: 0; transform: scale(4.2); }
}

/* --- Die Seite --- */
.web-stage {
  position: absolute; inset: 0; display: block; opacity: 0;
  animation: web-stage 7.5s cubic-bezier(.16,1,.3,1) infinite;
}
@keyframes web-stage {
  0%, 24% { opacity: 0; transform: scale(1.32); }
  33%     { opacity: 1; transform: scale(1); }
  100%    { opacity: 1; transform: scale(1); }
}
.browser {
  position: relative; z-index: 2; height: 26px; display: flex; align-items: center; gap: 8px;
  padding: 0 10px; background: rgba(255, 255, 255, 0.05); border-bottom: 1px solid var(--line);
}
.dots i { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: rgba(255, 255, 255, 0.22); margin-right: 4px; }
.url {
  font-family: var(--font-ui); font-size: 10px; letter-spacing: 0.08em; color: var(--ink-soft);
  background: rgba(0, 0, 0, 0.4); border-radius: 999px; padding: 2px 10px;
}
.frames { position: absolute; inset: 26px 0 0 0; overflow: hidden; }
.frames img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center;
  opacity: 0;
  animation: svc-shot 7.5s linear infinite, svc-kb-in 7.5s ease-out infinite;
}
/* Jedes zweite Bild fährt andersherum und scrollt in die Gegenrichtung,
   sonst pumpt die ganze Reihe im selben Takt. */
.frames img:nth-child(even) { animation-name: svc-shot, svc-kb-out; }
.frames img:nth-child(1) { animation-delay: 2.25s; }
.frames img:nth-child(2) { animation-delay: 3s; }
.frames img:nth-child(3) { animation-delay: 3.75s; }
.frames img:nth-child(4) { animation-delay: 4.5s; }
.frames img:nth-child(5) { animation-delay: 5.25s; }
.frames img:nth-child(6) { animation-delay: 6s; }
.frames img:nth-child(7) { animation-delay: 6.75s; }
@keyframes svc-shot { 0% { opacity: 1; } 10% { opacity: 1; } 10.01% { opacity: 0; } 100% { opacity: 0; } }
@keyframes svc-kb-in {
  0%       { transform: scale(1) translateY(0); }
  10%,100% { transform: scale(1.12) translateY(-3.5%); }
}
@keyframes svc-kb-out {
  0%       { transform: scale(1.12) translateY(-3%); }
  10%,100% { transform: scale(1) translateY(0); }
}

/* --- Der Zeiger und sein Play-Knopf --- */
.pointer {
  position: absolute; z-index: 3; width: 12px; height: 12px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.9); box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.18);
  opacity: 0;
  animation: svc-click 7.5s steps(1, end) infinite, web-pointer 7.5s linear infinite;
}
@keyframes web-pointer { 0%, 28% { opacity: 0; } 30%, 100% { opacity: 1; } }
/* Der Play-Knopf blitzt bei jedem Klick auf — eine eigene 0.75s-Schlaufe, die
   in die 7.5s der Karte genau zehnmal passt und darum nie aus dem Takt fällt.
   Während des Intros ist der Zeiger unsichtbar, dort sieht man ihn nicht. */
.pointer-play {
  position: absolute; left: 50%; top: 50%; width: 30px; height: 30px; margin: -15px 0 0 -15px;
  border-radius: 50%; border: 1.5px solid var(--accent-light);
  background: rgba(168, 218, 207, .16);
  animation: web-play .75s cubic-bezier(.16,1,.3,1) infinite;
}
.pointer-play::after {
  content: ""; position: absolute; left: 11px; top: 8px;
  border-left: 9px solid var(--accent-light);
  border-top: 6.5px solid transparent; border-bottom: 6.5px solid transparent;
}
@keyframes web-play {
  0%   { opacity: 0; transform: scale(.5); }
  16%  { opacity: 1; transform: scale(1.06); }
  34%  { opacity: .95; transform: scale(.9); }
  60%  { opacity: 0; transform: scale(1.3); }
  100% { opacity: 0; transform: scale(1.3); }
}
@keyframes svc-click {
  0%,   28% { left: 22%; top: 64%; }
  30%  { left: 22%; top: 64%; }
  40%  { left: 70%; top: 38%; }
  50%  { left: 38%; top: 72%; }
  60%  { left: 64%; top: 52%; }
  70%  { left: 30%; top: 44%; }
  80%  { left: 74%; top: 66%; }
  90%  { left: 46%; top: 34%; }
}

@media (prefers-reduced-motion: reduce) {
  .web-intro, .web-logo, .web-wave, .web-stage,
  .frames img, .pointer, .pointer-play { animation: none; }
  .web-intro, .web-wave, .pointer { opacity: 0; }
  .web-stage { opacity: 1; transform: none; }
  .frames img { opacity: 0; transform: none; }
  .frames img:first-child { opacity: 1; }
}

@media (max-width: 1000px) {
  .tier-1 .svc { flex-direction: column; min-height: 0; }
  .tier-1 .svc-media { height: 280px; flex: none; }
  .tier-1 .svc-media::after { background: linear-gradient(180deg, rgba(14, 15, 17, 0.1), rgba(14, 15, 17, 0.8)); }
  .tier-1 .svc-body { padding: 34px 30px; }
  .tier-2, .tier-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .tier-2, .tier-3 { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .svc-ticker-track, .frames img, .pointer { animation: none; }
  .frames img { opacity: 0; }
  .frames img:first-child { opacity: 1; }
  .pointer { display: none; }
}

/* ---------- Case-Filter ----------
   Die Kategorien folgen der Leistungsseite, damit ein Besucher den Case
   findet, der zu der Leistung passt, die ihn hergebracht hat. */
.case-filters {
  display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 28px;
}
.case-filter {
  font-family: var(--font-ui); font-size: 14px; color: var(--ink);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px; padding: 9px 18px; cursor: pointer;
  transition: background .2s ease, border-color .2s ease, color .2s ease;
}
.case-filter:hover { background: rgba(255, 255, 255, 0.09); }
.case-filter.is-active {
  background: var(--accent-light); border-color: var(--accent-light); color: #0e0f11;
}
/* a.case-card setzt display:block und schlägt damit das eingebaute
   [hidden] des Browsers — deshalb hier ausdrücklich ausblenden. */
.case-card[hidden] { display: none; }
.case-empty { margin-top: 12px; color: var(--ink-soft); }
@media (max-width: 560px) {
  .case-filter { font-size: 13px; padding: 8px 14px; }
}

/* Das Interview mit Mario wurde flach gedreht (Log-Profil, nicht gegradet).
   Eine milde Gradation im Browser reicht, damit die Karte nicht ausgewaschen
   neben den anderen steht — bewusst zurückhaltend, rund 25 %. */
.testi-card img.bg[src$="delfos-metallbau.jpg"] {
  filter: saturate(1.28) contrast(1.07) brightness(1.03);
}

/* ---------- Kategorie auf der Case-Karte ----------
   Dieselbe Form wie die Filter-Pillen vorher, aber als Auszeichnung:
   sie sagt, welche Leistung hinter dem Case steckt. */
/* Die Kategorie sitzt unter dem Bild im dunklen Teil der Karte, rechts unten:
   im Bild verdeckte sie einen Teil der Aufnahme. Eckig mit weichen Kanten,
   und sie schreibt sich beim Reinscrollen selbst — das Skript setzt vorher
   die Breite fest, damit der Kasten dabei nicht wächst. */
a.case-card, .case-card { display: flex; flex-direction: column; }
.case-card img, .case-card video { order: 1; }
.case-card h3 { order: 2; }
.case-card p { order: 3; }
.case-tag {
  order: 4; align-self: flex-end; margin-top: auto;
  font-family: var(--font-ui); font-size: 12.5px; font-weight: 600; line-height: 20px;
  letter-spacing: .01em;
  color: var(--accent-light);
  background: rgba(137, 184, 174, 0.10);
  border: 1px solid rgba(137, 184, 174, 0.34);
  border-radius: 8px; padding: 6px 12px;
  white-space: nowrap; pointer-events: none;
}
/* Der Cursor blinkt nur, solange geschrieben wird. */
.case-tag::after {
  content: "";
  display: inline-block; width: 1px; height: 13px;
  margin-left: 3px; vertical-align: -2px;
  background: var(--accent-light); opacity: 0;
}
.case-tag.is-typing::after { opacity: 1; animation: caret .8s steps(1) infinite; }
@keyframes caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

@media (max-width: 560px) {
  .case-tag { font-size: 11.5px; padding: 5px 10px; }
}

/* ---------- Pfeil auf den Weiter-Buttons ---------- */
.btn .arrow {
  display: inline-block; margin-left: 10px;
  transition: transform .2s ease;
}
.btn:hover .arrow { transform: translateX(4px); }

/* =========================================================
   BEWEGUNG — Überschriften, Linien, Helligkeit, Seitenwechsel
   Alles hängt an .is-visible, das der Beobachter im Skript setzt,
   und schaltet sich bei "Bewegung reduzieren" komplett ab.
   ========================================================= */

/* Überschriften steigen aus einer Maske. Das Skript legt den Inhalt jeder
   Überschrift in .rise-inner; .rise selbst ist die Blende davor. */
.rise { display: block; overflow: hidden; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.rise-inner {
  display: block;
  transform: translateY(105%);
  transition: transform 1s cubic-bezier(.16, 1, .3, 1);
}
.is-visible > .rise > .rise-inner,
.rise.is-visible > .rise-inner { transform: translateY(0); }

/* Die Haarlinie unter einem Sektionskopf zieht sich beim Erscheinen auf. */
.section-head::after, .sec-head::after {
  content: ""; display: block; height: 1px; margin-top: 24px;
  background: var(--line);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 1.2s cubic-bezier(.16, 1, .3, 1) .15s;
}
.section-head.is-visible::after, .sec-head.is-visible::after { transform: scaleX(1); }

/* Medien kommen dunkel herein und hellen auf, sobald die Karte steht. */
.case-card img, .case-card video { filter: brightness(.45); transition: filter 1.1s ease; }
.case-grid.is-visible .case-card img, .case-grid.is-visible .case-card video { filter: brightness(1); }
.svc .svc-media video { filter: brightness(.45) saturate(.92) contrast(1.05); }
.svc.is-visible .svc-media video { filter: saturate(.92) contrast(1.05); }
.package-card .bg { filter: brightness(.5); transition: filter 1.1s ease; }
.package-grid.is-visible .package-card .bg { filter: brightness(1); }

/* ---------- Cases fast in Schwarzweiss ----------
   Die Cases liegen weitgehend entfärbt im Raster — ein Rest Farbe von rund
   15% bleibt stehen, damit sie nicht kalt wirken. Erst der Cursor holt einer
   Karte die volle Farbe zurück. Geräte ohne Zeigegerät kennen kein
   Darüberfahren — dort bleiben die Videos farbig, sonst wäre die Farbe dort
   nie zu sehen. */
@media (hover: hover) {
  .case-card img, .case-card video { filter: brightness(.45) grayscale(.85); }
  .case-grid.is-visible .case-card img,
  .case-grid.is-visible .case-card video { filter: brightness(1) grayscale(.85); }

  .case-card:hover img, .case-card:hover video,
  .case-card:focus-visible img, .case-card:focus-visible video,
  .case-grid.is-visible .case-card:hover img,
  .case-grid.is-visible .case-card:hover video,
  .case-grid.is-visible .case-card:focus-visible img,
  .case-grid.is-visible .case-card:focus-visible video {
    filter: brightness(1) grayscale(0);
    transition: filter .45s ease;
  }
}

/* Ein Druck auf eine Karte gibt nach, bevor die nächste Seite kommt. */
a.case-card:active, a.package-card:active, .btn:active { transform: scale(.985); }

/* Seitenwechsel: der neue Inhalt zoomt herein, der alte weicht zurück.
   Browser ohne View Transitions wechseln wie bisher. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vt-out .32s cubic-bezier(.4, 0, 1, 1) forwards; }
::view-transition-new(root) { animation: vt-in .5s cubic-bezier(.16, 1, .3, 1); }
@keyframes vt-out { to { opacity: 0; transform: scale(1.03); } }
@keyframes vt-in { from { opacity: 0; transform: scale(.982); } }

@media (prefers-reduced-motion: reduce) {
  .rise-inner { transform: none; }
  .section-head::after, .sec-head::after { transform: scaleX(1); }
  .case-card img, .case-card video, .package-card .bg { filter: none; }
  .svc .svc-media video { filter: saturate(.92) contrast(1.05); }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* ---------- Neonring auf den Cases ----------
   Ein Lichtpunkt läuft beim Darüberfahren einmal um die Karte. Der Ring ist
   ein Kegelverlauf, aus dem eine Maske alles ausser einem Rahmen von 1.5px
   herausschneidet — so leuchtet nur die Kante, nicht die Fläche.
   Browser ohne @property zeigen den Ring ruhig statt umlaufend. */
@property --ring-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
.case-card { position: relative; isolation: isolate; }
.case-card::before, .package-card .ring {
  content: ""; position: absolute; inset: -1px; z-index: 3; pointer-events: none;
  border-radius: inherit; padding: 1.5px;
  background: conic-gradient(
    from var(--ring-angle),
    rgba(168, 218, 207, 0) 0deg,
    rgba(168, 218, 207, 0) 200deg,
    var(--accent) 290deg,
    var(--accent-light) 340deg,
    rgba(168, 218, 207, 0) 360deg
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0; transition: opacity .35s ease;
}
.case-card:hover::before, .case-card:focus-visible::before,
.package-card:hover .ring, .package-card:focus-visible .ring {
  opacity: 1;
  animation: ring-run 2.2s linear infinite;
}
@keyframes ring-run { to { --ring-angle: 360deg; } }

/* Ein zweiter, sehr weicher Schein darunter — das ist, was den Ring als Neon
   lesbar macht statt als gezeichnete Linie. */
.case-card::after {
  content: ""; position: absolute; inset: -1px; z-index: 2; pointer-events: none;
  border-radius: inherit;
  box-shadow: 0 0 24px rgba(137, 184, 174, 0.35);
  opacity: 0; transition: opacity .35s ease;
}
.case-card:hover::after { opacity: 1; }
.package-card { isolation: isolate; }
.package-card .ring { border-radius: 16px; box-shadow: 0 0 24px rgba(137, 184, 174, .28); }

@media (prefers-reduced-motion: reduce) {
  .case-card:hover::before, .package-card:hover .ring { animation: none; }
}

/* ---------- Klick-Zeichen ----------
   Ein Klick setzt für einen Moment den Play-Button der Marke an die Stelle,
   auf die gedrückt wurde: er erscheint, wird gedrückt und verschwindet,
   während die nächste Seite schon lädt. Der Zeiger selbst bleibt normal. */
.click-play {
  position: fixed; z-index: 999; width: 46px; height: 46px;
  margin: -23px 0 0 -23px; pointer-events: none;
  animation: click-play .42s cubic-bezier(.16, 1, .3, 1) forwards;
}
.click-play svg { display: block; width: 100%; height: 100%; }
@keyframes click-play {
  0%   { opacity: 0; transform: scale(.55); }
  28%  { opacity: 1; transform: scale(1.06); }
  52%  { transform: scale(.86); }
  72%  { opacity: .9; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.25); }
}
@media (prefers-reduced-motion: reduce) { .click-play { display: none; } }

/* ---------- Logo-Aufbau auf der Startseite ----------
   Das Zeichen fällt in die Mitte des Logofelds, staucht beim Aufsetzen,
   wird gedrückt — mit Wellen vom Druckpunkt — und wandert dann an seinen
   Platz, während die Buchstaben hinter ihm hervorkommen.

   Die Grafik liegt in zwei Dateien: Wortmarke ohne Zeichen, Zeichen allein,
   beide mit dem viewBox des Originals. Getrennt wird bei x=94 von 340 —
   mitten in der Lücke zwischen R und G. An der Dreieckskante (x=118) lag die
   Trennung zu weit rechts: das G ragt bis x=115 und wurde angeschnitten.
   Was zwischen Trennkante und Zeichen liegt, verdeckt ohnehin das Zeichen. */
.logo.anim { position: relative; display: block; width: 150px; height: 38px; }
.logo.anim span {
  position: absolute; inset: 0;
  background: url("/assets/logo-letters.svg") center / cover no-repeat;
  will-change: clip-path, transform;
}
.logo.anim .l { clip-path: inset(0 72.37% 0 0); animation: logo-wipe-l .75s cubic-bezier(.42, 0, .38, 1) .95s both; }
.logo.anim .r { clip-path: inset(0 0 0 27.63%); animation: logo-wipe-r .75s cubic-bezier(.42, 0, .38, 1) .95s both; }
.logo.anim .t {
  background-image: url("/assets/logo-mark.svg");
  transform-origin: 29.1% 50%;
  animation: logo-mark 1.7s both;
}
/* Zwei Wellen vom Druckpunkt — dünn, halbdurchsichtig, leicht versetzt. */
.logo.anim .w1, .logo.anim .w2 {
  background: none;
  left: 50%; top: 50%; right: auto; bottom: auto;
  width: 26px; height: 26px; margin: -13px 0 0 -13px;
  border: 1px solid rgba(168, 218, 207, .5);
  border-radius: 50%;
  opacity: 0;
  animation: logo-wave .95s cubic-bezier(.2, .7, .3, 1) .82s both;
}
.logo.anim .w2 { animation-delay: .93s; border-color: rgba(255, 255, 255, .32); }
@keyframes logo-wave {
  0%   { opacity: 0; transform: scale(.35); }
  18%  { opacity: .85; }
  100% { opacity: 0; transform: scale(3.1); }
}
/* Die Kanten der Buchstaben folgen dem Zeichen, während es nach links zieht. */
@keyframes logo-wipe-l {
  from { clip-path: inset(0 55.61% 0 44.39%); }
  to   { clip-path: inset(0 72.37% 0 0); }
}
@keyframes logo-wipe-r {
  from { clip-path: inset(0 44.39% 0 55.61%); }
  to   { clip-path: inset(0 0 0 27.63%); }
}
/* Fallen, Aufsetzen, Nachfedern, Druck, dann der Weg an den Platz. Beim
   Druck geht das Zeichen kurz dunkler und minim tiefer — so liest es sich
   als gedrückt und nicht bloss als kleiner. */
@keyframes logo-mark {
  0%   { opacity: 0; transform: translate(31.3px, -26px) scale(.92); animation-timing-function: cubic-bezier(.55, 0, .85, .2); }
  18%  { opacity: 1; transform: translate(31.3px, 4px) scale(1.1, .88); animation-timing-function: cubic-bezier(.2, 0, .2, 1); }
  27%  { transform: translate(31.3px, -5px) scale(.95, 1.06); animation-timing-function: cubic-bezier(.5, 0, .8, .3); }
  36%  { transform: translate(31.3px, 0) scale(1.02, .98); animation-timing-function: cubic-bezier(.2, 0, .3, 1); }
  43%  { transform: translate(31.3px, 0) scale(1); filter: brightness(1); animation-timing-function: cubic-bezier(.4, 0, .2, 1); }
  50%  { transform: translate(31.3px, 1.5px) scale(.82); filter: brightness(.62); animation-timing-function: cubic-bezier(.3, 0, .2, 1); }
  58%  { transform: translate(31.3px, 0) scale(1); filter: brightness(1); animation-timing-function: cubic-bezier(.42, 0, .38, 1); }
  100% { transform: translate(0, 0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .logo.anim .l, .logo.anim .r, .logo.anim .t { animation: none; }
  .logo.anim .w1, .logo.anim .w2 { display: none; }
}

/* ---------- WhatsApp ----------
   In der Schweiz läuft Geschäftliches oft über WhatsApp, und die meisten
   Besucher kommen vom Handy. Der Knopf öffnet einen Chat mit vorgeschriebener
   Nachricht — auf dem Handy schwebend, am Rechner unten in der Fusszeile,
   damit er die Bildkomposition nicht stört. */
.wa-float {
  position: fixed; right: 18px; bottom: 18px; z-index: 60;
  display: none; align-items: center; gap: 9px;
  padding: 12px 18px 12px 15px; border-radius: 999px;
  background: var(--accent-light); color: #0e0f11;
  font-family: var(--font-ui); font-size: 14.5px; font-weight: 600;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
  text-decoration: none;
}
.wa-float:active { transform: scale(.97); }
@media (max-width: 860px) { .wa-float { display: inline-flex; } }
.wa-inline {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--accent-light); text-decoration: none; font-family: var(--font-ui);
  font-size: 14px; margin-top: 10px;
}
.wa-inline:hover { color: #fff; }
