/* Goodsides Motion – eigener Code, Regeln: motion-library/README.md. Effekte: accordion, blur-in, fade-left, fade-up, glow-pointer, grain, header-shrink, image-reveal, lightbox, magnetic, menu, nudge, page-transition, shine, split-lines, split-words, spotlight, stagger, tilt, underline */

/* Goodsides Motion – Kern. Eigener Code, keine fremden Bibliotheken. Regeln: motion-library/README.md */

:root {
  --gs-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --gs-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --gs-dur: 0.9s;
  --gs-delay: 0ms;
  --gs-dist: 2rem;
  --gs-accent: currentColor;
  /* Übergang für Einblend-Effekte – Hover-Module hängen ihre eigenen Eigenschaften an */
  --gs-t-reveal: opacity var(--gs-dur) var(--gs-ease) var(--gs-delay), transform var(--gs-dur) var(--gs-ease) var(--gs-delay),
    filter var(--gs-dur) var(--gs-ease) var(--gs-delay), clip-path var(--gs-dur) var(--gs-ease) var(--gs-delay);
}

/* Nur für Screenreader sichtbar (z. B. ganzer Satz bei zerteiltem Text) */
.gs-sr {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Unter dem Bildschirmrand: unsichtbar, bis es ins Bild scrollt (nur mit JavaScript gesetzt) */
.gs-pending {
  opacity: 0 !important;
}

/* Sicherheitsnetz: Läuft das Skript nicht, wird nach 3 Sekunden alles normal angezeigt */
.gs-js:not(.gs-ready) [data-gs] {
  animation: gs-failsafe 0s linear 3s forwards;
}

@keyframes gs-failsafe {
  to {
    opacity: 1;
    transform: none;
    filter: none;
    clip-path: none;
  }
}

/* Pause-Knopf für alles, was sich länger als 5 Sekunden bewegt (WCAG 2.2.2) */
.gs-pause {
  position: absolute;
  z-index: 40;
  right: max(0.75rem, env(safe-area-inset-right));
  bottom: max(0.75rem, env(safe-area-inset-bottom));
  width: 44px;
  height: 44px;
  display: inline-grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  cursor: pointer;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  opacity: 0.75;
  transition: opacity 0.2s ease;
}

.gs-pause:hover,
.gs-pause:focus-visible {
  opacity: 1;
}

.gs-pause:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 2px;
}

.gs-pause svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

[data-gs-paused] *,
[data-gs-paused] *::before,
[data-gs-paused] *::after,
[data-gs-paused]::before,
[data-gs-paused]::after,
[data-gs-paused] {
  animation-play-state: paused !important;
}

/* „Weniger Bewegung“: keine Bewegung, keine Endlos-Animation, alles sofort sichtbar */
@media (prefers-reduced-motion: reduce) {
  [data-gs],
  [data-gs] *,
  [data-gs]::before,
  [data-gs]::after {
    animation: none !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }

  .gs-pending {
    opacity: 1 !important;
  }

  .gs-pause {
    display: none;
  }
}

/* Goodsides Motion – Einblenden beim Scrollen */

[data-gs~='fade-up'] { --gs-from: translate3d(0, var(--gs-dist), 0); }
[data-gs~='fade-down'] { --gs-from: translate3d(0, calc(var(--gs-dist) * -1), 0); }
[data-gs~='fade-left'] { --gs-from: translate3d(calc(var(--gs-dist) * -1.25), 0, 0); }
[data-gs~='fade-right'] { --gs-from: translate3d(calc(var(--gs-dist) * 1.25), 0, 0); }
[data-gs~='zoom-in'] { --gs-from: scale(0.92); }
[data-gs~='blur-in'] { --gs-from: scale(1.03); }
[data-gs~='rotate-in'] { --gs-from: translate3d(0, 1.5rem, 0) rotate(-3deg); transform-origin: 0 100%; }
[data-gs~='flip-up'] { --gs-from: perspective(900px) translate3d(0, 1.5rem, 0) rotateX(16deg); transform-origin: 50% 100%; }
.gs-stagger-child { --gs-from: translate3d(0, 1.25rem, 0); }

