/* ============================================
   ASSEMBLY LINE — shared shell for the pinned, scroll-indexed capability
   stacks on industry pages. Markup: template-parts/components/assembly-line.php
   (+ assembly-line/{variant}.php) · driver: assets/js/assembly-line.js.
   Variants: tv (displays — TVs on a conveyor, assembly-line-tv.css), robot
   (robotics — a rail-mounted cobot moving signs, assembly-line-robot.css), box
   (consumer electronics — a box collecting labels, assembly-line-box.css) and
   tote (automotive — a tote of suspect parts through the sort,
   assembly-line-tote.css). The roller conveyor at the end is box's and tote's.

   Two modes:
   - static (default): a grid of lit panels. What reduced-motion visitors,
     short viewports and a failed GSAP load get — every step readable at once.
   - .line--live (added by JS): the frame pins, scroll indexes the line one
     station per step, and the panel at the station powers on.

   Drawing: the hero's toon style — ink outlines, flat faces, 45° oblique depth
   (.line-box). Every size in a rig is a multiple of --u (the panel width /
   400), set on .line__rig from the stage's container size; each variant sets
   --line-w and the rig height (--rig-h, in u). --u must be declared on the same
   element as --line-w: an unregistered custom property substitutes var() where
   it is declared, so a descendant override of --line-w would not reach an
   inherited --u.
   ============================================ */

.line {
  --line-ink: #0A1322;
  --line-stroke: 2px;
  --line-white: #F3F0EB;
  --line-white-top: #FFFFFF;
  --line-white-side: #C2BAAE;
  --line-steel: #808B9A;
  --line-steel-top: #A9B2BE;
  --line-steel-side: #5B6575;
  --line-alloy: #CDD3DB;
  --line-alloy-top: #EEF1F4;
  --line-alloy-side: #96A0AD;
  --line-belt: #2B323D;
  --line-screen-off: #0E151F;
  --line-lit-top: #FFB24A;
  --line-lit: #F39014;
  --line-lit-low: #E4800A;
  --line-pass: #6EE39A;
}

/* ── Oblique box: front face is the element, top + side faces are pseudos ──
   Faces sit outside the outline (bottom/left offset by the line width) so the
   front face's own border draws the shared edge. */
.line-box {
  position: absolute;
  box-sizing: border-box;
  background: var(--f, var(--line-white));
  border: var(--line-stroke) solid var(--line-ink);
}

.line-box::before,
.line-box::after {
  content: '';
  position: absolute;
  box-sizing: border-box;
  border: var(--line-stroke) solid var(--line-ink);
  pointer-events: none;
}

.line-box::before {
  left: calc(-1 * var(--line-stroke));
  right: calc(-1 * var(--line-stroke));
  bottom: calc(100% + var(--line-stroke));
  height: var(--d, 8px);
  background: var(--t, var(--line-white-top));
  border-bottom: 0;
  transform-origin: 0 100%;
  transform: skewX(-45deg);
}

.line-box::after {
  top: calc(-1 * var(--line-stroke));
  bottom: calc(-1 * var(--line-stroke));
  left: calc(100% + var(--line-stroke));
  width: var(--d, 8px);
  background: var(--s, var(--line-white-side));
  border-left: 0;
  transform-origin: 0 0;
  transform: skewY(-45deg);
}


/* ── Section chrome ── */
.line .section__header {
  position: relative;
  z-index: 1;
}

/* ============================================
   STATIC MODE (default)
   ============================================ */

.line__frame {
  position: relative;
  z-index: 1;
}

.line__stage,
.line__rig {
  position: relative;
}

.line__scene,
.line__nav {
  display: none;
}

/* Scoped to static mode: on the track itself this would shadow the rig's
   --line-w in live mode. */
.line:not(.line--live) .line__track {
  --line-w: 340px;
  --u: calc(var(--line-w) / 400);
}

.line__track {
  list-style: none;
  margin: 0 auto;
  padding: 0 var(--gutter);
  max-width: var(--container-max);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr));
  gap: var(--space-8) var(--space-10);
  justify-items: center;
}

@media (max-width: 420px) {
  .line:not(.line--live) .line__track {
    --line-w: calc(100vw - 2 * var(--gutter) - 14px);
  }
}

/* ── Panel: the TV body / sign frame that carries a screen ── */
.line__panel {
  left: 0;
  bottom: 0;
  width: 100%;
  height: calc(241 * var(--u));
  --d: calc(9 * var(--u));
  border-radius: 3px;
  transition: box-shadow 0.4s var(--ease-out);
}

