/* =========================
   HERO — carbon, exactly one viewport tall
   Two columns on the 12-column grid: the text (cols 1–6) and the CAD rig
   (cols 7–12). Below 960px they stack, rig first. The rig's square SVG scales
   to fit its box (never clipped, never under the type).
   The drawing is an exploded view of a car headlamp: lens cover, projector
   module, reflector, bulb, housing (and its screw), wiring harness, mounting
   brackets, on a -24° diagonal, each part named by a label.
   Signature move: from the first frame the parts appear exploded with their
   labels and slide home front to back while the view pushes in (each label
   leaves as its part moves); the projector and bulb light amber at about 2.3s. It plays on load and again every time the
   rig comes back into view (js/assembly.js parks it exploded while off screen).
   Transform + opacity only. The resting state (no JS, reduced motion) is the
   assembled, lit lamp, without labels; below 960px the labels are not shown
   (too small to read at that size).
========================= */

/* The hero slides up under the sticky header (same carbon) so the section
   itself is one full viewport; its top padding keeps content clear of the bar. */
.hero {
  position: relative;
  display: flex;
  min-height: 100vh;
  min-height: 100svh;
  margin-top: calc(-1 * var(--header-h));
  padding-top: var(--header-h);
  overflow: hidden;
  background: var(--carbon);
  color: var(--ink-inverse);

  /* Stage pose: exploded (start) and assembled (end). Computed from the parts'
     outlines by the drawing's generator so both fit the 1000 × 1000 box. */
  --asm-from: translate(-1.2px, 39.1px) scale(0.6);
  --asm-to: translate(-92.9px, 82px) scale(1.7);
}

.hero__inner {
  flex: 1;
  grid-template-rows: minmax(0, 1fr);
}

/* ---------- Text column ---------- */
.hero__text {
  grid-column: 1 / 7;
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
  padding-block: clamp(1.5rem, 6vh, 4.5rem);
}

/* Centred in the column; the credential sits at its foot */
.hero__main {
  margin-block: auto;
}

/* Type sizes also answer to viewport height, so short laptop screens still fit */
.hero__title {
  font-size: min(clamp(2.75rem, 1rem + 4.2vw, 6.5rem), 11vh);
  font-weight: 400;
  line-height: 0.95;
  letter-spacing: -0.035em;
  max-width: 9.5em;
}

.hero__lead {
  max-width: 36ch;
  margin-top: clamp(1.25rem, 3.5vh, 2.25rem);
  font-size: min(var(--step-lead), 3.2vh);
  line-height: 1.4;
  color: var(--ink-inverse);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
  margin-top: clamp(1.5rem, 4.5vh, 3rem);
}

/* Secondary: a plain text action; its underline draws from the left on hover */
.hero__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-weight: 600;
  color: var(--ink-inverse);
}

.hero__link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.55rem;
  height: 1px;
  background: currentColor;
  transform-origin: left;
  transform: scaleX(0.3);
  transition: transform 0.45s var(--ease);
}

.hero__link:hover::after,
.hero__link:focus-visible::after {
  transform: scaleX(1);
}

/* Credential: the "20+" set large in white with the "+" in the accent, the
   statement beside it. The figure counts up from 0 (js/build.js, [data-count]);
   tabular figures and a two-figure slot keep the "+" and the text still while it does. */
/* The figure set large; the statement sits on its baseline */
.hero__credential {
  display: flex;
  align-items: flex-end;
  gap: clamp(1rem, 0.5rem + 1vw, 1.75rem);
  padding-top: clamp(1rem, 2.5vh, 1.75rem);
  border-top: 1px solid var(--rule-dark);
}

.hero__credential-num {
  flex: none;
  font-size: min(clamp(4.5rem, 2rem + 6vw, 8.5rem), 14vh);
  font-weight: 300;
  font-variant-numeric: tabular-nums;
  line-height: 0.8;
  letter-spacing: -0.05em;
  color: var(--ink-inverse);
}

/* Two tracked figures wide, so "20" sits flush with the column */
.hero__credential-num [data-count] {
  display: inline-block;
  min-width: calc(2ch - 0.1em);
  text-align: right;
}

.hero__credential-plus {
  color: var(--accent-bright);
}

.hero__credential-text {
  max-width: 22ch;
  padding-bottom: 0.1em;
  font-size: min(var(--step-lead), 3.2vh);
  font-weight: 600;
  line-height: 1.2;
}

/* ---------- CAD rig column ---------- */
.hero__rig {
  grid-column: 7 / -1;
  position: relative;
  min-height: 0;
}

.rig__canvas {
  position: absolute;
  inset: clamp(1rem, 4vh, 3rem) 0;
}