:is([data-gs~='fade-up'], [data-gs~='fade-down'], [data-gs~='fade-left'], [data-gs~='fade-right'], [data-gs~='zoom-in'],
  [data-gs~='blur-in'], [data-gs~='rotate-in'], [data-gs~='flip-up'], .gs-stagger-child) {
  transition: var(--gs-t-reveal);
}

@media (prefers-reduced-motion: no-preference) {
  /* Vor dem Start (Klasse gs-js setzt ein Mini-Skript im <head>): kaum sichtbar, aber nie unsichtbar (LCP) */
  .gs-js :is([data-gs~='fade-up'], [data-gs~='fade-down'], [data-gs~='fade-left'], [data-gs~='fade-right'], [data-gs~='zoom-in'],
    [data-gs~='blur-in'], [data-gs~='rotate-in'], [data-gs~='flip-up'], .gs-stagger-child):not(.gs-in),
  :is([data-gs~='fade-up'], [data-gs~='fade-down'], [data-gs~='fade-left'], [data-gs~='fade-right'], [data-gs~='zoom-in'],
    [data-gs~='blur-in'], [data-gs~='rotate-in'], [data-gs~='flip-up'], .gs-stagger-child).gs-pending {
    opacity: 0.15;
    transform: var(--gs-from);
  }

  .gs-js [data-gs~='blur-in']:not(.gs-in),
  [data-gs~='blur-in'].gs-pending {
    filter: blur(14px);
  }
}

:is([data-gs~='fade-up'], [data-gs~='fade-down'], [data-gs~='fade-left'], [data-gs~='fade-right'], [data-gs~='zoom-in'],
  [data-gs~='blur-in'], [data-gs~='rotate-in'], [data-gs~='flip-up'], .gs-stagger-child).gs-in {
  opacity: 1;
  transform: none;
  filter: none;
}

/* Vorhang: eine Farbfläche zieht weg und gibt den (schon gezeichneten) Inhalt frei */
[data-gs~='curtain'] {
  position: relative;
  isolation: isolate;
}

[data-gs~='curtain']::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--gs-curtain, var(--gs-accent));
  transform: scaleX(0);
  transform-origin: 100% 50%;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .gs-js [data-gs~='curtain']:not(.gs-in)::after,
  [data-gs~='curtain'].gs-pending::after {
    transform: scaleX(1);
  }

  [data-gs~='curtain'].gs-in::after {
    transition: transform 1.1s var(--gs-ease-in-out) var(--gs-delay);
  }

  /* Der Vorhang selbst blendet nicht aus – der Inhalt darunter bleibt immer gezeichnet */
  [data-gs~='curtain'].gs-pending {
    opacity: 1 !important;
  }
}

/* Goodsides Motion – Text */

/* Zerteilter Text: Wörter/Zeilen/Buchstaben steigen auf. Screenreader lesen den ganzen Satz (.gs-sr). */
.gs-split {
  display: inline;
}

.gs-w,
.gs-line {
  display: inline-block;
  vertical-align: top;
}

.gs-line {
  display: block;
}

.gs-wi,
.gs-li,
.gs-c {
  display: inline-block;
  transition: opacity 0.7s var(--gs-ease), transform 0.9s var(--gs-ease);
  transition-delay: calc(var(--gs-delay) + var(--i, 0) * var(--gs-step, 45ms));
}

/* Unter dem Bildschirmrand: Zeilen kommen aus einer Maske; im Bild nie unsichtbar (LCP) */
.gs-mask {
  overflow: hidden;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}

