/* ==========================================================================
   Nueform V3 — the living artifacts (SITE-SPEC-V3)
   Layered after styles.css. Adds: render assembly, the exploded anatomy,
   the depth marquee, the console, pointer tilt. No V2 rules are rewritten.
   ========================================================================== */

/* ---------- 1 · Render assembly ----------
   A render card builds itself when it enters view. Initial hidden states are
   gated behind html.js + no-preference so no-JS / reduced-motion see the
   finished card. Replayable: drop .in, reflow, re-add. */
@media (prefers-reduced-motion: no-preference) {
  html.js .rdr-assemble .cx-card > *,
  html.js .rdr-assemble .cx-slide > * { opacity: 0; }
  html.js .rdr-assemble .cx-card,
  html.js .rdr-assemble .cx-slide { opacity: 0; }

  html.js .rdr-assemble.in .cx-card,
  html.js .rdr-assemble.in .cx-slide { animation: rdr-canvas 0.45s var(--ease) forwards; }
  html.js .rdr-assemble.in .cx-card-glow, html.js .rdr-assemble.in .cx-card-glow-2,
  html.js .rdr-assemble.in .cx-card-wheel, html.js .rdr-assemble.in .cx-card-wheel-mask,
  html.js .rdr-assemble.in .cx-glow, html.js .rdr-assemble.in .cx-glow-2,
  html.js .rdr-assemble.in .cx-wheel, html.js .rdr-assemble.in .cx-wheel-mask {
    animation: rdr-bloom 0.9s var(--ease) 0.2s forwards;
  }
  html.js .rdr-assemble.in .cx-card-chrome, html.js .rdr-assemble.in .cx-chrome {
    animation: rdr-drop 0.55s var(--ease) 0.5s forwards;
  }
  html.js .rdr-assemble.in .cx-card-body, html.js .rdr-assemble.in .cx-body {
    animation: rdr-wipe 0.65s var(--ease) 0.72s forwards;
  }
  html.js .rdr-assemble.in .cx-card-footer, html.js .rdr-assemble.in .cx-footer,
  html.js .rdr-assemble.in .cx-data-strip {
    animation: rdr-rise 0.5s var(--ease) 1.0s forwards;
  }
  html.js .rdr-assemble.in .rdr-chip { animation: rdr-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) 1.35s forwards; }
}
@keyframes rdr-canvas { from { opacity: 0; } to { opacity: 1; } }
@keyframes rdr-bloom { from { opacity: 0; filter: blur(14px); } to { opacity: 1; filter: blur(0); } }
@keyframes rdr-drop { from { opacity: 0; transform: translateY(-16px); } to { opacity: 1; transform: translateY(0); } }
@keyframes rdr-wipe {
  from { opacity: 1; clip-path: inset(0 100% 0 0); }
  to { opacity: 1; clip-path: inset(0 0% 0 0); }
}
@keyframes rdr-rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
@keyframes rdr-pop { from { opacity: 0; transform: scale(0.4); } to { opacity: 1; transform: scale(1); } }

/* the RENDERED chip — outside the scaled card so it stays crisp */
.rdr-chip {
  position: absolute; top: 10px; right: 10px; z-index: 3; opacity: 0;
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.12em;
  color: var(--ok); background: rgba(10, 10, 10, 0.82); border: 1px solid rgba(53, 194, 110, 0.5);
  border-radius: 5px; padding: 3px 8px; text-transform: uppercase; pointer-events: none;
}
html:not(.js) .rdr-chip, /* no-JS: show it, the card is complete */
.rdr-chip { opacity: 1; }
@media (prefers-reduced-motion: no-preference) { html.js .rdr-chip { opacity: 0; } }

/* pointer tilt (JS sets --tx/--ty; fine pointers only) */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .render-scale[data-tilt] {
    transform: perspective(900px) rotateX(var(--ty, 0deg)) rotateY(var(--tx, 0deg));
    transition: transform 180ms var(--ease);
    will-change: transform;
  }
}

/* ---------- 2 · Anatomy of a render (exploded 3D) ---------- */
/* Register --xf as a typed, inheritable custom property. GSAP scrubs it 0 → 1
   and the .xr-layer transforms read it inside a translateZ() calc. Chromium
   repaints those transforms when an *unregistered* custom property changes, but
   Safari/WebKit does NOT — so without @property the scrub updates the value yet
   the layers never re-transform and the diagram sits frozen in its default
   exploded state (--xf:1). Registering it makes the value a real animatable
   <number> and forces the dependent transforms to repaint everywhere. */
@property --xf {
  syntax: '<number>';
  inherits: true;
  initial-value: 1;
}
.anatomy-grid { display: grid; grid-template-columns: 0.62fr 1.38fr; gap: clamp(20px, 3vw, 44px); align-items: center; }
.anatomy-grid > * { min-width: 0; }
.xr-labels { list-style: none; margin: 0; padding: 0; display: grid; gap: 22px; }
.xr-labels li { display: grid; gap: 4px; padding-left: 18px; position: relative; }
.xr-labels li::before {
  content: ""; position: absolute; left: 0; top: 9px; width: 10px; height: 1px; background: var(--accent);
}
.xr-labels .xl-n { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; color: var(--accent); }
.xr-labels .xl-t { font-family: var(--font-display); font-weight: 600; font-size: 15.5px; letter-spacing: -0.01em; }
.xr-labels .xl-d { font-size: 13.5px; color: var(--dim); max-width: 34ch; }