.line__led {
  position: absolute;
  left: calc(20 * var(--u));
  bottom: calc(5 * var(--u));
  width: max(4px, calc(5 * var(--u)));
  aspect-ratio: 1;
  border-radius: 50%;
  background: #E0483E;
  box-shadow: 0 0 0 1px var(--line-ink), 0 0 6px rgba(224, 72, 62, 0.75);
  transition: background-color 0.3s, box-shadow 0.3s;
}

/* ── Screen ── */
.line__screen {
  position: absolute;
  left: calc(10 * var(--u));
  right: calc(10 * var(--u));
  top: calc(10 * var(--u));
  bottom: calc(16 * var(--u));
  overflow: hidden;
  border: var(--line-stroke) solid var(--line-ink);
  border-radius: 2px;
  background: linear-gradient(160deg, #1A2432 0%, var(--line-screen-off) 55%);
  /* Screen text scales with the screen, not the page. */
  container-type: inline-size;
}

.line__light {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: 4.6cqw 5.4cqw 5cqw;
  background:
    radial-gradient(120% 90% at 18% 10%, var(--line-lit-top) 0%, transparent 60%),
    linear-gradient(170deg, var(--line-lit) 30%, var(--line-lit-low) 100%);
  color: var(--color-navy);
  opacity: 0;
  transition: opacity 0.25s ease;
}

.line__osd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 3cqw;
  font-family: var(--font-mono);
  font-size: clamp(10px, 2.45cqw, 14px);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
}

.line__num b {
  display: inline-block;
  padding: 0.35em 0.5em 0.3em;
  margin-inline: 0.15em 0.1em;
  border-radius: 3px;
  background: var(--color-navy);
  color: var(--line-lit-top);
  font-weight: 700;
}

/* Step icon: a navy tile in the lit screen's top-right, the space the
   bottom-aligned title and description leave empty. Out of flow, so it never
   pushes the text; fit.js checks it clears the title at every size. */
.line__badge {
  position: absolute;
  top: 4.6cqw;
  right: 5.4cqw;
  display: grid;
  place-items: center;
  width: clamp(34px, 12.5cqw, 80px);
  aspect-ratio: 1;
  border-radius: 22%;
  background: var(--color-navy);
  color: var(--line-lit-top);
}

/* Where the title would reach it: a badge no taller than the Step row. The
   driver sets .is-tight per screen; the static grid, where no script
   measures, always uses it (its screens are phone-sized). */
.line__unit.is-tight .line__badge,
.line:not(.line--live) .line__badge {
  top: calc(4.6cqw - 4px);
  width: 24px;
}

.line__icon {
  width: 56%;
  height: auto;
  stroke-width: 1.6;
}

.line .line__title {
  margin: auto 0 1.8cqw;
  padding-top: 2cqw;
  font-size: clamp(15px, 5.2cqw, 32px);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--color-navy);
  text-shadow: none; /* .section--navy h3 adds one — a halo on the lit screen */
  text-wrap: balance;
}

.line__desc {
  margin: 0;
  font-size: clamp(12.5px, 3.15cqw, 19px);
  line-height: 1.5;
  color: rgba(12, 24, 41, 0.86);
  text-wrap: pretty;
}

.line__pass {
  position: absolute;
  right: 5.4cqw;
  top: 4.6cqw;
  display: inline-flex;
  align-items: center;
  gap: 1.2cqw;
  font-family: var(--font-mono);
  font-size: clamp(10px, 2.45cqw, 14px);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--line-pass);
  opacity: 0;
  transition: opacity 0.12s ease;
}

.line__pass-icon {
  width: 1.3em;
  height: auto;
  stroke-width: 2.5;
}

/* Toon glass: two hard-edged highlight bands. */
.line__glare {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(115deg,
    transparent 0 34%,
    rgba(255, 255, 255, 0.08) 34% 47%,
    transparent 47% 51%,
    rgba(255, 255, 255, 0.05) 51% 55%,
    transparent 55%);
}

/* Lit screens: static mode lights them all; live mode lights .is-on. */
.line:not(.line--live) .line__light,
.line__unit.is-on .line__light {
  opacity: 1;
}

.line:not(.line--live) .line__glare,
.line__unit.is-on .line__glare {
  opacity: 0.55;
}

