/* ============================================================
   BEVISIBLE — Redesign
   Design tokens, 3 mischbare Richtungen (A/B/C), Motion, UI
   ============================================================ */

/* ---------- Fonts ---------- */
/* Archivo  = Web-Ersatz für Trade Gothic Next (neo-grotesk, 100–900)
   Space Mono = technische Micro-Labels (Karten-Index, Footer-Spaltenkoepfe,
                Projekt-Kategorien). NICHT die #-Kicker — die laufen in Archivo,
                siehe Kommentar bei .kicker weiter unten.

   Beide selbst gehostet aus public/assets/fonts/ — KEIN Google-Fonts-Abruf mehr.
   Zwei Gründe: Datenschutz (keine Besucher-IP an Google, siehe Datenschutzerklärung)
   und Darstellung — über Google brauchte die Schrift bis zu 4 s, in denen der Browser
   die Fallback-Schrift zeigte. Beim Logo-„#" ist das sichtbar, weil dort ein
   animierter Verlauf per background-clip:text durch die Glyphe gemalt wird: bei der
   falschen Glyphe entsteht der blaue Schweif. Selbst gehostet fällt der Umweg über
   zwei fremde Hosts weg, die kritischen Schnitte werden vorgeladen (siehe index.html).

   Archivo ist eine Variable Font (ein Datei pro Subset deckt 100–900 ab) —
   deutlich kleiner als sieben Einzelschnitte.
   Lizenz beider Schriften: SIL Open Font License 1.1 (frei, auch kommerziell,
   Selbst-Hosting ausdrücklich erlaubt). Herkunft siehe Vault-Notiz „Schriften". */