@media (prefers-reduced-motion: no-preference) {
  .gs-js :is([data-gs~='split-words'], [data-gs~='split-lines'], [data-gs~='split-chars']):not(.gs-split-ready) {
    opacity: 0.15;
  }

  .gs-split-ready:not(.gs-in) .gs-wi,
  .gs-split-ready:not(.gs-in) .gs-c {
    opacity: 0.15;
    transform: translate3d(0, 0.55em, 0);
  }

  .gs-split-ready:not(.gs-in) .gs-li {
    opacity: 0.15;
    transform: translate3d(0, 0.6em, 0);
  }

  .gs-split-ready.gs-masked:not(.gs-in) .gs-li {
    opacity: 1;
    transform: translate3d(0, 105%, 0);
  }
}

/* Schreibmaschine: Buchstaben erscheinen nacheinander, der Platz ist von Anfang an reserviert (kein Springen) */
.gs-tw .gs-c {
  transition: opacity 0s linear;
  transition-delay: calc(var(--gs-delay) + var(--i, 0) * var(--gs-step, 38ms));
}

@media (prefers-reduced-motion: no-preference) {
  .gs-tw:not(.gs-in) .gs-c {
    opacity: 0;
    transform: none;
  }

  .gs-tw.gs-in::after {
    content: '';
    display: inline-block;
    width: 0.08em;
    height: 1em;
    margin-left: 0.06em;
    vertical-align: -0.12em;
    background: currentColor;
    animation: gs-caret 0.8s steps(1) 5;
  }
}

@keyframes gs-caret {
  50% {
    opacity: 0;
  }
}

/* Wechselnde Wörter: alle Wörter liegen übereinander (Breite = längstes Wort, kein Springen) */
.gs-rw {
  display: inline-grid;
  vertical-align: bottom;
}

.gs-rw > span {
  grid-area: 1 / 1;
  transition: opacity 0.5s var(--gs-ease), transform 0.6s var(--gs-ease);
}

.gs-rw > span:not(.gs-on) {
  opacity: 0;
  transform: translate3d(0, 0.5em, 0);
}

.gs-rw > span.gs-off {
  transform: translate3d(0, -0.5em, 0);
}

/* Marker: Hervorhebung zieht sich unter den Text (auch über Zeilenumbrüche) */
[data-gs~='highlight'] {
  background-image: linear-gradient(var(--gs-mark, color-mix(in srgb, var(--gs-accent) 30%, transparent)), var(--gs-mark, color-mix(in srgb, var(--gs-accent) 30%, transparent)));
  background-repeat: no-repeat;
  background-position: 0 88%;
  background-size: 100% 0.38em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition: background-size 1s var(--gs-ease) calc(var(--gs-delay) + 0.2s);
}

@media (prefers-reduced-motion: no-preference) {
  .gs-js [data-gs~='highlight']:not(.gs-in),
  [data-gs~='highlight'].gs-wait {
    background-size: 0% 0.38em;
  }
}

/* Einmaliger Glanz über eine Überschrift */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .gs-shine-run {
    background-image: linear-gradient(105deg, var(--gs-text) 42%, var(--gs-shine, #fff) 50%, var(--gs-text) 58%);
    background-size: 260% 100%;
    background-position: 100% 0;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: gs-shine 1.8s var(--gs-ease-in-out) 1 forwards;
  }
}

@keyframes gs-shine {
  to {
    background-position: 0 0;
  }
}

/* Zähler: Ziffern gleich breit, damit nichts springt */
[data-gs~='counter'] {
  font-variant-numeric: tabular-nums;
}

/* Goodsides Motion – Bilder */

/* Langsamer Zoom (Ken Burns): Bild in einem Rahmen mit overflow:hidden. Endlos → Pause-Knopf. */
[data-gs~='ken-burns'] {
  transform-origin: var(--gs-kb-origin, 60% 40%);
}

@media (prefers-reduced-motion: no-preference) {
  [data-gs~='ken-burns'].gs-kb-on {
    animation: gs-ken-burns var(--gs-kb-dur, 22s) var(--gs-ease-in-out) infinite alternate;
  }
}

@keyframes gs-ken-burns {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.12) translate3d(-1.5%, -1%, 0);
  }
}

