/* biome-ignore-all lint/complexity/noImportantStyles: design nodes carry their values inline; breakpoint, state and motion rules must win over them */
/*
 * Landing v2 (site.pen board 27): the desktop page (iZ2am, 1440) from 1024 px up, the mobile
 * frames (zzzOY + UWQ1Y, 390) below. Above 1440 the sections keep their full-bleed fills and the
 * content keeps the design's 1312 px column (side padding grows past 64).
 */
:root {
  /* board 27's own variables (site.pen `v2-*`) */
  --kimo-v2-bg: #040404;
  --kimo-v2-surface: #0d0d0d;
  --kimo-v2-surface-2: #151515;
  --kimo-v2-line: #ffffff14;
  --kimo-v2-line-strong: #ffffff29;
  --kimo-v2-text: #f5f1ec;
  --kimo-v2-text-2: #a9a39d;
  --kimo-v2-text-3: #847e78;
  --kimo-v2-warm: #ff7a3d;
  --kimo-v2-peach: #ffc9a3;
  --kimo-v2-warm-glow: #ff7a3d33;
  --kimo-v2-cta: #f5f1ec;
  --kimo-v2-on-cta: #0a0a0a;
}
html:has(.landing-v2) {
  background: var(--kimo-v2-bg);
  color-scheme: dark;
}
.landing-v2 {
  display: block;
  background: var(--kimo-v2-bg);
}
.landing--mobile {
  display: none !important;
}
@media (max-width: 1023.98px) {
  .landing--desktop {
    display: none !important;
  }
  .landing--mobile {
    display: flex !important;
    flex-direction: column;
  }
}
@media (min-width: 1441px) {
  .landing--desktop .gutter {
    padding-left: max(64px, calc((100% - 1312px) / 2)) !important;
    padding-right: max(64px, calc((100% - 1312px) / 2)) !important;
  }
}
.landing pre {
  font: inherit;
}

/* Links and buttons: rest states are the design's; hover uses house behaviour. */
.lk {
  transition:
    opacity 120ms,
    color 120ms;
}
.lk:hover {
  opacity: 0.78;
}
.menu-btn {
  align-items: center;
  justify-content: center;
}

/* Hero: the shader canvas fades in over the committed still of the same shader. */
.hero__gl {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 300ms ease-out;
}
.hero.is-live .hero__gl {
  opacity: 1;
}
.hero__still {
  transition: opacity 300ms ease-out;
}
.hero.is-live .hero__still {
  opacity: 0;
}
.hero__copy {
  will-change: opacity, transform;
}

/* Final CTA aura: a still of the shader's aura pass (mode 2) for the chosen chrome. */
.cta__aura {
  background: radial-gradient(
    closest-side at 50% 26.3%,
    rgba(217, 224, 242, 0.11),
    rgba(217, 224, 242, 0.04) 45%,
    transparent
  );
}

/* 01 · The loop: with motion, the four states play in turn on one pinned stage
   (client/landing.ts adds .is-sticky; without it the design's 2 × 2 layout shows every state).
   A sticky box only travels inside its parent's content box, so the scroll run is a flex item
   after the stage (::after), not padding: padding gives the stage no room to stay pinned. */
.story-section.is-sticky::after {
  content: "";
  display: block;
  flex: none;
  height: 220vh;
}
.story.is-sticky {
  position: sticky !important;
  /* centred: a pinned state is 640 px tall at full size */
  top: max(32px, calc(50vh - 320px));
  display: grid !important;
  justify-items: center;
}
.story.is-sticky > [data-node^="Row"] {
  display: contents !important;
}
.story.is-sticky .story__state {
  grid-area: 1 / 1;
  /* on short viewports the 16:9 stage shrinks so the pinned state (its 100 px heading included)
     fits 32 px inside the top and bottom edges */
  width: min(960px, 100%, (100vh - 164px) * 16 / 9) !important;
  flex: none !important;
  opacity: 0;
  transition: opacity 450ms ease;
}
.story.is-sticky .story__state.is-on {
  opacity: 1;
}
/* The stages crossfade over 450 ms; the captions take turns inside the same 450 ms (the old one
   out in 200 ms, the new one in over 250 ms after it), so two headings never show at once. */
.story.is-sticky .story__state [data-node="Caption"] {
  opacity: 0;
  transition: opacity 200ms ease;
}
.story.is-sticky .story__state.is-on [data-node="Caption"] {
  opacity: 1;
  transition: opacity 250ms ease 200ms;
}
.story.is-sticky .story__state [data-node="Stage"] {
  height: auto !important;
  aspect-ratio: 640 / 360;
}