.anatomy-stage {
  perspective: 2000px;
  min-height: 600px;
  position: relative;
}
.xr {
  width: 1080px; height: 1350px;
  position: absolute; top: 62%; left: 60%;
  transform-style: preserve-3d;
  /* .xr's own layout box is 1080x1350 — transforms don't affect layout, so it's
     taken out of flow (absolute) and self-centered; otherwise it inflates
     .anatomy-stage to its untransformed size and the rotated/scaled card
     renders far from where the label list actually sits. The exploded layers
     lean up-and-left (higher-Z planes project that way), so top/left sit past
     centre to drop the visual mass down-right, clear of the heading + copy. */
  transform: translate(-50%, -50%) rotateX(55deg) rotateZ(-34deg) scale(var(--xs, 0.34));
  --xf: 1; /* explosion factor: 1 = exploded (default, no-JS); JS scrubs 0 → 1 */
}
.xr-layer {
  position: absolute; inset: 0;
  transform: translateZ(calc(var(--z, 0) * var(--xf) * 1px));
  border: 2px solid rgba(255, 61, 0, 0.4);
  border-radius: 48px;
  background: rgba(14, 14, 15, 0.44);
  box-shadow: 0 0 80px rgba(0, 0, 0, 0.55);
}
.xr-layer .cx-card { border-radius: 48px; }
/* transparent layers: only the base keeps the card's canvas */
.xr-layer--t .cx-card { background: transparent !important; }
.xr-layer--t .cx-card::before, .xr-layer--t .cx-card::after { display: none !important; }
/* plane number — a callout just off the plane's right edge, on-plane in 3D */
.xr-num {
  position: absolute; top: 40px; right: -170px;
  font-family: var(--font-mono); font-size: 58px; font-weight: 600;
  letter-spacing: 0.1em; color: rgba(255, 61, 0, 0.6);
}
.xr-num::before {
  content: ""; position: absolute; left: -66px; top: 50%;
  width: 52px; height: 2px; background: rgba(255, 61, 0, 0.4);
}
.anatomy-note { margin-top: 12px; }

@media (max-width: 1080px) {
  .anatomy-grid { grid-template-columns: 1fr; }
  .anatomy-stage { min-height: 470px; }
  /* single column: recentre (the desktop down-right nudge clears the side copy,
     which no longer sits beside the stage here) */
  .xr { --xs: 0.24; top: 50%; left: 50%; }
  .xr-labels { grid-template-columns: 1fr 1fr; gap: 16px; }
}
@media (max-width: 640px) {
  .anatomy-stage { min-height: 370px; }
  .xr { --xs: 0.17; }
  .xr-labels { grid-template-columns: 1fr; }
}

/* ---------- 3 · Depth marquee ---------- */
.mq { perspective: 1200px; padding: 40px 0 46px; }
.mq .mq-track { transform: rotateX(9deg); }
.mq-track--back {
  position: absolute; top: 12px; left: 0;
  transform: translateZ(-240px) rotateX(9deg);
  opacity: 0.45; filter: saturate(0.8) brightness(0.8);
  animation-direction: reverse; animation-duration: 64s;
  pointer-events: none;
}
.mq::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: linear-gradient(90deg, var(--bg-2), transparent 16%, transparent 84%, var(--bg-2));
}
.mq-label { z-index: 4; }

/* ---------- 4 · The console (/content) ---------- */
.console-panel {
  border: 1px solid var(--line); border-radius: var(--rad-lg);
  background: linear-gradient(175deg, var(--panel-2), var(--panel));
  padding: clamp(22px, 3.4vw, 42px); display: grid; gap: 26px;
  box-shadow: var(--shadow-2); position: relative; overflow: clip;
}
.console-grid { display: grid; grid-template-columns: 1fr auto; gap: clamp(22px, 3.4vw, 48px); align-items: center; }
.console-grid > * { min-width: 0; }
.console-controls { display: grid; gap: 22px; align-content: start; }
.console-group { display: grid; gap: 10px; }
.console-group > .label {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--faint);
}
.console-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.console-chip {
  cursor: pointer; border: 1px solid var(--line-strong); border-radius: 8px; background: none;
  padding: 9px 14px; font-family: var(--font-body); font-size: 13.5px; color: var(--dim); text-align: left;
  transition: border-color var(--speed) var(--ease), color var(--speed) var(--ease), background var(--speed) var(--ease);
  max-width: 100%;
}
.console-chip:hover { border-color: var(--text); color: var(--text); }
.console-chip[aria-pressed="true"] { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }
.console-run { justify-self: start; }
.console-status {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; color: var(--faint);
  text-transform: uppercase; min-height: 1.4em;
}
.console-status .busy { color: var(--warn); }
.console-status .done { color: var(--ok); }
.console-stage { display: grid; gap: 12px; justify-items: center; }
.console-stage .render-scale { --rs: 0.32; }
.console-note { font-family: var(--font-mono); font-size: 11.5px; color: var(--faint); line-height: 1.8; }

@media (max-width: 1080px) {
  .console-grid { grid-template-columns: 1fr; }
  .console-stage { justify-items: start; }
}

/* ---------- 5 · Hero float production loop ---------- */
.hf-caret { display: inline-block; width: 1px; height: 1em; background: var(--accent); vertical-align: -0.15em; margin-left: 1px; animation: hf-blink 0.9s steps(1) infinite; }
@keyframes hf-blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .hf-caret { display: none; } }
.hf-render { border-radius: 8px; overflow: hidden; position: relative; }
.hf-render .render-scale { --rs: 0.185; box-shadow: none; border-radius: 8px; }
.hf-status {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ok); border: 1px solid rgba(53, 194, 110, 0.45); border-radius: 4px; padding: 2px 7px;
  opacity: 0; transition: opacity 0.3s var(--ease);
}
.hf-status.on { opacity: 1; }
