/* ============================================================================
   Jonas Ryan Charles — Interactive layer
   Adds the premium interaction surfaces on top of styles.css (base + tokens).
   Organized by concern: tokens+ · preloader · hero two-col · robot node ·
   focus areas · console · scroll progress · return-to-top · responsive.
   All motion is opacity/transform only and respects prefers-reduced-motion.
   ============================================================================ */

/* ---- Extra semantic tokens (aliases + new) -------------------------------- */
:root {
  --color-bg: var(--bg);
  --color-surface: var(--bg-raised);
  --color-surface-raised: var(--bg-card);
  --color-text: var(--ink);
  --color-text-muted: var(--ink-dim);
  --color-signal: var(--signal);
  --color-signal-dim: var(--signal-dim);
  --color-measurement: var(--trace-amber);
  --color-border: var(--border);
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --shadow-signal: 0 0 40px -12px var(--signal-glow);
  --z-preloader: 1000;
  --z-tooltip: 900;
  --z-progress: 300;
  /* The hero breaks out wider than the page container so the left content and
     the robot can reach toward the viewport edges. Sections below keep --maxw. */
  --hero-maxw: 1500px;
}

/* Hero + nav share the wider width so the JRC logo lines up above the name
   and the header links sit above the robot area. Sections below keep --maxw. */
.hero > .container,
.nav .container {
  max-width: var(--hero-maxw);
}
/* .hero is a flex row; the terminal is a sibling of .container, so allow it to
   wrap onto its own line once it leaves absolute positioning (tablet/mobile). */
.hero {
  flex-wrap: wrap;
}

/* ============================================================================
   Preloader — short instrument boot sequence. Content mounts behind it.
   ============================================================================ */
.preloader {
  position: fixed;
  inset: 0;
  z-index: var(--z-preloader);
  display: grid;
  place-items: center;
  background: var(--bg);
  transition: transform 0.7s var(--ease-out-expo), opacity 0.5s ease;
  will-change: transform;
}
.preloader.is-done {
  transform: translateY(-100%);
  opacity: 0;
  pointer-events: none;
}
.preloader__inner {
  width: min(460px, 82vw);
  font-family: var(--font-mono);
}
.preloader__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--signal);
  font-weight: 700;
  letter-spacing: 0.18em;
  font-size: var(--fs-sm);
  margin-bottom: var(--space-5);
}
.preloader__brand .chip__led {
  animation: led-pulse 1.1s ease-in-out infinite;
}
.preloader__log {
  min-height: 5.2em;
  font-size: var(--fs-xs);
  color: var(--ink-dim);
  letter-spacing: 0.06em;
}
.preloader__log-line {
  opacity: 0;
  transform: translateY(4px);
  animation: pl-in 0.35s var(--ease) forwards;
}
.preloader__log-line .ok {
  color: var(--signal);
}
@keyframes pl-in {
  to { opacity: 1; transform: none; }
}
.preloader__bar {
  margin-top: var(--space-4);
  height: 2px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
}
.preloader__bar span {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--signal-dim), var(--signal));
  transition: width 0.2s linear;
}

/* ============================================================================
   Scroll progress — thin signal bar under the nav.
   ============================================================================ */
.scroll-progress {
  position: fixed;
  top: var(--nav-h);
  left: 0;
  height: 2px;
  width: 100%;
  z-index: var(--z-progress);
  background: transparent;
  pointer-events: none;
}
.scroll-progress__bar {
  height: 100%;
  width: 0;
  transform-origin: left center;
  background: linear-gradient(90deg, var(--signal), var(--trace-amber));
  box-shadow: 0 0 10px -2px var(--signal-glow);
}

/* ============================================================================
   Hero — two-column layout: identity (left) + engineering node (right).
   Overrides the single-column hero from styles.css at desktop widths.
   ============================================================================ */
.hero__grid {
  position: relative;
  z-index: 2;
  display: grid;
  /* Left content fills the wide "yellow" region, robot takes the right. */
  grid-template-columns: minmax(0, 54%) minmax(0, 46%);
  align-items: start;
  gap: clamp(24px, 3vw, 56px);
  width: 100%;
}
.hero__inner {
  max-width: none; /* fill the column; individual elements cap themselves */
}
.hero__subline {
  max-width: 650px;
}
/* Soft scrim behind copy so the robot/glow never reduces text legibility. */
.hero__inner::before {
  content: "";
  position: absolute;
  inset: -6% -8% -6% -8%;
  z-index: -1;
  background: radial-gradient(
    120% 90% at 20% 40%,
    color-mix(in srgb, var(--bg) 82%, transparent) 0%,
    color-mix(in srgb, var(--bg) 60%, transparent) 45%,
    transparent 78%
  );
  pointer-events: none;
}