/* Archivo — latin */
@font-face {
  font-family:'Archivo';
  font-style:normal;
  font-weight:100 900;
  font-stretch:100%;
  font-display:swap;
  src:url('assets/fonts/archivo-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
/* Archivo — latin-ext */
@font-face {
  font-family:'Archivo';
  font-style:normal;
  font-weight:100 900;
  font-stretch:100%;
  font-display:swap;
  src:url('assets/fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Space Mono 400 — latin / latin-ext */
@font-face {
  font-family:'Space Mono'; font-style:normal; font-weight:400; font-display:swap;
  src:url('assets/fonts/spacemono-400-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family:'Space Mono'; font-style:normal; font-weight:400; font-display:swap;
  src:url('assets/fonts/spacemono-400-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Space Mono 700 — latin / latin-ext */
@font-face {
  font-family:'Space Mono'; font-style:normal; font-weight:700; font-display:swap;
  src:url('assets/fonts/spacemono-700-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family:'Space Mono'; font-style:normal; font-weight:700; font-display:swap;
  src:url('assets/fonts/spacemono-700-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Hologramm-Spektrum (aus Farbverlauf gesampelt) */
  --holo-sky:#8dd1f0;
  --holo-peri:#728cc4;
  --holo-lav:#a08bbe;
  --holo-pink:#d396c1;
  --holo-blush:#f9c7cc;
  --holo-rose:#f2d0d8;
  --holo-cream:#f6ddd1;

  --ink:#1a1a1a;        /* 90% black */
  --ink-soft:#3a3a3a;

  /* Akzent-Verlauf (crisp, für Logo/Buttons/Highlights) */
  --holo: linear-gradient(110deg,
      var(--holo-sky) 0%,
      var(--holo-peri) 22%,
      var(--holo-lav) 42%,
      var(--holo-pink) 62%,
      var(--holo-blush) 80%,
      var(--holo-cream) 100%);
  --holo-soft: linear-gradient(115deg,
      #aee0f5, #9fb0dd, #c0a9d6, #e6b6d2, #fbd6da, #fae6dc);

  /* Motion (0..1) — wird per Tweak gesetzt */
  --motion: 1;
  --accent: 1;          /* Akzent-Intensität 0..1 */

  /* Typo-Skala: Theme-Basis × User-Tweak */
  --scale-base: 1;
  --scale-user: 1;
  --scale: calc(var(--scale-base) * var(--scale-user));
  --glow-mult: 1;

  --ease: cubic-bezier(.2,.7,.2,1);
  --maxw: 1280px;
  --gutter: clamp(20px, 5vw, 72px);

  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ============================================================
   3 RICHTUNGEN  (data-dir auf <html>)
   A = Editorial Mono  ·  B = Dark Stage  ·  C = Kinetic Pop
   ============================================================ */

html[data-dir="a"] {
  --bg:#ffffff;  --bg-2:#f5f3ef;  --panel:#ffffff;
  --text:#1a1a1a; --text-soft:#5d5a55; --text-dim:#8a8680;
  --line: rgba(26,26,26,.12);
  --line-strong: rgba(26,26,26,.9);
  --bg-glow:.5;          /* Hintergrund-Verlauf-Stärke */
  --scale-base: 1;
  --display-weight: 850;
  --radius: 4px;
  --on-accent:#1a1a1a;
}
html[data-dir="b"] {
  --bg:#101013;  --bg-2:#17171b;  --panel:#1b1b20;
  --text:#f4f3f0; --text-soft:#aba9a4; --text-dim:#76746f;
  --line: rgba(255,255,255,.14);
  --line-strong: rgba(255,255,255,.85);
  --bg-glow:.70;
  --scale-base: 1.04;
  --display-weight: 800;
  --radius: 6px;
  --on-accent:#101013;
}
html[data-dir="c"] {
  --bg:#f4f1 ec;  --bg-2:#ffffff;  --panel:#ffffff;
  --text:#141414; --text-soft:#56524c; --text-dim:#8a857d;
  --line: rgba(20,20,20,.14);
  --line-strong: rgba(20,20,20,.92);
  --bg-glow:.56;
  --scale-base: 1.16;     /* grössere kinetische Typo */
  --display-weight: 900;
  --radius: 14px;
  --on-accent:#141414;
}
/* fix accidental space */
html[data-dir="c"] { --bg:#f4f1ec; }

/* ---------- Reset ---------- */
*,*::before,*::after { box-sizing:border-box; }
html,body { margin:0; padding:0; }
/* Kein overflow-x auf <html> — das würde position:sticky brechen.
   Der horizontale Überlauf wird an der Quelle (about-sticky/glow) geklippt. */
body {
  background:var(--bg);
  color:var(--text);
  font-family:'Archivo', system-ui, sans-serif;
  font-size:18px;
  line-height:1.55;
  overflow-x:hidden;
  transition: background .6s var(--ease), color .6s var(--ease);
}
img { max-width:100%; display:block; }
a { color:inherit; text-decoration:none; }
button { font-family:inherit; }
::selection { background:var(--holo-pink); color:#fff; }

/* ============================================================
   TYPOGRAFIE
   ============================================================ */
/* Die #-Kicker laufen in Archivo, nicht in Space Mono: das Corporate Design kennt
   nur Trade Gothic Next (Web-Ersatz Archivo), siehe content-extraktion.md §3.
   Space Mono bleibt den echten Micro-Labels (Karten-Index, Footer-Spalten,
   Projekt-Kategorien) als technischer Akzent vorbehalten. */
.kicker {
  font-family:'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-weight:700;
  font-size:13px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--text-soft);
  display:inline-flex;
  align-items:center;
  gap:.6em;
}
.kicker::before {
  content:"#";
  background:var(--holo);
  -webkit-background-clip:text; background-clip:text;
  color:transparent;
  font-weight:800;
}

.display {
  font-weight:var(--display-weight);
  line-height:.92;
  letter-spacing:-.02em;
  text-transform:uppercase;
  margin:0;
  font-size:clamp(48px, calc(9vw * var(--scale)), 150px);
}
/* overflow-wrap als Sicherheitsnetz: lange Einzelwörter ("REDAKTIONSPLANUNG")
   dürfen in schmalen Karten umbrechen statt abgeschnitten zu werden. */
h1,h2,h3 { margin:0; font-weight:800; letter-spacing:-.015em; line-height:1.0; overflow-wrap:break-word; }
h2.section-title {
  font-size:clamp(34px, calc(5.2vw * var(--scale)), 76px);
  text-transform:uppercase;
  line-height:.94;
}
h3 { font-size:clamp(20px,2.2vw,28px); }
p { margin:0 0 1em; }
.lead { font-size:clamp(19px,1.7vw,24px); color:var(--text-soft); line-height:1.5; font-weight:400; }
.small { font-size:14px; color:var(--text-dim); }

/* Gradient text */
.grad-text {
  background:var(--holo);
  background-size:200% 100%;
  -webkit-background-clip:text; background-clip:text;
  color:transparent;
  animation: hueShift calc(14s / var(--motion, 1)) linear infinite;
}
@keyframes hueShift { to { background-position:200% 0; } }

/* outline display text (kinetic) */
.outline-text {
  color:transparent;
  -webkit-text-stroke: 1.5px var(--line-strong);
}

/* ============================================================
   LAYOUT
   ============================================================ */
.wrap { width:100%; max-width:var(--maxw); margin:0 auto; padding-inline:var(--gutter); }
.section { position:relative; padding-block: clamp(72px, 11vh, 150px); }
.section--tight { padding-block: clamp(48px,7vh,96px); }
/* Engerer Übergang nur auf einer Seite: Auf der Startseite schliessen Expertise,
   Vorgehen, Kunden und Feedback aneinander an. Mit zwei vollen Abständen lagen
   dazwischen 165–190 px (bei 900 px Fensterhöhe, auf hohen Bildschirmen bis
   300 px). Logo-Band davor und Kontaktband danach behalten den vollen Abstand. */
.section--eng-oben { padding-top: clamp(48px,7vh,96px); }
.section--eng-unten { padding-bottom: clamp(48px,7vh,96px); }

/* Helle "Bänder": leicht durchscheinend, damit die fixe Holo-Verlaufs-Ebene
   (inkl. Cursor-Glühen) überall auf hellem Grund konsistent durchscheint.
   Auf dunklem Theme bleiben sie undurchsichtig (kein Verlauf auf dunkel). */
/* Sektionen teilen sich einen durchgehenden Hintergrund — keine sichtbaren
   "Bänder"/Übergänge mehr (Tint entfernt). */
.band { background: transparent; }
html[data-dir="b"] .band { background: transparent; }
.grid { display:grid; gap: clamp(20px,3vw,40px); }
/* Spalten-Utilities statt Inline-Styles — Inline-Styles würden die Breakpoints
   unten aushebeln (Grund für die zerquetschten Karten auf dem Handy). */
.grid--3 { grid-template-columns: repeat(3,1fr); }
.grid--2 { grid-template-columns: repeat(2,1fr); }
@media (max-width: 900px) { .grid--3 { grid-template-columns: repeat(2,1fr); } }
@media (max-width: 620px) { .grid--3, .grid--2 { grid-template-columns: 1fr; } }
.eyebrow-row { display:flex; align-items:center; justify-content:space-between; gap:24px; flex-wrap:wrap; margin-bottom: clamp(28px,4vw,56px); }

/* ============================================================
   HOLO BACKGROUND (animated, cursor-reactive)
   ============================================================ */
.holo-bg {
  position:fixed; inset:0; z-index:0;
  pointer-events:none; overflow:hidden;
  opacity:calc(var(--bg-glow) * var(--glow-mult));
  transition:opacity .6s var(--ease);
}
.holo-blob {
  position:absolute; border-radius:50%;
  filter: blur(60px);
  mix-blend-mode: screen;
  will-change: transform;
}
html[data-dir="a"] .holo-blob, html[data-dir="c"] .holo-blob { mix-blend-mode: multiply; }

/* flächige Grundtönung auf hellem Grund — Verlauf überall dezent sichtbar,
   nicht nur an den Blob-Ecken */
html[data-dir="a"] .holo-bg, html[data-dir="c"] .holo-bg {
  background:
    radial-gradient(95vw 85vh at 82% -8%, color-mix(in srgb, var(--holo-peri) 72%, transparent), transparent 58%),
    radial-gradient(95vw 85vh at 8% 110%, color-mix(in srgb, var(--holo-pink) 66%, transparent), transparent 58%),
    radial-gradient(85vw 75vh at 52% 50%, color-mix(in srgb, var(--holo-sky) 52%, transparent), transparent 64%);
}
.holo-blob.b1 { width:46vw; height:46vw; left:-8vw; top:-10vw;
  background: radial-gradient(circle at 50% 50%, var(--holo-sky), transparent 68%);
  animation: drift1 calc(26s / var(--motion,1)) var(--ease) infinite alternate; }
.holo-blob.b2 { width:50vw; height:50vw; right:-12vw; top:6vw;
  background: radial-gradient(circle at 50% 50%, var(--holo-peri), transparent 66%);
  animation: drift2 calc(32s / var(--motion,1)) var(--ease) infinite alternate; }
.holo-blob.b3 { width:42vw; height:42vw; left:18vw; bottom:-16vw;
  background: radial-gradient(circle at 50% 50%, var(--holo-pink), transparent 66%);
  animation: drift3 calc(29s / var(--motion,1)) var(--ease) infinite alternate; }
.holo-blob.b4 { width:38vw; height:38vw; right:6vw; bottom:-10vw;
  background: radial-gradient(circle at 50% 50%, var(--holo-cream), transparent 64%);
  animation: drift1 calc(35s / var(--motion,1)) var(--ease) infinite alternate-reverse; }
.holo-cursor {
  position:absolute; width:34vw; height:34vw; border-radius:50%;
  background: radial-gradient(circle at 50% 50%, var(--holo-lav), transparent 60%);
  filter: blur(70px); mix-blend-mode:screen;
  transform: translate3d(var(--cx,50vw), var(--cy,50vh), 0) translate(-50%,-50%);
  transition: transform .35s cubic-bezier(.2,.8,.2,1);
  will-change: transform;
}
html[data-dir="a"] .holo-cursor, html[data-dir="c"] .holo-cursor { mix-blend-mode:multiply; opacity:1; width:42vw; height:42vw; }
html[data-cursor="0"] .holo-cursor { display:none; }

@keyframes drift1 { from{transform:translate(0,0) scale(1)} to{transform:translate(8vw,6vh) scale(1.15)} }
@keyframes drift2 { from{transform:translate(0,0) scale(1.1)} to{transform:translate(-7vw,8vh) scale(.92)} }
@keyframes drift3 { from{transform:translate(0,0) scale(.95)} to{transform:translate(6vw,-7vh) scale(1.2)} }

/* respect motion off */
html[data-motion="0"] .holo-blob, html[data-motion="0"] .grad-text { animation:none !important; }

#root { position:relative; z-index:1; }

/* page transition */
.page-enter { animation: pageIn .55s var(--ease) forwards; }
@keyframes pageIn { from { opacity:0; } to { opacity:1; } }
html[data-motion="0"] .page-enter { animation:none; }

/* ============================================================
   NAV
   ============================================================ */
.nav {
  position:fixed; top:0; left:0; right:0; z-index:60;
  display:flex; align-items:center; justify-content:space-between;
  padding: 18px var(--gutter);
  transition: background .4s var(--ease), padding .4s var(--ease), border-color .4s;
  border-bottom:1px solid transparent;
}
.nav.scrolled {
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border-bottom:1px solid var(--line);
  padding-block:12px;
}
.nav-links { display:flex; gap: clamp(18px,2vw,34px); align-items:center; }
.nav-link {
  font-size:15px; font-weight:600; letter-spacing:.01em;
  position:relative; padding:6px 2px; color:var(--text);
  background:none; border:none; cursor:pointer;
}
.nav-link::after {
  content:""; position:absolute; left:0; right:0; bottom:0; height:2px;
  background:var(--holo); transform:scaleX(0); transform-origin:left;
  transition: transform .35s var(--ease);
}
.nav-link:hover::after, .nav-link.active::after { transform:scaleX(1); }
.nav-link.active { color:var(--text); }
.nav-cta { margin-left:8px; }
.burger { display:none; background:none; border:none; cursor:pointer; flex-direction:column; align-items:center; justify-content:center; gap:5px; padding:0; width:44px; height:44px; margin-right:-8px; }
.burger span { width:24px; height:2px; background:var(--text); display:block; transition:.3s; }

/* Nav über dem dunklen Cover: hell & transparent */
.nav.on-cover { background:transparent !important; backdrop-filter:none !important; -webkit-backdrop-filter:none !important; border-color:transparent !important; }
.nav.on-cover .logo-bild, .nav.on-cover .nav-link { color:#fff; }
.nav.on-cover .burger span { background:#fff; }

/* Rechte Nav-Gruppe: mobiler CTA + Burger */
.nav-right { display:flex; align-items:center; gap:10px; margin-right:-8px; }
/* Der grosse "Anfragen"-Button steckt in .nav-links und ist ab 920px weg —
   ohne diesen kompakten Ersatz verschwindet der Haupt-CTA mobil komplett. */
.nav-cta-mobile {
  display:none; align-items:center; justify-content:center; min-height:44px; padding:0 18px;
  border-radius:999px; background:var(--holo); background-size:160% 160%; color:#1a1a1a;
  font-size:14px; font-weight:800; letter-spacing:.02em; text-transform:uppercase; cursor:pointer;
}
.nav.on-cover .nav-cta-mobile { color:#1a1a1a; }
/* Bei offenem Menü steht der grosse "Projekt anfragen"-Button im Overlay —
   der kompakte CTA in der Leiste wäre doppelt. */
.nav.menu-open .nav-cta-mobile { display:none; }

/* mobile menu */
.mobile-menu {
  position:fixed; inset:0; z-index:55; background:var(--bg);
  display:flex; flex-direction:column; justify-content:center; gap:8px;
  padding: calc(var(--gutter) + 64px) var(--gutter) var(--gutter);
  overflow-y:auto; overscroll-behavior:contain;
  transform:translateY(-100%); transition:transform .5s var(--ease);
}
.mobile-menu.open { transform:translateY(0); }
/* Nur die Menü-Links gross setzen — vorher traf der Selektor auch den
   "Projekt anfragen"-Button, dessen Text dadurch aus der Pille lief. */
.mobile-menu-links { display:flex; flex-direction:column; }
.mobile-menu-links a {
  text-align:left; cursor:pointer; color:var(--text);
  font-weight:800; text-transform:uppercase; letter-spacing:-.01em;
  font-size:clamp(30px,8vw,58px); line-height:1.1; padding:6px 0;
}
.mobile-menu-links a.is-active {
  background:var(--holo); background-size:200% 100%;
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
.mobile-menu-cta { margin-top:28px; }

/* ============================================================
   LOGO
   ============================================================ */
.logo { display:inline-flex; align-items:center; cursor:pointer; }
/* Das Originallogo (Backend/uploads/Logo_vektorisiert.svg), zerlegt in zwei
   Dateien mit identischer viewBox, die deckungsgleich übereinanderliegen:
   - logo-hash.svg: das "#" mit seinem festen Verlauf aus dem Logo. Das Original
     beschneidet ein eingebettetes Rasterbild mit der #-Form; das Rasterbild ist
     hier auf ein Drittel verkleinert und als JPEG eingebettet (weicher Verlauf,
     voll deckend). 5 KB statt 182 KB, die Kanten bleiben Vektor.
   - logo-wort.svg: die Wortmarke in Trade Gothic als Vektorpfade, als Maske
     eingesetzt. So kommt ihre Farbe aus `color`: Logofarbe #373836 auf hellem
     Grund, weiss auf dem dunklen Cover.
   Die Höhe ist die einzige Steuergrösse, die Breite folgt aus dem Seitenverhältnis. */
.logo-bild {
  position:relative; display:block; height:40px; aspect-ratio: 396.183 / 90.744;
  color:#373836;
}
.logo-bild::before, .logo-bild::after { content:""; position:absolute; inset:0; }
.logo-bild::before { background:url('assets/logo-hash.svg') center/contain no-repeat; }
.logo-bild::after {
  background:currentColor;
  -webkit-mask:url('assets/logo-wort.svg') center/contain no-repeat;
  mask:url('assets/logo-wort.svg') center/contain no-repeat;
}
html[data-dir="b"] .logo-bild { color:var(--text); }

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  --b-pad-y:15px; --b-pad-x:30px;
  position:relative; display:inline-flex; align-items:center; gap:10px;
  padding: var(--b-pad-y) var(--b-pad-x);
  font-weight:700; font-size:15px; letter-spacing:.02em;
  border:none; cursor:pointer; border-radius: 999px;
  text-transform:uppercase; overflow:hidden; isolation:isolate;
  transition: transform .35s var(--ease), color .35s var(--ease), box-shadow .35s;
}
.btn .lbl { position:relative; z-index:2; display:inline-flex; align-items:center; gap:8px; }
.btn .arrow { transition: transform .35s var(--ease); }
.btn:hover .arrow { transform: translateX(4px); }

/* primary = holo fill */
.btn-primary { color:#1a1a1a; background:var(--holo); background-size:160% 160%; }
.btn-primary::before {
  content:""; position:absolute; inset:0; z-index:1; background:var(--holo); background-size:160% 160%;
  animation: hueMove calc(8s / var(--motion,1)) linear infinite;
}
.btn-primary:hover { transform: translateY(-3px); box-shadow: 0 14px 34px -12px var(--holo-peri); }
@keyframes hueMove { 0%{background-position:0 0} 50%{background-position:100% 100%} 100%{background-position:0 0} }

/* outline */
.btn-outline { color:var(--text); background:transparent; border:1.5px solid var(--line-strong); }
.btn-outline::before { content:""; position:absolute; inset:0; z-index:1; background:var(--holo); transform:translateY(101%); transition:transform .4s var(--ease); }
.btn-outline:hover { color:#1a1a1a; border-color:transparent; }
.btn-outline:hover::before { transform:translateY(0); }

/* ghost text link */
.linkarrow { display:inline-flex; align-items:center; gap:8px; font-weight:700; cursor:pointer; background:none; border:none; color:var(--text); padding:4px 0; }
.linkarrow .ln { background-image:var(--holo); background-size:100% 2px; background-repeat:no-repeat; background-position:0 100%; padding-bottom:3px; transition: background-size .4s var(--ease); }
.linkarrow:hover .ln { background-size:100% 100%; -webkit-background-clip:text; background-clip:text; color:transparent; }
.linkarrow svg { transition:transform .35s var(--ease); }
.linkarrow:hover svg { transform:translateX(4px); }

/* ============================================================
   REVEAL (scroll)
   ============================================================ */
.reveal { opacity:0; transform: translateY(34px); transition: opacity .9s var(--ease), transform .9s var(--ease); }
.reveal.in { opacity:1; transform:none; }
html[data-motion="0"] .reveal { opacity:1; transform:none; transition:none; }

/* ============================================================
   CARDS
   ============================================================ */
.card {
  position:relative; background:var(--panel); border:1px solid var(--line);
  border-radius: var(--radius); padding: clamp(24px,3vw,38px);
  overflow:hidden; transition: transform .45s var(--ease), border-color .45s, box-shadow .45s;
}
.card::after { /* holo wash on hover */
  content:""; position:absolute; inset:0; background:var(--holo-soft); opacity:0;
  transition: opacity .5s var(--ease); pointer-events:none; mix-blend-mode:soft-light;
}
.card:hover { transform: translateY(-6px); border-color: transparent; box-shadow: 0 22px 50px -26px var(--holo-peri); }
.card:hover::after { opacity:.5; }
.card .idx { font-family:'Space Mono',monospace; font-size:13px; color:var(--text-dim); letter-spacing:.1em; }
/* Kartentext eine Stufe über .small: die Haltung-Karten tragen nur Titel und einen
   Satz, mit 14 px wirkte der Satz neben dem Titel verloren. */
.card .card-text { font-size:clamp(16px,1.3vw,18px); line-height:1.5; color:var(--text-soft); margin-bottom:0; }
.card .ic { width:48px; height:48px; display:grid; place-items:center; border-radius:12px; background:var(--holo-soft); margin-bottom:18px; }

/* service big list rows */
.srow { position:relative; display:grid; grid-template-columns: 64px 1fr auto; gap:20px; align-items:center;
  padding: clamp(22px,2.6vw,34px) 0; border-top:1px solid var(--line); cursor:pointer; }
.srow:last-child { border-bottom:1px solid var(--line); }
.srow .snum { font-family:'Space Mono',monospace; color:var(--text-dim); font-size:15px; }
.srow .stitle { font-size:clamp(26px,3.6vw,48px); font-weight:800; text-transform:uppercase; letter-spacing:-.01em; transition: transform .4s var(--ease), color .4s; line-height:1; }
.srow .sdesc { max-width:46ch; color:var(--text-soft); font-size:16px; max-height:0; opacity:0; overflow:hidden; transition: all .5s var(--ease); }
.srow:hover .stitle { transform: translateX(14px); }
.srow:hover .sdesc { max-height:120px; opacity:1; margin-top:10px; }
.srow .splus { width:46px; height:46px; border-radius:50%; border:1.5px solid var(--line); display:grid; place-items:center; transition:.4s var(--ease); }
.srow:hover .splus { background:var(--holo); border-color:transparent; transform:rotate(90deg); }

/* ============================================================
   BENTO — Leistungen
   ============================================================ */
.bento {
  display:grid; gap:16px; margin-top: clamp(28px,4vw,52px);
  grid-template-columns: 1.18fr 1fr 1fr;
  grid-template-areas:
    "konzept content content"
    "konzept betreuung schulung"
    "ads ads schulung";
}
.bento > .reveal { display:flex; min-width:0; }
.bento .c-konzept { grid-area:konzept; }
.bento .c-content { grid-area:content; }
.bento .c-schulung { grid-area:schulung; }
.bento .c-betreuung { grid-area:betreuung; }
.bento .c-ads { grid-area:ads; }

.bento-card {
  position:relative; overflow:hidden; isolation:isolate;
  flex:1; width:100%; min-height:210px;
  /* Untergrenze der Polsterung bei 26px statt 22px: unterhalb von ~1180px greift
     ohnehin nur noch der clamp-Minimalwert, und dort stand der Text zu dicht am Rand. */
  border-radius:24px; padding: clamp(26px,2.2vw,30px);
  /* flex-end: Seit die Icon-Kachel oben weg ist (Kundenwunsch 2026-10-05), bleibt der
     Text unten stehen. Mit space-between rutschte er als einziges Kind nach oben. */
  display:flex; flex-direction:column; justify-content:flex-end;
  border:1px solid var(--line); cursor:pointer; color:var(--text);
  transition: transform .45s var(--ease), box-shadow .45s var(--ease);
}
.bento .c-betreuung .bento-card, .bento .c-ads .bento-card, .bento .c-schulung .bento-card { min-height:240px; }
/* Karten mit Geisterwort bekommen unten ein reserviertes Band, damit das Wort nicht
   hinter dem Fliesstext liegt. Ohne die Reserve endet der Absatz (die Karte schiebt
   den Text per flex-end nach unten) genau dort, wo das Wort steht.
   :has() statt fester Kartenliste — so gilt die Regel automatisch für jede Karte,
   die künftig ein `wm` bekommt. */
.bento-card:has(.bento-wm) { padding-bottom: clamp(74px, 9vw, 116px); }
.bento-card:hover { transform: translateY(-5px); box-shadow: 0 26px 54px -30px rgba(20,16,40,.45); }

/* hover arrow badge */
.bento-arrow {
  position:absolute; top: clamp(22px,2.2vw,30px); right: clamp(22px,2.2vw,30px); z-index:2;
  width:38px; height:38px; border-radius:50%; display:grid; place-items:center;
  border:1.5px solid color-mix(in srgb, var(--ink) 22%, transparent);
  color:var(--ink); opacity:0; transform: translate(4px,-4px) rotate(-30deg);
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.bento-card:hover .bento-arrow { opacity:1; transform: translate(0,0) rotate(0deg); }

.bento-body { position:relative; z-index:2; }
/* hyphens statt des globalen overflow-wrap:break-word (Regel für h1–h3 weiter oben):
   „KANALBETREUUNG" wurde sonst hart umbrochen und liess ein einzelnes „G" auf der
   nächsten Zeile stehen.
   hyphens:manual statt auto, weil die automatischen Trennmuster an der falschen Stelle
   getrennt haben („KANALBETREU-UNG"). Die Trennstellen stehen jetzt als Weichtrennzeichen
   (U+00AD) in den Titeln in home.jsx — wer dort einen Titel ergänzt, muss die Trennstelle
   selbst setzen, sonst wird gar nicht getrennt. */
.bento-title { margin:0; font-size:clamp(20px,1.9vw,30px); font-weight:900; text-transform:uppercase; letter-spacing:-.012em; line-height:1.06; hyphens:manual; overflow-wrap:normal; }
.bento-desc { margin:14px 0 0; font-size:15px; line-height:1.5; color:var(--text-soft); max-width:42ch; }

/* watermark
   Liegt mit z-index:0 hinter dem Text (.bento-body hat z-index:2), kollidierte optisch
   aber mit dem Fliesstext. Deshalb an den unteren Rand gerückt statt mittig hinter den
   Absatz, und schwächer eingefärbt (Werte bei den Varianten weiter unten). */
.bento-wm {
  position:absolute; left:0; right:0; bottom:-.12em; z-index:0;
  text-align:center; font-weight:900; text-transform:uppercase; letter-spacing:-.04em;
  font-size:clamp(64px,9vw,150px); line-height:1; pointer-events:none; white-space:nowrap;
}

/* variants */
.bento-card.v-holo {
  border-color:transparent; color:var(--ink);
  background: linear-gradient(155deg,
    var(--holo-sky) 0%, var(--holo-peri) 34%, var(--holo-lav) 62%, var(--holo-pink) 100%);
}
.bento-card.v-holo .bento-desc { color: rgba(26,22,38,.74); }
.bento-card.v-holo .bento-wm { color: rgba(255,255,255,.14); }

.bento-card.v-light { background: color-mix(in srgb, var(--bg-2) 70%, #fff); }

.bento-card.v-blush {
  border-color:transparent; color:var(--ink);
  background: linear-gradient(140deg, var(--holo-rose) 0%, var(--holo-blush) 100%);
}
.bento-card.v-blush .bento-desc { color: rgba(60,30,40,.7); }

.bento-card.v-lavender {
  border-color:transparent; color:var(--ink);
  background: linear-gradient(140deg,
    color-mix(in srgb, var(--holo-sky) 30%, #fff) 0%,
    color-mix(in srgb, var(--holo-lav) 45%, #fff) 100%);
}
.bento-card.v-lavender .bento-desc { color: rgba(40,36,60,.68); }

.bento-card.v-dark {
  border-color:transparent; color:#fff; background:#0e0e12;
}
.bento-card.v-dark .bento-arrow { border-color: rgba(255,255,255,.3); color:#fff; }
.bento-card.v-dark .bento-desc { color: rgba(255,255,255,.66); }
.bento-card.v-dark .bento-wm { color: rgba(255,255,255,.05); }

@media (max-width: 880px) {
  .bento {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "konzept content"
      "betreuung schulung"
      "ads ads";
  }
}
@media (max-width: 560px) {
  .bento {
    grid-template-columns: 1fr;
    grid-template-areas: "konzept" "content" "betreuung" "schulung" "ads";
  }
  /* Einspaltig umschliesst jede Karte ihren Text, oben beginnend. Mit der früheren
     Mindesthöhe von 190 px und dem Text unten (flex-end) hatten kurze Karten wie
     «Content Creation» oben eine grosse Leerfläche, lange keine: ungleiche Abstände
     (Rückmeldung vom iPhone, 2026-10-13). Am Desktop bleibt der Text unten. */
  .bento-card, .bento .c-betreuung .bento-card, .bento .c-ads .bento-card, .bento .c-schulung .bento-card { min-height:0; justify-content:flex-start; }
}

/* ============================================================
   MARQUEE
   ============================================================ */
/* ============================================================
   TEAM
   ============================================================ */
.team-grid { display:grid; grid-template-columns: repeat(3,1fr); gap: clamp(16px,2vw,28px); }
.team-card { position:relative; }
.team-photo { position:relative; aspect-ratio: 3/4; border-radius: var(--radius); overflow:hidden; background:var(--bg-2); border:1px solid var(--line); }
.team-card:hover .team-photo { box-shadow: 0 24px 60px -30px var(--holo-pink); }
/* ---- Umschlag-Karte: Businessfoto vorne, Freizeitfoto hinten ----
   overflow:hidden auf .team-photo würde die gedrehte Rückseite beschneiden, deshalb
   liegt der 3D-Kontext auf .team-flip und die Rundung auf den beiden Seiten. */
.team-photo--flip { overflow:visible; background:transparent; border:none; perspective:1400px; cursor:pointer; }
.team-photo--flip:focus-visible { outline:2px solid var(--holo-peri); outline-offset:4px; border-radius:var(--radius); }
.team-flip { position:relative; width:100%; height:100%; transform-style:preserve-3d;
  transition: transform .7s cubic-bezier(.22,.72,.24,1); }
.team-photo--flip.is-flipped .team-flip { transform: rotateY(180deg); }
.team-face { position:absolute; inset:0; backface-visibility:hidden; -webkit-backface-visibility:hidden;
  border-radius: var(--radius); overflow:hidden; background:var(--bg-2); border:1px solid var(--line); }
.team-face--back { transform: rotateY(180deg); }
.team-face picture { display:block; width:100%; height:100%; }
.team-card:hover .team-photo--flip .team-face { box-shadow: 0 24px 60px -30px var(--holo-pink); }
/* Hinweis, dass die Karte umschlagbar ist — sonst rät niemand, dass man klicken kann.
   Bewusst im Ruhezustand sichtbar statt erst bei Hover: auf dem Desktop war die
   Klickbarkeit vorher unentdeckbar, wer nie über die Karte fuhr, sah nur ein Foto. */
.team-flip-hint { position:absolute; right:12px; bottom:12px; z-index:3;
  display:inline-flex; align-items:center; gap:6px;
  font-family:'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-weight:700; font-size:11px; letter-spacing:.12em; text-transform:uppercase;
  padding:6px 11px; border-radius:999px; background:rgba(255,255,255,.88); color:#1a1a1a;
  backdrop-filter:blur(6px); opacity:.92;
  transition:opacity .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
  pointer-events:none; }
.team-card:hover .team-flip-hint, .team-photo--flip:focus-visible .team-flip-hint {
  opacity:1; transform:translateY(-2px); box-shadow:0 6px 18px -8px rgba(0,0,0,.35); }
/* Zweites Signal ohne Mauszeiger: nur die umschlagbare Karte bekommt den Holo-Rand.
   Personen ohne Freizeitfoto rendern ohne .team-photo--flip und bleiben schlicht. */
.team-photo--flip .team-face--front::after {
  content:""; position:absolute; inset:0; border-radius:var(--radius); pointer-events:none;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--holo-pink) 55%, transparent); }
/* Wer Bewegung reduziert, bekommt einen harten Wechsel statt der Drehung. */
@media (prefers-reduced-motion: reduce) { .team-flip { transition:none; } }

.team-name { margin-top:16px; font-size:22px; font-weight:800; text-transform:uppercase; }
.team-role { color:var(--text-soft); font-size:15px; }
.team-socials { display:flex; gap:10px; margin-top:10px; }
.team-socials a { width:34px; height:34px; border:1px solid var(--line); border-radius:8px; display:grid; place-items:center; transition:.3s; font-size:13px; font-weight:700; }
/* Die Kanal-Logos (SocialGlyph in ui.jsx) statt zweier Buchstaben: «In» und «Li»
   waren nicht als Instagram und LinkedIn erkennbar (Kundenrückmeldung 2026-10-07). */
.team-socials svg { width:17px; height:17px; }
.team-socials a:hover { background:var(--holo); border-color:transparent; color:#1a1a1a; }

/* Foto-Fallback (Initialen) + Hinzufügen-Karte + Upload-Dropzone */
.team-ph-fallback { position:absolute; inset:0; display:grid; place-items:center; background:var(--holo); }
.team-ph-fallback span { font-size:clamp(40px,5vw,56px); font-weight:900; color:#1a1a1a; }
.team-card.team-add { cursor:pointer; }
.team-add-photo { border:1.5px dashed var(--line-strong); display:grid; place-items:center; background:transparent; transition:border-color .3s; }
.team-card.team-add:hover .team-add-photo { border-color:var(--holo-peri); }
.team-add-photo .plus { width:64px; height:64px; border-radius:50%; background:var(--holo); display:grid; place-items:center; color:#1a1a1a; }
.dropzone { border:1.5px dashed var(--line-strong); border-radius:14px; padding:16px 18px; cursor:pointer; transition:border-color .3s; display:flex; align-items:center; gap:14px; color:var(--text-soft); }
.dropzone:hover { border-color:var(--holo-peri); }
.dropzone .dz-prev { width:54px; height:54px; border-radius:12px; object-fit:cover; flex:0 0 auto; }
.dropzone .dz-icon { width:44px; height:44px; border-radius:10px; background:var(--holo-soft); display:grid; place-items:center; color:#1a1a1a; flex:0 0 auto; }

/* ============================================================
   IMAGE / VIDEO PLACEHOLDER (Drop zones)
   ============================================================ */
.media-ph {
  position:relative; border-radius: var(--radius); overflow:hidden;
  background:
    repeating-linear-gradient(45deg, transparent, transparent 12px, color-mix(in srgb, var(--text) 5%, transparent) 12px, color-mix(in srgb, var(--text) 5%, transparent) 13px),
    var(--bg-2);
  border:1.5px dashed var(--line-strong);
  display:grid; place-items:center; color:var(--text-dim);
}
.media-ph .ph-inner { text-align:center; padding:24px; }
.media-ph .ph-tag { font-family:'Space Mono',monospace; font-size:12px; letter-spacing:.14em; text-transform:uppercase; }
.media-ph .ph-play { width:74px; height:74px; border-radius:50%; background:var(--holo); display:grid; place-items:center; margin:0 auto 16px; box-shadow:0 12px 40px -12px var(--holo-peri); }

/* ============================================================
   STATS
   ============================================================ */
.stats { display:grid; grid-template-columns:repeat(4,1fr); gap: clamp(16px,2vw,32px); }
.stat .num { font-size:clamp(40px,5.5vw,76px); font-weight:900; line-height:1; letter-spacing:-.02em; }
.stat .lab { color:var(--text-soft); font-size:14px; margin-top:6px; text-transform:uppercase; letter-spacing:.06em; }

/* ============================================================
   FORM
   ============================================================ */
.field { position:relative; margin-bottom:22px; }
.field input, .field textarea {
  width:100%; background:transparent; border:none; border-bottom:1.5px solid var(--line);
  padding:14px 0; font-size:18px; color:var(--text); font-family:inherit; outline:none;
  transition: border-color .3s;
}
.field textarea { resize:vertical; min-height:120px; }
.field label { position:absolute; left:0; top:14px; color:var(--text-dim); pointer-events:none; transition:.3s var(--ease); }
.field input:focus, .field textarea:focus { border-image: var(--holo) 1; }
.field input:focus + label, .field textarea:focus + label,
.field input:not(:placeholder-shown) + label, .field textarea:not(:placeholder-shown) + label {
  top:-12px; font-size:12px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-soft);
}

/* ============================================================
   FOOTER
   ============================================================ */
/* z-index:4 — über .reveal-stack (3) und dem fixen Cover .intro-fixed (1).
   Ohne das legt sich auf der Startseite das fixierte Cover über den Footer:
   Hintergrund und .foot-nav verschwinden, nur die Kinder mit z-index:2
   (.foot-mega, .footer-bottom) bleiben sichtbar. Sichtbar wird das, sobald
   <main class="page-enter"> keinen eigenen Stacking-Context mehr bildet —
   also bei `prefers-reduced-motion: reduce`, wo die pageIn-Animation entfällt.
   Der Abstand nach oben ist bewusst padding statt margin: ein Margin wäre
   durchsichtig und liesse auf der Startseite das Cover als Streifen durch. */
.footer { position:relative; z-index:4; background:var(--ink); color:#f4f3f0; padding: clamp(56px,5vw,76px) 0 clamp(16px,1.6vw,24px); overflow:hidden; }
html[data-dir="b"] .footer { background:#08080a; }
.footer a { color:#f4f3f0; }
.footer .foot-grid { display:grid; grid-template-columns: 1.4fr 1fr 1fr; gap: clamp(28px,4vw,60px); position:relative; z-index:2; }
.footer .foot-big { font-size:clamp(40px,7vw,100px); font-weight:900; text-transform:uppercase; line-height:.9; letter-spacing:-.02em; }
.footer .col-h { font-family:'Space Mono',monospace; font-size:12px; letter-spacing:.16em; text-transform:uppercase; color:#9a9893; margin-bottom:16px; }
.footer .fl { display:block; padding:6px 0; color:#cfcdc8; transition:.3s; }
.footer .fl:hover { color:#fff; }
.footer-bottom { display:flex; justify-content:space-between; flex-wrap:wrap; gap:10px 16px; margin-top:18px; padding-top:16px; border-top:1px solid rgba(255,255,255,.14); position:relative; z-index:2; color:#a8a6a1; font-size:14px; }
.footer .foot-lead { font-size:clamp(30px,3.6vw,52px); font-weight:900; text-transform:uppercase; line-height:.95; letter-spacing:-.02em; margin-top:10px; }
.footer-bottom .fb-legal { display:flex; gap:8px 22px; flex-wrap:wrap; }
.footer-bottom .fl { display:inline-flex; align-items:center; min-height:44px; padding:0; cursor:pointer; color:#cfcdc8; font-size:14px; }

/* Footer-Navigation — identische Struktur auf allen Breiten, nur andere
   Spaltenzahl. Bewusst nicht mehr in Display-Grösse: sie soll als Menü lesbar
   sein und nicht mit dem "BE VISIBLE WITH US"-Schriftzug darunter konkurrieren. */
.foot-nav { padding-bottom: clamp(16px,1.8vw,24px); border-bottom:1px solid rgba(255,255,255,.12); }
.foot-nav-list { list-style:none; margin:0; padding:0;
  display:flex; flex-wrap:wrap; gap:2px clamp(20px,3vw,44px); }
.foot-nav-link { position:relative; display:inline-flex; align-items:center; min-height:44px; cursor:pointer;
  font-weight:800; text-transform:uppercase; letter-spacing:-.005em; line-height:1.1;
  font-size: clamp(17px, 1.5vw, 22px); color:#cfcdc8; -webkit-text-fill-color:#cfcdc8;
  transition: color .3s var(--ease), -webkit-text-fill-color .3s var(--ease); }
.foot-nav-link::after { content:""; position:absolute; left:0; bottom:9px; height:3px; width:0; background:var(--holo); transition: width .4s var(--ease); }
.foot-nav-link:hover, .foot-nav-link.is-active { color:#fff; -webkit-text-fill-color:#fff; }
.foot-nav-link.is-active::after, .foot-nav-link:hover::after { width:100%; }
/* Handy: zwei Spalten statt Riesen-Typo — kompakt, aber mit 44px Tap-Höhe */
@media (max-width:640px){
  .foot-nav-list { display:grid; grid-template-columns:1fr 1fr; gap:0 18px; }
  .foot-nav-link { font-size:17px; }
  .footer-bottom { flex-direction:column; align-items:flex-start; gap:2px; }
}

/* Riesen-Schriftzug ganz unten — gestapelt, gestaffelt eingeblendet */
.foot-mega { position:relative; z-index:2; width:100%; max-width:var(--maxw); margin-inline:auto; overflow:hidden;
  padding: clamp(8px,1.2vw,16px) var(--gutter) clamp(4px,.8vw,12px); text-align:left; }
.fm-word { display:block; color:#fff; font-weight:900; text-transform:uppercase; letter-spacing:-.03em;
  line-height:.9; font-size: clamp(34px, 7.4vw, 112px); }
/* "armed" = JS aktiv → Wörter erst versteckt, dann nacheinander herein */
.foot-mega.armed .fm-word { opacity:0; transform: translateY(46px); }
.foot-mega.armed.in .fm-word { animation: fmWordIn .72s cubic-bezier(.2,.85,.2,1) forwards; animation-delay: calc(var(--i) * 150ms); }
@keyframes fmWordIn { from { opacity:0; transform: translateY(46px); } to { opacity:1; transform:none; } }

/* ============================================================
   PILL / TAG
   ============================================================ */
.pill { display:inline-flex; align-items:center; gap:8px; padding:8px 16px; border:1px solid var(--line); border-radius:999px; font-size:13px; font-weight:600; letter-spacing:.02em; }
.pill.holo { background:var(--holo-soft); border-color:transparent; color:#1a1a1a; }

/* page header */
.page-hero { padding-top: clamp(130px,18vh,210px); padding-bottom: clamp(40px,6vw,80px); }

/* ============================================================
   PROJECTS
   ============================================================ */
.proj-grid { display:grid; grid-template-columns: repeat(2,1fr); gap: clamp(16px,2vw,30px); }
.proj { position:relative; border-radius:var(--radius); overflow:hidden; cursor:pointer; }
/* position:relative, damit die Bildzahl-Marke der Galerie darin sitzt; overflow
   kommt von .proj, die Rundung gilt also auch fuer das Bild. */
.proj .proj-media { position:relative; aspect-ratio: 4/3; }
/* Seit die Projekte aus dem CMS kommen, hat die Karte mehr als Titel und Tags:
   Kunde/Jahr, Beschreibung und Link stehen untereinander statt nebeneinander. */
.proj .proj-meta { display:flex; flex-direction:column; align-items:flex-start; margin-top:14px; gap:5px; }
.proj h3 { font-size:clamp(20px,2.4vw,30px); text-transform:uppercase; transition:.4s; }
.proj:hover h3 { background:var(--holo); -webkit-background-clip:text; background-clip:text; color:transparent; }
.proj .proj-cat { font-family:'Space Mono',monospace; font-size:12px; color:var(--text-dim); letter-spacing:.1em; }
.proj .proj-client { font-size:14px; color:var(--text-soft); font-weight:600; }
.proj .proj-desc { margin:4px 0 0; font-size:15px; line-height:1.5; color:var(--text-soft); max-width:46ch; }
.proj .proj-link { margin-top:4px; font-size:14px; font-weight:700; border-bottom:1px solid var(--line-strong); padding-bottom:1px; }
.proj .proj-link:hover { border-color:transparent; background:var(--holo); -webkit-background-clip:text; background-clip:text; color:transparent; }
/* Marke fuer mehrere Bilder — liegt auf dem Titelbild, nicht in der Textspalte. */
.proj .proj-count { position:absolute; right:10px; bottom:10px; z-index:2;
  font-family:'Space Mono',monospace; font-size:10px; letter-spacing:.1em; text-transform:uppercase;
  padding:5px 9px; border-radius:999px; background:rgba(255,255,255,.88); color:#1a1a1a;
  backdrop-filter:blur(6px); }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 920px) {
  body { font-size:17px; }
  .nav-links { display:none; }
  .burger { display:flex; }
  .nav-cta-mobile { display:inline-flex; }
  .team-grid { grid-template-columns: 1fr 1fr; }
  .stats { grid-template-columns: 1fr 1fr; }
  .footer .foot-grid { grid-template-columns:1fr; }
  .proj-grid { grid-template-columns:1fr; }
  .two-col { grid-template-columns:1fr !important; }
}
@media (max-width: 560px) {
  .srow { grid-template-columns: 40px 1fr; }
  .srow .splus { display:none; }
  /* Team einspaltig, dafür flacheres Bildformat — 3/4 auf voller Breite ergab
     pro Person ~470px Höhe und damit einen sehr langen Scroll. */
  .team-grid { grid-template-columns:1fr; }
  .team-photo { aspect-ratio: 4/5; }
  /* Titel und Tags eines Projekts untereinander statt nebeneinander */
  .proj .proj-meta { flex-direction:column; align-items:flex-start; gap:4px; }
  /* Wasserzeichen ganz weg: Auf einspaltigen Karten bleibt zwischen Titel, Absatz
     und Kartenrand kein Platz, in dem es nicht dem Text in die Quere käme. */
  .bento-wm { display:none; }
  /* Polsterung eine Stufe enger als am Desktop, sonst bleibt vom Textmass zu wenig */
  .bento-card { padding:24px; }
  /* Die Reserve unten für das Geisterwort braucht es hier nicht, das Wort ist
     ausgeblendet. Ohne diese Zeile gewann die spezifischere :has()-Regel, und
     «Strategie» und «Bezahlte Kampagnen» hatten 75 px leeres Band (Funktionstest F-08). */
  .bento-card:has(.bento-wm) { padding-bottom:24px; }
}

/* ── Lesbarkeit auf dem Handy: Micro-Typo eine Stufe grösser ───────────────── */
@media (max-width: 640px) {
  .small { font-size:15px; }
  .kicker { font-size:14px; }
  .team-role { font-size:16px; }
  .logo-bild { height:36px; }
  .bento-desc { font-size:16px; }
  /* Tap-Targets auf mindestens 44px */
  .pill { min-height:44px; padding:8px 18px; }
  .team-socials a { width:44px; height:44px; }
}

/* Sehr schmale Geräte (iPhone SE 1, 320px): Kopfzeile passt sonst nicht
   nebeneinander — Logo kleiner, CTA und Ränder kompakter. Der Claim im Logo
   bleibt stehen: er ist Teil der Bildmarke und lässt sich nicht einzeln
   ausblenden, ohne das Logo zu zerschneiden. */
@media (max-width: 380px) {
  .nav { padding-inline: 14px; }
  .logo-bild { height:31px; }
  /* Schmaler und kleiner gesetzt, aber nicht flacher — 44px Tap-Höhe bleibt
     auch auf dem iPhone SE stehen, die Breite gibt stattdessen nach. */
  .nav-cta-mobile { padding:0 13px; font-size:12.5px; }
  .nav-right { gap:6px; }
}

/* reduce motion — also covers offscreen capture envs that report reduced-motion */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration:.001ms !important; animation-iteration-count:1 !important; }
  .reveal { opacity:1 !important; transform:none !important; transition:none !important; }
  body, .holo-bg, .nav { transition:none !important; }
  .page-enter { animation:none !important; }
  /* gestaffelte Footer-Einblendung soll sichtbar bleiben */
  .foot-mega.armed.in .fm-word { animation-duration: .72s !important; }
}

/* ============================================================
   CINEMATIC COVER — fixes Teamfoto im Hintergrund,
   restlicher Inhalt schiebt sich beim Scrollen sauber darüber
   ============================================================ */
.intro { position:relative; }
.intro-fixed { position:fixed; inset:0; z-index:1; overflow:hidden; display:grid; place-items:center; }
.intro-spacer { height:100vh; }
.reveal-stack { position:relative; z-index:3; background:var(--bg); }
/* heller Verlauf direkt auf dem reveal-stack (deckt den fixen Cover ab UND
   zeigt den Verlauf): viewport-fixiert, mit Cursor-Radial über --cx/--cy */
html[data-dir="a"] .reveal-stack, html[data-dir="c"] .reveal-stack {
  background-color: var(--bg);
  background-image:
    radial-gradient(42vw 42vw at var(--cx,50%) var(--cy,45%), color-mix(in srgb, var(--holo-lav) 42%, transparent), transparent 58%),
    radial-gradient(95vw 88vh at 84% 6%, color-mix(in srgb, var(--holo-peri) 34%, transparent), transparent 58%),
    radial-gradient(95vw 88vh at 6% 96%, color-mix(in srgb, var(--holo-pink) 32%, transparent), transparent 58%),
    radial-gradient(85vw 78vh at 52% 50%, color-mix(in srgb, var(--holo-sky) 24%, transparent), transparent 64%);
  background-attachment: fixed, fixed, fixed, fixed;
  background-repeat: no-repeat;
}
html[data-dir="b"] .reveal-stack { background:var(--bg); }
.cover-photo { position:absolute; inset:0; z-index:0; will-change:transform; }
.cover-photo img { width:100%; height:100%; object-fit:cover; object-position:center 26%; display:block; }
.cover-photo .ph-fallback { position:absolute; inset:0; background:
   radial-gradient(60% 70% at 30% 20%, var(--holo-peri), transparent 70%),
   radial-gradient(70% 80% at 80% 60%, var(--holo-pink), transparent 70%), #2a2a33; }
/* Dichter als frueher: der Schriftzug wirkte truebe, und die Haelfte davon lag nicht
   an der Schrift, sondern am zu hellen Schleier ueber dem Foto. Mehr Dichte heisst
   mehr Kontrast gegen die weisse Wortmarke. */
.cover-scrim { position:absolute; inset:0; z-index:1; pointer-events:none; background:
   radial-gradient(120% 95% at 50% 30%, rgba(10,10,18,.18) 0%, rgba(8,8,16,.72) 100%),
   linear-gradient(180deg, rgba(8,8,16,.52) 0%, rgba(8,8,16,.18) 38%, rgba(8,8,16,.78) 100%); }
.cover-content { position:relative; z-index:2; text-align:center; width:100%; max-width: min(1500px, 94vw);
   padding-inline:var(--gutter); will-change:transform,opacity; }
/* Kein festes px-Minimum: mit clamp(52px, …) lief "#BEVISIBLE" bei nowrap auf
   320px-Geräten über den Rand hinaus und wurde abgeschnitten. */
.cover-content .hero-word { font-size: clamp(34px, calc(11.4vw * var(--scale)), 176px); filter: drop-shadow(0 8px 40px rgba(0,0,0,.35)); line-height:.86; white-space:nowrap; }
/* Die Glyphe sitzt als inline-block minimal unter der Grundlinie, damit sie optisch
   auf einer Hoehe mit den Versalien steht — deshalb hier NICHT auf baseline zuruecksetzen. */
.cover-content .hero-word .hero-word-text { vertical-align:baseline; }
.cover-kicker { display:inline-flex; align-items:center; gap:.6em;
   font-family:'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif; font-weight:700;
   font-size:13px; letter-spacing:.14em; text-transform:uppercase; color:rgba(255,255,255,.9); }
.cover-kicker::before { content:"#"; background:var(--holo); -webkit-background-clip:text; background-clip:text; color:transparent; font-weight:800; }
.cover-content .hero-claim { color:#fff; text-shadow:0 4px 30px rgba(0,0,0,.4); }
.cover-content .btn-outline { color:#fff; border-color:rgba(255,255,255,.6); }
.cover-content .btn-outline:hover { color:#1a1a1a; border-color:transparent; }
.cover-content .floats { inset:-150px -2vw; z-index:0; }
.cover-content .somark { background:rgba(255,255,255,.12); border-color:rgba(255,255,255,.25); color:#fff; backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px); }
.cover-content .somark:hover { color:#1a1a1a; }

/* ============================================================
   KUNDEN-FEEDBACK — Kundenstimmen als gestapelter Slider
   ============================================================ */
/* Buehne. Feste Hoehe, weil die Karten absolut positioniert sind und sonst keinen
   Platz beanspruchen wuerden. touch-action:pan-y laesst dem Browser die Y-Achse —
   die X-Achse werten wir selbst aus (siehe testimonials.jsx). */
.tstack {
  --tcard-w: 364px; --tcard-h: 480px; --tstage-h: 560px;
  /* Versatz waechst mit der Breite mit: bei 1440px faechert der Stapel weit auf,
     bei 800px rueckt er zusammen, ohne aus dem .wrap zu laufen. */
  --t1: clamp(120px, 14vw, 205px); --t2: clamp(200px, 25vw, 360px);
  --cut: clamp(22px, calc(14px + var(--radius) * 1.6), 40px);
  --tclip: polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, 0 100%);
  position:relative; height:var(--tstage-h); margin-top: clamp(8px,1.6vw,20px);
  touch-action: pan-y; user-select:none;
}
.tstack:focus-visible { outline:2px solid var(--holo-peri); outline-offset:6px; border-radius:var(--radius); }

.tstack-item {
  position:absolute; left:50%; top:50%; width:var(--tcard-w); height:var(--tcard-h);
  translate: calc(-50% + var(--tx) + var(--dragx, 0px)) calc(-50% + var(--ty));
  rotate: var(--rot); scale: var(--sc); opacity: var(--op); z-index: var(--z);
  transition: translate .44s var(--ease), rotate .44s var(--ease),
              scale .44s var(--ease), opacity .44s var(--ease);
}
/* Vorzeichen der Drehung folgt dem X-Versatz, damit der Stapel nach aussen
   auffaechert statt sich zu verschraenken. */
.tstack-item[data-pos="0"]     { --tx:0px;    --ty:0px;  --rot:0deg;    --sc:1;   --op:1;   --z:30; }
.tstack-item[data-pos="1"]     { --tx:var(--t1);          --ty:22px; --rot:4deg;  --sc:.92; --op:.9;  --z:20; }
.tstack-item[data-pos="-1"]    { --tx:calc(var(--t1) * -1); --ty:22px; --rot:-4deg; --sc:.92; --op:.9;  --z:20; }
.tstack-item[data-pos="2"]     { --tx:var(--t2);          --ty:46px; --rot:7deg;  --sc:.84; --op:.55; --z:10; }
.tstack-item[data-pos="-2"]    { --tx:calc(var(--t2) * -1); --ty:46px; --rot:-7deg; --sc:.84; --op:.55; --z:10; }
.tstack-item[data-pos="far-r"],
.tstack-item[data-pos="far-l"] { --ty:50px; --sc:.8; --op:0; --z:1; pointer-events:none; visibility:hidden;
  transition: translate .44s var(--ease), rotate .44s var(--ease), scale .44s var(--ease),
              opacity .44s var(--ease), visibility 0s linear .44s; }
.tstack-item[data-pos="far-r"] { --tx:160px;  --rot:8deg; }
.tstack-item[data-pos="far-l"] { --tx:-160px; --rot:-8deg; }

/* Waehrend des Wischens der Karte nicht hinterherlaufen lassen */
.tstack[data-dragging="true"] .tstack-item { transition:none; }

/* Rahmenschicht: 1px Flaeche in --line hinter der Inhaltsflaeche. Ein echtes border
   wuerde der Schraegkante nicht folgen (border haelt sich an die Border-Box, nicht
   an den Zuschnitt) — so ist der Rahmen auf allen fuenf Kanten gleich stark. */
.tcard { position:relative; z-index:1; width:100%; height:100%;
  background:var(--line); padding:1px;
  border-radius: calc(var(--radius) * 2); clip-path: var(--tclip);
  transition: background .44s var(--ease); }
.tcard-in { height:100%; background:var(--panel); position:relative; overflow:hidden;
  border-radius: calc(var(--radius) * 2); clip-path: var(--tclip);
  padding: 26px 28px; display:flex; flex-direction:column;
  transition: background .44s var(--ease), color .44s var(--ease); }
.tcard-in::after { content:""; position:absolute; inset:0; background:var(--holo-soft);
  opacity:0; mix-blend-mode:soft-light; transition:opacity .5s; pointer-events:none; }
.tstack-item:not([data-pos="0"]):hover .tcard-in::after { opacity:.4; }

/* Versetzte Schattenflaeche statt box-shadow — clip-path wuerde einen Schatten
   mit abschneiden. Nur die aktive Karte wirft ihn. */
.tcard-sh { position:absolute; inset:0; z-index:0;
  border-radius: calc(var(--radius) * 2); clip-path: var(--tclip);
  translate: 10px 13px; background: color-mix(in srgb, var(--holo-peri) 42%, transparent);
  opacity:0; transition: opacity .44s var(--ease), translate .3s var(--ease); }
.tstack-item[data-pos="0"] .tcard-sh { opacity:1; }
.tstack-item[data-pos="0"]:hover .tcard-sh { translate: 14px 18px; }

/* Klickflaeche der Nachbarkarten */
.tcard-hit { position:absolute; inset:0; z-index:2; border:none; background:none; cursor:pointer; padding:0; }

.tcard .quote { font-size:36px; line-height:.6; font-weight:900;
  background:var(--holo); -webkit-background-clip:text; background-clip:text; color:transparent; }
/* Eine Schriftgroesse fuer alle Karten: Im Stapel sind Nachbarn sichtbar, gestufte
   Groessen nebeneinander wuerden auffallen. line-clamp ist die Notbremse — der Server
   erlaubt 2000 Zeichen, die 8 Bestandstexte liegen alle darunter. */
.tcard .qtext { margin-top:14px; font-size:15.5px; line-height:1.5; color:var(--text); flex:1;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:13; line-clamp:13; overflow:hidden; }
.tmeta { display:flex; align-items:center; gap:14px; margin-top:20px; padding-top:16px; border-top:1px solid var(--line); }
.tavatar { width:46px; height:46px; border-radius:50%; background:var(--holo); display:grid; place-items:center;
  font-weight:800; font-size:16px; color:#1a1a1a; flex:0 0 auto; }
.tavatar img { width:100%; height:100%; object-fit:cover; border-radius:50%; }
.tname { font-weight:800; line-height:1.15; }
.trole { color:var(--text-soft); font-size:13px; }
.tstars { display:flex; gap:3px; margin-top:12px; color:var(--holo-pink); }

/* ---- Aktive Karte im Holo-Verlauf ----
   Auf dem Verlauf verschwinden mehrere Elemente, die sonst selbst holo-farbig sind
   (Quote-Glyphe, Sterne) — die bekommen hier dunkle Werte. Gleiches Muster wie bei
   .bento-card.v-holo weiter oben. */
.tstack-item[data-pos="0"] .tcard { background:transparent; }
.tstack-item[data-pos="0"] .tcard-in {
  background: linear-gradient(155deg, var(--holo-sky) 0%, var(--holo-peri) 34%,
                              var(--holo-lav) 62%, var(--holo-pink) 100%);
  color: var(--ink);
}
.tstack-item[data-pos="0"] .quote { background:none; -webkit-text-fill-color: rgba(26,22,38,.3); color: rgba(26,22,38,.3); }
.tstack-item[data-pos="0"] .qtext { color: rgba(26,22,38,.92); }
.tstack-item[data-pos="0"] .tstars { color: rgba(26,22,38,.72); }
.tstack-item[data-pos="0"] .tmeta { border-top-color: rgba(26,22,38,.22); }
.tstack-item[data-pos="0"] .tname { color: var(--ink); }
.tstack-item[data-pos="0"] .trole { color: rgba(26,22,38,.72); }
.tstack-item[data-pos="0"] .tavatar { background: rgba(255,255,255,.88); }

/* Wer Bewegung reduziert, bekommt einen Positionssprung statt der Fahrt. Der globale
   reduced-motion-Block weiter oben schaltet nur animation ab, keine transition. */
@media (prefers-reduced-motion: reduce) {
  .tstack-item { transition: opacity .15s linear !important; }
  .tstack { --dragx: 0px !important; }
}

/* Nur fuer Screenreader */
.tvh { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap; border:0; }

/* Positionsanzeige — anders als frueher auch am Desktop, weil ohne Scrollbar sonst
   nichts die Position im Stapel verraet. */
.tdots { display:flex; gap:8px; justify-content:center; margin-top:4px; }
.tdots button { width:44px; height:44px; padding:0; border:none; background:none; cursor:pointer;
  display:grid; place-items:center; }
.tdots button::before { content:""; width:8px; height:8px; border-radius:50%;
  background:var(--line-strong); opacity:.28; transition: opacity .3s, transform .3s var(--ease); }
.tdots button.on::before { opacity:1; transform:scale(1.5); background:var(--holo-peri); }
.tdots button:focus-visible { outline:2px solid var(--holo-peri); outline-offset:-6px; border-radius:50%; }

/* Pfeile und Punkte in einer Reihe unter dem Stapel. Die Pfeile standen vorher
   oben rechts neben der Überschrift — weit weg von den Punkten, obwohl beide
   dasselbe steuern. clamp beim Abstand, damit die Reihe auf dem Handy nicht
   auseinanderfällt. */
.tnav-row { display:flex; align-items:center; justify-content:center;
  gap: clamp(6px,1.4vw,18px); margin-top:4px; }
.tnav-arrow { width:clamp(44px,4.4vw,52px); height:clamp(44px,4.4vw,52px); border-radius:50%;
  border:1.5px solid var(--line); background:transparent; display:grid; place-items:center;
  cursor:pointer; color:var(--text); transition:.3s var(--ease); flex:0 0 auto; }
.tnav-arrow:hover:not(:disabled) { background:var(--holo); border-color:transparent; color:#1a1a1a; transform:translateY(-2px); }
.tnav-arrow:disabled { opacity:.3; cursor:default; }
.tnav-arrow:focus-visible { outline:2px solid var(--holo-peri); outline-offset:3px; }
/* Der eigene margin-top entfällt, die Reihe bringt ihn mit. */
.tnav-row .tdots { margin-top:0; }
/* Der Zähler ersetzt die Punkte erst auf schmalen Geräten (Regel im
   MOBILE-FEINSCHLIFF am Dateiende) — hier ist er aus dem Weg. */
.tnav-zaehler { display:none; font-family:'Space Mono',monospace; font-size:13px;
  letter-spacing:.08em; color:var(--text-dim); min-width:4.5em; text-align:center; }
/* «8 Stimmen» unter der zentrierten Pfeil-Reihe ebenfalls mittig, sonst hängt die
   Zeile allein am linken Rand. */
.tstimmen { justify-content:center; }

/* gerahmtes Inline-Foto (z.B. Statement-Sektion) */
.media-frame { position:relative; border-radius: calc(var(--radius) * 2.2); overflow:hidden;
  border:1px solid var(--line); box-shadow: 0 44px 90px -46px var(--holo-peri); isolation:isolate; }
.media-frame img { width:100%; height:100%; object-fit:cover; display:block; aspect-ratio: 4 / 3.1; }
.media-frame::after { content:""; position:absolute; inset:0; background:var(--holo-soft); opacity:0;
  mix-blend-mode:soft-light; transition:opacity .5s var(--ease); pointer-events:none; }
.media-frame:hover::after { opacity:.45; }
.media-badge { position:absolute; left:16px; bottom:16px; z-index:2; box-shadow:0 8px 24px -10px rgba(0,0,0,.4); }

/* ============================================================
   HERO 2.0 — Wordmark + Claim + Teamfoto + schwebende SoMe-Icons
   ============================================================ */
.hero2 { position:relative; padding-top: clamp(120px,15vh,180px); padding-bottom: clamp(40px,6vw,72px); }
.hero2-stage { position:relative; text-align:center; padding-block: clamp(16px,4vw,48px); }
/* Das h1 malt bewusst KEINEN eigenen Verlauf mehr. Vorher stand hier
   background:var(--holo) + background-clip:text + color:transparent — damit hat das
   h1 den Verlauf durch seinen gesamten Text gemalt, also auch durch das „#" im
   Kindelement .hero-hash. Weil .hero-hash sein „#" zusätzlich selbst malt und dabei
   geschrägt ist, standen zwei „#" nebeneinander: das linke, blaue wirkte wie ein
   Schatten des rechten. Gemalt wird jetzt ausschliesslich in den Kindern —
   .hero-hash (Holo) und .hero-word-text (hell). */
.hero-word {
  font-weight:900; line-height:.82; letter-spacing:-.03em; margin:0; text-transform:uppercase;
  font-size: clamp(64px, calc(17vw * var(--scale)), 280px);
  position:relative; z-index:2;
}
@keyframes heroHue { 0%{background-position:0% 0} 50%{background-position:100% 0} 100%{background-position:0% 0} }
/* Die echte Logo-Glyphe als CSS-Maske (assets/hash.svg), gefuellt mit dem
   Holo-Verlauf. Kein Schrift-"#" und kein skewX mehr — die Schraeglage ist Teil
   der Zeichnung. Der helle Ausschnitt ohne den dunklen --holo-peri bleibt: dessen
   Stop sass auf dem linken Balken und las sich dort wie ein blauer Schatten. */
.hero-word .hero-hash {
  display:inline-block; margin-right:.07em;
  /* Im Originallogo ueberragt die Glyphe die Wortmarke deutlich — das bleibt so,
     sonst wirkt sie neben dem schweren Schriftzug wie ein Beistrich. */
  height:.96em;
  aspect-ratio: 75.027 / 85.124;
  vertical-align:-.1em;
  background: linear-gradient(110deg,
      var(--holo-sky) 0%,
      var(--holo-lav) 34%,
      var(--holo-pink) 64%,
      var(--holo-blush) 100%);
  background-size:135% 100%;
  -webkit-mask: url('assets/hash.svg') center/contain no-repeat;
  mask: url('assets/hash.svg') center/contain no-repeat;
  animation: heroHue calc(16s / var(--motion,1)) linear infinite, hashPop .7s cubic-bezier(.2,.8,.2,1) backwards;
}
@keyframes hashPop { from { opacity:0; transform: translateY(.4em) scale(.55); } to { opacity:1; transform:none; } }
.hero-word .hero-word-text { position:relative; display:inline-block; color:#eceaf2; -webkit-text-fill-color:#eceaf2; }
/* Satinierte Wortmarke: Verlauf von gleissendem Weiss oben nach kuehlem Grau unten,
   dazu eine 1px-Lichtkante. Der Verlauf sitzt bewusst auf den EINZELNEN Buchstaben
   und nicht auf .hero-word-text: die Buchstaben fliegen beim Laden mit transform ein,
   und ein background-clip:text auf dem Elternteil malt waehrend dieser Bewegung an
   der Endposition weiter — es entstuenden kurz zwei Wortmarken uebereinander.
   Genau diese Falle hat beim "#" die Doppelglyphe erzeugt (siehe dont.md). */
.hero-word .hl {
  background: linear-gradient(180deg, #ffffff 0%, #ffffff 42%, #d9dcea 72%, #aab0c8 100%);
  -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
}
/* Buchstaben-Einflug (A1) */
.hero-word .hl { position:relative; z-index:1; display:inline-block; opacity:0; transform: translateY(.55em) rotateX(-50deg); filter: blur(7px);
  animation: letterIn 1s cubic-bezier(.2,.75,.25,1) forwards; animation-delay: calc(var(--i) * 95ms + .45s); }
@keyframes letterIn { to { opacity:1; transform:none; filter: blur(0); } }
/* Glint-Sweep (A3) — heller Lichtstreifen über die Buchstaben */
.hwt-shine { position:absolute; left:0; top:0; z-index:2; pointer-events:none; white-space:nowrap;
  background: linear-gradient(100deg, transparent 38%, rgba(255,255,255,.55) 46%, #fff 50%, rgba(255,255,255,.55) 54%, transparent 62%);
  background-size: 250% 100%; background-position: 130% 0;
  -webkit-background-clip:text; background-clip:text; color:transparent; -webkit-text-fill-color:transparent;
  filter: drop-shadow(0 0 14px rgba(190,225,255,.55));
  animation: heroShine 5.5s ease-in-out 1.9s infinite; }
@keyframes heroShine { 0% { background-position:130% 0; } 32%,100% { background-position:-50% 0; } }
/* 3D-Tiefe (C) + Ambient-Float */
.hero-stage { perspective: 1000px; position:relative; z-index:2; }
.hero-tilt { transform-style: preserve-3d; transition: transform .25s ease-out; will-change: transform; }
.hero-floaty { animation: heroFloat 7s ease-in-out infinite alternate; }
@keyframes heroFloat { from { transform: translateY(-7px); } to { transform: translateY(11px); } }
/* Claim-Rotator — Überblendung statt Schnitt.
   block statt inline-block, damit die abgehende Zeile mit left/right:0 über der
   vollen Breite liegt und ihre Zentrierung erbt. Bei inline-block richtete sie
   sich an der Breite der NEUEN Zeile aus und sprang bei unterschiedlich langen
   Claims seitlich weg. */
.claim-rot { position:relative; display:block; }
/* Unsichtbarer Platzhalter mit dem längsten Claim — er allein hält die Höhe.
   visibility:hidden statt display:none, weil er Platz beanspruchen MUSS.
   Beide echten Zeilen liegen absolut darüber und ändern die Höhe nie. */
.claim-mass { display:block; visibility:hidden; }
.claim-zeile { position:absolute; left:0; right:0; top:0; display:block; }
.claim-zeile--weg { pointer-events:none;
  animation: claimWeg .8s cubic-bezier(.3,.6,.3,1) forwards; }
/* Sanfter Anstieg und Aufblenden, kein 3D-Kippen mehr — das wirkte mechanisch.
   Der kleine Versatz lässt die neue Zeile erst einsetzen, wenn die alte schon
   halb verblasst ist; sonst überlagern sich zwei volle Zeilen sichtbar. */
.claim-zeile--neu { animation: claimNeu 1.1s cubic-bezier(.22,.7,.25,1) .14s backwards; }
@keyframes claimNeu { from { opacity:0; transform: translateY(.2em); } to { opacity:1; transform:none; } }
@keyframes claimWeg { from { opacity:1; transform:none; } to { opacity:0; transform: translateY(-.14em); } }
/* Motion-Off: alles ruhig stellen */
html[data-motion="0"] .hero-floaty,
html[data-motion="0"] .hwt-shine,
html[data-motion="0"] .claim-zeile,
html[data-motion="0"] .hero-word .hero-hash { animation:none; }
html[data-motion="0"] .hero-word .hl { animation:none; opacity:1; transform:none; filter:none; }
.hero-claim {
  position:relative; z-index:2; margin: clamp(14px,2vw,26px) auto 0;
  font-weight:800; text-transform:uppercase; letter-spacing:-.01em; line-height:1;
  /* Obergrenze 55 statt 62 px: bei 62 px brauchte der längste Claim („Wir machen
     Dich unverwechselbar.") 1310 px, der Textblock ist aber nur 1210 px breit —
     die Zeile brach um. Seit der Claim überblendet, fiel dieser Höhensprung von
     einer auf zwei Zeilen mitten in die Blende und machte sie wieder ruppig. */
  font-size: clamp(24px, calc(4.1vw * var(--scale)), 55px); color:var(--text);
}
.hero-claim .u { position:relative; white-space:nowrap; }
.hero-claim .u::after { content:""; position:absolute; left:0; right:0; bottom:.04em; height:.12em; background:var(--holo); border-radius:2px; }
.hero-ctas { position:relative; z-index:3; display:flex; gap:16px; justify-content:center; flex-wrap:wrap; margin-top: clamp(26px,3.5vw,44px); }

/* Teamfoto banner */
.hero-photo { position:relative; margin-top: clamp(30px,4vw,56px); border-radius: calc(var(--radius) * 2); overflow:hidden; z-index:1;
  box-shadow: 0 40px 90px -50px var(--holo-peri); border:1px solid var(--line); }
.hero-photo img { width:100%; height:clamp(280px,42vw,560px); object-fit:cover; object-position:center 28%; display:block; }
.hero-photo::after { content:""; position:absolute; inset:0; background:linear-gradient(180deg, transparent 55%, color-mix(in srgb, var(--bg) 30%, transparent)); pointer-events:none; }
html[data-dir="b"] .hero-photo::after { background:linear-gradient(180deg, transparent 50%, color-mix(in srgb, #000 55%, transparent)); }

/* schwebende SoMe-Chips */
.floats { position:absolute; inset:-4% -2% -2%; z-index:1; pointer-events:none; }
/* Handy: Chips nur im oberen Bereich, kleinere Auslenkung und weniger Stück —
   sonst wandern sie über den Claim und halb aus dem Bild. */
@media (max-width: 600px) {
  /* bottom:100% legt die Chip-Ebene komplett ÜBER den Textblock — sonst
     wandern sie auf schmalen Displays quer über den "#BEVISIBLE"-Schriftzug. */
  .cover-content .floats { inset: auto 4% 100% 4%; height: min(210px, 22vh); }
  .float-chip.opt { display:none; }
  /* Eigener Pfad fürs Handy: Die Chip-Ebene liegt hier komplett ÜBER dem Textblock
     (bottom:100%), deshalb ist Bewegung in dieser Zone ungefährlich. Früher nur ein
     12-px-Wippen — das sah man praktisch nicht. Jetzt eine echte kleine Runde,
     die aber in der Bandhöhe von max. 210 px bleibt. Die Dauer steht im Block
     MOBILE-FEINSCHLIFF: hier wäre sie schwächer als die Regeln je Kanal weiter
     unten und bliebe wirkungslos (so war es mit den früheren 11 s). */
  .float-bob { animation-name: bobM !important; }
}
@keyframes bobM {
  0%   { transform: translate(0,0) rotate(var(--r,0deg)); }
  22%  { transform: translate(5vw, -26px) rotate(calc(var(--r,0deg) * -1.8)); }
  45%  { transform: translate(-3.5vw, -38px) rotate(calc(var(--r,0deg) * 1.6)); }
  68%  { transform: translate(-5vw, -14px) rotate(calc(var(--r,0deg) * -1.3)); }
  86%  { transform: translate(3vw, 10px) rotate(calc(var(--r,0deg) * 2)); }
  100% { transform: translate(0,0) rotate(var(--r,0deg)); }
}
.float-chip { position:absolute; will-change:transform; transition: transform .5s cubic-bezier(.2,.8,.2,1); }
/* Positionen je Kanal — früher Inline-Style in ui.jsx, was jede Media Query
   überstimmt hat. Hier lassen sie sich mobil überschreiben. */
/* Die Startpunkte sitzen bewusst weit oben bzw. weit unten: der Schriftzug belegt
   ein waagrechtes Band in der Mitte (bei 1440x820 etwa y 295–540), darüber und
   darunter ist die volle Breite frei. Dort dürfen die Eck-Icons weit wandern. */
.float-chip[data-soc="instagram"] { left:3%;  top:7%; }
.float-chip[data-soc="tiktok"]    { right:5%; top:3%; }
.float-chip[data-soc="youtube"]   { right:1%; top:44%; }
.float-chip[data-soc="linkedin"]  { left:8%;  bottom:5%; }
.float-chip[data-soc="facebook"]  { left:0%;  top:50%; }
.float-chip[data-soc="x"]         { right:12%; bottom:3%; }
/* Umherschweben in Randspuren. Die Bewegung ist deutlich kräftiger als früher
   (max. 13vw/11vh über 23–31 s, was man kaum als Bewegung wahrnahm), aber bewusst
   in Spuren gebahnt: der Weg betont die SENKRECHTE (±16vh, gut sichtbar) und hält
   waagrecht die eigene Seite (links nur nach rechts, rechts nur nach links, je ≤6vw).
   Grund: bei freier Wanderung mit grosser Weite legten sich die Icons über
   „#BEVISIBLE" und den Claim und liefen halb aus dem Bild — die Zuordnung nach
   data-soc statt nth-child hält sie jetzt in ihrer Spur.
   Tempo: Massstab ist die Geschwindigkeit, nicht die Umlaufzeit. Als die Wege
   auf die ganze Breite verlängert wurden (Instagram 910 statt 380 px), stieg die
   Umlaufzeit nur von 15 auf 27 s — die Icons wurden dadurch schneller statt
   langsamer und wirkten nervös. Jetzt rund 20–25 px/s im Mittel bei 1440 px,
   die Umlaufzeiten sind entsprechend 55–78 s. Die negativen Verzögerungen
   stehen im selben Verhältnis zur Dauer wie vorher, damit die Icons nicht
   im Gleichtakt starten. */
.float-bob { animation: wanderLinks var(--wdur,70s) ease-in-out infinite; }
.float-chip[data-soc="instagram"] .float-bob { animation-name: wanderLinks;  --wdur:75s; animation-delay:-8s; }
.float-chip[data-soc="linkedin"]  .float-bob { animation-name: wanderLinks2; --wdur:72s; animation-delay:-42s; }
.float-chip[data-soc="tiktok"]    .float-bob { animation-name: wanderRechts; --wdur:78s; animation-delay:-19s; }
.float-chip[data-soc="x"]         .float-bob { animation-name: wanderRechts2;--wdur:70s; animation-delay:-32s; }
/* Facebook und YouTube stehen als einzige auf halber Höhe, also genau neben dem
   Schriftzug. Sie bekommen deshalb eine fast reine Senkrechtbewegung — jede
   nennenswerte Seitwärtsbewegung schöbe sie über den Claim. */
.float-chip[data-soc="facebook"]  .float-bob { animation-name: wanderSenkrecht;  --wdur:55s; animation-delay:-20s; }
.float-chip[data-soc="youtube"]   .float-bob { animation-name: wanderSenkrecht2; --wdur:60s; animation-delay:-38s; }
/* Die beiden Rand-Icons ziehen dafuer ueber die ganze HOEHE: ihre x-Position liegt
   ausserhalb der Schrift (links unter 134 px, rechts ueber 1306 px), waagrecht
   duerfen sie sich deshalb kaum ruehren, senkrecht aber vom Kopf bis zum Fuss. */
@keyframes wanderSenkrecht {
  0%   { transform: translate(0,0) rotate(var(--r,0deg)); }
  22%  { transform: translate(1.5vw, -28vh) rotate(calc(var(--r,0deg) * -1.8)); }
  45%  { transform: translate(0, -11vh) rotate(calc(var(--r,0deg) * 1.5)); }
  68%  { transform: translate(1vw, 26vh) rotate(calc(var(--r,0deg) * -1.2)); }
  87%  { transform: translate(0, 9vh) rotate(calc(var(--r,0deg) * 2)); }
  100% { transform: translate(0,0) rotate(var(--r,0deg)); }
}
@keyframes wanderSenkrecht2 {
  0%   { transform: translate(0,0) rotate(var(--r,0deg)); }
  24%  { transform: translate(-1vw, 27vh) rotate(calc(var(--r,0deg) * 1.7)); }
  47%  { transform: translate(0, 8vh) rotate(calc(var(--r,0deg) * -1.4)); }
  71%  { transform: translate(-1.5vw, -25vh) rotate(calc(var(--r,0deg) * 1.9)); }
  89%  { transform: translate(0, -9vh) rotate(calc(var(--r,0deg) * -1.1)); }
  100% { transform: translate(0,0) rotate(var(--r,0deg)); }
}
/* Oberes Band: ueber die GANZE Breite. Der Schriftzug belegt nur ein waagrechtes
   Band in der Mitte (gemessen y 295-540) — darueber ist die volle Breite frei,
   deshalb duerfen diese beiden quer durch den Header ziehen. Die Senkrechte
   bleibt eng begrenzt, sonst tauchen sie in die Schrift ein. */
@keyframes wanderLinks {
  0%   { transform: translate(0,0) rotate(var(--r,0deg)); }
  16%  { transform: translate(16vw, -5vh) rotate(calc(var(--r,0deg) * -1.8)); }
  33%  { transform: translate(37vw, -10vh) rotate(calc(var(--r,0deg) * 1.5)); }
  50%  { transform: translate(58vw, -2vh) rotate(calc(var(--r,0deg) * -1.2)); }
  67%  { transform: translate(44vw, 3vh) rotate(calc(var(--r,0deg) * 2)); }
  84%  { transform: translate(21vw, -8vh) rotate(calc(var(--r,0deg) * -1.4)); }
  100% { transform: translate(0,0) rotate(var(--r,0deg)); }
}
/* Unteres Band, von links. Senkrechte nach oben begrenzt, damit der Claim frei bleibt. */
@keyframes wanderLinks2 {
  0%   { transform: translate(0,0) rotate(var(--r,0deg)); }
  18%  { transform: translate(14vw, 5vh) rotate(calc(var(--r,0deg) * 1.7)); }
  37%  { transform: translate(34vw, 9vh) rotate(calc(var(--r,0deg) * -1.4)); }
  55%  { transform: translate(52vw, 2vh) rotate(calc(var(--r,0deg) * 1.1)); }
  73%  { transform: translate(33vw, 10vh) rotate(calc(var(--r,0deg) * -1.9)); }
  89%  { transform: translate(12vw, 4vh) rotate(calc(var(--r,0deg) * 1.3)); }
  100% { transform: translate(0,0) rotate(var(--r,0deg)); }
}
/* Oberes Band, von rechts. */
@keyframes wanderRechts {
  0%   { transform: translate(0,0) rotate(var(--r,0deg)); }
  17%  { transform: translate(-18vw, -4vh) rotate(calc(var(--r,0deg) * 1.6)); }
  35%  { transform: translate(-40vw, -9vh) rotate(calc(var(--r,0deg) * -1.8)); }
  52%  { transform: translate(-60vw, -1vh) rotate(calc(var(--r,0deg) * 1.3)); }
  70%  { transform: translate(-41vw, 4vh) rotate(calc(var(--r,0deg) * -1.1)); }
  87%  { transform: translate(-19vw, -7vh) rotate(var(--r,0deg)); }
  100% { transform: translate(0,0) rotate(var(--r,0deg)); }
}
/* Unteres Band, von rechts. */
@keyframes wanderRechts2 {
  0%   { transform: translate(0,0) rotate(var(--r,0deg)); }
  19%  { transform: translate(-15vw, 6vh) rotate(calc(var(--r,0deg) * -1.5)); }
  38%  { transform: translate(-35vw, 10vh) rotate(calc(var(--r,0deg) * 1.9)); }
  57%  { transform: translate(-54vw, 3vh) rotate(calc(var(--r,0deg) * -1.2)); }
  76%  { transform: translate(-32vw, 9vh) rotate(calc(var(--r,0deg) * 1.4)); }
  91%  { transform: translate(-13vw, 5vh) rotate(calc(var(--r,0deg) * -1.7)); }
  100% { transform: translate(0,0) rotate(var(--r,0deg)); }
}
html[data-motion="0"] .float-bob { animation:none; }
.somark {
  width: clamp(48px,5.2vw,68px); height: clamp(48px,5.2vw,68px); border-radius: 22%;
  background:var(--panel); border:1px solid var(--line); display:grid; place-items:center;
  box-shadow: 0 18px 40px -18px rgba(20,20,40,.45); color:var(--text); pointer-events:auto; cursor:pointer;
  transition: transform .3s var(--ease), box-shadow .3s, border-color .3s;
}
html[data-dir="b"] .somark { box-shadow: 0 18px 50px -18px rgba(0,0,0,.7); }
.somark::before { content:""; position:absolute; inset:0; border-radius:inherit; background:var(--holo); opacity:0; transition:opacity .35s; z-index:-1; }
.somark { position:relative; isolation:isolate; }
.somark:hover { transform: scale(1.12) rotate(-4deg); border-color:transparent; color:#1a1a1a; }
.somark:hover::before { opacity:1; }
.somark svg { width:54%; height:54%; }
/* Kanäle ohne hinterlegte Adresse sind reine Zierde: kein Zeigefinger, kein
   Vergrössern beim Überfahren. Der Mauszeiger soll keinen Klick versprechen,
   den es nicht gibt. */
.somark--deko { cursor:default; }
.somark--deko:hover { transform:none; border-color:var(--line); color:var(--text); }
.somark--deko:hover::before { opacity:0; }
.somark:focus-visible { outline:2px solid var(--holo-peri); outline-offset:3px; }
/* faint holo tint per chip */
.float-chip:nth-child(odd) .somark { box-shadow: 0 18px 44px -18px var(--holo-peri); }
.float-chip:nth-child(even) .somark { box-shadow: 0 18px 44px -18px var(--holo-pink); }

/* ============================================================
   KUNDEN-LOGO-BAND (Zug-Effekt, links → rechts)
   ============================================================ */
/* Ohne Trennstriche: das Band soll als ruhige Flaeche zwischen den Sektionen liegen,
   nicht als eingerahmtes Element.
   Die Polsterung bleibt bewusst auf dem alten Wert, obwohl die Logos gewachsen sind.
   Waechst sie im selben Verhaeltnis mit, bleibt das Groessenverhaeltnis Logo zu Band
   gleich und die Logos wirken trotz mehr Pixeln nicht groesser. */
.logoband { overflow:hidden; padding-block: clamp(24px,2.6vw,38px); position:relative; }
.logoband__label { position:absolute; left:var(--gutter); top:50%; transform:translateY(-50%); z-index:3;
  background:var(--bg); padding-right:22px; }
/* 40 s je Durchgang (vorher 20 s, Kundenrückmeldung 2026-10-05: zu schnell). Das
   Tempo hängt an der Breite des Bands: mit mehr Logos im CMS wird es bei gleicher
   Dauer schneller. */
.logoband__track { display:flex; gap: clamp(52px,6.6vw,108px); width:max-content; align-items:center;
  animation: bandLTR calc(40s / var(--motion,1)) linear infinite; }
@keyframes bandLTR { from { transform: translateX(-50%); } to { transform: translateX(0); } }
html[data-motion="0"] .logoband__track { animation:none; }
.logo-ph { display:flex; align-items:center; gap:13px; flex:0 0 auto; opacity:.5;
  filter:grayscale(1); transition: opacity .4s, filter .4s; }
.logo-ph:hover { opacity:1; filter:none; }
.logo-ph .lp-mark { width:34px; height:34px; flex:0 0 auto; }
.logo-ph .lp-name { font-weight:800; font-size:21px; letter-spacing:-.02em; text-transform:uppercase; color:var(--text); white-space:nowrap; }

.logo-ph.logo-img { gap:0; }
.logo-ph .lp-sub { font-family:'Space Mono',monospace; font-size:10px; letter-spacing:.12em; color:var(--text-dim); display:block; text-transform:uppercase; }
.logo-ph .lp-logo { height: clamp(46px, 3.6vw, 60px); width:auto; max-width:220px; object-fit:contain; display:block; }

@media (max-width: 720px) {
  .floats .float-chip.opt { display:none; }
}

/* ============================================================
   KUNDENPORTAL — Login + Schulungs-Dashboard
   ============================================================ */
.portal-sec { padding-top: clamp(116px,15vh,190px); padding-bottom: clamp(56px,9vh,110px); }

/* ---- Login ---- */
.portal-card { display:grid; grid-template-columns: 0.92fr 1.08fr; max-width: 1000px; margin-inline:auto;
  background:var(--panel); border:1px solid var(--line); border-radius: calc(var(--radius)*2.4);
  overflow:hidden; box-shadow: 0 60px 130px -54px rgba(20,16,40,.5); }
.portal-aside { position:relative; isolation:isolate; padding: clamp(30px,3.4vw,52px); color:#1a1a1a;
  display:flex; flex-direction:column; justify-content:space-between; gap: clamp(28px,4vw,52px);
  background: linear-gradient(155deg, var(--holo-sky), var(--holo-peri) 34%, var(--holo-lav) 60%, var(--holo-pink) 100%); }
.portal-aside-mark { width:54px; height:54px; border-radius:16px; display:grid; place-items:center;
  background:rgba(255,255,255,.35); backdrop-filter:blur(6px); }
.portal-aside-mark span { font-weight:900; font-size:30px; line-height:1; color:#1a1a1a; }
.portal-aside-title { font-size:clamp(30px,3.4vw,46px); font-weight:900; text-transform:uppercase; line-height:.92; letter-spacing:-.02em; margin:0; }
.portal-aside-text { margin-top:14px; font-size:15px; line-height:1.5; color:rgba(26,22,38,.78); max-width:28ch; }
.portal-aside-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:11px; }
.portal-aside-list li { position:relative; padding-left:26px; font-weight:600; font-size:14.5px; color:rgba(26,22,38,.86); }
.portal-aside-list li::before { content:""; position:absolute; left:0; top:7px; width:13px; height:13px; border-radius:50%;
  background:#1a1a1a; -webkit-mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e%3cpath fill='black' d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/%3e%3c/svg%3e") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e%3cpath fill='black' d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/%3e%3c/svg%3e") center/contain no-repeat; }

.portal-form { padding: clamp(30px,3.4vw,54px); display:flex; flex-direction:column; justify-content:center; }
.portal-form-title { font-size:clamp(24px,2.4vw,34px); font-weight:900; text-transform:uppercase; letter-spacing:-.02em; margin:12px 0 0; }
.portal-form-sub { color:var(--text-soft); font-size:15px; margin:8px 0 26px; }
.portal-row { display:flex; align-items:center; justify-content:space-between; gap:12px; margin:4px 0 22px; flex-wrap:wrap; }
.portal-check { display:inline-flex; align-items:center; gap:8px; font-size:13.5px; color:var(--text-soft); cursor:pointer; }
.portal-check input { accent-color: var(--holo-peri); width:15px; height:15px; }
.portal-link { font-size:13.5px; color:var(--text-soft); cursor:pointer; transition:color .3s; }
.portal-link:hover { color:var(--text); }
.portal-hint { display:flex; align-items:center; gap:8px; margin-top:20px; font-size:12.5px; color:var(--text-dim); }
.portal-lock { display:grid; place-items:center; color:var(--text-dim); }

/* ---- Dashboard ---- */
.portal-dash-head { display:flex; align-items:flex-end; justify-content:space-between; gap:20px; flex-wrap:wrap; margin-bottom: clamp(28px,4vw,48px); }
.portal-dash-title { font-size:clamp(30px,4vw,58px); font-weight:900; text-transform:uppercase; letter-spacing:-.02em; line-height:.95; margin:14px 0 0; }
.portal-dash-sub { color:var(--text-soft); font-size:14px; margin-top:10px; }
.portal-logout { display:inline-flex; align-items:center; gap:9px; padding:11px 20px; border-radius:999px;
  border:1px solid var(--line); background:var(--panel); color:var(--text); font-weight:700; font-size:14px; cursor:pointer;
  transition: border-color .3s, transform .3s var(--ease), box-shadow .3s; }
.portal-logout:hover { transform:translateY(-2px); border-color:transparent; box-shadow:0 14px 30px -16px var(--holo-peri); }

/* Tabs */
.portal-tabs { display:flex; gap:18px; margin-bottom: clamp(22px,3vw,34px); border-bottom:1px solid var(--line); }
.portal-tab { position:relative; padding:12px 2px; background:none; border:none; cursor:pointer; font:inherit;
  font-weight:700; font-size:15px; color:var(--text-dim); text-transform:uppercase; letter-spacing:.02em; transition:color .3s; }
.portal-tab:hover { color:var(--text-soft); }
.portal-tab.on { color:var(--text); }
.portal-tab.on::after { content:""; position:absolute; left:0; right:0; bottom:-1px; height:2.5px; background:var(--holo); border-radius:3px; }

/* Rechnungen */
.inv-stats { display:grid; grid-template-columns:repeat(3,1fr); gap: clamp(14px,1.6vw,22px); margin-bottom: clamp(22px,3vw,32px); }
.inv-stat { border:1px solid var(--line); border-radius: calc(var(--radius)*1.5); padding: clamp(16px,1.8vw,24px); background:var(--panel); }
.inv-stat-l { display:block; font-family:'Space Mono',monospace; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--text-dim); }
.inv-stat-v { display:block; margin-top:10px; font-size:clamp(20px,2vw,28px); font-weight:900; letter-spacing:-.01em; }
.inv-stat--over .inv-stat-v { color:#e0436b; }

.inv-table { border:1px solid var(--line); border-radius: calc(var(--radius)*1.5); overflow:hidden; background:var(--panel); }
.inv-row { display:grid; grid-template-columns: 1.1fr 1.7fr .9fr .8fr .85fr auto; gap:14px; align-items:center; padding:16px clamp(16px,1.8vw,24px); border-top:1px solid var(--line); }
.inv-row:first-child { border-top:none; }
.inv-row--head { background:var(--bg-2); font-family:'Space Mono',monospace; font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--text-dim); padding-block:12px; }
.inv-nr { font-weight:700; font-size:14px; display:flex; flex-direction:column; gap:3px; }
.inv-nr em { font-style:normal; font-weight:500; font-size:12px; color:var(--text-dim); }
.inv-desc { color:var(--text-soft); font-size:14px; }
.inv-amt { font-weight:800; font-size:15px; }
.inv-due { color:var(--text-soft); font-size:13.5px; }
.inv-badge { display:inline-flex; align-items:center; gap:6px; padding:5px 11px; border-radius:999px; font-size:12px; font-weight:700; white-space:nowrap; }
.inv-badge::before { content:""; width:7px; height:7px; border-radius:50%; }
.inv-badge.paid { background:rgba(31,138,91,.12); color:#1f8a5b; }
.inv-badge.paid::before { background:#1f8a5b; }
.inv-badge.open { background:rgba(120,120,130,.14); color:var(--text-soft); }
.inv-badge.open::before { background:#9a9893; }
.inv-badge.overdue { background:rgba(224,67,107,.13); color:#e0436b; }
.inv-badge.overdue::before { background:#e0436b; }
.inv-act { text-align:right; }
.inv-dl { display:inline-flex; align-items:center; gap:6px; padding:8px 14px; border-radius:999px; border:1px solid var(--line);
  background:transparent; color:var(--text); font:inherit; font-weight:700; font-size:13px; cursor:pointer; transition:border-color .3s, background .3s; }
.inv-dl:hover { border-color:transparent; background:var(--holo); color:#1a1a1a; }

@media (max-width:760px){
  .inv-stats { grid-template-columns:1fr; }
  .inv-row--head { display:none; }
  .inv-row { grid-template-columns:1fr 1fr; gap:9px 14px; }
  .inv-row > span[data-l]::before { content:attr(data-l) " · "; font-family:'Space Mono',monospace; font-size:10px; letter-spacing:.08em; text-transform:uppercase; color:var(--text-dim); }
  .inv-desc { grid-column:1/-1; }
  .inv-act { grid-column:1/-1; text-align:left; }
}

.portal-grid { display:grid; grid-template-columns: repeat(3, 1fr); gap: clamp(18px,2vw,26px); }
.vcard { text-align:left; border:1px solid var(--line); border-radius: calc(var(--radius)*1.8); overflow:hidden;
  background:var(--panel); cursor:pointer; padding:0; font:inherit; color:inherit;
  transition: transform .4s var(--ease), box-shadow .4s var(--ease), border-color .4s; }
.vcard:hover { transform:translateY(-5px); border-color:transparent; box-shadow:0 28px 56px -30px rgba(20,16,40,.45); }
.vthumb { position:relative; aspect-ratio:16/10; display:grid; place-items:center; }
.vthumb.g0 { background:linear-gradient(150deg, var(--holo-peri), var(--holo-lav) 60%, var(--holo-pink)); }
.vthumb.g1 { background:linear-gradient(150deg, var(--holo-sky), var(--holo-lav) 55%, var(--holo-blush)); }
.vthumb.g2 { background:linear-gradient(150deg, var(--holo-lav), var(--holo-pink) 55%, var(--holo-cream)); }
.vthumb::after { content:""; position:absolute; inset:0; background:linear-gradient(180deg, rgba(0,0,0,.02) 50%, rgba(0,0,0,.34)); }
.vplay { position:relative; z-index:2; width:56px; height:56px; border-radius:50%; display:grid; place-items:center;
  background:rgba(255,255,255,.28); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px); border:1px solid rgba(255,255,255,.5); color:#fff;
  transition: transform .3s var(--ease), background .3s; }
.vcard:hover .vplay { transform:scale(1.1); background:rgba(255,255,255,.42); }
.vplay--lg { width:74px; height:74px; }
.vdur { position:absolute; z-index:2; right:12px; bottom:11px; display:inline-flex; align-items:center; gap:5px;
  background:rgba(0,0,0,.46); color:#fff; font-size:11px; font-weight:700; padding:4px 9px; border-radius:7px; backdrop-filter:blur(4px); }
.vdur svg { opacity:.85; }
.vtag { position:absolute; z-index:2; left:12px; top:11px; font-family:'Space Mono',monospace; font-size:9px; letter-spacing:.12em;
  text-transform:uppercase; color:rgba(255,255,255,.85); background:rgba(0,0,0,.32); padding:4px 9px; border-radius:20px; backdrop-filter:blur(4px); }
.vbody { padding: clamp(16px,1.6vw,22px); }
.vmeta { display:flex; align-items:center; gap:12px; }
.vlessons { display:inline-flex; align-items:center; gap:5px; font-size:12px; color:var(--text-dim); }
.vtitle { margin:12px 0 0; font-size:clamp(17px,1.4vw,20px); font-weight:800; text-transform:uppercase; letter-spacing:-.01em; line-height:1.1; }
.vdesc { margin:8px 0 0; font-size:13.5px; line-height:1.5; color:var(--text-soft); }
.vprog { margin-top:16px; height:5px; border-radius:5px; background:var(--line); overflow:hidden; }
.vprog i { display:block; height:100%; background:var(--holo); border-radius:5px; }

/* ---- Video-Modal ---- */
@keyframes fadeIn { from{opacity:0} to{opacity:1} }
@keyframes popIn { from{opacity:0; transform:translateY(20px) scale(.98)} to{opacity:1; transform:none} }
.vmodal-back { position:fixed; inset:0; z-index:200; background:rgba(10,10,18,.6); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  display:grid; place-items:center; padding: clamp(16px,4vw,48px); animation: fadeIn .3s ease; }
.vmodal { position:relative; background:var(--panel); border:1px solid var(--line); border-radius: calc(var(--radius)*2.2);
  width:min(760px,100%); overflow:hidden; box-shadow:0 60px 140px -50px rgba(0,0,0,.7); animation: popIn .4s var(--ease); }
.vmodal-close { position:absolute; top:14px; right:14px; z-index:5; width:38px; height:38px; border-radius:50%;
  border:1px solid rgba(255,255,255,.3); background:rgba(0,0,0,.3); color:#fff; cursor:pointer; font-size:15px; backdrop-filter:blur(4px); }
.vmodal-player { position:relative; aspect-ratio:16/9; display:grid; place-items:center; gap:14px; }
.vmodal-player.g0 { background:linear-gradient(150deg, var(--holo-peri), var(--holo-lav) 60%, var(--holo-pink)); }
.vmodal-player.g1 { background:linear-gradient(150deg, var(--holo-sky), var(--holo-lav) 55%, var(--holo-blush)); }
.vmodal-player.g2 { background:linear-gradient(150deg, var(--holo-lav), var(--holo-pink) 55%, var(--holo-cream)); }
.vmodal-ph { position:absolute; bottom:16px; font-family:'Space Mono',monospace; font-size:11px; letter-spacing:.12em; text-transform:uppercase;
  color:rgba(255,255,255,.9); background:rgba(0,0,0,.32); padding:5px 11px; border-radius:20px; backdrop-filter:blur(4px); }
.vmodal-info { padding: clamp(22px,2.6vw,34px); }
.vmodal-title { margin:12px 0 0; font-size:clamp(22px,2.2vw,30px); font-weight:900; text-transform:uppercase; letter-spacing:-.01em; }
.vmodal-desc { margin:10px 0 0; color:var(--text-soft); font-size:15px; line-height:1.55; }
.vmodal-meta { display:flex; gap:20px; margin-top:20px; padding-top:18px; border-top:1px solid var(--line); }
.vmodal-meta span { display:inline-flex; align-items:center; gap:7px; font-size:13.5px; color:var(--text-dim); }

@media (max-width: 860px) {
  .portal-card { grid-template-columns:1fr; }
  .portal-aside { flex-direction:row; flex-wrap:wrap; align-items:center; gap:18px; }
  .portal-aside-list { display:none; }
  .portal-grid { grid-template-columns: repeat(2,1fr); }
}
@media (max-width: 560px) {
  .portal-grid { grid-template-columns:1fr; }
  .portal-dash-head { align-items:flex-start; }
}

/* utility */
.two-col { display:grid; grid-template-columns: 1.05fr .95fr; gap: clamp(32px,5vw,80px); align-items:center; }

/* ============================================================
   ÜBER BEVISIBLE — scroll-gedrehtes Phone mit wechselnden Medien
   ============================================================ */
/* Gewöhnliche Sektion. Vorher: height:340vh plus ein position:sticky-Panel, damit die
   drei Begleitsätze scroll-gesteuert durchwechselten — das kostete rund 30 % der
   Startseitenhöhe (3060 von 10134 px) für drei Sätze. Jetzt stehen alle drei
   gleichzeitig. Die Klassennamen bleiben, sticky ist hier nichts mehr. */
.about-scrolly { position:relative; padding-block: clamp(56px,7vw,104px); }
/* overflow:hidden bleibt: der Glow hinter dem Phone ragt seitlich hinaus und würde
   sonst horizontalen Überlauf erzeugen (siehe dont.md — nicht an html/body klippen). */
.about-sticky { overflow:hidden; display:flex; align-items:center; justify-content:center; gap: clamp(16px,2.4vw,44px); }
/* Kein perspective/preserve-3d mehr: Das Phone dreht sich seit dem echten Teamfoto
   nicht mehr, es zeigt durchgehend dasselbe Bild (siehe about-scrolly.jsx). */
.aphone-stage { position:relative; display:grid; place-items:center; flex:0 0 auto; }
.aphone-glow { position:absolute; left:50%; top:50%; width:48vh; height:48vh; margin:-24vh 0 0 -24vh; border-radius:50%; background:var(--holo-soft); filter:blur(72px); opacity:.45; pointer-events:none; z-index:0;
  animation: reelGlow 9s ease-in-out infinite alternate; }
.aphone-scaler { position:relative; z-index:1; will-change:transform; }
/* Trägt weiterhin die Grösse des Phones (auch die mobile Override-Regel weiter
   unten hängt daran), rotiert aber nicht mehr. */
.aphone-rotor { position:relative; width: clamp(228px,23vw,300px); aspect-ratio: 9 / 19.3; }
.aphone-frame { position:absolute; inset:0; background:#0c0c0e; border-radius: 16% / 7.5%; padding:9px;
  box-shadow: 0 54px 104px -34px rgba(18,18,38,.62), inset 0 0 0 2px rgba(255,255,255,.08); }
.aphone-screen { position:relative; width:100%; height:100%; border-radius: 12% / 6%; overflow:hidden; background:#111; }
.aphone-island { position:absolute; top:10px; left:50%; transform:translateX(-50%); width:30%; height:15px; background:#000; border-radius:10px; z-index:7; }
.amedia { position:absolute; inset:0; opacity:0; transition:opacity .4s ease; display:grid; place-items:center; }
.amedia.on { opacity:1; }
/* picture muss die Fläche selbst füllen — sonst schrumpft es als Grid-Element auf
   Inhaltsgrösse und das object-fit:cover des img greift ins Leere. */
.amedia picture { display:block; width:100%; height:100%; }
.amedia img { width:100%; height:100%; object-fit:cover; object-position:center; }
.amedia.s1 { background:linear-gradient(165deg, var(--holo-sky), var(--holo-lav) 55%, var(--holo-pink)); }
.amedia.s2 { background:linear-gradient(165deg, var(--holo-lav), var(--holo-pink) 55%, var(--holo-cream)); }
.amedia .aghost { position:relative; z-index:2; color:rgba(255,255,255,.78); filter: drop-shadow(0 8px 22px rgba(0,0,0,.28)); }
/* Die dunkle Maske am unteren Rand diente allein der Lesbarkeit der Bildunterschrift.
   Seit die weg ist, bleibt nur ein dezenter Hauch für Tiefe — 55 % Schwarz hätten das
   Teamfoto ohne Grund abgedunkelt. */
.amedia::after { content:""; position:absolute; inset:0; background:linear-gradient(180deg, rgba(0,0,0,0) 55%, rgba(0,0,0,.18)); }
.amedia-cap { position:absolute; left:14px; bottom:16px; right:14px; z-index:3; color:#fff; font-weight:800; font-size:13px; text-shadow:0 1px 8px rgba(0,0,0,.5); }

.about-copy { position:relative; order:-1; flex:0 0 auto; width: clamp(300px, 34vw, 440px); z-index:5; }
.about-body { position:relative; }
/* Die drei Sätze standen früher absolut übereinander und wurden einzeln eingeblendet;
   dafür brauchte der Block eine feste min-height. Jetzt laufen sie im normalen Fluss. */
.about-steps { margin-top: clamp(20px,2.6vw,30px); display:flex; flex-direction:column; gap: clamp(12px,1.4vw,18px); }
.about-step { margin:0; color:var(--text); font-size:clamp(17px,1.45vw,21px); line-height:1.55; font-weight:500; }
.about-cta { margin-top: clamp(16px,2.2vw,26px); }

@media (max-width: 920px) {
  /* Einspaltig: erst der Text, dann das Phone. Ohne sticky-Panel muss hier nichts
     mehr in 100vh passen — das Phone darf seine natürliche Höhe behalten. */
  .about-sticky { flex-direction:column; align-items:center; gap: clamp(26px,5vw,40px); }
  .aphone-stage { order:2; width:100%; }
  .aphone-rotor { width:auto; height: min(52vh, 420px); }
  .aphone-glow { width:34vh; height:34vh; margin:-17vh 0 0 -17vh; }
  .about-copy { order:1; text-align:center; width: min(34ch, 92vw); margin:0 auto; }
  /* Die Überschrift ist auf 13ch begrenzt. Ohne margin-inline:auto stand dieser Block
     links im zentrierten Textblock: «Wir sind Dein» und «Social Media» sassen links,
     «Team.» mittig (Rückmeldung vom iPhone, 2026-10-13). */
  .about-copy .about-h2 { margin-inline:auto; }
  .about-cta { display:flex; justify-content:center; }
}

/* Eingebettetes Kontaktformular im "Werde sichtbar"-Abschnitt */
.contact-embed { display:grid; grid-template-columns: 1.15fr .85fr; gap: clamp(30px,4.5vw,64px);
  text-align:left; max-width:960px; margin-inline:auto; align-items:start; }
.contact-embed .contact-form form { display:flex; flex-direction:column; }
/* Der Holo-Verlauf endet im hellen Rosa. Durch die Glyphen gezogen war das ".ch"
   am Ende der Adresse auf hellem Grund praktisch unsichtbar — ausgerechnet beim
   wichtigsten Kontaktweg der Seite. Der Verlauf sitzt jetzt als Balken unter der
   Adresse, wo er die Marke zeigt, ohne die Lesbarkeit zu kosten. */
.contact-embed .h-mail { position:relative; width:max-content; padding-bottom:5px; text-decoration:none; }
.contact-embed .h-mail::after { content:""; position:absolute; left:0; right:0; bottom:0;
  height:3px; border-radius:2px; background:var(--holo); }
@media (max-width: 760px) { .contact-embed { grid-template-columns:1fr; gap: clamp(28px,7vw,40px); } }

/* ============================================================
   PROJEKTE — interaktiver Phone-Stack (Reels)
   ============================================================ */
.showcase { display:grid; grid-template-columns: 1.05fr .95fr; gap: clamp(30px,5vw,80px); align-items:center; }
@media (max-width:920px){ .showcase{ grid-template-columns:1fr; } }

.pstack { position:relative; height: clamp(440px,50vw,600px); }
.phone {
  position:absolute; top:50%; left:50%; width: clamp(214px,22vw,278px); aspect-ratio: 9 / 19.3;
  cursor:pointer; will-change:transform;
  transition: transform .6s cubic-bezier(.2,.85,.2,1), filter .5s;
}
.phone.is-back:hover { filter:brightness(1.04); }
/* Der Stack fächert per JS um feste ±66px auf — auf schmalen Displays ragte die
   hintere Karte sonst über den Rand hinaus. */
@media (max-width: 560px) {
  .phone { width: min(214px, 50vw); }
  .pstack { height: clamp(360px, 108vw, 520px); }
}
.phone-frame { position:absolute; inset:0; background:#0c0c0e; border-radius: 16% / 7.5%;
  padding:9px; box-shadow: 0 50px 90px -34px rgba(18,18,38,.55), inset 0 0 0 2px rgba(255,255,255,.07); }
html[data-dir="b"] .phone-frame { box-shadow: 0 50px 90px -30px rgba(0,0,0,.8), inset 0 0 0 2px rgba(255,255,255,.09); }
.phone-screen { position:relative; width:100%; height:100%; border-radius: 12% / 6%; overflow:hidden; }
.phone-screen.g0 { background: linear-gradient(165deg, var(--holo-peri), var(--holo-lav) 55%, var(--holo-pink)); }
.phone-screen.g1 { background: linear-gradient(165deg, var(--holo-sky), var(--holo-lav) 50%, var(--holo-blush)); }
.phone-screen.g2 { background: linear-gradient(165deg, var(--holo-lav), var(--holo-pink) 55%, var(--holo-cream)); }
/* Kundenvideo im Mockup. z-index:0 — es liegt unter allen Bedienelementen
   (Island 6, Fortschritt 6, LIVE 5, Schiene und Text 4) und über dem
   Farbverlauf des Bildschirms, der bis zum Standbild als Grund dient.
   object-fit:cover: die Clips sind 9:16, der Bildschirm 9:19.3 — es werden
   links und rechts je rund 8 % beschnitten, die Bildmitte bleibt. */
.reel-video { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  z-index:0; border-radius:inherit; background:#111; display:block; }
/* Abdunklung am unteren Rand. Handle und Bildunterschrift sind weiss und standen
   vorher ohne Grund auf dem Videobild — bei hellen Clips (Autohaus im Freien)
   verschwanden sie. Liegt über dem Video (0) und unter den Bedienelementen (4).
   Die Fläche deckt bewusst den ganzen Bildschirm, der Verlauf beginnt erst bei 48 %.
   Vorher stand hier height:52% mit bottom:0, aber eine frühere Regel hatte
   inset:0 gesetzt: top:0 blieb stehen, und bei top + height wird bottom
   ignoriert. Die Abdunklung sass dadurch in der OBEREN Hälfte und endete mit
   abgerundeter Kante mitten im Bild. Mit voller Fläche passt auch
   border-radius:inherit genau auf die Ecken des Bildschirms. */
.phone-screen::after { content:""; position:absolute; inset:0;
  background:linear-gradient(180deg, transparent 48%, rgba(0,0,0,.26) 69%, rgba(0,0,0,.82));
  z-index:1; pointer-events:none; border-radius:inherit; }
.island { position:absolute; top:9px; left:50%; transform:translateX(-50%); width:32%; height:16px; background:#000; border-radius:10px; z-index:6; }

.reel-play { position:absolute; inset:0; margin:auto; width:60px; height:60px; border-radius:50%;
  background:rgba(255,255,255,.22); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  border:1px solid rgba(255,255,255,.4); display:grid; place-items:center; z-index:4; cursor:pointer;
  transition: transform .3s var(--ease), background .3s; color:#fff; }
.reel-play:hover { transform: scale(1.08); background:rgba(255,255,255,.32); }

/* Ohne Zahlen unter den Symbolen (seit 2026-10-07) stehen Herz und Kommentar enger.
   10px Abstand lassen der unsichtbaren 44px-Tapfläche des Herzens genug Luft. */
.reel-rail { position:absolute; right:11px; bottom:74px; display:flex; flex-direction:column; gap:10px; align-items:center; z-index:4; }
.reel-btn { width:36px; height:36px; border-radius:50%; background:rgba(255,255,255,.16);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); display:grid; place-items:center;
  color:#fff; cursor:pointer; transition: transform .25s var(--ease), background .25s; }
.reel-btn:hover { transform: scale(1.14); background:rgba(255,255,255,.28); }
/* Das Herz ist der einzige echte Knopf in der Reihe. Es bleibt optisch 36px
   klein — im massstäblichen Phone-Mockup wäre ein 44px-Kreis grotesk —, bekommt
   die Tap-Fläche aber unsichtbar über einen Overlay. Das Deko-Symbol (Kommentar)
   darunter ist ein <span> und braucht keine. */
button.reel-btn { position:relative; border:none; padding:0; font:inherit; }
button.reel-btn::after { content:""; position:absolute; top:50%; left:50%;
  width:44px; height:44px; transform:translate(-50%,-50%); }
.reel-btn.liked { background:#ff3b5c; }

.reel-meta { position:absolute; left:14px; bottom:18px; right:60px; color:#fff; z-index:4; text-shadow:0 1px 8px rgba(0,0,0,.5); }
.reel-handle { font-weight:800; font-size:14px; }
.reel-cap { font-size:11.5px; opacity:.95; margin-top:3px; line-height:1.35; }

.reel-prog { position:absolute; left:0; right:0; bottom:0; height:3px; background:rgba(255,255,255,.28); z-index:6; }
.reel-prog i { display:block; height:100%; width:0; background:var(--holo); }
/* Die Clips sind 8 s lang und laufen in Schleife — die Leiste deshalb ebenso,
   nicht `forwards` (das blieb nach einem Durchlauf voll stehen). */
.reel-prog.playing i { animation: reelProg 8s linear infinite; }
@keyframes reelProg { from{ width:0; } to{ width:100%; } }
html[data-motion="0"] .reel-prog.playing i { width:60%; animation:none; }

/* client chips */
.client-chips { display:flex; flex-wrap:wrap; gap:10px; }
.client-chip { padding:11px 18px; border:1px solid var(--line); border-radius:999px; font-weight:700; font-size:14px;
  background:var(--panel); transition: transform .3s var(--ease), border-color .3s, box-shadow .3s; cursor:default; }
.client-chip:hover { transform: translateY(-3px); border-color:transparent; box-shadow:0 14px 30px -16px var(--holo-peri); }
.client-chip:hover .cc-dot { transform:scale(1.4); }
.cc-dot { display:inline-block; width:7px; height:7px; border-radius:50%; background:var(--holo); margin-right:8px; vertical-align:middle; transition:transform .3s; }
.mt-s{margin-top:14px}.mt-m{margin-top:28px}.mt-l{margin-top:48px}
.flex{display:flex}.gap-s{gap:12px}.gap-m{gap:20px}.wrap-f{flex-wrap:wrap}.aic{align-items:center}
.tcenter{text-align:center}
.divider{height:1px;background:var(--line);border:none;margin:0}

/* ============================================================
   VORGEHEN — "Der Weg nach oben" (Journey-Pfad statt 4 Kacheln)
   ============================================================ */
.journey { position:relative; margin-top: clamp(40px,5vw,76px); }

/* ---- Aufsteigende Schiene: Nodes auf einer Holo-Diagonale ---- */
.journey-rail { position:relative; height: clamp(240px,27vw,320px); }
.journey-svg { position:absolute; inset:0; width:100%; height:100%; overflow:visible; z-index:0; pointer-events:none; }
.journey-svg .jline { fill:none; stroke:url(#jgrad); stroke-width:2.5; stroke-linecap:round; stroke-linejoin:round; vector-effect:non-scaling-stroke; }
.journey-svg .jline-bg { fill:none; stroke:var(--line); stroke-width:1.5; vector-effect:non-scaling-stroke; }

.jnode-wrap { position:absolute; left:var(--cx); top:var(--cy); transform:translate(-50%,-50%); z-index:2; }

/* Node-Kreis */
.jstep-node {
  position:relative; width: clamp(64px,7vw,84px); height: clamp(64px,7vw,84px);
  border-radius:50%; display:grid; place-items:center; background:var(--panel); border:1px solid var(--line);
  color:var(--text); box-shadow: 0 14px 34px -18px rgba(20,16,40,.5);
  transition: transform .5s var(--ease), box-shadow .5s, border-color .5s, background .5s, color .5s;
}
/* dünner Holo-Ring um jeden Node, damit er auf der Schiene „sitzt" */
.jstep-node::before {
  content:""; position:absolute; inset:-5px; border-radius:50%; z-index:-1;
  background:var(--holo); opacity:.18; transition:opacity .5s var(--ease);
}
.jnode-wrap:hover .jstep-node {
  border-color:transparent; background:var(--holo); color:#1a1a1a;
  transform: translateY(-7px) scale(1.07); box-shadow: 0 26px 48px -18px var(--holo-peri);
}
.jnode-wrap:hover .jstep-node::before { opacity:.45; }

/* Zielschritt = Belohnung, dauerhaft holo-gefüllt + grösser */
.jnode-wrap.is-goal .jstep-node {
  background:var(--holo); border-color:transparent; color:#1a1a1a;
  box-shadow: 0 22px 46px -18px var(--holo-peri); transform: scale(1.12);
}
.jnode-wrap.is-goal:hover .jstep-node { transform: translateY(-7px) scale(1.18); }
.jnode-wrap.is-goal .jstep-node::before { opacity:.4; inset:-7px; }

/* Info-Reihe (sauber ausgerichtet, Nummer lebt hier — kein Überlappen) */
.journey-infos { display:grid; grid-template-columns: repeat(4,1fr); gap: clamp(14px,2vw,30px); margin-top: clamp(20px,2.4vw,34px); }
.jstep-info { text-align:center; padding-inline: clamp(4px,1vw,16px); }
.jstep-num {
  display:inline-block; font-weight:900; font-size: clamp(30px,3vw,44px); line-height:1; letter-spacing:-.04em;
  color:transparent; -webkit-text-stroke:1.4px var(--line-strong); opacity:.5;
}
.jstep-info.is-goal .jstep-num { -webkit-text-stroke:0; background:var(--holo); -webkit-background-clip:text; background-clip:text; color:transparent; opacity:1; }
.jstep-info h3 { margin:10px 0 8px; font-size:clamp(17px,1.5vw,22px); text-transform:uppercase; letter-spacing:-.01em; line-height:1; }
.jstep-info.is-goal h3 { background:var(--holo); -webkit-background-clip:text; background-clip:text; color:transparent; }
.jstep-info p { margin:0; font-size:14.5px; line-height:1.5; color:var(--text-soft); max-width:25ch; margin-inline:auto; text-wrap:pretty; }

@media (max-width: 880px) {
  .journey-rail { display:none; }
  .journey-infos { grid-template-columns: repeat(2,1fr); gap: clamp(20px,4vw,30px); }
  .jstep-num { -webkit-text-stroke:1.2px var(--line-strong); }
}
@media (max-width: 480px) {
  .journey-infos { grid-template-columns: 1fr; }
}

/* ─── Cookie-Consent ─────────────────────────────────────────────────────────
   Schlichte, nicht aufdringliche Leiste unten. Theme-adaptiv über die
   Design-Variablen (--panel/--text/--line/--holo), passt sich a/b/c an. */
/* Zentrierte Karte statt Leiste am unteren Rand. Der Grund dahinter wird
   abgedunkelt — der Hinweis soll als Entscheidung wahrgenommen werden, nicht
   als Randnotiz. padding-top schafft Platz für den Keks, der oben überlappt. */
.cc-overlay {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center; padding: 20px;
  background: rgba(12,12,20,.52);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  animation: cc-grund .35s ease both;
}
.cookie-consent {
  position: relative; width: 100%; max-width: 420px;
  padding: 62px 30px 26px; text-align: left;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) + 10px);
  box-shadow: 0 30px 80px -24px rgba(12,12,30,.5);
  animation: cc-in .45s cubic-bezier(.22,1,.36,1) both;
}
/* Der Keks sitzt zur Hälfte über der Kartenkante — das nimmt der Karte die
   Strenge und ist das Erste, was das Auge findet. */
.cc-keks {
  position: absolute; top: -46px; left: 50%; transform: translateX(-50%);
  width: 92px; height: 92px; display: block;
  filter: drop-shadow(0 10px 20px rgba(60,40,20,.28));
}
.cc-titel { font-size: clamp(21px,2.2vw,26px); line-height: 1.2; margin: 0 0 12px;
  text-transform: none; letter-spacing: -.01em; }
/* Die Karte bekommt den Fokus, damit die Vorlesesoftware im Dialog landet —
   ein Fokusring um die ganze Karte waere dabei aber nur Laerm. */
.cookie-consent:focus { outline: none; }
@keyframes cc-grund { from { opacity: 0; } to { opacity: 1; } }
@keyframes cc-in { from { opacity: 0; transform: translateY(16px) scale(.97); } to { opacity: 1; transform: none; } }
html[data-motion="0"] .cookie-consent,
html[data-motion="0"] .cc-overlay { animation: none; }
.cc-text { margin: 0 0 22px; font-size: 14.5px; line-height: 1.55; color: var(--text-soft); }
/* white-space:nowrap entfaellt: der Link ist jetzt ein ganzer Satzteil und muss
   umbrechen duerfen, sonst sprengt er die Karte auf schmalen Geraeten. */
.cc-link { color: var(--text); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.cc-actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }
.cc-btn {
  font-family: inherit; font-size: 13.5px; font-weight: 700; letter-spacing: .01em;
  padding: 11px 20px; border-radius: calc(var(--radius) + 2px); cursor: pointer;
  border: 1px solid var(--line); white-space: nowrap;
  transition: transform .15s ease, opacity .15s ease, border-color .15s ease, color .15s ease;
}
.cc-btn:focus-visible { outline: 2px solid var(--holo-peri); outline-offset: 2px; }
.cc-btn:active { transform: scale(.97); }
.cc-decline { background: transparent; color: var(--text-soft); }
.cc-decline:hover { border-color: var(--line-strong); color: var(--text); }
/* Ink statt Weiss: der Holo-Verlauf ist pastellfarben, weisser Text kam je nach
   Stop nur auf 1,30 bis 3,35 Kontrast und fiel damit durch WCAG AA (4,5 nötig).
   Mit #1a1a1a sind es 5,19 bis 13,41. Entspricht auch allen anderen Flächen auf
   dem Verlauf (aktive Pille, Bento-Karten, Social-Chip beim Überfahren). */
.cc-accept { background: var(--holo); color: #1a1a1a; border-color: transparent; font-weight: 800; }
.cc-accept:hover { opacity: .92; }
@media (max-width: 520px) {
  /* Die frühere Leiste am unteren Rand brauchte hier eine Spaltenumstellung und
     eine Safe-Area-Korrektur. Beides entfällt seit der zentrierten Karte — sie
     steht ohnehin mittig und wird vom Rand des Overlays gehalten.
     Geblieben ist: Knöpfe über die volle Breite und 44 px Tap-Höhe. */
  .cookie-consent { padding: 56px 22px 22px; }
  .cc-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .cc-btn { min-height: 44px; font-size: 14px; padding-inline: 12px; }
}

/* Captcha-Container im Kontaktformular. Mit appearance:"interaction-only" ist das
   Turnstile-Widget normalerweise unsichtbar und der Container 0 px hoch — der
   Abstand entsteht nur, wenn Cloudflare tatsächlich ein Challenge einblendet.
   Ohne konfigurierte Keys bleibt das Element komplett leer. */
.captcha-box:not(:empty) { margin: 18px 0 4px; }

/* ============================================================
   RECHTLICHES — Impressum und Datenschutz (legal.jsx)
   Lesetext bewusst 16 px in --text-soft statt .small/--text-dim: Rechtstexte
   werden gelesen, nicht überflogen, und --text-dim verfehlt auf Weiss AA.
   Dienstleister und Cookies stehen als Kästen statt als Tabelle — eine
   dreispaltige Tabelle liefe bei 320 px über den Rand.
   ============================================================ */
.legal { max-width:74ch; }
.legal-sec { padding-block:clamp(28px,3.5vw,44px); border-top:1px solid var(--line); }
.legal-sec:first-child { border-top:0; padding-top:0; }
.legal-kopf { display:flex; align-items:baseline; gap:16px; margin-bottom:16px; }
.legal-nr { font-family:'Space Mono',monospace; font-size:13px; letter-spacing:.1em; color:var(--text-soft); flex:none; }
/* min-width:0, sonst schrumpft die Überschrift im Flex-Kopf nie unter ihr längstes
   Wort und «VERTRETUNGSBERECHTIGTE» schob die Seite bei 320 px um 72 px über den
   Rand. Die Trennstellen stehen als Weichtrennzeichen in legal.jsx (wie .bento-title). */
.legal h2 { font-size:clamp(22px,2.4vw,30px); text-transform:uppercase; line-height:1.1; min-width:0; hyphens:manual; }
.legal h3 { font-size:17px; letter-spacing:0; line-height:1.3; margin:24px 0 8px; font-weight:700; }
.legal p, .legal li { font-size:16px; line-height:1.65; color:var(--text-soft); }
.legal ul { margin:0 0 1em; padding-left:1.2em; }
.legal li { margin-bottom:4px; }
.legal a { color:var(--text); text-decoration:underline; text-underline-offset:3px; overflow-wrap:anywhere; }
.legal strong { color:var(--text); font-weight:700; }
.legal address { font-style:normal; }
.legal-kaesten { display:grid; gap:12px; margin:8px 0 18px; }
.legal-kasten { border:1px solid var(--line); border-radius:var(--radius); background:var(--panel); padding:16px 18px; }
.legal-kasten p { margin:4px 0 0; }
.legal-kasten .legal-meta { font-size:14px; }
.legal-einwilligung { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:14px 24px; }
.legal-einwilligung p { margin:0; }
.legal-stand { font-size:14px; color:var(--text-soft); margin-top:8px; }

/* ============================================================
   MOBILE-FEINSCHLIFF — bewusst am Dateiende
   Diese Regeln überschreiben Basis-Definitionen, die weiter oben stehen.
   Bei gleicher Spezifität entscheidet die Reihenfolge, deshalb ganz unten.
   ============================================================ */
@media (max-width: 760px) {
  /* Die Pfeile sassen früher im .eyebrow-row weit über den Karten und wurden
     mobil ausgeblendet. Seit sie in derselben Reihe wie die Punkte stehen,
     bleiben sie auch auf dem Handy — sie führen dort zusammen mit dem Wischen.
     44 px Kantenlänge halten das Tap-Ziel ein.
     Die Punkte weichen dafür dem Zähler: acht Punkte à 44 px plus zwei Pfeile
     ergeben 440 px und sprengten 390 px um 59 px. Der Zähler bleibt bei jeder
     Anzahl Kundenstimmen gleich breit. */
  .tnav-row .tdots { display:none; }
  .tnav-zaehler { display:block; }
  /* Kleinere Karte, und nur noch die direkten Nachbarn: Bei ±2 bliebe von der
     dritten Karte ein 28-px-Streifen übrig, zu wenig zum Antippen. Der grössere
     X-Versatz hält die sichtbare Lasche bei 47 px, also über dem 44-px-Tap-Ziel. */
  .tstack { --tcard-w: 300px; --tcard-h: 465px; --tstage-h: 520px; --cut: 24px;
    --t1: 58px; --t2: 120px;
    /* Der Stapel nutzt die volle Viewport-Breite und wird dort geklippt.
       Nötig, weil visibility:hidden ein Element NICHT aus dem Layout nimmt — die
       ausgeblendeten Karten erzeugten sonst 118 px horizontalen Überlauf.
       clip statt hidden, damit kein Scroll-Container entsteht (overflow:hidden
       würde ausserdem die y-Achse mit einfangen). */
    margin-inline: calc(var(--gutter) * -1); overflow-x: clip; }
  .tstack-item[data-pos="1"], .tstack-item[data-pos="-1"] { --ty:14px; }
  /* Bei plus/minus 2 blieben nur 28px Streifen uebrig — zu wenig zum Antippen,
     deshalb auf dem Handy nur die direkten Nachbarn zeigen. */
  .tstack-item[data-pos="2"],
  .tstack-item[data-pos="-2"] { --op:0; --z:1; pointer-events:none; visibility:hidden; }
  .tcard-in { padding: 20px 22px; }
  .tcard .qtext { font-size:14.5px; line-height:1.45; -webkit-line-clamp:14; line-clamp:14; }
  .tavatar { width:44px; height:44px; }
}
@media (max-width: 640px) {
  .tcard .trole { font-size:14px; }
  .amedia-cap { font-size:14px; }
  .jstep-info p { font-size:15.5px; }
}
@media (max-width: 640px) {
  /* mailto-Link auf 44px Tap-Höhe bringen (7px ergaben gemessen 43px) */
  .h-mail { padding-block: 8px; }
}
@media (max-width: 640px) {
  /* Firmenlogos im Band auf dem Handy kleiner als am Desktop — Logos in voller
     Desktop-Höhe neben 44 px Tap-Zielen wirken zu dominant und drängen das Band
     aus der Breite. Wächst mit der Desktop-Grösse mit (dort 46–60 px). */
  .logo-ph .lp-logo { height:36px; max-width:150px; }
}

@media (max-width: 920px) {
  /* Mobil bleiben von sechs Chips nur drei stehen (.opt ist ausgeblendet). Mit
     den Desktop-Koordinaten standen Instagram und Facebook fast senkrecht
     übereinander am linken Rand und YouTube allein rechts — das Bild kippte nach
     links und wirkte zufällig. Hier ein flacher Bogen über die Bandbreite:
     links tief, Mitte hoch, rechts tief. */
  .float-chip[data-soc="instagram"] { left:0%;   top:52%;  right:auto; bottom:auto; }
  .float-chip[data-soc="facebook"]  { left:36%;  top:4%;   right:auto; bottom:auto; }
  .float-chip[data-soc="youtube"]   { right:0%;  top:46%;  left:auto;  bottom:auto; }
}

@media (max-width: 600px) {
  /* Dauer der kleinen Handy-Runde (bobM). Die Umlaufzeiten je Kanal sind auf die
     langen Desktop-Wege ausgelegt (55–78 s); auf dem rund 140 px kurzen Handy-Weg
     stünden die Icons damit fast still. 40 s ergibt rund 3,5 px/s. Gleiche
     Spezifität wie die Regeln je Kanal, gewinnt also nur, weil sie danach steht. */
  .float-chip[data-soc] .float-bob { --wdur:40s; }
}

@media (max-width: 640px) {
  /* Die Textlinks sind die Wegweiser zwischen den Abschnitten und mit 28px die
     am schwersten zu treffenden Ziele der Seite. Das Polster wirkt nur nach
     aussen, die Unterstreichung sitzt weiterhin am Text. */
  .linkarrow { padding-block: 8px; min-height: 44px; }
}

@media (max-width: 640px) {
  /* Der diagonale Verlaufspfad (.journey-rail) ist auf dem Handy ausgeblendet —
     ohne Ersatz bleibt von „In vier Schritten sichtbar" eine zentrierte
     Aufzählung ohne Weg. Hier läuft derselbe Pfad senkrecht: die Schrittnummern
     sind die Knoten, die Holo-Segmente dazwischen verbinden sie. Die Nummer des
     letzten Schritts ist bereits per .is-goal holo-gefüllt und schliesst die
     Kette sichtbar ab. */
  .journey-infos { grid-template-columns: 1fr; gap: 0; }
  .jstep-info { position:relative; display:grid; grid-template-columns: 44px 1fr;
    column-gap: 16px; text-align:left; padding: 0 0 26px; }
  .jstep-info:last-child { padding-bottom: 0; }
  .jstep-info::before { content:""; position:absolute; left:21px; top:48px; bottom:2px;
    width:2px; border-radius:1px; background:var(--holo); opacity:.5; }
  .jstep-info:last-child::before { display:none; }
  .jstep-num { grid-column:1; grid-row:1 / span 2; justify-self:center;
    width:44px; height:44px; display:grid; place-items:center;
    font-size:19px; line-height:1; }
  .jstep-info h3 { grid-column:2; grid-row:1; margin:9px 0 0; }
  .jstep-info p { grid-column:2; grid-row:2; margin-inline:0; max-width:none; }
}