/* Parallax und Wachsen beim Scrollen: nur wo der Browser Scroll-Animationen kann (Chrome, Safari) – sonst ruhig */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    [data-gs~='parallax'] {
      animation: gs-parallax linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }

    [data-gs~='scroll-zoom'] {
      animation: gs-scroll-zoom linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 45%;
    }
  }
}

@keyframes gs-parallax {
  from {
    transform: translate3d(0, calc(var(--gs-speed, 0.25) * -12vh), 0) scale(var(--gs-parallax-scale, 1.12));
  }
  to {
    transform: translate3d(0, calc(var(--gs-speed, 0.25) * 12vh), 0) scale(var(--gs-parallax-scale, 1.12));
  }
}

@keyframes gs-scroll-zoom {
  from {
    transform: scale(0.86);
  }
  to {
    transform: scale(1);
  }
}

/* Bild aufdecken: Farbfläche zieht weg, das Bild darunter zoomt leicht zurück */
[data-gs~='image-reveal'] {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

[data-gs~='image-reveal']::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--gs-curtain, var(--gs-accent));
  transform: scaleY(0);
  transform-origin: 50% 0;
  pointer-events: none;
}

[data-gs~='image-reveal'] img {
  transition: transform 1.4s var(--gs-ease) var(--gs-delay);
}

@media (prefers-reduced-motion: no-preference) {
  .gs-js [data-gs~='image-reveal']:not(.gs-in)::after,
  [data-gs~='image-reveal'].gs-wait::after {
    transform: scaleY(1);
  }

  .gs-js [data-gs~='image-reveal']:not(.gs-in) img,
  [data-gs~='image-reveal'].gs-wait img {
    transform: scale(1.18);
  }

  [data-gs~='image-reveal'].gs-in::after {
    transition: transform 1s var(--gs-ease-in-out) var(--gs-delay);
  }
}

/* Vorher/Nachher: ohne JavaScript nebeneinander, mit JavaScript übereinander mit Schieber */
[data-gs~='before-after'] {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
}

[data-gs~='before-after'] > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

[data-gs~='before-after'].gs-ba-on {
  display: block;
  overflow: hidden;
  touch-action: pan-y;
}

[data-gs~='before-after'].gs-ba-on > img:last-of-type {
  position: absolute;
  inset: 0;
  clip-path: inset(0 0 0 var(--gs-ba, 50%));
}

.gs-ba-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--gs-ba, 50%);
  width: 2px;
  margin-left: -1px;
  background: #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
  pointer-events: none;
  z-index: 3;
}

.gs-ba-line::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 6l-6 6 6 6M15 6l6 6-6 6' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 22px no-repeat;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
}

.gs-ba-range {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
}

.gs-ba-range:focus-visible + .gs-ba-line::after {
  outline: 3px solid var(--gs-accent, #111);
  outline-offset: 3px;
}

.gs-ba-label {
  position: absolute;
  top: 0.75rem;
  z-index: 3;
  padding: 0.3rem 0.65rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  pointer-events: none;
}

.gs-ba-label.gs-before {
  left: 0.75rem;
}

.gs-ba-label.gs-after {
  right: 0.75rem;
}

/* 3D-Kippen: nur mit Maus */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  [data-gs~='tilt'] {
    transition: var(--gs-t-reveal), rotate 0.4s var(--gs-ease);
    transform-style: preserve-3d;
  }

  [data-gs~='tilt'].gs-tilting {
    transform: perspective(900px) rotateX(var(--gs-rx, 0deg)) rotateY(var(--gs-ry, 0deg));
    transition: transform 0.15s linear;
  }
}

/* Großansicht (Lightbox) */
.gs-lightbox {
  max-width: min(92vw, 1400px);
  max-height: 92vh;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: visible;
}

.gs-lightbox::backdrop {
  background: rgba(0, 0, 0, 0.88);
}

.gs-lightbox img {
  display: block;
  max-width: 100%;
  max-height: 88vh;
  margin: 0 auto;
  border-radius: 0.5rem;
}