/* 01 · The loop, phones and tablets: the stage swaps the four states (client/landing.ts pins the
   stage and its step list); without motion it shows state 02, as the design does. */
.mstage__state {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 450ms ease;
}
.mstage:not(.is-live) .mstage__state[data-step="1"],
.mstage.is-live .mstage__state.is-on {
  opacity: 1;
}
#loop-m.is-sticky::after {
  content: "";
  display: block;
  flex: none;
  height: 150svh;
}
#loop-m.is-sticky [data-story-stage],
#loop-m.is-sticky [data-story-steps] {
  position: sticky !important;
  z-index: 1;
  background-color: var(--kimo-v2-bg);
}
#loop-m.is-sticky [data-story-stage] {
  background-color: var(--kimo-v2-surface) !important;
}
.mstep [data-node="Title"] {
  transition:
    color 300ms,
    font-weight 300ms;
}
.mstep.is-on [data-node="Title"] {
  color: var(--kimo-v2-text) !important;
  font-weight: 600 !important;
}
.mstep.is-off [data-node="Title"] {
  color: var(--kimo-v2-text-3) !important;
  font-weight: 400 !important;
}

/* 02 · Agent, live: the demo (src/landing/demo.ts, client/demo.ts). The 1440 × 900 editor stage
   scales to its box; the layers sit at their editor px. The markup is the done state. */
.demo[data-agent-demo="desktop"] {
  position: absolute;
  left: 0;
  top: 0;
  width: 1440px;
  height: 900px;
  transform-origin: 0 0;
}
.demo__base {
  position: absolute;
  left: 0;
  top: 0;
  width: 1440px;
  height: 901px;
}
.demo__layer {
  position: absolute;
  transform-origin: 50% 0;
  will-change: opacity, transform;
}
.demo__part {
  display: flex;
}
.demo__trace {
  outline: 1.5px dashed var(--kimo-agent);
  outline-offset: -0.75px;
}
[data-agent-demo]:not(.is-live) [data-l="cursor"],
[data-agent-demo]:not(.is-live) [data-l="claim"],
[data-agent-demo]:not(.is-live) [data-l="trace"],
[data-agent-demo]:not(.is-live) [data-l="pro-in"] {
  opacity: 0;
}
.demo__card {
  transform-origin: 50% 0;
}
.demo__spin {
  animation: demo-spin 1s linear infinite;
}
@keyframes demo-spin {
  to {
    transform: rotate(360deg);
  }
}
.demo__caret {
  display: inline-block;
  width: 1px;
  height: 1em;
  margin-left: 1px;
  vertical-align: -2px;
  background: currentColor;
  animation: demo-caret 1s steps(1) infinite;
}
@keyframes demo-caret {
  50% {
    opacity: 0;
  }
}

/* 02 · Agent, live: key frames light up in turn. */
/* the key frames light in step with the demo */
.keys .key {
  transition:
    background-color 300ms,
    outline-color 300ms;
}
.keys .key.is-on {
  background: #2bc4d41f !important;
  outline-color: var(--kimo-agent) !important;
}
.keys .key.is-off {
  background: #ffffff08 !important;
  outline-color: var(--kimo-v2-line) !important;
}
.keys .key.is-on [data-node="Time"] {
  color: var(--kimo-agent) !important;
}
.keys .key.is-off [data-node="Time"] {
  color: var(--kimo-v2-text-3) !important;
}
.keys .key.is-on [data-node="Label"] {
  color: var(--kimo-v2-text) !important;
}
.keys .key.is-off [data-node="Label"] {
  color: var(--kimo-v2-text-2) !important;
}

/* 03 · Multiplayer: live cursors drift on small loops. */
@media (prefers-reduced-motion: no-preference) {
  .cursor {
    animation: cursor-drift 7s ease-in-out infinite alternate;
  }
  .cursor[data-cursor="1"] {
    animation-duration: 5.5s;
    animation-delay: -2s;
  }
  .cursor[data-cursor="2"] {
    animation-duration: 8s;
    animation-delay: -4s;
  }
  .cursor[data-cursor="3"] {
    animation-duration: 6.5s;
    animation-delay: -1s;
  }
}
@keyframes cursor-drift {
  0% {
    transform: translate(0, 0);
  }
  35% {
    transform: translate(18px, -10px);
  }
  70% {
    transform: translate(-12px, 14px);
  }
  100% {
    transform: translate(10px, 6px);
  }
}

/* Between 1024 and 1440 the key-frame pills wrap instead of running off the page. */
@media (max-width: 1439.98px) {
  .landing--desktop .keys {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 12px;
    max-width: calc(100% - 128px);
  }
}
