/* Site-wide motion layer (see motion.js).
   Extends the hero's language (cursor-reactive letters, scroll-driven reveals, light that
   follows the pointer) to every section. Everything here is progressive: the page is
   fully readable without JS or with reduced motion. */

@property --amb-a {
  syntax: "<color>";
  inherits: true;
  initial-value: #3f7cff;
}

@property --amb-b {
  syntax: "<color>";
  inherits: true;
  initial-value: #39e0ca;
}

/* ------------------------------------------------------------------ ambient layer */

.ambient {
  position: fixed;
  z-index: 0;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  --sp: 0;
  --px: 0.5;
  --py: 0.5;
  transition: --amb-a 1400ms ease, --amb-b 1400ms ease;
}

.ambient i {
  position: absolute;
  width: 62vmax;
  height: 62vmax;
  border-radius: 50%;
  filter: blur(110px);
  will-change: transform;
}

.ambient .amb-a {
  top: -14vmax;
  left: -20vmax;
  opacity: 0.3;
  background: radial-gradient(circle, var(--amb-a), transparent 66%);
  transform: translate3d(calc(var(--sp) * 46vw + (var(--px) - 0.5) * 7vw), calc(var(--sp) * 64vh + (var(--py) - 0.5) * 6vh), 0);
}

.ambient .amb-b {
  right: -22vmax;
  bottom: -20vmax;
  opacity: 0.22;
  background: radial-gradient(circle, var(--amb-b), transparent 66%);
  transform: translate3d(calc(var(--sp) * -34vw - (var(--px) - 0.5) * 6vw), calc(var(--sp) * -52vh - (var(--py) - 0.5) * 5vh), 0);
}

.page-glow {
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  width: 620px;
  height: 620px;
  margin: -310px 0 0 -310px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(131, 170, 255, 0.12), rgba(131, 170, 255, 0.04) 42%, transparent 66%);
  mix-blend-mode: screen;
  opacity: 0;
  pointer-events: none;
  transition: opacity 500ms ease;
  will-change: transform;
}

.page-glow.is-on {
  opacity: 1;
}