.gs-lightbox-close {
  position: absolute;
  top: -3.25rem;
  right: 0;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: #fff;
  color: #111;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

@media (prefers-reduced-motion: no-preference) {
  .gs-lightbox[open] {
    animation: gs-pop 0.35s var(--gs-ease);
  }
}

@keyframes gs-pop {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
}

/* Goodsides Motion – Scrollen (natives Scrollen bleibt immer erhalten, keine Scroll-Übernahme) */

/* Fortschrittsbalken oben: <div data-gs="progress"></div> */
[data-gs~='progress'] {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  height: 3px;
  background: var(--gs-progress, var(--gs-accent));
  transform: scaleX(var(--gs-p, 0));
  transform-origin: 0 50%;
  pointer-events: none;
}

@supports (animation-timeline: scroll()) {
  [data-gs~='progress'] {
    animation: gs-progress linear both;
    animation-timeline: scroll(root);
  }
}

@keyframes gs-progress {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/* Karten stapeln sich: direkte Kinder kleben nacheinander oben fest */
[data-gs~='stack'] > * {
  position: sticky;
  top: calc(var(--gs-stack-top, 5.5rem) + var(--i, 0) * var(--gs-stack-step, 1rem));
}

/* Waagerecht wischen (natives Scrollen mit Einrasten) + Knöpfe */
[data-gs~='snap-row'] {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: var(--gs-snap-width, min(82%, 22rem));
  gap: var(--gs-snap-gap, 1rem);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gs-snap-pad, 0px);
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}

[data-gs~='snap-row'] > * {
  scroll-snap-align: start;
}

[data-gs~='snap-row']:focus-visible {
  outline: 3px solid var(--gs-accent);
  outline-offset: 4px;
}

.gs-snap-nav {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.gs-snap-nav button {
  width: 44px;
  height: 44px;
  display: inline-grid;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.gs-snap-nav button:disabled {
  opacity: 0.35;
  cursor: default;
}

/* Kopfzeile wird beim Scrollen kompakt (Hintergrund + Schatten, Logo etwas kleiner) */
[data-gs~='header-shrink'] {
  transition: background-color 0.35s ease, box-shadow 0.35s ease, -webkit-backdrop-filter 0.35s ease, backdrop-filter 0.35s ease;
}

[data-gs~='header-shrink'] .gs-logo,
[data-gs~='header-shrink'] [data-gs-logo] {
  transition: transform 0.35s var(--gs-ease);
  transform-origin: 0 50%;
}

[data-gs~='header-shrink'].gs-scrolled {
  background-color: var(--gs-header-bg, rgba(255, 255, 255, 0.86));
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}

[data-gs~='header-shrink'].gs-scrolled .gs-logo,
[data-gs~='header-shrink'].gs-scrolled [data-gs-logo] {
  transform: scale(0.86);
}

/* Nach oben */
[data-gs~='to-top'] {
  position: fixed;
  right: max(1rem, env(safe-area-inset-right));
  bottom: max(1rem, env(safe-area-inset-bottom));
  z-index: 50;
  width: 48px;
  height: 48px;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  background: var(--gs-to-top-bg, #111);
  color: var(--gs-to-top-fg, #fff);
  text-decoration: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
  transition: opacity 0.3s ease, transform 0.4s var(--gs-ease);
}

.gs-ready [data-gs~='to-top']:not(.gs-show) {
  opacity: 0;
  transform: translate3d(0, 1rem, 0);
  pointer-events: none;
}

/* Goodsides Motion – Hover & Klick (Hover nur mit Maus; Tastatur-Fokus bekommt den gleichen Effekt) */

/* Unterstreichung wächst */
[data-gs~='underline'] {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: var(--gs-t-reveal), background-size 0.35s var(--gs-ease);
}

[data-gs~='underline'][aria-current='page'],
[data-gs~='underline']:focus-visible {
  background-size: 100% 1px;
}

/* Karte hebt sich */
[data-gs~='lift'] {
  transition: var(--gs-t-reveal), translate 0.4s var(--gs-ease), box-shadow 0.4s var(--gs-ease);
}

[data-gs~='lift']:focus-within {
  translate: 0 -6px;
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.28);
}

/* Knopf folgt der Maus */
[data-gs~='magnetic'] {
  transition: var(--gs-t-reveal), translate 0.35s var(--gs-ease);
}

/* Glanz läuft über den Knopf */
[data-gs~='shine'] {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

[data-gs~='shine']::after {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.45), transparent);
  transform: translate3d(-120%, 0, 0) skewX(-18deg);
  pointer-events: none;
}

[data-gs~='shine']:focus-visible::after {
  transform: translate3d(320%, 0, 0) skewX(-18deg);
  transition: transform 0.9s var(--gs-ease);
}

/* Pfeil/Symbol schiebt nach rechts */
[data-gs~='nudge'] :is(svg, .gs-arrow) {
  transition: translate 0.35s var(--gs-ease);
}

[data-gs~='nudge']:focus-visible :is(svg, .gs-arrow) {
  translate: 0.3em 0;
}

@media (hover: hover) and (pointer: fine) {
  [data-gs~='underline']:hover {
    background-size: 100% 1px;
  }

  [data-gs~='lift']:hover {
    translate: 0 -6px;
    box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.28);
  }

  [data-gs~='magnetic'].gs-magnet {
    translate: var(--gs-mx, 0) var(--gs-my, 0);
    transition: var(--gs-t-reveal), translate 0.12s linear;
  }

  [data-gs~='shine']:hover::after {
    transform: translate3d(320%, 0, 0) skewX(-18deg);
    transition: transform 0.9s var(--gs-ease);
  }

  [data-gs~='nudge']:hover :is(svg, .gs-arrow) {
    translate: 0.3em 0;
  }

  /* Lichtschein auf der Karte folgt der Maus */
  [data-gs~='spotlight'] {
    position: relative;
    isolation: isolate;
  }

  [data-gs~='spotlight']::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: radial-gradient(circle at var(--gs-x, 50%) var(--gs-y, 50%), var(--gs-spot, rgba(255, 255, 255, 0.16)), transparent 45%);
    opacity: 0;
    transition: opacity 0.35s ease;
    pointer-events: none;
  }

  [data-gs~='spotlight']:hover::before {
    opacity: 1;
  }
}

/* Puls-Ring: pulsiert 3-mal und hört auf (unter 5 Sekunden, WCAG 2.2.2) */
[data-gs~='ping'] {
  position: relative;
}

@media (prefers-reduced-motion: no-preference) {
  [data-gs~='ping'].gs-in::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    border: 2px solid var(--gs-ping, currentColor);
    pointer-events: none;
    animation: gs-ping 1.5s cubic-bezier(0, 0, 0.2, 1) 3;
  }
}

