/*
  Every desktop measurement is expressed in --u: one pixel of the 838×632
  reference recording. The composition scales as a whole, fitted to whichever
  viewport dimension is tighter, so proportions match the reference at any size.
*/
:root {
  --u: min(calc(100vw / 838), calc(100svh / 632));
  --black: #000;
  --white: #fff;
  --nav-muted: rgba(255,255,255,.5);
  --body-text: rgba(255,255,255,.8);
  --violet: #a35fe0;

  /* Ribbon plate is the reference cropped from y=300 → 632 (838×332). */
  --ribbon-h: calc(332 * var(--u));
  /* Reference content axis sits 4px left of the frame centre. */
  --axis-shift: calc(-4 * var(--u));
}

* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100%; background: var(--black); }
body {
  overflow-x: hidden;
  font-family: Onest, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; }

.hero {
  --mx: 0; --my: 0; --act: 0; --lx: -9999px; --ly: -9999px; --ax: 50%; --ay: 40%;
  position: relative;
  height: 100svh;
  min-height: calc(632 * var(--u));
  width: 100%;
  overflow: hidden;
  isolation: isolate;
  background: #000;
}

/* Animated signature visual: clean ribbon plate extracted from the reference. */
.ribbon-layer {
  position: absolute;
  z-index: 0;
  left: 0;
  right: 0;
  bottom: 0;
  /* Wider-than-reference screens stretch the plate horizontally (capped at 1.4×);
     taller ones grow it to at least 45% of the viewport and crop the sides. */
  height: max(var(--ribbon-h), calc(100vw * 332 / 838 / 1.4), 45svh);
  pointer-events: none;
  overflow: hidden;
  isolation: isolate;               /* the light layer blends with the ribbon only */
}
.ribbon {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
  display: block;
  background: #000;
  /* Liquid depth: a whisper of parallax and tilt, driven by the smoothed cursor
     (--mx/--my in -1..1, --act 0..1). At rest every term is zero. */
  transform-origin: 50% 50%;
  transform:
    perspective(1600px)
    translate3d(calc(var(--mx) * -16px), calc(var(--my) * -6px), 0)
    rotateY(calc(var(--mx) * 1.1deg)) rotateX(calc(var(--my) * -.7deg))
    scale(calc(1 + var(--act) * .05));
  will-change: transform;
}
/* A soft lavender "light source" carried by the cursor. Overlay blending leaves
   black untouched, so it only lifts the ribbon's own reflections — no visible disc. */
.ribbon-light {
  position: absolute;
  left: 0;
  top: 0;
  width: calc(860 * var(--u));
  height: calc(860 * var(--u));
  margin: calc(-430 * var(--u)) 0 0 calc(-430 * var(--u));
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(206,172,255,.9) 0%, rgba(176,128,255,.45) 38%, rgba(160,110,255,.12) 70%, rgba(160,110,255,0) 100%);
  mix-blend-mode: overlay;
  opacity: calc(var(--act) * .75);
  transform: translate3d(var(--lx), var(--ly), 0);
  will-change: transform, opacity;
  pointer-events: none;
}