/* Fits the box in both directions (preserveAspectRatio meet): nothing spills or clips */
.hero__assembly {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Drawing language: carbon tones filled, outlined in the inverse ink */
.hero__assembly :is(path, ellipse, circle) {
  stroke: var(--ink-inverse);
  stroke-width: 1.2;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.hero__assembly .fill-body { fill: var(--carbon-3); }
.hero__assembly .fill-face { fill: var(--carbon-2); }
.hero__assembly .fill-top { fill: #33383e; }
.hero__assembly .fill-dark { fill: var(--carbon); }
.hero__assembly .fill-board { fill: #1c2023; }
.hero__assembly .fill-bezel { fill: var(--rule-dark); }
.hero__assembly .fill-metal { fill: var(--ink-inverse-soft); }
.hero__assembly .fill-guide { fill: rgba(242, 241, 237, 0.1); stroke: var(--ink-inverse-soft); }
.hero__assembly .fill-glass { fill: rgba(242, 241, 237, 0.05); }
.hero__assembly .fill-optic { fill: url(#asm-optic); stroke: none; }
.hero__assembly .fill-none { fill: none; }
.hero__assembly .line-soft { stroke: #5a5e63; }
.hero__assembly .line-glint { stroke: var(--ink-inverse); stroke-width: 2; stroke-linecap: round; opacity: 0.5; }
.hero__assembly :is(.fill-led, .fill-led-on, .fill-amber, .assembly__glow) { stroke: none; }
.hero__assembly .fill-led { fill: #3a3e43; }
.hero__assembly :is(.fill-led-on, .fill-amber) { fill: var(--amber); }
.hero__assembly #asm-optic circle { fill: var(--ink-inverse-soft); stroke: none; opacity: 0.55; }
.hero__assembly .line-cable { fill: none; stroke: var(--ink-inverse-soft); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }

/* Labels: a leader and a name per part, shown only while the view is exploded */
.hero__assembly .line-leader { fill: none; stroke: var(--ink-inverse-soft); stroke-width: 1; }
.hero__assembly .fill-label-dot { fill: var(--ink-inverse); stroke: none; }
.hero__assembly text {
  font-family: var(--font);
  font-size: 34px;
  font-weight: 600;
  letter-spacing: -0.01em;
  fill: var(--ink-inverse);
}

.assembly__label {
  opacity: 0;
}

/* Assembled, lit resting state */
.assembly__stage {
  transform-origin: 0 0;
  transform: var(--asm-to);
}

.assembly__light {
  opacity: 1;
}

/* ---------- Motion ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* Intro, from the first frame: the parts appear exploded with their labels and start home
     at once, front to back (--d from 0.3s); each label leaves as its part moves. The stage
     pushes in alongside and the lamp lights as the last parts seat. */
  .hero__assembly .part {
    animation:
      asm-part-in 0.5s var(--ease) var(--in) both,
      asm-seat 1.1s var(--ease) var(--d) both;
  }

  .assembly__label {
    animation: asm-label-out 0.35s var(--ease) var(--d) both;
  }

  .assembly__stage {
    animation: asm-push 2s cubic-bezier(0.65, 0, 0.35, 1) 0.2s both;
  }

  .assembly__light {
    animation: asm-light 0.9s var(--ease) 2.2s both;
  }

  /* Replay when the rig comes back into view: parts are already visible, so no fade */
  [data-assembly].is-replay .part {
    animation: asm-seat 1.1s var(--ease) var(--d) both;
  }

  [data-assembly].is-replay .assembly__label {
    animation: asm-label-out 0.35s var(--ease) var(--d) both;
  }

  [data-assembly].is-replay .assembly__stage {
    animation: asm-push 1.9s cubic-bezier(0.65, 0, 0.35, 1) 0.15s both;
  }

  [data-assembly].is-replay .assembly__light {
    animation: asm-light 0.9s var(--ease) 2.1s both;
  }

  .hero__lead,
  .hero__actions,
  .hero__credential {
    animation: hero-rise 0.9s var(--ease) both;
  }

  .hero__lead { animation-delay: 0.2s; }
  .hero__actions { animation-delay: 0.35s; }
  .hero__credential { animation-delay: 0.5s; }
}

/* Parked exploded while the rig is off screen (js/assembly.js); snaps, nobody is watching.
   Comes after the motion rules so it wins over them. */
[data-assembly].is-exploded .part {
  animation: none;
  transform: translate(var(--x), var(--y, 0px));
}

[data-assembly].is-exploded .assembly__label {
  animation: none;
  opacity: 0;
}

[data-assembly].is-exploded .assembly__stage {
  animation: none;
  transform: var(--asm-from);
}

[data-assembly].is-exploded .assembly__light {
  animation: none;
  opacity: 0;
}

@keyframes asm-part-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes asm-seat {
  from { transform: translate(var(--x), var(--y, 0px)); }
  to { transform: none; }
}

/* Shown until its part starts home */
@keyframes asm-label-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

@keyframes asm-push {
  from { transform: var(--asm-from); }
  to { transform: var(--asm-to); }
}

@keyframes asm-light {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes hero-rise {
  from { opacity: 0; transform: translate3d(0, 28px, 0); }
  to { opacity: 1; transform: none; }
}

/* ---------- Narrow screens: stacked, rig first ---------- */
@media (max-width: 960px) {
  .hero__inner {
    grid-template-rows: auto 1fr;
  }

  .hero__rig {
    grid-column: 1 / -1;
    grid-row: 1;
    height: min(58vw, 36vh);
  }

  .rig__canvas {
    inset: 1rem 0 0;
  }

  .assembly__label {
    display: none;
  }

  .hero__text {
    grid-column: 1 / -1;
    grid-row: 2;
    gap: 2rem;
    padding-block: 1.5rem 2rem;
  }

  .hero__main {
    margin-block: 0;
  }

  .hero__lead {
    max-width: none;
  }

  .hero__actions {
    gap: 0.75rem 1.5rem;
  }

  /* Clear air between the actions and the large figure, even when the screen is short */
  .hero__main {
    padding-bottom: 1rem;
  }

  .hero__credential {
    margin-top: auto;
  }

  .hero__credential-num {
    font-size: min(4rem, 7.5vh);
  }

  .hero__credential-text {
    max-width: none;
  }
}