@keyframes gs-ping {
  from {
    opacity: 0.7;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(1.6);
  }
}

/* Klick-Welle */
[data-gs~='ripple'] {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.gs-ripple {
  position: absolute;
  z-index: -1;
  width: var(--gs-r);
  height: var(--gs-r);
  margin: calc(var(--gs-r) / -2) 0 0 calc(var(--gs-r) / -2);
  border-radius: 50%;
  background: var(--gs-ripple, currentColor);
  opacity: 0.25;
  transform: scale(0);
  animation: gs-ripple 0.6s var(--gs-ease) forwards;
  pointer-events: none;
}

@keyframes gs-ripple {
  to {
    transform: scale(1);
    opacity: 0;
  }
}

/* Goodsides Motion – Hintergrund (Endlos-Bewegung immer mit Pause-Knopf) */

/* Wandernder Farbverlauf: Farben über --gs-c1, --gs-c2, --gs-c3 */
[data-gs~='gradient-drift'] {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

[data-gs~='gradient-drift']::before {
  content: '';
  position: absolute;
  inset: -40%;
  z-index: -1;
  background:
    radial-gradient(40% 40% at 25% 30%, var(--gs-c1, rgba(99, 102, 241, 0.35)), transparent 70%),
    radial-gradient(35% 35% at 75% 60%, var(--gs-c2, rgba(236, 72, 153, 0.28)), transparent 70%),
    radial-gradient(45% 45% at 50% 85%, var(--gs-c3, rgba(16, 185, 129, 0.22)), transparent 70%);
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  [data-gs~='gradient-drift'].gs-loop-on::before {
    animation: gs-drift 24s var(--gs-ease-in-out) infinite alternate;
  }
}

@keyframes gs-drift {
  to {
    transform: translate3d(8%, -6%, 0) rotate(8deg) scale(1.08);
  }
}

/* Schwebende Formen (vom Skript eingefügt, aria-hidden) */
[data-gs~='shapes'] {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

.gs-shape {
  position: absolute;
  z-index: -1;
  width: var(--gs-size);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--gs-shape, var(--gs-c1, rgba(99, 102, 241, 0.22)));
  filter: blur(var(--gs-blur, 40px));
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .gs-loop-on > .gs-shape {
    animation: gs-float var(--gs-float-dur, 16s) var(--gs-ease-in-out) var(--gs-float-delay, 0s) infinite alternate;
  }
}

@keyframes gs-float {
  to {
    transform: translate3d(var(--gs-fx, 6vw), var(--gs-fy, -5vh), 0) scale(1.15);
  }
}

/* Filmkorn: steht still, nur Struktur */
[data-gs~='grain'] {
  position: relative;
  isolation: isolate;
}

[data-gs~='grain']::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: var(--gs-grain, 0.08);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Lichtschein folgt der Maus; ohne Maus ruht er in der Mitte oben */
[data-gs~='glow-pointer'] {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

[data-gs~='glow-pointer']::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(var(--gs-glow-size, 520px) circle at var(--gs-x, 50%) var(--gs-y, 20%), var(--gs-glow, rgba(120, 140, 255, 0.28)), transparent 70%);
  transition: background-position 0.2s linear;
  pointer-events: none;
}

/* Goodsides Motion – Menü, FAQ, Fenster (funktioniert ohne JavaScript, das Skript ergänzt nur Komfort) */

/*
 * Handy-Menü mit dem eingebauten Popover (ohne JavaScript bedienbar, Escape schließt):
 * <button class="gs-menu-button" popovertarget="menu" aria-label="Menü öffnen">…</button>
 * <nav id="menu" popover data-gs="menu" aria-label="Hauptmenü">…Links…</nav>
 * Ab --gs-menu-desktop (Standard 1024px) steht die Navigation normal in der Kopfzeile (siehe Hero-Vorlagen).
 */
/* Grundform mit :where() (Spezifität 0) – Hero-Vorlagen und eigenes CSS überschreiben sie leicht */
:where([data-gs~='menu'][popover]) {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: max(5.5rem, calc(env(safe-area-inset-top) + 4.5rem)) 1.5rem max(2rem, env(safe-area-inset-bottom));
  border: 0;
  background: var(--gs-menu-bg, rgba(10, 10, 10, 0.96));
  color: var(--gs-menu-fg, #fff);
  overflow-y: auto;
}

:where([data-gs~='menu'][popover]):popover-open {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

:where([data-gs~='menu'][popover]) a {
  display: block;
  padding: 0.75rem 0;
  min-height: 44px;
  color: inherit;
  font-size: var(--gs-menu-size, 1.6rem);
  text-decoration: none;
}

.gs-menu-close {
  position: absolute;
  top: max(1rem, env(safe-area-inset-top));
  right: 1rem;
  width: 48px;
  height: 48px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: inherit;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
}

@media (prefers-reduced-motion: no-preference) {
  :where([data-gs~='menu'][popover]) {
    transition: opacity 0.35s var(--gs-ease), transform 0.45s var(--gs-ease), overlay 0.45s allow-discrete, display 0.45s allow-discrete;
    opacity: 0;
    transform: translate3d(0, -1rem, 0);
  }

  :where([data-gs~='menu'][popover]):popover-open {
    opacity: 1;
    transform: none;
  }

  @starting-style {
    :where([data-gs~='menu'][popover]):popover-open {
      opacity: 0;
      transform: translate3d(0, -1rem, 0);
    }
  }

  :where([data-gs~='menu'][popover]):popover-open a {
    animation: gs-menu-item 0.5s var(--gs-ease) both;
    animation-delay: calc(0.05s + var(--i, 0) * 0.05s);
  }
}

@keyframes gs-menu-item {
  from {
    opacity: 0;
    transform: translate3d(0, 0.75rem, 0);
  }
}

/* Ab 1024 px steht die Navigation normal in der Kopfzeile (außer data-gs-menu="always") */
@media (min-width: 1024px) {
  :where([data-gs~='menu'][popover]:not([data-gs-menu='always'])) {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--gs-nav-gap, 2rem);
    position: static;
    inset: auto;
    width: auto;
    height: auto;
    padding: 0;
    background: none;
    color: inherit;
    overflow: visible;
    opacity: 1;
    transform: none;
  }

  :where([data-gs~='menu'][popover]:not([data-gs-menu='always'])) a {
    display: inline-block;
    min-height: 0;
    padding: 0.5rem 0;
    font-size: inherit;
    animation: none;
  }

  [data-gs~='menu']:not([data-gs-menu='always']) > .gs-menu-close,
  :where(.gs-menu-button):not([data-gs-menu='always']) {
    display: none;
  }
}

/* FAQ: <details data-gs="accordion"><summary>Frage</summary><p>Antwort</p></details> */
[data-gs~='accordion'] > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 44px;
}

[data-gs~='accordion'] > summary::-webkit-details-marker {
  display: none;
}

[data-gs~='accordion'] > summary::after {
  content: '';
  flex: none;
  width: 0.65em;
  height: 0.65em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-25%) rotate(45deg);
  transition: transform 0.35s var(--gs-ease);
}

[data-gs~='accordion'][open] > summary::after {
  transform: translateY(15%) rotate(225deg);
}

@media (prefers-reduced-motion: no-preference) {
  [data-gs~='accordion'][open] > :not(summary) {
    animation: gs-accordion 0.45s var(--gs-ease);
  }
}

@keyframes gs-accordion {
  from {
    opacity: 0;
    transform: translate3d(0, -0.4rem, 0);
  }
}

/* Fenster: <a href="kontakt.html" data-gs="modal" data-gs-target="rueckruf">…</a> + <dialog id="rueckruf">…</dialog> */
dialog.gs-modal {
  width: min(92vw, 40rem);
  max-height: 88vh;
  padding: 1.5rem;
  border: 0;
  border-radius: 1rem;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
}

dialog.gs-modal::backdrop {
  background: rgba(0, 0, 0, 0.6);
}

@media (prefers-reduced-motion: no-preference) {
  dialog.gs-modal[open] {
    animation: gs-modal-in 0.4s var(--gs-ease);
  }

  dialog.gs-modal[open]::backdrop {
    animation: gs-fade 0.4s ease;
  }
}

@keyframes gs-modal-in {
  from {
    opacity: 0;
    transform: translate3d(0, 1.5rem, 0) scale(0.97);
  }
}

@keyframes gs-fade {
  from {
    opacity: 0;
  }
}

/* Goodsides Motion – weicher Seitenwechsel, Effekt 'page-transition' (Chrome, Edge, Safari; andere Browser wechseln normal).
   Wirkt für die ganze Website: Das Modul wird nur eingebunden, wenn eine Seite <body data-gs="page-transition"> nutzt. */

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }

  ::view-transition-old(root) {
    animation: gs-page-out 0.28s var(--gs-ease-in-out, ease) both;
  }

  ::view-transition-new(root) {
    animation: gs-page-in 0.45s var(--gs-ease, ease) both;
  }
}

@keyframes gs-page-out {
  to {
    opacity: 0;
    transform: translate3d(0, -0.75rem, 0);
  }
}

@keyframes gs-page-in {
  from {
    opacity: 0;
    transform: translate3d(0, 0.75rem, 0);
  }
}