.line:not(.line--live) .line__led,
.line__unit.is-on .line__led,
.line__unit.is-done .line__led {
  background: #DDF3FF;
  box-shadow: 0 0 0 1px var(--line-ink), 0 0 5px rgba(221, 243, 255, 0.6);
}

.line__unit.is-on .line__panel {
  box-shadow: 0 0 70px 8px rgba(243, 144, 20, 0.26);
}

.line__unit.is-done .line__pass {
  opacity: 1;
  transition: opacity 0.3s ease 0.15s;
}

/* Power-on: the old CRT collapse run backwards — a dot, a line, the picture. */
.line__unit.is-powering .line__light {
  animation: line-power 0.55s var(--ease-out) both;
}

@keyframes line-power {
  0%   { opacity: 1; transform: scale(0.02, 0.006); filter: brightness(2.6); }
  30%  { opacity: 1; transform: scale(1, 0.006);    filter: brightness(2.6); }
  65%  { opacity: 1; transform: scale(1, 1);        filter: brightness(1.35); }
  100% { opacity: 1; transform: none;               filter: none; }
}


/* ============================================
   LIVE MODE — pinned assembly line
   ============================================ */

.line--live {
  padding-bottom: 0;
}

.line--live .section__header {
  margin-bottom: 0;
}

.line--live .line__frame {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100svh;
  /* The fixed header covers the top of the frame while it is pinned. */
  padding-top: var(--header-height-scrolled);
  background:
    radial-gradient(46% 52% at 50% 56%, rgba(43, 94, 167, 0.26), transparent 72%),
    var(--color-navy);
}

/* Logged in, the admin bar pushes the fixed header down (header.css); the
   frame has to clear both or the stack light hides behind the header. */
.admin-bar .line--live .line__frame {
  padding-top: calc(var(--header-height-scrolled) + 32px);
}

@media screen and (max-width: 782px) {
  .admin-bar .line--live .line__frame {
    padding-top: calc(var(--header-height-scrolled) + 46px);
  }
}

/* The hero's 80px grid, faded in so it has no hard top edge under the
   section header. */
.line--live .line__frame::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px);
  background-size: 80px 80px;
  background-position: 50% 0;
  -webkit-mask-image: linear-gradient(transparent, #000 35%);
  mask-image: linear-gradient(transparent, #000 35%);
}

.line--live .line__stage {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  container-type: size;
}

.line--live .line__rig {
  --u: calc(var(--line-w) / 400);
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: calc(var(--rig-h) * var(--u));
  transform: translateY(-50%);
}

@media (max-width: 640px) {
  .line { --line-stroke: 1.5px; }
}

.line--live .line__scene {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}


.line__walkway {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 100vh;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0.03), transparent calc(160 * var(--u)));
}

.line__walkway::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: calc(26 * var(--u));
  height: calc(9 * var(--u));
  opacity: 0.38;
  background: repeating-linear-gradient(135deg,
    var(--color-saffron) 0 calc(6 * var(--u)),
    transparent calc(6 * var(--u)) calc(12 * var(--u)));
}

.line__floor {
  position: absolute;
  left: -5%;
  right: -5%;
  bottom: calc(-4 * var(--u));
  height: calc(16 * var(--u));
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.32);
  filter: blur(8px);
}