/* Staged hero entrance (opacity/transform only). JS adds .is-in per element
   after the preloader clears — element-level class to match the proven
   .reveal/.is-visible pattern. */
.hero [data-enter] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.65s var(--ease-out-expo),
    transform 0.65s var(--ease-out-expo);
  transition-delay: calc(var(--enter, 0) * 1ms);
}
.hero [data-enter].is-in {
  opacity: 1;
  transform: none;
}

/* ============================================================================
   Hero engineering metrics + closing statement (left column)
   ============================================================================ */
.metrics {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)); /* desktop: 4 across */
  gap: var(--space-3);
  margin-top: var(--space-8);
  padding: 0;
  list-style: none;
}
.metric {
  position: relative;
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: linear-gradient(180deg, var(--bg-card), var(--bg-raised));
  overflow: hidden;
  transition: border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
/* Short teal accent along the top-left. */
.metric::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 34px;
  height: 2px;
  background: var(--signal);
}
.metric:hover {
  border-color: var(--signal-dim);
  transform: translateY(-2px);
}
.metric__icon {
  display: block;
  color: var(--ink-dim);
  margin-bottom: var(--space-3);
}
.metric__value {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: 700;
  line-height: 1;
  color: var(--signal);
}
.metric__value-sub {
  font-size: 0.45em;
  font-weight: 500;
  color: var(--ink-dim);
  letter-spacing: 0.04em;
}
.metric__label {
  display: block;
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  line-height: 1.35;
  /* Reserve two lines so single- and double-line labels align, keeping every
     card's sub-line on the same baseline across the row. */
  min-height: 2.7em;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
}
.metric__sub {
  display: block;
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.35;
  min-height: 2.7em; /* reserve two lines (some subs wrap, some don't) */
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.hero__statement {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
}
.hero__statement-text {
  color: var(--ink-dim);
  font-size: var(--fs-sm);
  margin: 0;
}
.hero__statement-text em {
  color: var(--signal);
  font-style: italic;
}
.hero__statement-cta {
  flex: none;
}

/* ============================================================================
   Typewriter identity (inside the existing hero <h1>)
   Inherits ALL typography from .hero__title — no font, size, weight, tracking
   or colour changes. Only reserves height so nothing below can shift.
   ============================================================================ */
.ident {
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Exactly the two-line height the static heading occupied
     (2 lines x line-height .94) — one-line roles centre inside it. */
  min-height: 1.88em;
}
.ident__line {
  display: block;
  min-height: 0.94em; /* an empty line still occupies its line box */
}
/* Matches the previous .hero__title-line:last-child surname colour exactly. */
.ident__seg--dim {
  color: color-mix(in srgb, var(--ink) 82%, var(--bg));
}
.ident__caret {
  display: inline-block;
  width: 0.06em;
  height: 0.74em;
  margin-left: 0.06em;
  background: var(--signal);
  box-shadow: 0 0 10px var(--signal-dim);
  vertical-align: baseline;
}
/* Blinks only while a completed phrase is holding. */
.ident.is-holding .ident__caret {
  animation: ident-blink 800ms steps(1) infinite;
}
@keyframes ident-blink {
  0%, 50% { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

/* ============================================================================
   Hero right column: interactive humanoid Nexbot (Spline) + terminal
   z-order: grid(0) < robot(1) < text(2) < terminal(3) < hotspot/tooltip(4)
   ============================================================================ */
.hero__viz {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-width: 0;
  /* Bleed into the page gutter so the robot reaches toward the right edge. */
  margin-right: calc(var(--gutter) * -1);
}

.robot {
  position: relative;
  z-index: 1;
  width: 100%;
  /* Sized via the native container (crisp render, not CSS zoom). Height is
     viewport-bounded so the whole hero still fits one screen; the size increase
     comes from the wider column + gutter bleed. */
  height: clamp(420px, 76vh, 880px);
}
.robot__stage {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}

/* Humanoid silhouette: reserves space (no CLS) + is the fallback poster. */
.robot__silhouette {
  height: 100%;
  width: auto;
  max-width: 100%;
  opacity: 0.9;
  filter: drop-shadow(0 12px 40px rgba(0, 0, 0, 0.5));
  transition: opacity 0.6s var(--ease-out-expo);
}
.robot__core {
  animation: robot-core 2.6s ease-in-out infinite;
}
@keyframes robot-core {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/* Spline canvas — injected by robot.js; transparent, fades in when ready. */
.robot__spline {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  display: block;
  background: transparent !important;
  opacity: 0;
  transition: opacity 0.9s var(--ease-out-expo);
}
.robot--ready .robot__spline { opacity: 1; }
.robot--ready .robot__silhouette { opacity: 0; }
.robot--ready .robot__loader { display: none; }

/* Themed loader (only while Spline is loading). */
.robot__loader {
  position: absolute;
  inset: auto 0 12% 0;
  display: none;
  justify-content: center;
  pointer-events: none;
}
.robot--loading .robot__loader { display: flex; }
.robot__loader-label {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.2em;
  color: var(--signal);
}
.robot__loader-label .cur {
  display: inline-block;
  width: 7px;
  height: 1em;
  margin-left: 4px;
  background: var(--signal);
  vertical-align: -2px;
  animation: term-cur 1s steps(1) infinite;
}

/* Accessible identity hotspot over the robot (upper body, face-clear). */
.robot__hotspot {
  position: absolute;
  z-index: 4;
  top: 4%;
  left: 12%;
  right: 12%;
  bottom: 34%;
  border: 0;
  background: transparent;
  cursor: help;
}
.robot__hotspot:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 4px;
}
/* Static caption — the tooltip's info is never hover-only. */
.robot__caption {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.16em;
  color: var(--ink-dim);
  z-index: 2;
}
.robot__caption .accent { color: var(--signal); }

/* Floating tooltip (follows cursor / appears on focus). */
.robot__tooltip {
  position: fixed;
  left: 0;
  top: 0;
  transform: translate(var(--tx, 0), var(--ty, 0));
  z-index: var(--z-tooltip);
  padding: var(--space-3) var(--space-4);
  background: color-mix(in srgb, var(--bg-card) 92%, transparent);
  border: 1px solid var(--signal-dim);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-signal);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  line-height: 1.7;
  letter-spacing: 0.08em;
  color: var(--ink);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s var(--ease);
  max-width: 260px;
}
.robot--tip .robot__tooltip { opacity: 1; }
.robot__tooltip .k { color: var(--signal); }
.robot__tooltip .m { color: var(--trace-amber); }

/* ============================================================================
   Focus Areas — controlled scroll story (// What I Do)
   ============================================================================ */
.focus-list {
  display: grid;
  gap: var(--space-4);
}
.focus-item {
  display: grid;
  grid-template-columns: 7ch 1fr;
  gap: var(--space-5);
  align-items: start;
  padding: var(--space-6) var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--bg-card), var(--bg-raised));
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease),
    box-shadow 0.3s var(--ease);
}
.focus-item:hover {
  border-color: var(--signal);
  transform: translateY(-3px);
  box-shadow: var(--shadow-glow);
}
.focus-item__id {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.16em;
  color: var(--signal);
  padding-top: 0.35em;
}
.focus-item__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: 0;
}
.focus-item__blurb {
  margin-top: var(--space-2);
  color: var(--ink-dim);
}
.focus-item__tools {
  margin-top: var(--space-4);
}
@media (max-width: 640px) {
  .focus-item {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
}

/* ============================================================================
   HDL profile terminal (in-hero; overlaps robot lower torso on desktop)
   ============================================================================ */
/* Anchored to .hero's lower-right, over the robot's thighs/lower torso, and
   always fully inside the hero (no negative margins, never below the fold). */
.terminal-wrap {
  position: absolute;
  z-index: 4;
  right: clamp(24px, 4vw, 72px);
  bottom: clamp(20px, 3.5vh, 48px);
  width: clamp(400px, 34vw, 560px);
  max-width: calc(100% - 48px);
  margin: 0;
}
/* Semi-transparent so the robot stays visible behind the panel. Light blur
   only — this page already runs Spline (WebGL) + the electrical canvas. */
.terminal {
  border: 1px solid rgba(0, 220, 176, 0.34);
  border-radius: var(--radius);
  background: linear-gradient(
    180deg,
    rgba(8, 14, 20, 0.72),
    rgba(5, 10, 15, 0.58)
  );
  backdrop-filter: blur(5px) saturate(105%);
  -webkit-backdrop-filter: blur(5px) saturate(105%);
  overflow: hidden;
  box-shadow: 0 22px 65px rgba(0, 0, 0, 0.34),
    inset 0 1px 0 rgba(255, 255, 255, 0.025);
}
.terminal__bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--border);
  background: rgba(8, 14, 20, 0.5); /* translucent to match the panel */
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.terminal__dots {
  display: inline-flex;
  gap: 6px;
}
.terminal__dots i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--border-strong);
}
.terminal__dots i:nth-child(1) { background: var(--trace-amber); }
.terminal__dots i:nth-child(2) { background: var(--signal); opacity: 0.7; }
.terminal__title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Busy indicator while a command is processing/printing. */
.terminal__status {
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  color: var(--trace-amber);
  opacity: 0;
  transition: opacity 0.2s var(--ease);
}
.terminal.is-busy .terminal__status { opacity: 1; }
.terminal.is-busy .terminal__prompt { opacity: 0.45; }
.terminal.is-busy .terminal__input { opacity: 0.45; }
.terminal__output {
  padding: var(--space-4);
  height: clamp(130px, 20vh, 190px);
  overflow-y: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--ink);
  white-space: pre-wrap;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.terminal__line { min-height: 1.05em; }
