/* ==========================================================================
   Home hero (owner 2026-10-11): NexNode models floating over a faint pattern
   that answers the cursor. Drawn on a 1440 x 792 board; --u scales the whole
   board with the window, so the composition is the same at every desktop size.
   Six background patterns ship; data-bg on #hero picks one (?bg= overrides it
   for comparing). The previous node-graph hero lives in git history.

   Smoothness: everything that moves per frame moves by TRANSFORM on its own
   layer (will-change), so the cursor never makes the browser repaint. The red
   glow is a small masked window slid over the hero, not a mask redrawn at the
   cursor, and models draw their frames into a canvas (hero.js).
   ========================================================================== */
.hx {
  /* The board fits the width AND the screen height, so on a desktop the brand
     strip under the hero is still on the first screen (owner 2026-10-18). */
  --u: min(calc(min(100vw, 1680px) / 1440), calc((100svh - 180px) / 744));
  --px: 0; --py: 0; --on: 0;
  --cx: 50%; --cy: 50%; --rdx: 0px; --rdy: 0px;
  position: relative; isolation: isolate; overflow: hidden; contain: layout paint;
  height: max(560px, min(calc(100svh - 180px), calc(792 * var(--u))));
}
.hx.is-off * { animation-play-state: paused !important; }

/* ---------- background patterns ---------- */
.hx-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.hx-l { position: absolute; inset: -80px; display: none; will-change: transform; }
/* The glow: a 380px window (moved by hero.js) whose content is moved back the
   same amount, so the red copy of the pattern lines up with the dim one. */
