/*
 *  Copyright (c) 2020 Frederick Umminger. All Rights Reserved.
 *  nebulacoding.com — landing page styles
 */

/* ---------------------------------------------------------------- tokens */

:root {
  --bg: #05060b;
  --bg-lift: #0b0d18;

  --ink: #f4f6fb;
  --ink-soft: #b9c1d4;
  --ink-mute: #78829a;

  --violet: #7c6cf7;
  --cyan: #35d0da;

  --gutter: clamp(1.5rem, 5vw, 4rem);

  --font-display: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ------------------------------------------------------------------ base */

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;

  background-color: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

::selection {
  background: rgba(124, 108, 247, 0.35);
  color: #fff;
}

/* -------------------------------------------------------------- backdrop */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: var(--bg);
}

/* The generative clip reads as drifting particles: enlarged, screened over the
   glow, and masked away from the centre so type stays clean. `.backdrop::after`
   carries the same treatment for the still fallback (see reduced-motion below). */
#background-video,
.backdrop::after {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.16;
  transform: scale(1.6);
  filter: contrast(0.85);
  mix-blend-mode: screen;
  -webkit-mask-image: radial-gradient(58% 58% at 50% 46%, transparent 0%, rgba(0, 0, 0, 0.65) 55%, #000 100%);
  mask-image: radial-gradient(58% 58% at 50% 46%, transparent 0%, rgba(0, 0, 0, 0.65) 55%, #000 100%);
}

/* Slow-drifting nebula light, layered over the video */
.backdrop__glow {
  position: absolute;
  inset: -20%;
  background:
    radial-gradient(38% 42% at 22% 28%, rgba(124, 108, 247, 0.34), transparent 65%),
    radial-gradient(34% 38% at 78% 68%, rgba(53, 208, 218, 0.22), transparent 62%),
    radial-gradient(52% 52% at 50% 50%, rgba(191, 120, 255, 0.10), transparent 70%);
  will-change: transform;
  animation: drift 26s var(--ease) infinite alternate;
}

/* Darkened edges so the type always sits on quiet ground */
.backdrop__vignette {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 90% at 50% 45%, transparent 28%, rgba(5, 6, 11, 0.55) 68%, rgba(5, 6, 11, 0.9) 100%),
    linear-gradient(180deg, rgba(5, 6, 11, 0.72) 0%, rgba(5, 6, 11, 0.25) 35%, rgba(5, 6, 11, 0.85) 100%);
}

/* Fine film grain, keeps the large flat areas from banding.
   Deliberately NOT mix-blend-mode: overlay — a full-screen blend mode over the
   drifting glow forces the whole stack to re-composite on every frame. */
.backdrop__grain {
  position: absolute;
  inset: 0;
  opacity: 0.032;
  pointer-events: none;
  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.8' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------------ hero */

.hero {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  padding: clamp(4rem, 12vh, 8rem) var(--gutter) 2rem;
  text-align: center;
}

/* mark */

.mark {
  position: relative;
  width: clamp(72px, 12vw, 104px);
  aspect-ratio: 1;
  color: var(--ink);
}

/* Glow sits on its own static layer. Putting it on the spinning element as a
   drop-shadow filter forces the browser to re-render the shadow every frame. */
.mark::before {
  content: "";
  position: absolute;
  inset: -60%;
  background: radial-gradient(circle at 50% 50%, rgba(124, 108, 247, 0.34) 0%, rgba(124, 108, 247, 0.12) 32%, rgba(124, 108, 247, 0.04) 52%, transparent 72%);
  pointer-events: none;
}

.mark__svg {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: visible;
  animation: spin 45s linear infinite;

  /* Promote to its own compositing layer so the GPU rotates a cached raster
     instead of re-rasterising the vector paths on every frame.
     Note: do NOT add a static `transform` here (e.g. translateZ(0)). The spin
     keyframes would then interpolate between two mismatched transform lists,
     fall back to matrix interpolation, and — since rotate(360deg) decomposes to
     the identity matrix — the logo would sit perfectly still. */
  will-change: transform;
  backface-visibility: hidden;
}

/* The core sits outside the rotating SVG: animating a child inside it would
   dirty that layer every frame and cancel the promotion above. */
.mark__core {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 11.25%;
  aspect-ratio: 1;
  margin: -5.625% 0 0 -5.625%;
  border-radius: 50%;
  background: currentColor;
  will-change: opacity;
  animation: pulse 4.5s ease-in-out infinite;
}

/* type */

.eyebrow {
  margin: 0;
  font-size: clamp(0.66rem, 1.5vw, 0.76rem);
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.6rem, 9vw, 5.5rem);
  line-height: 1.02;
  letter-spacing: -0.035em;

  background: linear-gradient(180deg, #ffffff 18%, #c9c6f5 72%, #9d97e8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.tagline {
  margin: 0;
  max-width: 32ch;
  font-size: clamp(1.02rem, 2.3vw, 1.35rem);
  line-height: 1.5;
  color: var(--ink-soft);
  text-wrap: balance;
}

.rule {
  width: clamp(92px, 18vw, 148px);
  height: 1px;
  margin-top: 0.75rem;
  background: linear-gradient(90deg, transparent, rgba(150, 138, 255, 1), rgba(90, 226, 235, 0.9), transparent);
  box-shadow: 0 0 14px rgba(124, 108, 247, 0.55);
}

.contact a {
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid rgba(185, 193, 212, 0.35);
  padding-bottom: 2px;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.contact a:hover,
.contact a:focus-visible {
  color: #fff;
  border-color: var(--violet);
}

:focus-visible {
  outline: 2px solid var(--violet);
  outline-offset: 4px;
  border-radius: 2px;
}

/* ---------------------------------------------------------------- footer */

.footer {
  padding: 0 var(--gutter) clamp(1.5rem, 4vh, 2.5rem);
  text-align: center;
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/* ------------------------------------------------------------ animations */

.reveal {
  opacity: 0;
  transform: translateY(16px);
  animation: reveal 0.9s var(--ease) forwards;
  animation-delay: var(--delay, 0ms);
}

@keyframes reveal {
  to {
    opacity: 1;
    transform: none;
  }
}

/* Both endpoints stated explicitly, so the browser interpolates rotation
   per-function rather than guessing an implicit start value. */
@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes pulse {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1; }
}

@keyframes drift {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to   { transform: translate3d(2%, 2%, 0) scale(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
    animation: none;
  }

  .mark__svg,
  .mark__core,
  .backdrop__glow {
    animation: none;
  }

  /* Swap the clip for its own poster frame, so the texture survives without motion. */
  #background-video {
    display: none;
  }

  .backdrop::after {
    content: "";
    background: url("../images/bg-poster.jpg") center / cover no-repeat;
  }
}

/* ------------------------------------------------------------ responsive */

@media (max-width: 640px) {
  .hero {
    gap: 1rem;
    justify-content: center;
  }

  .eyebrow {
    letter-spacing: 0.24em;
  }
}
