/* =====================================================================
   EFFECTS — Schiefer-Untergrund, Glas, Glow, Kristalle, Animationen.
   Alles prozedural: keine Bilddateien, keine externen Requests.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1) SCHIEFER-HINTERGRUND
   Vier gestapelte Ebenen ergeben den Moselschiefer aus der Vorlage:
      .bg__photo   – optionales echtes Foto (Hook in tokens.css)
      .bg__grain   – SVG-Rauschen = Schieferkorn
      .bg__strata  – schräge Spaltflächen des Gesteins
      #bg-canvas   – driftende Punktwolke (JS-Modul "background")
   --------------------------------------------------------------------- */

.bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(120% 90% at 12% -10%, rgba(62, 240, 180, 0.16), transparent 55%),
    radial-gradient(110% 80% at 88% 0%,  rgba(168, 119, 255, 0.18), transparent 58%),
    radial-gradient(90% 70% at 50% 108%, rgba(56, 200, 255, 0.14), transparent 60%),
    linear-gradient(178deg, var(--slate-800), var(--slate-900) 45%, #05090c);
}

.bg > * { position: absolute; inset: 0; }

.bg__photo {
  background-image: var(--bg-photo);
  background-size: cover;
  background-position: center;
  opacity: var(--bg-photo-opacity);
  mix-blend-mode: luminosity;
}

/* Schieferkorn: feines Rauschen, per SVG-Filter erzeugt */
.bg__grain {
  background-image: url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'>\
<filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/>\
<feColorMatrix type='saturate' values='0'/></filter>\
<rect width='220' height='220' filter='url(%23n)' opacity='0.55'/></svg>");
  opacity: 0.16;
  mix-blend-mode: overlay;
}

/* Spaltflächen — der plattige Bruch von Schiefer */
.bg__strata {
  background-image:
    repeating-linear-gradient(101deg,
      rgba(255, 255, 255, 0.028) 0 1px,
      transparent 1px 5px,
      rgba(0, 0, 0, 0.14) 5px 7px,
      transparent 7px 26px),
    repeating-linear-gradient(96deg,
      rgba(255, 255, 255, 0.02) 0 2px,
      transparent 2px 60px);
  opacity: 0.7;
  -webkit-mask-image: radial-gradient(130% 100% at 50% 30%, #000 25%, transparent 88%);
          mask-image: radial-gradient(130% 100% at 50% 30%, #000 25%, transparent 88%);
}

#bg-canvas { width: 100%; height: 100%; opacity: 0.85; }

/* ---------------------------------------------------------------------
   2) GLAS
   .glass       – Standard-Glasfläche
   .glass--lit  – zusätzlich innerer Farbverlauf (die "Tafel")
   .glass--edge – heller Lichtsaum an der Oberkante
   --------------------------------------------------------------------- */

.glass {
  position: relative;
  background: var(--glass-bg);
  border-radius: var(--r-lg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(140%);
          backdrop-filter: blur(var(--glass-blur)) saturate(140%);
  box-shadow:
    0 0 0 1px var(--glass-line) inset,
    0 26px 60px -32px rgba(0, 0, 0, 0.9);
}

.glass--soft { background: var(--glass-bg-soft); }

.glass--lit::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--grad-panel);
  opacity: 0.75;
  pointer-events: none;
}

/* Lichtkante oben — lässt die Fläche wie eine echte Scheibe wirken */
.glass--edge::after {
  content: "";
  position: absolute;
  inset-inline: 12%;
  top: 0;
  height: 1px;
  background: var(--grad-line);
  opacity: 0.85;
  pointer-events: none;
}

/* Inhalt über den Pseudo-Ebenen halten */
.glass > * { position: relative; z-index: 1; }

/* ---------------------------------------------------------------------
   3) INTERAKTIVER GLANZ
   Ein dem Cursor folgender Lichtfleck. Die Position setzt
   js/modules/glow.js über --mx / --my.
   --------------------------------------------------------------------- */

.sheen { --mx: 50%; --my: 0%; overflow: hidden; }
.sheen > .sheen__layer {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(260px circle at var(--mx) var(--my),
              rgba(120, 240, 220, 0.16), transparent 62%);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
  pointer-events: none;
  z-index: 0;
}
.sheen:hover > .sheen__layer { opacity: 1; }

/* ---------------------------------------------------------------------
   4) KRISTALLE — schwebende Wireframe-Polyeder wie in der Vorlage
   --------------------------------------------------------------------- */

.crystal {
  position: absolute;
  pointer-events: none;
  opacity: 0.5;
  filter: drop-shadow(0 0 14px currentColor);
  animation: float 15s var(--ease) infinite;
}
.crystal--mint   { color: var(--c-mint); }
.crystal--violet { color: var(--c-violet); }
.crystal--cyan   { color: var(--c-cyan); }
.crystal--slow   { animation-duration: 23s; }
.crystal--delay  { animation-delay: -7s; }

@keyframes float {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
  50%      { transform: translate3d(0, -26px, 0) rotate(7deg); }
}

/* Auf schmalen Displays würden die Kristalle über der Schrift liegen */
@media (max-width: 780px) { .crystal { display: none; } }

/* ---------------------------------------------------------------------
   5) LICHTSTROM — der türkis/lila Fluss aus der Vorlage.
   Interpretiert zugleich die Mosel: eine Linie, die durch den Fels läuft.
   --------------------------------------------------------------------- */

.stream {
  position: relative;
  height: 2px;
  border-radius: 2px;
  background: var(--grad-line);
  overflow: visible;
}
.stream::after {
  content: "";
  position: absolute;
  top: -3px; left: 0;
  width: 90px; height: 8px;
  border-radius: 999px;
  background: radial-gradient(closest-side, rgba(180, 255, 245, 0.95), transparent);
  animation: stream-run 6.5s linear infinite;
}
@keyframes stream-run {
  0%   { left: -12%; opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { left: 102%; opacity: 0; }
}

/* ---------------------------------------------------------------------
   6) NETZGRAPH — der Knotenverbund aus der Bildmitte
   --------------------------------------------------------------------- */

.netgraph { width: 100%; height: auto; overflow: visible; }
.netgraph .edge {
  stroke-dasharray: 3 5;
  animation: dash 9s linear infinite;
}
.netgraph .node { transform-box: fill-box; transform-origin: center; }
.netgraph .node--pulse { animation: pulse 3.4s var(--ease) infinite; }
.netgraph .node--pulse:nth-of-type(even) { animation-delay: -1.7s; }

@keyframes dash  { to { stroke-dashoffset: -80; } }
@keyframes pulse {
  0%, 100% { transform: scale(1);   opacity: 0.85; }
  50%      { transform: scale(1.5); opacity: 1; }
}

/* ---------------------------------------------------------------------
   7) REVEAL — Einblenden beim Scrollen (js/modules/reveal.js)
   --------------------------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }
.reveal:nth-child(2) { transition-delay: 0.07s; }
.reveal:nth-child(3) { transition-delay: 0.14s; }
.reveal:nth-child(4) { transition-delay: 0.21s; }
.reveal:nth-child(5) { transition-delay: 0.28s; }
.reveal:nth-child(6) { transition-delay: 0.35s; }

/* ---------------------------------------------------------------------
   8) BARRIEREFREIHEIT — Bewegung abschalten, wenn das System es will
   --------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
}

/* Backdrop-Filter nicht verfügbar? Dann kräftigere Füllung,
   damit Text lesbar bleibt. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass { background: rgba(11, 20, 26, 0.88); }
}