.hx-glow {
  position: absolute; left: 0; top: 0; width: 380px; height: 380px; overflow: hidden;
  opacity: var(--on); transition: opacity .4s; will-change: transform, opacity;
  -webkit-mask-image: radial-gradient(circle 190px at 50% 50%, #000, transparent 72%);
  mask-image: radial-gradient(circle 190px at 50% 50%, #000, transparent 72%);
}
.hx-glow-in { position: absolute; left: 0; top: 0; width: 100vw; height: 100%; will-change: transform; }
.hx-band { display: none; }
.hx-vignette { position: absolute; inset: 0; z-index: 1; pointer-events: none; background: radial-gradient(ellipse 72% 70% at 50% 52%, transparent 50%, var(--ink) 100%); }

/* 1 · dot field: still (owner 2026-10-11); only the red glow follows the cursor */
[data-bg="dots"] .hx-l1, [data-bg="dots"] .hx-g1 { display: block; background-size: 22px 22px; will-change: auto; }
/* Dark until the cursor comes near, then a soft white, never red (owner 2026-10-18, like flora.ai). */
[data-bg="dots"] .hx-l1 { background-image: radial-gradient(#251c1f 1.1px, transparent 1.6px); }
[data-bg="dots"] .hx-g1 { background-image: radial-gradient(rgba(242,234,231,.62) 1.25px, transparent 1.75px); }

/* 2 · pixel stars: three depths */
[data-bg="stars"] .hx-l1, [data-bg="stars"] .hx-l2, [data-bg="stars"] .hx-l3, [data-bg="stars"] .hx-g1, [data-bg="stars"] .hx-g2 { display: block; }
[data-bg="stars"] .hx-l1, [data-bg="stars"] .hx-g1 { transform: translate(calc(var(--px) * 10px), calc(var(--py) * 6px)); background-size: 41px 41px; }
[data-bg="stars"] .hx-l2, [data-bg="stars"] .hx-g2 { transform: translate(calc(var(--px) * 22px), calc(var(--py) * 13px)); background-size: 67px 67px; background-position: 13px 29px; }
[data-bg="stars"] .hx-l1 { background-image: conic-gradient(at 2px 2px, transparent 75%, #3a2c30 0); }
[data-bg="stars"] .hx-l2 { background-image: conic-gradient(at 2px 2px, transparent 75%, #30252a 0); }
[data-bg="stars"] .hx-g1, [data-bg="stars"] .hx-g2 { background-image: conic-gradient(at 2px 2px, transparent 75%, rgba(248,49,60,.75) 0); }
[data-bg="stars"] .hx-l3 { transform: translate(calc(var(--px) * 36px), calc(var(--py) * 22px)); background-image: conic-gradient(at 3px 3px, transparent 75%, #4a383d 0); background-size: 103px 103px; background-position: 51px 7px; animation: hx-twinkle 3.2s steps(2, end) infinite alternate; }
@keyframes hx-twinkle { from { opacity: .3; } to { opacity: 1; } }

/* 3 · wire lattice */
[data-bg="lattice"] .hx-l1, [data-bg="lattice"] .hx-g1 { display: block; inset: -220px; transform: translate(calc(var(--px) * 14px), calc(var(--py) * 8px)) rotate(calc(var(--px) * 1.2deg)); }
[data-bg="lattice"] .hx-l1 { background-image: repeating-linear-gradient(30deg, #271e21 0 1px, transparent 1px 34px), repeating-linear-gradient(150deg, #271e21 0 1px, transparent 1px 34px), repeating-linear-gradient(90deg, #271e21 0 1px, transparent 1px 34px); animation: hx-breathe 7s ease-in-out infinite alternate; }
[data-bg="lattice"] .hx-g1 { background-image: repeating-linear-gradient(30deg, rgba(248,49,60,.55) 0 1px, transparent 1px 34px), repeating-linear-gradient(150deg, rgba(248,49,60,.55) 0 1px, transparent 1px 34px), repeating-linear-gradient(90deg, rgba(248,49,60,.55) 0 1px, transparent 1px 34px); }
@keyframes hx-breathe { from { opacity: .65; } to { opacity: 1; } }

/* 4 · contour rings: the centre follows the cursor, late */
[data-bg="rings"] .hx-l1, [data-bg="rings"] .hx-l2, [data-bg="rings"] .hx-g1 {
  display: block; inset: auto; left: 50%; top: 50%; width: 3000px; height: 3000px; margin: -1500px 0 0 -1500px;
  transform: translate(var(--rdx), var(--rdy)); transition: transform 1.4s var(--ease);
}
[data-bg="rings"] .hx-l1 { background: repeating-radial-gradient(circle at 50% 50%, transparent 0 26px, #2a2024 26px 27px); }
[data-bg="rings"] .hx-g1 { background: repeating-radial-gradient(circle at 50% 50%, transparent 0 26px, rgba(248,49,60,.75) 26px 27px); }
[data-bg="rings"] .hx-l2::before { content: ''; position: absolute; inset: 0; background: repeating-radial-gradient(circle at 47% 53%, transparent 0 33px, rgba(42,32,36,.7) 33px 34px); animation: hx-spin 90s linear infinite; }
@keyframes hx-spin { to { transform: rotate(360deg); } }

/* 5 · scanlines */
[data-bg="scan"] .hx-l1, [data-bg="scan"] .hx-g1 { display: block; transform: translate(calc(var(--px) * 10px), calc(var(--py) * 6px)); }
[data-bg="scan"] .hx-l1 { background-image: repeating-linear-gradient(to bottom, rgba(242,234,231,.045) 0 1px, transparent 1px 4px); }
[data-bg="scan"] .hx-g1 { background-image: repeating-linear-gradient(to bottom, rgba(248,49,60,.55) 0 1px, transparent 1px 4px); }
[data-bg="scan"] .hx-band { display: block; position: absolute; left: 0; right: 0; top: -200px; height: 200px; background: linear-gradient(to bottom, transparent, rgba(242,234,231,.035) 65%, transparent); animation: hx-band 9s linear infinite; }
@keyframes hx-band { to { transform: translateY(1300px); } }

/* 6 · plus marks: two sizes, two depths */
[data-bg="plus"] .hx-l1, [data-bg="plus"] .hx-l2, [data-bg="plus"] .hx-g1 { display: block; }
[data-bg="plus"] .hx-l1, [data-bg="plus"] .hx-g1 { transform: translate(calc(var(--px) * 10px), calc(var(--py) * 6px)); background-size: 44px 44px; }
[data-bg="plus"] .hx-l1 { background-image: url(/assets/hero/plus-dim.svg); animation: hx-breathe 6s ease-in-out infinite alternate; }
[data-bg="plus"] .hx-g1 { background-image: url(/assets/hero/plus-red.svg); opacity: .8; }
[data-bg="plus"] .hx-l2 { transform: translate(calc(var(--px) * 36px), calc(var(--py) * 22px)); background-image: url(/assets/hero/plus-dim.svg); background-size: 132px 132px; background-position: 30px 52px; image-rendering: pixelated; opacity: .45; }

/* ---------- models ---------- */
/* The stage holds every model. On a desktop it is the whole hero (the 1440 x 792
   board); below 1024px it is its own box under the copy (see the end of the file). */
.hx-stage { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.hx-models { position: absolute; inset: 0; pointer-events: none; }
.hx-m, .hx-ground {
  position: absolute; aspect-ratio: 1;
  left: calc(50% + (var(--x) - 720) * var(--u)); top: calc(var(--y) * var(--u)); width: calc(var(--s) * var(--u));
}
.hx-m { transform: translate(calc(var(--px) * var(--d) * 26px), calc(var(--py) * var(--d) * 16px)); will-change: transform; }
/* A random tilt and a small random shift per visit (hero.js sets --rot, --jx, --jy in -1..1). */
.hx-m { translate: calc(var(--jx, 0) * 26 * var(--u)) calc(var(--jy, 0) * 20 * var(--u)); }
.hx-m .hx-sprite, .hx-ground .hx-sprite { rotate: var(--rot, 0deg); }
.hx-bob { width: 100%; height: 100%; animation: hx-bob var(--dur, 8s) ease-in-out var(--delay, 0s) infinite alternate; }
@keyframes hx-bob { from { transform: translateY(-8px); } to { transform: translateY(8px); } }
.hx-sprite { position: relative; width: 100%; height: 100%; background-repeat: no-repeat; background-position: center; background-size: 100% 100%; }
.hx-sprite.is-atlas { background-image: none !important; } /* the canvas below draws the turning views */
.hx-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; opacity: 0; transition: opacity .5s ease; }
.hx-canvas.is-on { opacity: 1; } /* fades in over the still picture (hero.js) */
.hx-mid .hx-sprite { filter: brightness(.85); }
.hx-far .hx-sprite { filter: brightness(.8); } /* no blur: every model stays sharp (owner 2026-10-18) */
.hx-ground { z-index: 2; transform: translate(calc(var(--px) * 24px), calc(var(--py) * 14px)); will-change: transform; }
.hx-shadow { position: absolute; left: 16%; right: 16%; bottom: 4%; height: 9%; background: radial-gradient(closest-side, rgba(0,0,0,.8), transparent); }
/* The boot floats like the others (owner 2026-10-18); its shadow shrinks and fades as it rises. */
/* the boot is the biggest model, so it floats further to read as floating (owner 2026-10-18) */
.hx-ground .hx-sprite { animation: hx-bob-big 5.5s ease-in-out -2s infinite alternate; }
.hx-ground .hx-shadow { animation: hx-shadow 5.5s ease-in-out -2s infinite alternate; }
@keyframes hx-bob-big { from { transform: translateY(-16px); } to { transform: translateY(14px); } }
@keyframes hx-shadow { from { transform: scaleX(.8); opacity: .55; } to { transform: scaleX(1); opacity: 1; } }

/* ---------- copy ---------- */
.hx-copy {
  position: absolute; z-index: 3; left: 0; right: 0; top: calc(148 * var(--u));
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding-inline: var(--gutter); pointer-events: none;
}
.hx-title { margin: 0; font-family: var(--f-display); font-weight: 600; font-size: max(30px, calc(58 * var(--u))); letter-spacing: -.035em; line-height: 1.05; white-space: nowrap; }
.hx-title em { font-style: normal; font-family: var(--f-accent); font-weight: 400; font-synthesis: none; text-transform: uppercase; letter-spacing: 0; font-size: .8em; color: var(--accent-fill); }
.hx-lead { margin: max(14px, calc(18 * var(--u))) 0 0; font-size: max(16px, calc(18 * var(--u))); line-height: 1.6; color: var(--dust); }
.hx-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: max(22px, calc(28 * var(--u))); pointer-events: auto; }

/* Pixel-cornered buttons. The step clip sits on the inner face so the focus ring on the link stays visible. */
.pbtn { display: inline-flex; border-radius: 2px; transition: transform .25s var(--ease); }
.pbtn:hover { transform: translateY(-1px); }
.pbtn-face {
  display: inline-flex; align-items: center; gap: 10px; height: 48px; padding: 0 22px;
  font-weight: 650; font-size: 16px; letter-spacing: -.01em; white-space: nowrap; transition: background-color .25s;
  clip-path: polygon(0 8px,4px 8px,4px 4px,8px 4px,8px 0,calc(100% - 8px) 0,calc(100% - 8px) 4px,calc(100% - 4px) 4px,calc(100% - 4px) 8px,100% 8px,100% calc(100% - 8px),calc(100% - 4px) calc(100% - 8px),calc(100% - 4px) calc(100% - 4px),calc(100% - 8px) calc(100% - 4px),calc(100% - 8px) 100%,8px 100%,8px calc(100% - 4px),4px calc(100% - 4px),4px calc(100% - 8px),0 calc(100% - 8px));
}
.pbtn-accent .pbtn-face { background: var(--accent-fill); color: var(--on-accent); }
.pbtn-accent:hover .pbtn-face { background: var(--accent-fill-hover); }
.pbtn-ghost .pbtn-face { padding: 2px; background: var(--line-2); }
.pbtn-ghost:hover .pbtn-face { background: var(--bone); }
.pbtn-in {
  display: inline-flex; align-items: center; height: 44px; padding: 0 20px; background: var(--ink); color: var(--bone);
  clip-path: polygon(0 8px,4px 8px,4px 4px,8px 4px,8px 0,calc(100% - 8px) 0,calc(100% - 8px) 4px,calc(100% - 4px) 4px,calc(100% - 4px) 8px,100% 8px,100% calc(100% - 8px),calc(100% - 4px) calc(100% - 8px),calc(100% - 4px) calc(100% - 4px),calc(100% - 8px) calc(100% - 4px),calc(100% - 8px) 100%,8px 100%,8px calc(100% - 4px),4px calc(100% - 4px),4px calc(100% - 8px),0 calc(100% - 8px));
}
.pbtn:hover .btn-arrow { transform: translateX(4px); }

/* ---------- below 1024px: models spread around the copy ----------
   Some above the title, some under the buttons, none over the text. The copy
   flows in the middle; top models hang from the hero's top edge and bottom
   models stand on its bottom edge, so they follow the copy's real height.
   Units are hero widths: 1cqw = 1% of the hero (container on .hx). */
@media (max-width: 1023px) {
  .hx { height: auto; container-type: inline-size; padding: 23vw 0 44vw; }
  .hx-copy { position: relative; top: auto; }
  .hx-title { font-size: clamp(34px, 6.2vw, 52px); }
  .hx-lead { font-size: clamp(15px, 2vw, 18px); margin-top: 14px; }
  .hx-actions { margin-top: 24px; }
  .hx-stage .hx-m, .hx-stage .hx-ground { left: calc(var(--mx) * 1cqw); width: calc(var(--ms) * 1cqw); top: auto; bottom: auto; }
  .hx-stage [data-k="helmet"], .hx-stage [data-k="fuel"], .hx-stage [data-k="hammer"] { top: calc(var(--my) * 1cqw); }
  .hx-stage [data-k="boot"], .hx-stage [data-k="chair"], .hx-stage [data-k="candle"] { bottom: calc(var(--mb) * 1cqw); }
  .hx-stage [data-k="helmet"] { --mx: 4;  --my: 3; --ms: 18; }
  .hx-stage [data-k="fuel"]   { --mx: 78; --my: 2; --ms: 19; }
  .hx-stage [data-k="hammer"] { --mx: 63; --my: 4; --ms: 8; }
  .hx-stage [data-k="boot"]   { --mx: 38; --mb: 6; --ms: 30; }
  .hx-stage [data-k="chair"]  { --mx: 4;  --mb: 5; --ms: 22; }
  .hx-stage [data-k="candle"] { --mx: 79; --mb: 6; --ms: 16; }
  .hx-stage .hx-ground { transform: translate(calc(var(--px) * 12px), calc(var(--py) * 8px)); }
  .hx-stage .hx-m { transform: translate(calc(var(--px) * var(--d) * 14px), calc(var(--py) * var(--d) * 9px)); translate: calc(var(--jx, 0) * 2.5cqw) calc(var(--jy, 0) * 2.5cqw); }
}
@media (max-width: 599px) {
  .hx { padding: 34vw 0 60vw; }
  .hx-title { white-space: normal; text-wrap: balance; font-size: clamp(32px, 9.6vw, 44px); }
  .hx-stage [data-k="helmet"] { --mx: 2;  --my: 4; --ms: 27; }
  .hx-stage [data-k="fuel"]   { --mx: 71; --my: 2; --ms: 27; }
  .hx-stage [data-k="hammer"] { --mx: 45; --my: 7; --ms: 11; }
  .hx-stage [data-k="boot"]   { --mx: 30; --mb: 7; --ms: 46; }
  .hx-stage [data-k="chair"]  { --mx: 1;  --mb: 8; --ms: 26; }
  .hx-stage [data-k="candle"] { --mx: 78; --mb: 9; --ms: 19; }
}

/* ---------- brand strip under the hero (owner 2026-10-18, like flora.ai) ----------
   No rules; the hero fades to black into it; white names that brighten on hover. */
.hx::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 90px; z-index: 2; pointer-events: none; background: linear-gradient(to bottom, transparent, var(--ink)); }
.hx + .ticker { border-block: 0; background: var(--ink); padding: 18px 0 22px; }
.hx + .ticker .partners li { color: rgba(255, 255, 255, .4); opacity: 1; }
.hx + .ticker .partners li:hover { color: #fff; }
/* a strip of names, not text to edit or copy: arrow cursor, no selection (owner 2026-10-18) */
.hx + .ticker { cursor: default; -webkit-user-select: none; user-select: none; }
/* Keeps moving under the cursor; a name lights up on hover (owner 2026-10-18). Smaller and ~12% slower on screen (owner 2026-11-01): the track is ~20% shorter, so 68s. */
.hx + .ticker .ticker-track:has(.partners) { animation-duration: 68s; }
.hx + .ticker:hover .ticker-track { animation-play-state: running; }
.hx + .ticker .partners li { font-size: 18px; gap: 11px; padding-right: 60px; }
.hx + .ticker .partners svg { width: 22px; height: 22px; }
@media (max-width: 599px) {
  .hx + .ticker .partners li { font-size: 15px; padding-right: 42px; }
  .hx + .ticker .partners svg { width: 19px; height: 19px; }
}

@media (prefers-reduced-motion: reduce) {
  .hx-l, .hx-l::before, .hx-band, .hx-bob, .hx-ground .hx-sprite, .hx-ground .hx-shadow { animation: none !important; }
  .hx-band { display: none !important; }
  .hx-l, .hx-glow { transition: none; }
}
