/* ============================================================
   ChipMart — Scroll-driven product camera & teardown hero
   Scope: .hs-stage (homepage only). Prefixed hs- to avoid
   collisions with site.css. Loaded via asset_v() so the
   filemtime cache-buster refreshes it after every deploy.
   ============================================================ */

.hs-stage {
  position: relative;
  height: 360vh;
  /* The header is sticky, so the stage starts below it. --hs-head is set by
     hero-scroll.js from the real header height (it changes on narrow
     screens); the 64px fallback matches the desktop header. */
  --hs-head: 64px;
  /* Space left below the hero so the next section peeks in and the visitor
     can see there is more to scroll to. This value decides how much of the
     next section is visible once the teardown finishes — see the note on
     .hs-next below. */
  --hs-bottom-gap: 208px;
  /* Height reserved for the teaser strip that sits under the hero panel. */
  --hs-teaser-h: 132px;
}

/* Full-bleed width, but shorter than the viewport: the hero never fills the
   screen, so the page below stays visible and the scroll target is obvious. */
.hs-sticky {
  position: sticky;
  top: var(--hs-head);
  width: 100%;
  height: calc(100vh - var(--hs-head) - var(--hs-bottom-gap));
  overflow: hidden;
  color: var(--navy);
  background:
    radial-gradient(120% 130% at 78% -10%, rgba(120,180,255,.50), transparent 58%),
    radial-gradient(110% 120% at 4% 108%, rgba(180,205,255,.45), transparent 58%),
    linear-gradient(135deg, #eaf3ff 0%, #dcebff 52%, #f6faff 100%);
}

/* The section right after the hero opens with 54px of empty padding, so the
   sliver visible under the hero would look blank. Pull it up so the next
   heading is already peeking into view. */
.hs-next { padding-top: 4px; }

/* ---------- background ----------
   No grid: a PCB-style trace field with light pulses travelling along the
   traces, plus rising particles. It reads as "electronics" rather than
   "generic tech", and it is what a components brand should be showing. */
.hs-bg { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }

.hs-traces {
  position: absolute; inset: -4%;
  width: 108%; height: 108%;
  opacity: .85;
}
.hs-trace {
  fill: none;
  stroke: rgba(21,101,192,.20);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.hs-trace.pulse {
  stroke: rgba(0,176,255,.62);
  stroke-width: 2.2;
  animation: hsFlow 6s linear infinite;
}
@keyframes hsFlow { to { stroke-dashoffset: var(--end, -1200px); } }
.hs-node { fill: rgba(21,101,192,.30); }
.hs-node.hot { fill: rgba(0,176,255,.75); }

.hs-particles { position: absolute; inset: 0; }
.hs-particles span {
  position: absolute; bottom: -20px;
  width: 4px; height: 4px; border-radius: 50%;
  background: rgba(21,101,192,.34);
  box-shadow: 0 0 8px rgba(0,176,255,.45);
  opacity: 0;
  animation: hsRise 13s linear infinite;
}
@keyframes hsRise {
  0%   { transform: translateY(0); opacity: 0; }
  12%  { opacity: .85; }
  88%  { opacity: .85; }
  100% { transform: translateY(-620px); opacity: 0; }
}

.hs-glow {
  position: absolute; left: 50%; top: 46%;
  width: 860px; height: 860px; margin: -430px 0 0 -430px;
  background: radial-gradient(circle, rgba(33,118,255,.20), transparent 62%);
  filter: blur(10px);
  animation: hsPulse 9s ease-in-out infinite;
}
@keyframes hsPulse {
  0%, 100% { opacity: .55; transform: scale(1); }
  50%      { opacity: .9;  transform: scale(1.12); }
}
.hs-sweep {
  position: absolute; inset: -20% -40%;
  background: linear-gradient(105deg, transparent 42%, rgba(255,255,255,.55) 50%, transparent 58%);
  opacity: 0; mix-blend-mode: screen;
}

/* ---------- 3D scene ---------- */
.hs-scene {
  position: absolute; inset: 0;
  perspective: 1400px;
  perspective-origin: 50% 50%;
}
.hs-world {
  position: absolute; left: 50%; top: 50%; width: 0; height: 0;
  transform-style: preserve-3d;
  will-change: transform;
}
.hs-part {
  position: absolute; left: -200px; top: -200px; width: 400px; height: 400px;
  transform-style: preserve-3d;
  will-change: transform;
}
.hs-part svg { display: block; width: 100%; height: 100%; overflow: visible; }

/* The callout overlay sits OUTSIDE the perspective container on purpose:
   its coordinates are already screen-space projections, and applying a
   perspective to them would distort the labels. */
.hs-overlay { position: absolute; inset: 0; pointer-events: none; z-index: 6; }
.hs-leaders { position: absolute; inset: 0; width: 100%; height: 100%; }
.hs-leaders path { fill: none; stroke: rgba(21,101,192,.55); stroke-width: 1.2; }
.hs-leaders circle { fill: #fff; stroke: var(--primary); stroke-width: 2; }

.hs-labels { position: absolute; inset: 0; }
.hs-lbl {
  position: absolute; left: 0; top: 0; opacity: 0; white-space: nowrap;
  will-change: transform, opacity;
}
.hs-lbl .hs-box {
  display: block;
  background: rgba(255,255,255,.92);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  border: 1px solid rgba(21,101,192,.22);
  border-radius: 9px;
  padding: 6px 11px;
  box-shadow: 0 8px 22px rgba(20,60,120,.16);
  text-align: left;
}
.hs-lbl.is-left .hs-box { text-align: right; }
.hs-lbl b { display: block; font-size: 13px; color: var(--navy); line-height: 1.2; }
.hs-lbl i { display: block; font-style: normal; font-size: 11px; color: var(--muted); margin-top: 2px; }

/* ---------- HUD ---------- */
.hs-hud { position: absolute; inset: 0; pointer-events: none; z-index: 9; }

/* Every copy block shares one left-hand slot and crossfades in place.
   The width is a percentage of the 16:9 window, not of the viewport, so the
   headline keeps its line breaks as the window resizes. */
.hs-slot {
  position: absolute; left: 4.5%; top: 50%;
  width: 42%;
  transform: translateY(-50%);
  opacity: 0;
}
.hs-slot > * { pointer-events: auto; }

.hs-kicker {
  display: inline-block; font-size: 12px; letter-spacing: 2.6px; text-transform: uppercase;
  color: var(--primary); font-weight: 700; padding: 6px 14px; border-radius: 999px;
  border: 1px solid rgba(21,101,192,.28); background: rgba(255,255,255,.62);
}
.hs-slot h1, .hs-slot h2 { color: var(--navy); }
.hs-slot h1 {
  font-size: clamp(22px, 2.55vw, 38px); line-height: 1.14; margin: 16px 0 14px; font-weight: 800;
}
.hs-slot h1 .hs-line { display: block; }
/* The product list is one phrase — never let it wrap mid-list. */
.hs-slot h1 .grad {
  white-space: nowrap;
  font-size: .92em;
  background: linear-gradient(90deg, #1565c0, #6a5cff);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hs-slot h2 { font-size: 25px; margin: 0 0 10px; font-weight: 800; }
.hs-slot p { margin: 0; color: var(--muted); font-size: 15px; line-height: 1.7; }
.hs-slot .hs-num { font-size: 12px; letter-spacing: 2.4px; color: var(--primary); font-weight: 800; margin-bottom: 8px; }

.hs-cta {
  display: inline-block; margin-top: 20px; padding: 12px 24px; border-radius: 10px;
  background: linear-gradient(90deg, #1565c0, #4f7fe8); color: #fff; font-weight: 700;
  font-size: 15px; text-decoration: none;
  box-shadow: 0 14px 30px rgba(21,101,192,.32);
}
.hs-cta-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.hs-cta-row .hs-cta { margin-top: 20px; }
.hs-cta-alt {
  background: rgba(255,255,255,.72);
  color: var(--primary);
  border: 1px solid rgba(21,101,192,.32);
  box-shadow: none;
}
.hs-cta-alt:hover { background: #fff; border-color: var(--primary); }

.hs-spec {
  background: rgba(255,255,255,.92);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid rgba(21,101,192,.2); border-radius: 16px; padding: 20px 22px;
  box-shadow: 0 26px 60px rgba(20,60,120,.20);
}
.hs-spec h3 { font-size: 17px; margin: 0 0 12px; color: var(--navy); }
.hs-spec table { width: 100%; border-collapse: collapse; font-size: 13px; }
.hs-spec td { padding: 7px 0; border-bottom: 1px dashed rgba(21,101,192,.2); color: var(--muted); }
.hs-spec td:last-child { text-align: right; color: var(--navy); font-weight: 700; }
.hs-spec .hs-cta { display: block; margin-top: 16px; text-align: center; padding: 11px 16px; font-size: 14px; }

/* The spec panel arrives last, when the callout column has faded out, so it
   takes the right-hand slot instead of covering the exploded stack. */
#hsSlotSpec { left: auto; right: max(24px, 3.4vw); width: min(340px, 30vw); }

.hs-rail {
  position: absolute; top: 22px; left: 4.5%;
  display: flex; gap: 16px; align-items: center;
}
.hs-rail .hs-step {
  display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
  opacity: .35; transition: opacity .35s;
}
.hs-rail .hs-step.on { opacity: 1; }
.hs-rail .hs-step .hs-t { font-size: 10px; letter-spacing: 1.6px; color: var(--navy); font-weight: 700; }
.hs-rail .hs-step .hs-bar {
  width: 30px; height: 2px; background: var(--primary); border-radius: 2px; transition: width .35s;
}
.hs-rail .hs-step.on .hs-bar { width: 54px; }

.hs-hint {
  position: absolute; left: 50%; bottom: 24px; transform: translateX(-50%);
  font-size: 11px; letter-spacing: 2.4px; color: var(--primary); font-weight: 700;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.hs-hint .hs-mouse {
  width: 22px; height: 34px; border: 2px solid rgba(21,101,192,.5);
  border-radius: 12px; position: relative;
}
.hs-hint .hs-mouse::after {
  content: ""; position: absolute; left: 50%; top: 6px; width: 3px; height: 7px;
  margin-left: -1.5px; background: var(--primary); border-radius: 2px;
  animation: hsWheel 1.7s ease-in-out infinite;
}
@keyframes hsWheel {
  0%   { transform: translateY(0); opacity: 1; }
  70%  { transform: translateY(12px); opacity: 0; }
  100% { opacity: 0; }
}

.hs-progress {
  position: absolute; left: 0; top: 0; height: 3px; width: 0;
  background: linear-gradient(90deg, var(--primary), var(--accent));
  z-index: 12;
}

/* Teaser strip. The hero panel is shorter than the viewport, so the strip of
   page below it stays on screen the whole time — this is what the visitor
   actually sees when the teardown ends, so it carries the real next-section
   title and a scroll cue instead of empty background. */
.hs-teaser {
  position: sticky;
  top: calc(var(--hs-head) + (100vh - var(--hs-head) - var(--hs-bottom-gap)) - var(--hs-teaser-h));
  display: flex; align-items: center; gap: 18px;
  width: min(100% - 40px, 1200px);
  margin: 0 auto;
  padding: 0 26px;
  height: var(--hs-teaser-h);
  text-decoration: none;
  color: var(--navy);
  background: rgba(255,255,255,.82);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid rgba(21,101,192,.16);
  border-radius: 14px;
  box-shadow: 0 10px 30px rgba(13,71,161,.10);
  pointer-events: auto;
  z-index: 4;
}
.hs-teaser-t { font-size: 17px; font-weight: 800; white-space: nowrap; }
.hs-teaser-s {
  font-size: 13px; color: var(--muted);
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  border-left: 1px solid rgba(21,101,192,.18);
  padding-left: 18px;
}
.hs-teaser-a { color: var(--primary); display: flex; animation: hsNudge 1.9s ease-in-out infinite; }
@keyframes hsNudge {
  0%, 100% { transform: translateY(0); opacity: .75; }
  50%      { transform: translateY(3px); opacity: 1; }
}

/* ---------- narrow layout ---------- */
@media (max-width: 1000px) {
  .hs-labels, .hs-leaders { display: none; }
  .hs-slot {
    left: 20px; right: 20px; width: auto; top: auto; bottom: 92px; transform: none;
  }
  #hsSlotSpec { left: 20px; right: 20px; width: auto; }
  .hs-slot h1 { font-size: 27px; }
  .hs-rail { display: none; }
  .hs-hint { display: none; }
}

/* ---------- reduced motion ----------
   The composed exploded view is still rendered (static, fully separated) so
   the content is not lost — only the animation is. */
@media (prefers-reduced-motion: reduce) {
  .hs-hint .hs-mouse::after { animation: none; }
  .hs-stage { height: auto; }
  .hs-sticky {
    position: relative;
    top: 0;
    height: auto;
    min-height: 640px;
  }
}
