/* ==========================================================================
   VANTRIX — base.css
   Reset, typography, layout primitives, ambient background, reveal motion.

   01. Reset
   02. Typography
   03. Layout utilities
   04. Ambient background FX
   05. Reveal motion
   06. Reduced motion
   ========================================================================== */

/* ==========================================================================
   01. Reset
   ========================================================================== */

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

/* The browser's own [hidden] rule is a normal-priority UA style, and any
   author rule setting `display` on the same element — even at equal or
   lower specificity — wins over it regardless of source order. Every
   component here that sets an explicit `display` (.dash, .dash-coach,
   .dash-loading, .settings-lock-note, the img reset below, …) silently
   ignored `el.hidden = true` as a result: the dashboard/history/settings
   shell rendered on top of its own loading screen from first paint,
   which is why the page loaded looking broken and needed scrolling to
   see the "hidden" splash above it. */
[hidden] {
  display: none !important;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 92px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100%;
  font-family: var(--font-body);
  font-size: clamp(0.98rem, 0.94rem + 0.2vw, 1.05rem);
  font-weight: 400;
  line-height: 1.65;
  color: var(--ink);
  background: var(--bg);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

body.is-locked {
  overflow: hidden;
}

img,
svg,
video {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input,
a {
  font: inherit;
  color: inherit;
}

button {
  border: 0;
  background: none;
  cursor: pointer;
}

ul,
ol,
dl,
dd,
figure,
blockquote {
  margin: 0;
  padding: 0;
}

li {
  list-style: none;
}

::selection {
  color: #fff;
  background: var(--accent-a45);
}

:focus-visible {
  outline: 2px solid var(--accent-3);
  outline-offset: 3px;
  border-radius: 6px;
}

.skip-link {
  position: fixed;
  top: -100px;
  left: 16px;
  z-index: 200;
  padding: 12px 20px;
  border-radius: var(--r-full);
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  transition: top var(--t) var(--ease);
}

.skip-link:focus-visible {
  top: 16px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.material-symbols-rounded {
  font-family: "Material Symbols Rounded";
  font-weight: 400;
  font-style: normal;
  font-size: 1.25em;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  letter-spacing: normal;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  font-variation-settings: "FILL" 0, "wght" 400, "GRAD" 0, "opsz" 24;
  -webkit-font-feature-settings: "liga";
  font-feature-settings: "liga";
}

/* ==========================================================================
   02. Typography
   ========================================================================== */

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

.h2 {
  font-size: var(--text-h2);
}

.muted {
  color: var(--ink-2);
}

.mono {
  font-family: var(--font-mono);
  font-size: 0.78em;
  letter-spacing: 0.02em;
}

/* Static gradient lifted from the logo's own ramp. Deliberately not
   animated — the mark doesn't shimmer, so neither does the type.
   Reserved for exactly one place: the hero's own headline phrase. Every
   other "emphasize this word" spot uses .text-accent (solid) instead —
   a page where every other heading shimmers isn't premium, it's wallpaper. */
.text-gradient {
  background: linear-gradient(105deg, #fff 0%, var(--accent-4) 34%, var(--accent-3) 66%, var(--accent-2) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.text-accent {
  color: var(--accent-4);
}

/* ==========================================================================
   03. Layout utilities
   ========================================================================== */

.container {
  width: 100%;
  max-width: calc(var(--max) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  position: relative;
  padding-block: var(--section-y);
}

.section--tight {
  padding-block: clamp(48px, 6vw, 90px);
}

.section--rule {
  border-top: 1px solid var(--line-soft);
}

.section-head {
  max-width: 680px;
  margin-bottom: clamp(38px, 5vw, 64px);
}

.section-head .h2 {
  margin-bottom: 18px;
}

/* ==========================================================================
   04. Ambient background FX
   Restored from the original design, but tuned: the canvas stays near-black
   so the logo's screen-blend works and the violet reads as light in the
   room rather than a wash over everything.
   ========================================================================== */

.fx {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
  background:
    radial-gradient(1100px 620px at 12% -8%, rgba(124, 58, 237, 0.15), transparent 62%),
    radial-gradient(900px 560px at 92% 4%, rgba(168, 85, 247, 0.1), transparent 64%),
    radial-gradient(1200px 700px at 50% 112%, rgba(76, 29, 149, 0.18), transparent 66%),
    linear-gradient(180deg, #050507 0%, #08060e 45%, #050507 100%);
}

.fx__aurora {
  position: absolute;
  border-radius: 50%;
  filter: blur(110px);
  mix-blend-mode: screen;
  will-change: transform;
}

.fx__aurora--1 {
  width: 46vw;
  height: 46vw;
  min-width: 380px;
  min-height: 380px;
  top: -14vw;
  left: -10vw;
  background: rgba(124, 58, 237, 0.26);
  animation: aurora-a 26s var(--ease-io) infinite alternate;
}

.fx__aurora--2 {
  width: 38vw;
  height: 38vw;
  min-width: 320px;
  min-height: 320px;
  top: 6vw;
  right: -10vw;
  background: rgba(192, 132, 252, 0.16);
  animation: aurora-b 32s var(--ease-io) infinite alternate;
}

.fx__aurora--3 {
  width: 42vw;
  height: 42vw;
  min-width: 340px;
  min-height: 340px;
  top: 58%;
  left: 22%;
  background: rgba(88, 28, 235, 0.2);
  animation: aurora-c 36s var(--ease-io) infinite alternate;
}

@keyframes aurora-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to { transform: translate3d(9vw, 7vw, 0) scale(1.18); }
}

@keyframes aurora-b {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to { transform: translate3d(-8vw, 9vw, 0) scale(0.92); }
}

@keyframes aurora-c {
  from { transform: translate3d(0, 0, 0) scale(0.95); }
  to { transform: translate3d(7vw, -8vw, 0) scale(1.2); }
}

.fx__vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 115% 85% at 50% 42%, transparent 38%, rgba(3, 2, 6, 0.9) 100%);
}

/* Mouse-follow glow — subtle, and only on fine pointers (see js/main.js). */
.cursor-glow {
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
  width: 620px;
  height: 620px;
  margin: -310px 0 0 -310px;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle, rgba(139, 92, 246, 0.14), rgba(139, 92, 246, 0.04) 42%, transparent 70%);
  transition: opacity var(--t-slow) var(--ease);
  will-change: transform;
}

.cursor-glow.is-active {
  opacity: 1;
}

/* ==========================================================================
   05. Reveal motion
   ========================================================================== */

/* Reveals use the independent `translate` property, never `transform`, so
   they compose with tilt/hover transforms instead of overriding them.
   Timing/offset match the "standard scroll reveal" tier (400–600ms,
   24px, power1/2-out) rather than the emphatic/expo curve — that curve
   is reserved for the hero headline's own signature reveal, not spent on
   every section header. */
.js .reveal {
  opacity: 0;
  translate: 0 24px;
  transition:
    opacity var(--duration-reveal-standard) var(--ease-reveal),
    translate var(--duration-reveal-standard) var(--ease-reveal);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, translate;
}

.js .reveal.is-visible {
  opacity: 1;
  translate: none;
  will-change: auto;
}

/* ==========================================================================
   06. Reduced motion
   ========================================================================== */

@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;
    scroll-behavior: auto !important;
  }

  .js .reveal,
  .js .hero__word {
    opacity: 1;
    translate: none;
  }

  .cursor-glow {
    display: none;
  }
}

@media (hover: none) {
  .cursor-glow {
    display: none;
  }
}