.scroll-progress {
  position: fixed;
  z-index: 90;
  top: 0;
  right: 0;
  left: 0;
  height: 2px;
  background: linear-gradient(90deg, #39e0ca, #83aaff 55%, #c9daff);
  box-shadow: 0 0 14px rgba(131, 170, 255, 0.55);
  pointer-events: none;
  transform: scaleX(var(--sp, 0));
  transform-origin: 0 50%;
}

/* sections let the ambient layer show through instead of painting their own seams */
body .manifesto-scene,
body .work-scene,
body .lab-scene,
body .experience-scene,
body .about-scene,
body .resume-scene {
  background: transparent;
}

body .manifesto-scene {
  border-top: 0;
  border-bottom: 0;
}

/* ------------------------------------------------------------------ reveals */

html.js .reveal {
  opacity: 0;
  transform: none;
  translate: 0 54px;
  scale: 0.985;
  filter: blur(5px);
  transition:
    opacity 900ms var(--ease),
    translate 1000ms var(--ease),
    scale 1000ms var(--ease),
    filter 800ms var(--ease);
  transition-delay: var(--rd, 0ms);
}

html.js .reveal.is-visible {
  opacity: 1;
  translate: 0 0;
  scale: 1;
  filter: blur(0);
}

html.js .reveal-delay {
  transition-delay: calc(var(--rd, 0ms) + 120ms);
}

/* large surfaces: skip the blur, it is costly on big layers */

/* staggered pop-in for grids of small tiles */
html.js .pop-item {
  opacity: 0;
  translate: 0 22px;
  scale: 0.86;
  filter: blur(4px);
  transition:
    opacity 700ms var(--ease),
    translate 800ms var(--ease),
    scale 800ms var(--ease),
    filter 600ms var(--ease);
  transition-delay: var(--pd, 0ms);
}

html.js .pop-group.is-in .pop-item {
  opacity: 1;
  translate: 0 0;
  scale: 1;
  filter: blur(0);
}

/* ------------------------------------------------------------------ split headings */

.split-wrap {
  display: inline;
  font: inherit;
  letter-spacing: inherit;
}

.sw {
  display: inline-block;
  font: inherit;
  font-style: normal;
  letter-spacing: inherit;
  white-space: nowrap;
}

.sc {
  display: inline-block;
  font: inherit;
  font-style: normal;
  letter-spacing: inherit;
  color: color-mix(in srgb, var(--sc-base, currentColor), var(--sc-hot, #8eb4ff) calc(var(--k, 0) * 100%));
  translate: var(--tx, 0px) var(--ty, 0px);
  scale: var(--s, 1);
  rotate: var(--r, 0deg);
  transform-origin: 50% 78%;
  will-change: translate, scale, rotate;
}

html.js [data-split]:not(.is-in) .sc {
  opacity: 0;
  transform: translateY(0.6em) rotate(6deg);
  filter: blur(8px);
}

html.js [data-split].is-in .sc {
  opacity: 1;
  transform: none;
  filter: none;
  transition:
    opacity 900ms var(--ease),
    transform 1000ms var(--ease),
    filter 900ms var(--ease);
  transition-delay: calc(var(--i, 0) * 24ms);
}

/* scroll-scrubbed statement: words light up as you read down the page */
.scrub-word {
  font-style: normal;
  opacity: calc(0.16 + var(--on, 1) * 0.84);
}

/* ------------------------------------------------------------------ section headings */

h2 {
  font-size: clamp(3.2rem, 7vw, 7.2rem);
}

.footer-scene .footer-heading h2,
.resume-scene h2 {
  font-size: clamp(3rem, 6.4vw, 6.4rem);
}

/* ------------------------------------------------------------------ tilt + glare */

[data-tilt] {
  transform-style: flat;
}

[data-tilt] > .tilt-glare {
  position: absolute;
  z-index: 2;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(420px circle at var(--gx, 50%) var(--gy, 50%), rgba(190, 215, 255, 0.17), transparent 56%);
  mix-blend-mode: screen;
  opacity: var(--ga, 0);
  pointer-events: none;
}

/* hover lift moves to `translate` so JS can own `transform` for the tilt */

/* ------------------------------------------------------------------ marquee */

.marquee {
  position: relative;
  z-index: 1;
  overflow: hidden;
  padding-block: clamp(14px, 2.4vw, 30px);
  border-block: 1px solid var(--line);
  user-select: none;
}

.marquee-track {
  display: flex;
  width: max-content;
  will-change: transform;
}

.marquee-set {
  display: flex;
  flex: none;
  align-items: center;
}

.marquee-set span {
  padding-inline: 0.32em;
  color: transparent;
  font: 600 clamp(3.4rem, 9.4vw, 9.6rem) / 1.05 var(--display);
  letter-spacing: -0.02em; /* looser than the headings so outlined glyphs don't overlap */
  white-space: nowrap;
  -webkit-text-stroke: 1.5px rgba(169, 199, 255, 0.4);
}

.marquee-set span.is-solid {
  color: var(--ink);
  -webkit-text-stroke: 0;
}

.marquee-set i {
  flex: none;
  width: clamp(10px, 1.5vw, 20px);
  height: clamp(10px, 1.5vw, 20px);
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 22px rgba(103, 226, 209, 0.7);
}

/* ------------------------------------------------------------------ numbers */

[data-count] {
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------ timeline */

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

body .footer-scene {
  background: transparent;
  color: var(--ink);
}

body .footer-scene::before {
  background: linear-gradient(90deg, transparent, rgba(131, 170, 255, 0.5), transparent);
}

body .footer-surface {
  min-height: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

body .footer-surface::after {
  display: none;
}

body .footer-hero {
  display: block;
  min-height: 0;
  padding-block: clamp(90px, 14vh, 150px) 30px;
}

body .footer-kicker {
  color: var(--signal);
  font: 600 12px/1.3 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

body .footer-scene .footer-heading h2 {
  max-width: none;
  margin: 0;
  color: var(--ink);
  font-size: clamp(3.4rem, 10.4vw, 10.6rem);
  line-height: 0.9;
}

/* the accent word sits inside the split wrapper, so target it by descendant */
body .footer-scene .footer-heading h2 span:not(.sr-only) {
  display: block;
  margin-top: 0.04em;
  color: var(--accent);
}

body .footer-scene .footer-focus {
  margin-top: 26px;
  color: var(--ink-soft);
}

body .footer-contact {
  padding-top: clamp(34px, 5vw, 56px);
}

body .footer-scene .footer-email {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35em;
  padding-bottom: 6px;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent);
  font-size: clamp(1.3rem, 3.4vw, 3.2rem);
  font-weight: 600;
  letter-spacing: -0.045em;
  text-shadow: none;
  transition: color 250ms ease, border-color 250ms ease, gap 400ms var(--ease);
}

body .footer-scene .footer-email:hover,
body .footer-scene .footer-email:focus-visible {
  gap: 0.6em;
  border-color: var(--signal);
  color: #d9e6ff;
}

body .footer-nav-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 28px clamp(48px, 9vw, 130px);
  width: var(--shell);
  margin-inline: auto;
  padding-bottom: clamp(30px, 5vw, 56px);
}

body .footer-nav-group h3 {
  color: var(--ink-faint);
  font: 600 11px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

body .footer-nav-group a {
  color: var(--ink-soft);
  transition: color 200ms ease, translate 300ms var(--ease);
}

body .footer-nav-group a:hover,
body .footer-nav-group a:focus-visible {
  color: var(--ink);
  translate: 6px 0;
}

.footer-wordmark {
  display: block;
  margin: 0;
  overflow: hidden;
  color: var(--ink);
  padding-bottom: 0.16em; /* room for the descender on the "g" */
  font: 700 clamp(3.4rem, 17.4vw, 20rem) / 0.9 var(--display);
  letter-spacing: -0.07em;
  text-align: center;
  white-space: nowrap;
  --sc-hot: var(--signal);
}

body .footer-bottom {
  border-top: 1px solid var(--line);
  color: var(--ink-faint);
}

/* ------------------------------------------------------------------ section rail */

/* On mid-width screens the rail sat on top of content (and blocked sliders). Keep just the
   numbers, tucked into the right margin; the full labels return on wide screens. */
@media (max-width: 1599px) {
  .section-rail {
    right: 10px;
  }

  .section-rail a strong,
  .section-rail-current {
    display: none;
  }
}

/* ------------------------------------------------------------------ spacing + small fixes */

.button {
  white-space: nowrap;
}

body .lab-scene {
  padding-block: clamp(90px, 11vw, 130px);
}

body .footer-hero {
  padding-block: clamp(64px, 10vh, 110px) 24px;
}

/* ------------------------------------------------------------------ responsive + reduced motion */

@media (hover: none), (pointer: coarse) {
  .page-glow {
    display: none;
  }
}

@media (max-width: 640px) {
  h2 {
    font-size: clamp(2.8rem, 13vw, 4.4rem);
  }

  html.js .reveal {
    translate: 0 34px;
  }

  .marquee-set span {
    -webkit-text-stroke-width: 1px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ambient i,
  .page-glow,
  .scroll-progress {
    display: none;
  }

  html.js .reveal,
  html.js .pop-item {
    opacity: 1;
    translate: none;
    scale: none;
    filter: none;
    transition: none;
  }

  .marquee-track {
    transform: none !important;
  }

  .scrub-word {
    opacity: 1;
  }
}