.terminal__line--cmd { color: var(--ink); }
.terminal__prompt { color: var(--signal); }
/* Verilog-ish syntax colors */
.terminal__line.c-comment { color: var(--ink-dim); opacity: 0.8; }
.terminal__line.c-ok { color: var(--signal); }
.terminal__line.c-param { color: var(--trace-amber); }
.terminal__line.c-err { color: #ff6b6b; }
.terminal__form {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
}
.terminal__form .terminal__prompt { white-space: nowrap; }
.terminal__input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 0;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  letter-spacing: 0.02em;
  caret-color: var(--signal);
}
.terminal__input:focus { outline: none; }
.terminal__hints {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
  justify-content: center;
}
.terminal__hint {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  color: var(--ink-dim);
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.terminal__hint:hover,
.terminal__hint:focus-visible {
  color: var(--signal);
  border-color: var(--signal-dim);
}
@keyframes term-cur {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

/* ============================================================================
   Return-to-top control
   ============================================================================ */
.to-top {
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: var(--z-progress);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: color-mix(in srgb, var(--bg-card) 88%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--ink);
  cursor: pointer;
  opacity: 0;
  transform: translateY(12px) scale(0.9);
  pointer-events: none;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease),
    border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.to-top.is-shown {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.to-top:hover {
  border-color: var(--signal);
  color: var(--signal);
}

/* Active-section nav link. */
.nav__link.is-active {
  color: var(--ink);
}
.nav__link.is-active::after {
  width: 100%;
}

/* ============================================================================
   Responsive — collapse hero to stacked, drop cursor interactions on touch
   ============================================================================ */
/* Compress the desktop hero so heading, cards, statement, robot AND terminal
   all fit a single short screen (e.g. 1366x768) without clipping. */
@media (min-width: 981px) and (max-height: 900px) {
  .hero {
    padding-top: calc(var(--nav-h) + clamp(20px, 3vh, 44px));
    padding-bottom: var(--space-6);
  }
  .hero__cta,
  .hero__stats,
  .metrics { margin-top: var(--space-5); }
  .hero__statement {
    margin-top: var(--space-4);
    padding-top: var(--space-4);
  }
  .metric { padding: var(--space-2) var(--space-3); }
  .metric__icon { margin-bottom: var(--space-2); }
  .metric__label { margin-top: var(--space-2); }
}

/* Short screens (<=820px tall): tighten further so the full hero — including
   the terminal — lands inside the first screen. */
@media (min-width: 981px) and (max-height: 820px) {
  .hero {
    padding-top: calc(var(--nav-h) + 16px);
    padding-bottom: var(--space-5);
  }
  /* The 4.75rem display cap is far too tall for a 720px screen. */
  .hero__title { font-size: clamp(2.5rem, 4.2vw, 3.5rem); }
  .hero__subline { margin-top: var(--space-3); }
  .hero__cta,
  .hero__stats,
  .metrics { margin-top: var(--space-4); }
  .hero__statement {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
  }
  .metric__icon { margin-bottom: var(--space-1); }
  .metric__label {
    margin-top: var(--space-1);
    font-size: 10px;
    letter-spacing: 0.06em;
  }
  .metric__sub { font-size: 9px; }
}

@media (max-width: 980px) {
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } /* tablet 2x2 */
  .hero > .container { max-width: var(--maxw); }
  .hero__grid {
    grid-template-columns: 1fr;
    gap: var(--space-6);
  }
  .hero__inner { max-width: none; }
  .hero__viz { margin-right: 0; }
  .robot { height: clamp(300px, 46vh, 420px); }
  /* Back into normal flow beneath the robot on stacked layouts. */
  .terminal-wrap {
    position: static;
    width: 100%;
    max-width: none;
    margin-top: var(--space-6);
    padding-inline: var(--gutter);
  }
}

/* Only collapse to a single column on very narrow phones. */
@media (max-width: 340px) {
  .metrics { grid-template-columns: 1fr; }
}

@media (max-width: 520px) {
  .robot { height: clamp(240px, 40vh, 340px); }
  .terminal__output { height: clamp(160px, 34vh, 220px); }
  .terminal__hints { justify-content: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  .preloader { transition: opacity 0.2s ease; }
  .preloader.is-done { transform: none; }
  .robot__core,
  .robot__loader-label .cur,
  .ident.is-holding .ident__caret,
  .terminal__input { animation: none; }
  .robot__spline,
  .robot__silhouette { transition: none; }
  .hero [data-enter] { opacity: 1 !important; transform: none !important; transition: none; }
}

/* Coarse pointers: never rely on hover; the static caption carries identity. */
@media (pointer: coarse) {
  .robot__hotspot { cursor: default; }
}
