/* turiyo.app — same tokens as the app, nothing invented */

/* latin-ext carries the "ī" in turīya (U+012B); declared first so the latin
   face below wins for the codepoints they'd otherwise share */
@font-face {
  font-family: 'Hanken Grotesk';
  src: url('fonts/hanken-grotesk-latin-ext-wght-normal.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Hanken Grotesk';
  src: url('fonts/hanken-grotesk-latin-wght-normal.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('fonts/ibm-plex-mono-latin-300-normal.woff2') format('woff2');
  font-weight: 300;
  font-display: swap;
}

:root {
  --bg: #fbfcfe;
  --ink: #10143a;
  --muted: rgba(16, 20, 58, 0.62);
  --faint: rgba(16, 20, 58, 0.38);
  --hairline: rgba(16, 20, 58, 0.1);
  --accent: #2b45e0;
  --sans: 'Hanken Grotesk', 'Helvetica Neue', Helvetica, system-ui, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --text-micro: 0.625rem;
  --edge: clamp(1.75rem, 7vw, 6.5rem);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  background: var(--bg);
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 380;
  font-size: 16px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

p {
  text-wrap: pretty;
}

.micro {
  font-family: var(--mono);
  font-size: var(--text-micro);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.vertical {
  writing-mode: vertical-rl;
}

/* ── hero ─────────────────────────────────────────────────────────────── */

.hero {
  position: relative;
  min-height: 100vh; /* fallback where svh is unsupported */
  min-height: 100svh;
  overflow: hidden;
}

.bloom {
  position: absolute;
  width: min(125vmin, 980px);
  aspect-ratio: 1;
  top: calc(min(125vmin, 980px) * -0.38);
  right: calc(min(125vmin, 980px) * -0.32);
  pointer-events: none;
  /* the bloom inhales into being, then drifts */
  animation:
    bloom-in 1600ms cubic-bezier(0.22, 0.6, 0.2, 1) both,
    bloom-drift 11s ease-in-out infinite;
}

@keyframes bloom-in {
  from {
    opacity: 0;
  }
}

@keyframes bloom-drift {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.04);
  }
}

/* ── motion ───────────────────────────────────────────────────────────────
   The bloom is the only living thing; everything else settles like paper.
   Hero entrance is pure CSS (works with no JS). Scroll reveals are gated on
   html.anim, which anim.js adds only when JS runs and motion is allowed —
   without it, everything is simply visible. */

/* starts at 0.01, not 0: fully transparent paints are ignored for LCP, and
   the hero text is this page's LCP element */
@keyframes rise-in {
  from {
    opacity: 0.01;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.hero .identity {
  animation: rise-in 900ms cubic-bezier(0.22, 0.6, 0.2, 1) both;
}
.hero h1 {
  animation: rise-in 950ms cubic-bezier(0.22, 0.6, 0.2, 1) 120ms both;
}
.hero .lede {
  animation: rise-in 950ms cubic-bezier(0.22, 0.6, 0.2, 1) 260ms both;
}
.hero .cta {
  animation: rise-in 950ms cubic-bezier(0.22, 0.6, 0.2, 1) 420ms both;
}
.hero .tagline {
  animation: rise-in 1100ms cubic-bezier(0.22, 0.6, 0.2, 1) 600ms both;
}

html.anim .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 1000ms cubic-bezier(0.22, 0.6, 0.2, 1),
    transform 1000ms cubic-bezier(0.22, 0.6, 0.2, 1);
}

html.anim .reveal.in {
  opacity: 1;
  transform: none;
}

/* a section whose children carry the stagger fades in place — one motion
   layer per element, so the cascade below is the only travel */
html.anim .reveal-stagger {
  transform: none;
}

/* the seven phases arrive one breath apart. NOTE: nothing inside .reveal is
   focusable today; if interactive content is ever added here, wire a
   reveal-on-focus path so keyboard users can't tab into invisible controls */
html.anim .reveal .phases li {
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 700ms cubic-bezier(0.22, 0.6, 0.2, 1),
    transform 700ms cubic-bezier(0.22, 0.6, 0.2, 1);
}

html.anim .reveal.in .phases li {
  opacity: 1;
  transform: none;
}

html.anim .reveal.in .phases li:nth-child(2) { transition-delay: 80ms; }
html.anim .reveal.in .phases li:nth-child(3) { transition-delay: 160ms; }
html.anim .reveal.in .phases li:nth-child(4) { transition-delay: 240ms; }
html.anim .reveal.in .phases li:nth-child(5) { transition-delay: 320ms; }
html.anim .reveal.in .phases li:nth-child(6) { transition-delay: 400ms; }
html.anim .reveal.in .phases li:nth-child(7) { transition-delay: 480ms; }

/* one cascade on the page: the seven phases earn it, the durations row
   arrives as a single unit with its section */

@media print {
  html.anim .reveal,
  html.anim .reveal .phases li {
    opacity: 1;
    transform: none;
  }
}

/* gradient stand-in when WebGL is unavailable */
.bloom-fallback {
  border-radius: 50%;
  background: radial-gradient(
    circle at 52% 48%,
    #101c6e 0%,
    #1c33bd 18%,
    #2b49e4 32%,
    #5d83ea 46%,
    #8fb0f2 58%,
    rgba(164, 196, 245, 0.6) 68%,
    rgba(198, 220, 248, 0.32) 77%,
    rgba(224, 237, 251, 0.12) 86%,
    rgba(244, 249, 253, 0.03) 93%,
    rgba(251, 252, 254, 0) 100%
  );
  filter: blur(22px);
}

.hero .identity {
  position: absolute;
  top: 1.75rem;
  left: var(--edge);
  display: flex;
  align-items: center;
  gap: 0.8rem;
  color: var(--ink);
}

.hero .tagline {
  position: absolute;
  right: 1.9rem;
  bottom: 6rem;
  color: var(--faint);
}

@media (max-width: 700px) {
  .hero .tagline {
    display: none;
  }
}

.hero .lockup {
  position: absolute;
  left: var(--edge);
  bottom: clamp(3.5rem, 12vh, 7rem);
  max-width: 34rem;
  padding-right: 1.75rem;
}

h1 {
  font-size: clamp(1.7rem, 4.5vw, 2.6rem);
  font-weight: 420;
  letter-spacing: -0.01em;
  line-height: 1.25;
  text-wrap: balance;
}

.lede {
  margin-top: 1.4rem;
  color: var(--muted);
  font-size: 1rem;
  max-width: 30rem;
}

.cta {
  margin-top: 2.4rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.btn-ghost {
  font-family: var(--mono);
  font-size: var(--text-micro);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink);
  border: 1px solid rgba(16, 20, 58, 0.28);
  border-radius: 2px;
  padding: 1em 2em;
  background: none;
  display: inline-block;
  text-decoration: none;
}

.cta .micro {
  color: var(--faint);
}

/* ── sections ─────────────────────────────────────────────────────────── */

main {
  display: block;
}

section {
  padding: clamp(4.5rem, 12vh, 8rem) var(--edge);
  max-width: 46rem;
}

section .label {
  color: var(--faint);
  display: block;
  margin-bottom: 2.2rem;
}

h2 {
  font-size: clamp(1.2rem, 2.6vw, 1.45rem);
  font-weight: 430;
  letter-spacing: -0.005em;
  line-height: 1.4;
  margin-bottom: 1.2rem;
  text-wrap: balance;
}

section p {
  color: var(--muted);
  font-size: 0.9375rem;
  max-width: 36rem;
}

section p + p {
  margin-top: 1.1rem;
}

.note {
  margin-top: 2rem;
  color: var(--faint);
}

/* durations row, borrowed from the app's home screen */
.durations {
  display: flex;
  gap: 2.6rem;
  align-items: baseline;
  margin-bottom: 2.6rem;
}

.durations .n {
  font-family: var(--mono);
  font-weight: 300;
  font-size: 2.1rem;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.durations .u {
  color: var(--faint);
  margin-left: 0.5rem;
}

/* the seven phases, as numbered rows */
.phases {
  list-style: none;
  margin-top: 0.5rem;
}

.phases li {
  display: flex;
  gap: 1.3rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--hairline);
  align-items: baseline;
}

.phases li:last-child {
  border-bottom: 0;
}

.phases .idx {
  color: var(--faint);
  flex: 0 0 auto;
}

.phases .name {
  font-weight: 450;
  font-size: 0.9375rem;
  flex: 0 0 9.5rem;
}

.phases .desc {
  color: var(--muted);
  font-size: 0.9375rem;
}

@media (max-width: 560px) {
  .phases li {
    flex-wrap: wrap;
  }
  .phases .desc {
    flex-basis: 100%;
    padding-left: 2.3rem;
  }
}

/* ── closing + footer ─────────────────────────────────────────────────── */

.closing {
  padding: clamp(5rem, 16vh, 9rem) var(--edge) 5rem;
  max-width: 46rem;
}

.closing .mark {
  margin-bottom: 1.8rem;
}

footer {
  padding: 2.5rem var(--edge) 3rem;
  border-top: 1px solid var(--hairline);
  max-width: 46rem;
}

footer p {
  color: var(--faint);
  font-size: 0.8125rem;
  max-width: 34rem;
}

footer p + p {
  margin-top: 0.9rem;
}

@media (prefers-reduced-motion: reduce) {
  .bloom,
  .hero .identity,
  .hero h1,
  .hero .lede,
  .hero .cta,
  .hero .tagline {
    animation: none;
  }
  /* anim.js also skips adding html.anim under reduced motion; this is the
     belt to that suspender */
  html.anim .reveal,
  html.anim .reveal .phases li {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