.nav {
  position: absolute;
  z-index: 4;
  top: 0;
  left: 0;
  width: 100%;
  height: calc(54 * var(--u));
  padding: 0 calc(71 * var(--u)) 0 calc(47 * var(--u));
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.brand {
  display: inline-flex;
  align-items: flex-start;
  font-size: calc(27 * var(--u));
  font-weight: 500;
  letter-spacing: -0.035em;
  line-height: 1;
  color: #e9e9e9;
  transform: translateY(calc(-.5 * var(--u)));
}
.registered {
  display: inline-grid;
  place-items: center;
  width: calc(11 * var(--u));
  height: calc(11 * var(--u));
  margin: calc(1 * var(--u)) 0 0 calc(1.5 * var(--u));
  border-radius: 50%;
  background: #cfcfcf;
  color: #000;
  font-size: calc(7.5 * var(--u));
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1;
}
.nav-links {
  position: absolute;
  left: calc(50% + 7 * var(--u));
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  gap: calc(20.5 * var(--u));
}
.nav a:not(.brand) {
  font-size: calc(13 * var(--u));
  line-height: 1;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--nav-muted);
  transition: color .25s ease;
  white-space: nowrap;
}
.nav a.is-active { color: #fff; }
.nav a.is-active,
.nav a.contact { font-weight: 600; color: #fff; }
.nav a.contact { font-size: calc(12 * var(--u)); letter-spacing: -0.005em; }

.menu-toggle, .mobile-menu { display: none; }

.hero-content {
  position: relative;
  z-index: 3;
  width: 100%;
  margin: 0 auto;
  /* On taller-than-reference screens, sink the stack by 30% of the extra height. */
  padding-top: calc(112.5 * var(--u) + max(0px, 100svh - 632 * var(--u)) * .3);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  transform: translateX(var(--axis-shift));
}

.proof {
  display: inline-flex;
  align-items: center;
  gap: calc(6 * var(--u));
  color: var(--body-text);
  font-size: calc(11.5 * var(--u));
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1;
}
.proof-icon {
  width: calc(18 * var(--u));
  height: calc(19 * var(--u));
  display: grid;
  place-items: center;
  border-radius: calc(4.5 * var(--u));
  color: #fff;
  background: radial-gradient(circle at 45% 40%, #c79bf0 0%, #9d5fd8 55%, #7b3fc4 100%);
  box-shadow: 0 0 calc(12 * var(--u)) rgba(150,80,230,.35);
}
.proof-icon svg { width: calc(11 * var(--u)); height: calc(11 * var(--u)); opacity: .92; }

h1 {
  margin: calc(32.5 * var(--u)) 0 0;
  font-size: calc(67 * var(--u));
  line-height: calc(71 * var(--u));
  letter-spacing: -0.02em;
  font-weight: 500;
}
/* Each line carries its own white → lavender → violet fall-off, as in the reference. */
h1 > span {
  display: block;
  color: #fff;
  background: linear-gradient(180deg, #f3f3f4 0%, #f1f0f3 40%, #e4deeb 55%, #c9bade 68%, #ab91d3 80%, #9567ca 90%, #8a55c4 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.subtitle {
  margin: calc(22 * var(--u)) 0 0;
  color: var(--body-text);
  font-size: calc(16 * var(--u));
  line-height: calc(20 * var(--u));
  letter-spacing: 0.01em;
  font-weight: 400;
}

.cta {
  margin-top: calc(33 * var(--u));
  height: calc(39 * var(--u));
  padding: 0 calc(7 * var(--u)) 0 calc(17 * var(--u));
  display: inline-flex;
  align-items: center;
  gap: calc(9 * var(--u));
  border: 0;
  border-radius: 999px;
  background: #fff;
  color: #151515;
  font-size: calc(13 * var(--u));
  font-weight: 500;
  letter-spacing: -0.01em;
  cursor: pointer;
  /* Opaque, isolated layer above the ribbon: no dark shadow to smudge the ribbon. */
  position: relative;
  z-index: 20;
  isolation: isolate;
  opacity: 1;
  mix-blend-mode: normal;
  backdrop-filter: none;
}
.cta:focus-visible { outline: 2px solid #b98cff; outline-offset: 3px; }
.cta-dot {
  width: calc(23 * var(--u));
  height: calc(23 * var(--u));
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: #fff;
  background: radial-gradient(circle at 40% 35%, #c98ff0 0%, #a765e0 55%, #8e4ad6 100%);
  box-shadow: 0 0 calc(10 * var(--u)) rgba(160,90,230,.4);
}
.cta-dot svg { width: calc(10 * var(--u)); height: calc(10 * var(--u)); }

/* ==========================================================================
   INTERACTIVE LIQUID DEPTH
   One damped cursor loop (script.js) writes --mx/--my (-1..1), --act (0..1),
   --ax/--ay (hero coords), --lx/--ly (ribbon coords) and a per-element --near.
   Every value is 0 at rest, so the approved static hero is untouched.
   ========================================================================== */
:root { --ease-soft: cubic-bezier(.22,.8,.24,1); --lav: #c9adff; }

/* Depth 1: atmospheric light, embedded in the black (very low intensity). */
.hero-ambient {
  position: absolute;
  z-index: 1;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: var(--act);
}
/* the same 520x420u ellipse, as a fixed-size layer the GPU slides with the cursor
   (a gradient positioned by var() would repaint the whole hero every frame) */
.hero-ambient::before {
  content: "";
  position: absolute;
  left: 0; top: 0;
  width: calc(1040 * var(--u)); height: calc(840 * var(--u));
  margin: calc(-420 * var(--u)) 0 0 calc(-520 * var(--u));
  background: radial-gradient(closest-side, rgba(150,110,240,.075) 0%, rgba(140,100,235,.03) 45%, rgba(140,100,235,0) 100%);
  transform: translate3d(var(--ax), var(--ay), 0);
  will-change: transform;
}

/* Depths 3-5: foreground layers drift WITH the cursor by different amounts
   (max 7px); the ribbon (depth 2) drifts against it, which reads as depth. */
.nav                  { translate: calc(var(--mx) * 3px)   calc(var(--my) * 1.5px); }
.proof                { translate: calc(var(--mx) * 3px)   calc(var(--my) * 2px); }
h1 > span:first-child { translate: calc(var(--mx) * 5px)   calc(var(--my) * 3px); }
h1 > span:last-child  { translate: calc(var(--mx) * 6.5px) calc(var(--my) * 3.9px); }
.subtitle             { translate: calc(var(--mx) * 2px)   calc(var(--my) * 1.2px); }
.cta                  { translate: calc(var(--mx) * 7px)   calc(var(--my) * 4.5px); }

/* Purple accent: a faint reflective sheen travels across "Automated by AI."
   with the cursor, a little stronger as the cursor nears the headline. */
h1 > span:last-child {
  background:
    radial-gradient(22% 140% at calc(66% + var(--mx) * 26%) 78%,
      rgba(238,226,255, calc(var(--act) * .16 + var(--near, 0) * .22)) 0%, rgba(238,226,255,0) 70%),
    linear-gradient(180deg, #f3f3f4 0%, #f1f0f3 40%, #e4deeb 55%, #c9bade 68%, #ab91d3 80%, #9567ca 90%, #8a55c4 100%);
  -webkit-background-clip: text;
  background-clip: text;
}

/* Proximity: the element near the cursor becomes a touch more present. */
.proof > span:last-child { color: rgba(255,255,255, calc(.8 + var(--near, 0) * .14)); transition: color .35s ease; }
.subtitle                { color: rgba(255,255,255, calc(.8 + var(--near, 0) * .12)); }
.cta { box-shadow: 0 0 calc(26 * var(--u)) rgba(165,115,255, calc(var(--near, 0) * .16)); }

/* Logo: the sheen fill exists only while hovered, so the resting logo keeps
   its exact approved text rendering. */
.brand { transition: scale .45s var(--ease-soft), filter .45s ease; }
@media (max-width: 760px), (pointer: coarse) { .brand { padding: 11px 0; margin: -11px 0; } }   /* a 44px tap target, same look */
.registered { -webkit-text-fill-color: #000; transition: background-color .45s ease; }
@keyframes logo-sheen { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* Navigation */
.nav a:not(.brand) {
  position: relative;
  transition: color .28s ease, opacity .28s ease, transform .28s var(--ease-soft), scale .12s ease;
}
.nav a:not(.brand)::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: calc(-5 * var(--u));
  height: 1px;
  background: var(--lav);
  opacity: .75;
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform .32s var(--ease-soft);
}

/* Badge */
.proof { transition: transform .4s var(--ease-soft); }
.proof-icon { transition: transform .4s var(--ease-soft), filter .4s ease, box-shadow .4s ease; }

/* CTA */
.cta { transition: scale .4s var(--ease-soft), transform .4s var(--ease-soft), box-shadow .45s ease; }
.cta > span:first-child { transition: transform .4s var(--ease-soft); }
.cta-dot { transition: transform .45s var(--ease-soft), filter .45s ease, box-shadow .45s ease; }

@media (any-hover: hover) {
  .brand:hover {
    background: linear-gradient(100deg, #e9e9e9 0%, #e9e9e9 42%, #f6efff 49%, var(--lav) 52%, #e9e9e9 60%, #e9e9e9 100%) 0 0 / 260% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: logo-sheen .9s var(--ease-soft) both;
    scale: 1.015;
    filter: brightness(1.06);
  }
  .brand:hover .registered { background-color: #e6dcff; }

  .nav-links:hover a:not(:hover) { opacity: .62; }
  .nav a:not(.brand):hover { color: #fff; transform: translateY(-1.5px); }
  .nav a:not(.brand):hover::after { transform: scaleX(1); transform-origin: 0 50%; }

  .proof:hover { transform: translateY(-1.5px); }
  .proof:hover > span:last-child { color: rgba(255,255,255,.96); }
  .proof:hover .proof-icon {
    transform: rotate(4deg);
    filter: brightness(1.12);
    box-shadow: 0 0 calc(16 * var(--u)) rgba(170,110,245,.5);
  }

  .cta:hover {
    scale: 1.02;
    transform: translateY(-1.5px);
    box-shadow: 0 calc(8 * var(--u)) calc(24 * var(--u)) rgba(150,100,235,.26),
                0 0 calc(30 * var(--u)) rgba(175,130,255,.16);
  }
  .cta:hover > span:first-child { transform: translateX(1px); }
  .cta:hover .cta-dot {
    transform: translate(2px, -1px) rotate(10deg);
    filter: brightness(1.14) saturate(1.06);
    box-shadow: inset 0 1px 1.5px rgba(255,255,255,.45), 0 0 calc(14 * var(--u)) rgba(170,100,240,.55);
  }
}

/* Liquid membrane (liquid.js): one WebGL canvas above the ribbon and below the
   content. It fades in when the cursor enters; the DOM headline hides only once
   the canvas is fully opaque, and returns instantly as the canvas fades out, so
   the headline never dips. Badge, paragraph, CTA and nav stay crisp above it. */
.liquid {
  position: absolute;
  z-index: 2;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity .28s ease;
}
.hero.liquid-on .liquid { opacity: 1; }
.hero.liquid-on h1 { opacity: 0; transition: opacity 0s linear .3s; }

/* ==========================================================================
   INTRO (loader.js): purple liquid rising inside the "Zyric.tech" wordmark.
   Shown only when the inline head script sets .intro-on (so without JS the
   site simply appears), and a CSS failsafe hides it even if loader.js fails.
   ========================================================================== */
.intro { display: none; }
html.intro-on { overflow: hidden; }
.intro-on .intro {
  position: fixed;
  z-index: 1000;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--black);
  animation: intro-failsafe .6s ease 12s forwards;   /* only if the scripts fail: loader.js ends it by 8 s */
}
/* a barely-there violet atmosphere behind the wordmark */
.intro::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(38% 30% at 50% 50%, rgba(163,95,224,.07), rgba(163,95,224,0) 72%);
  opacity: 0;
  transition: opacity 1.4s ease;
}
.intro-go::before { opacity: 1; }
.intro-stage {
  position: relative;
  width: clamp(280px, 54vw, 1180px);
}
.intro-mark {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  opacity: 0;
  transition: opacity .5s ease;
}
.intro-go .intro-mark { opacity: 1; }
.intro text {
  font-family: Onest, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-weight: 700;
  font-size: 200px;
  letter-spacing: -.035em;
}
.intro-base { fill: #17161a; }
.intro-back { fill: #3a3fb8; opacity: .3; }
.intro-crest { fill: none; stroke: var(--lav); stroke-width: 1.4; opacity: .5; }
#intro-grad .g0 { stop-color: var(--lav); }
#intro-grad .g1 { stop-color: var(--violet); }
/* purple at the surface deepening into dark blue */
#intro-grad .g2 { stop-color: #6a4bd0; }
#intro-grad .g3 { stop-color: #1d2a8a; }
.intro-status {
  position: absolute;
  right: .4%;
  top: 100%;
  margin: 1.1em 0 0;
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: .04em;
  color: rgba(255,255,255,.3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  opacity: 0;
  transition: opacity .6s ease .2s;
}
.intro-go .intro-status { opacity: 1; }
/* exit: the full wordmark eases forward while the layer dissolves into the site */
.intro-out {
  opacity: 0;
  pointer-events: none;
  transition: opacity .7s cubic-bezier(.4,0,.2,1) .1s;
}
.intro-out .intro-mark { transform: scale(1.045); transition: transform .8s cubic-bezier(.22,.8,.24,1); }
.intro-out .intro-status { opacity: 0; transition: opacity .25s ease; }
@keyframes intro-failsafe { to { opacity: 0; visibility: hidden; } }
/* The hero rises softly into view while the intro dissolves (compositor-only:
   opacity and translate), already loaded, so nothing else starts during it. */
.hero-content { transition: opacity 1.1s cubic-bezier(.4,0,.2,1) .15s, translate 1.4s cubic-bezier(.2,.8,.2,1) .15s; }
/* .001, not 0: invisible, but the browser still paints it behind the intro, so the
   first frames of the fade don't have to paint the headline from scratch */
.intro-on:not(.intro-leaving) .hero-content { opacity: .001; translate: 0 18px; }
/* the nav's translate follows the cursor, so it only fades (no long translate transition) */
.nav { transition: opacity 1.1s cubic-bezier(.4,0,.2,1) .15s; }
.intro-on:not(.intro-leaving) .nav { opacity: .001; }
@media (max-width: 760px) {
  .intro-stage { width: 84vw; }
}

/* ==========================================================================
   LIVING ATMOSPHERE: slow light fields around the edges of the hero.
   Nine very soft radial fields and light shafts in saturated blue-violet
   (measured from the reference image). Each rides 2-3 CSS animations with prime-length durations
   (13-47s, alternating, ease-in-out), so the combined motion never visibly
   loops or jumps, and it all runs on the compositor with no JavaScript.
   The layer is screen-blended above the ribbon and the liquid canvas but below
   the content: it only ever adds light, so black becomes a faint glow while the
   text, CTA and ribbon keep their colours, and it stays visible during hover.
   A radial mask keeps the headline area dark; the cursor nudges the fields
   away very slightly (--mx/--my from script.js).
   ========================================================================== */
.hero-atmos {
  position: absolute;
  z-index: 2;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 1;
  -webkit-mask-image: radial-gradient(46% 48% at 50% 42%, rgba(0,0,0,.02) 0%, rgba(0,0,0,.1) 45%, rgba(0,0,0,.5) 75%, #000 100%);
          mask-image: radial-gradient(46% 48% at 50% 42%, rgba(0,0,0,.02) 0%, rgba(0,0,0,.1) 45%, rgba(0,0,0,.5) 75%, #000 100%);
}
.af {
  position: absolute;
  display: block;
  width: var(--w);
  height: var(--h);
  left: var(--l);
  top: var(--t);
  translate: calc(var(--mx) * var(--push-x, -14px)) calc(var(--my) * var(--push-y, -10px));
  /* movement runs ~2x faster and travels ~2x further than the base values */
  animation: af-drift calc(var(--d1) * .5) ease-in-out calc(var(--dl1) * .5) infinite alternate;
  will-change: transform;
}
.af > b {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  /* a long, gentle falloff: no edge anywhere */
  background: radial-gradient(closest-side,
    rgb(var(--c) / 1) 0%, rgb(var(--c) / .8) 16%, rgb(var(--c) / .5) 34%,
    rgb(var(--c) / .22) 54%, rgb(var(--c) / .06) 76%, rgb(var(--c) / 0) 100%);
  animation:
    af-morph calc(var(--d2) * .55) ease-in-out calc(var(--dl2) * .55) infinite alternate,
    af-breathe calc(var(--d3) * 1.25) ease-in-out var(--dl3) infinite alternate;
  will-change: transform, opacity;
}
@keyframes af-drift {
  0%   { transform: translate3d(0, 0, 0); }
  35%  { transform: translate3d(calc(var(--x1) * 1.8), calc(var(--y1) * 2), 0); }
  70%  { transform: translate3d(calc(var(--x2) * 1.8), calc(var(--y2) * 2), 0); }
  100% { transform: translate3d(calc(var(--x3) * 1.8), calc(var(--y3) * 2), 0); }
}
@keyframes af-morph {
  0%   { transform: rotate(var(--r0)) scale(1, 1); }
  50%  { transform: rotate(calc(var(--r0) + 14deg)) scale(var(--s1), var(--s2)); }
  100% { transform: rotate(calc(var(--r0) - 10deg)) scale(var(--s2), var(--s1)); }
}
/* each field fades almost fully out and back in on its own timer, so the
   light appears, dissolves and returns in different places */
@keyframes af-breathe {
  0%   { opacity: var(--o1); }
  25%  { opacity: var(--o0); }
  55%  { opacity: .03; }
  80%  { opacity: var(--o1); }
  100% { opacity: calc(var(--o0) * .55); }
}
/* colours and placement measured from the reference: saturated blue-violet
   (hue ~240-265deg), bright cores sitting on the edges, falling off to black */
/* top corners */
.af1 { --c: 104 58 248;  --w: 42vmax; --h: 36vmax; --l: -21vmax; --t: -19vmax; --r0: 20deg;
       --x1: 3vmax;  --y1: 4vmax;  --x2: 1vmax; --y2: 8vmax;  --x3: -2vmax; --y3: 3vmax;
       --s1: 1.16; --s2: .9; --o0: .86; --o1: 1; --d1: 29s; --d2: 19s; --d3: 13s; --dl1: -11s; --dl2: -7s; --dl3: -5s; }
.af2 { --c: 92 54 246;   --w: 44vmax; --h: 38vmax; --l: calc(100% - 24vmax); --t: -18vmax; --r0: -20deg;
       --x1: -3vmax; --y1: 5vmax;  --x2: -1vmax; --y2: 9vmax;  --x3: 2vmax; --y3: 2vmax;
       --s1: 1.14; --s2: .9; --o0: .84; --o1: 1; --d1: 31s; --d2: 23s; --d3: 17s; --dl1: -23s; --dl2: -19s; --dl3: -3s;
       --push-x: 12px; }
/* sides: tall bands hugging the left and right edges */
.af3 { --c: 66 46 236;   --w: 28vmax; --h: 64vmax; --l: -15vmax; --t: 6%; --r0: 4deg;
       --x1: 2vmax;  --y1: -7vmax; --x2: 3vmax; --y2: 6vmax;  --x3: 0vmax; --y3: -10vmax;
       --s1: 1.12; --s2: .9; --o0: .86; --o1: 1; --d1: 37s; --d2: 29s; --d3: 19s; --dl1: -37s; --dl2: -13s; --dl3: -17s; }
.af4 { --c: 50 40 226;   --w: 28vmax; --h: 64vmax; --l: calc(100% - 13vmax); --t: 8%; --r0: -4deg;
       --x1: -2vmax; --y1: 8vmax;  --x2: -3vmax; --y2: -6vmax; --x3: -1vmax; --y3: 4vmax;
       --s1: 1.12; --s2: .9; --o0: .82; --o1: 1; --d1: 41s; --d2: 31s; --d3: 23s; --dl1: -29s; --dl2: -31s; --dl3: -9s;
       --push-x: 12px; }
/* bottom corners, around the ribbon */
.af5 { --c: 84 52 238;   --w: 40vmax; --h: 30vmax; --l: -18vmax; --t: calc(100% - 18vmax); --r0: -12deg;
       --x1: 4vmax;  --y1: -4vmax; --x2: 6vmax; --y2: -1vmax;  --x3: 2vmax; --y3: -6vmax;
       --s1: 1.16; --s2: .9; --o0: .7; --o1: .88; --d1: 43s; --d2: 37s; --d3: 29s; --dl1: -41s; --dl2: -23s; --dl3: -27s;
       --push-y: 10px; }
.af6 { --c: 60 44 230;   --w: 40vmax; --h: 30vmax; --l: calc(100% - 22vmax); --t: calc(100% - 18vmax); --r0: 12deg;
       --x1: -4vmax; --y1: -3vmax; --x2: -2vmax; --y2: -6vmax; --x3: -6vmax; --y3: 0vmax;
       --s1: 1.12; --s2: .92; --o0: .72; --o1: .9; --d1: 47s; --d2: 41s; --d3: 31s; --dl1: -17s; --dl2: -41s; --dl3: -21s;
       --push-x: 12px; --push-y: 10px; }
/* angled light shafts, as in the reference: one sweeping in from the top-left
   corner, one down from the top-right, one slanting in at mid-right; plus the
   magenta-violet hot spot in the top-right corner */
.af7 { --c: 88 62 252;   --w: 52vmax; --h: 13vmax; --l: -16vmax; --t: -3vmax; --r0: 33deg;
       --x1: 2vmax;  --y1: 3vmax;  --x2: -1vmax; --y2: 5vmax; --x3: 1vmax; --y3: 1vmax;
       --s1: 1.1; --s2: .9; --o0: .46; --o1: .66; --d1: 23s; --d2: 17s; --d3: 11s; --dl1: -5s; --dl2: -9s; --dl3: -2s; }
.af8 { --c: 150 72 242;  --w: 24vmax; --h: 20vmax; --l: calc(100% - 13vmax); --t: -11vmax; --r0: -30deg;
       --x1: -2vmax; --y1: 2vmax;  --x2: -1vmax; --y2: 4vmax; --x3: 1vmax; --y3: 1vmax;
       --s1: 1.2; --s2: .88; --o0: .8; --o1: 1; --d1: 19s; --d2: 13s; --d3: 17s; --dl1: -7s; --dl2: -3s; --dl3: -11s;
       --push-x: 12px; }
.af9 { --c: 70 50 240;   --w: 40vmax; --h: 11vmax; --l: calc(100% - 30vmax); --t: 34%; --r0: -56deg;
       --x1: -2vmax; --y1: 4vmax;  --x2: 1vmax; --y2: -3vmax; --x3: -3vmax; --y3: 2vmax;
       --s1: 1.12; --s2: .9; --o0: .5; --o1: .72; --d1: 37s; --d2: 23s; --d3: 19s; --dl1: -13s; --dl2: -17s; --dl3: -7s;
       --push-x: 12px; }
@media (max-width: 760px), (hover: none) {
  /* phones: fewer, dimmer fields; the centre stays dark */
  .hero-atmos { opacity: .7; }
  .af3, .af4, .af9 { display: none; }
}

/* Click feedback (clickables only): 1 -> .98 -> 1 */
.cta:active { scale: .98; transition-duration: .12s; }
.nav a:active, .brand:active { scale: .98; }

@media (max-aspect-ratio: 838/632) {
  .ribbon { object-fit: cover; object-position: center bottom; }
}

@media (max-width: 760px) {
  :root {
    --u: calc(100vw / 600);
    --axis-shift: 0px;
    --ribbon-m: clamp(220px, 48svh, 420px);
  }
  .hero { height: auto; min-height: 100svh; }
  .nav {
    height: 64px;
    padding: 0 20px 0 22px;
  }
  .brand { font-size: 23px; transform: none; }
  .registered { width: 9px; height: 9px; font-size: 6.5px; margin-top: 1px; }
  .nav-links, .contact { display: none; }
  .menu-toggle {
    width: 44px;
    height: 44px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    border: 0;
    background: transparent;
    color: #fff;
    cursor: pointer;
  }
  .menu-toggle span { width: 18px; height: 1.5px; border-radius: 1px; background: #fff; opacity: .85; transition: transform .25s ease; }
  .menu-toggle[aria-expanded="true"] span:first-child { transform: translateY(3.25px) rotate(45deg); }
  .menu-toggle[aria-expanded="true"] span:last-child { transform: translateY(-3.25px) rotate(-45deg); }
  .mobile-menu {
    position: absolute;
    z-index: 5;
    top: 64px;
    left: 16px;
    right: 16px;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 0;
    padding-top: 10px; padding-bottom: 10px;
    border: 1px solid rgba(255,255,255,.08);
    border-radius: 16px;
    background: rgba(7,7,7,.94);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-8px);
    transition: opacity .25s ease, transform .25s ease;
  }
  .mobile-menu a { display: flex; align-items: center; min-height: 44px; font-size: 15px; color: rgba(255,255,255,.78); }
  .mobile-menu a:focus-visible { outline: 2px solid var(--lav); outline-offset: 2px; border-radius: 6px; }
  .mobile-menu.open { opacity: 1; pointer-events: auto; transform: translateY(0); }

  .hero-content {
    /* Reserve the ribbon band so it can rise beside, but never over, the CTA. */
    padding: clamp(112px, 17svh, 150px) 16px calc(var(--ribbon-m) - 40px);
    min-height: 100svh;
  }
  .proof { font-size: 12.5px; gap: 7px; }
  .proof-icon { width: 19px; height: 20px; border-radius: 5px; }
  .proof-icon svg { width: 11px; height: 11px; }
  h1 {
    margin-top: 30px;
    font-size: clamp(34px, 10.4vw, 52px);
    line-height: 1.07;
  }
  .subtitle {
    margin-top: 18px;
    max-width: 340px;
    font-size: 15px;
    line-height: 1.42;
  }
  .desktop-break { display: none; }
  .cta { margin-top: 30px; height: 46px; padding: 0 7px 0 20px; font-size: 15px; gap: 11px; }
  .cta-dot { width: 32px; height: 32px; }
  .cta-dot svg { width: 13px; height: 13px; }

  .ribbon-layer { height: var(--ribbon-m); }
  /* Frame the left of the plate: the full crest, clear of the area patched behind the desktop CTA. */
  .ribbon { object-fit: cover; object-position: left bottom; }
}

/* ==========================================================================
   STARFIELD (stars.js): a quiet, slowly living night sky across the hero.
   Screen-blended above the ribbon, the liquid canvas and the atmosphere but
   below the content, so it only ever adds light. The calm static layer shifts
   a hair with the cursor here; the live layer handles its own per-star
   twinkle, drift, depth parallax and glow in JS.
   ========================================================================== */
.hero-stars {
  position: absolute;
  z-index: 2;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  mix-blend-mode: screen;
}
.hero-stars canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.hero-stars .st-static { translate: calc(var(--mx) * -.8px) calc(var(--my) * -.6px); }

/* Seam into the next section: the lowest part of the hero (ribbon, atmosphere,
   stars) fades to black, so it melts into the black top of the platform section. */
.hero::after {
  content: "";
  position: absolute;
  z-index: 2;
  left: 0; right: 0; bottom: 0;
  height: 22%;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.35) 40%, rgba(0,0,0,.8) 75%, #000 100%);
}