.line__plate {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: 0.3em 0.8em 0.25em;
  border: 1.5px solid var(--line-ink);
  border-radius: 3px;
  background: var(--color-navy);
  color: rgba(255, 255, 255, 0.7);
  font-family: var(--font-mono);
  font-size: max(9px, calc(10 * var(--u)));
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

.line__plate b {
  color: var(--line-lit-top);
  font-weight: 700;
}

/* Status dot on a station plate (robot and box rigs; the tv rig has a stack
   light instead): green while docked, amber while the line cycles. */
.line__status {
  display: inline-block;
  width: 0.65em;
  height: 0.65em;
  margin-right: 0.7em;
  border-radius: 50%;
  vertical-align: 0;
  background: #FFC21A;
  box-shadow: 0 0 8px 1px rgba(255, 194, 26, 0.55);
}

.line__frame.is-docked .line__status {
  background: #3DDC7A;
  box-shadow: 0 0 8px 1px rgba(61, 220, 122, 0.6);
}

.line__frame.is-moving .line__status {
  animation: line-status-blink 0.5s steps(1, end) infinite;
}

@keyframes line-status-blink {
  50% { background: #5E4A16; box-shadow: none; }
}


/* Stack light on the beam: green while a unit is docked, amber while the line
   indexes (blinking only while it actually moves — it settles when scroll does). */

/* ── Station nav ── */
.line--live .line__nav {
  position: relative;
  z-index: 3;
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--gutter) var(--space-5);
}

.line__hint {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  transition: opacity 0.3s ease;
}

.line__frame.is-started .line__hint {
  opacity: 0;
}

.line__stations {
  position: relative;
  display: flex;
  gap: clamp(10px, 2.4vw, 22px);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Progress line behind the buttons; JS scales the fill. */
.line__stations::before,
.line__stations::after {
  content: '';
  position: absolute;
  left: 18px;
  right: 18px;
  top: 50%;
  height: 2px;
  margin-top: -1px;
  background: rgba(255, 255, 255, 0.14);
}

.line__stations::after {
  background: var(--color-saffron);
  transform-origin: 0 50%;
  transform: scaleX(var(--line-progress, 0));
}

.line__stations li {
  position: relative;
  z-index: 1;
}

.line__station {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1.5px solid rgba(255, 255, 255, 0.28);
  border-radius: 6px;
  background: var(--color-navy);
  color: rgba(255, 255, 255, 0.6);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: background-color var(--duration-fast), border-color var(--duration-fast), color var(--duration-fast);
}

.line__station:hover {
  border-color: rgba(255, 255, 255, 0.6);
  color: var(--color-white);
}

.line__station.is-done {
  border-color: rgba(243, 144, 20, 0.7);
  color: var(--color-saffron-light);
}

.line__station[aria-current="step"] {
  background: var(--color-saffron);
  border-color: var(--color-saffron);
  color: var(--color-navy);
}

.line__station:focus-visible {
  outline: 2px solid var(--color-white);
  outline-offset: 3px;
}

@media (max-width: 640px) {
  .line__station {
    width: 32px;
    height: 32px;
    font-size: 11px;
  }
  .line__stations::before,
  .line__stations::after {
    left: 16px;
    right: 16px;
  }
}


/* ============================================
   ROLLER CONVEYOR — used by the box (consumer electronics) and tote
   (automotive) rigs, which each decide when it shows. Roller bed behind the
   load, saffron side rail with turning axle caps and steel legs in front;
   the variant scripts scroll the rollers, axles and legs with the load.
   ============================================ */

.line__rollbed {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(36 * var(--u));
  height: calc(56 * var(--u));
  overflow: hidden;
  background: #2B323D;
  border-top: var(--line-stroke) solid var(--line-ink);
}

/* Roller tops seen from above: a light band per roller, along the depth
   axis (45°). */
.line__rollers {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: calc(100% + 80 * var(--u));
  background: repeating-linear-gradient(135deg,
    #4A5361 0 calc(8 * var(--u)),
    #69727F calc(8 * var(--u)) calc(12 * var(--u)),
    #2B323D calc(12 * var(--u)) calc(21.213 * var(--u)));
  will-change: transform;
}

.line__siderail {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(20 * var(--u));
  height: calc(16 * var(--u));
  overflow: hidden;
  background: var(--color-saffron);
  border-block: var(--line-stroke) solid var(--line-ink);
}

.line__axles {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(-40 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(20 * var(--u));
  will-change: transform;
}

.line__axle {
  position: relative;
  flex: none;
  width: calc(10 * var(--u));
  aspect-ratio: 1;
  border-radius: 50%;
  background: #FFE0B5;
  border: 1.5px solid var(--line-ink);
  transform: rotate(var(--roll, 0rad));
}

.line__axle::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 14%;
  bottom: 14%;
  width: 1.5px;
  margin-left: -0.75px;
  background: var(--line-ink);
}

.line__cvlegs {
  position: absolute;
  left: calc(-200 * var(--u));
  right: calc(-200 * var(--u));
  bottom: 0;
  height: calc(20 * var(--u));
  display: flex;
  justify-content: center;
  gap: calc(188 * var(--u));
  overflow: hidden;
  will-change: transform;
}

.line__cvleg {
  position: relative;
  flex: none;
  width: calc(12 * var(--u));
  height: 100%;
  --d: calc(8 * var(--u));
  --f: var(--line-steel);
  --t: var(--line-steel-top);
  --s: var(--line-steel-side);
}


