/* ==========================================================================
   NetrAI — "How We Work" as a routed circuit

   Four stages as four vias on a single trace that routes left to right,
   jogging between two rows the way a real board does: horizontal run, 45°
   mitre, vertical, 45° mitre, horizontal. Never a square corner — that is the
   whole reason it reads as a circuit rather than as a flowchart.

   The trace draws with scroll. Whichever via the pen has most recently passed
   is the live one, and the block underneath is that stage's copy — so the
   diagram is a control, not an illustration, and only one stage is ever asked
   for at a time.

   HOW IT WORKS
   js/effects/circuit.js measures the board, computes the via positions and emits the
   path; nothing here is hard-coded to four stages. One number — the pen's
   distance along the trace — drives the dash offset, which via is live, and
   which copy block is shown.
   ========================================================================== */

.ct {
  --ct-trace: var(--ink);
  --ct-dim: color-mix(in srgb, var(--ink) 26%, transparent);
  --ct-ghost: color-mix(in srgb, var(--ink) 11%, transparent);
  --ct-grid: color-mix(in srgb, var(--ink) 7%, transparent);
  --ct-live: var(--accent-fill);
  --ct-board: transparent;

  position: relative;
  max-width: 1180px;
  margin: 0 auto;
}

/* On black the trace is white and the live via glows, which is what sells it
   as a powered board rather than a printed diagram. */
[data-theme="dark"] .ct {
  --ct-trace: #ffffff;
  --ct-dim: rgba(255, 255, 255, 0.22);
  --ct-ghost: rgba(255, 255, 255, 0.09);
  --ct-grid: rgba(255, 255, 255, 0.055);
  --ct-live: #1f3bff;
}


/* --------------------------------------------------------------------------
   The pin

   The section holds still while the trace routes, then releases. Same
   mechanism as the hero scene and the reviews rail — a tall section with a
   sticky child and one JS progress number — rather than ScrollTrigger's `pin`,
   which clones and re-parents the element it pins.

   320vh gives 220vh of travel: about a viewport per stage plus a beat of
   stillness on the last one before the section lets go. Shorter and the stages
   flick past; longer and you are scrolling through nothing.
   -------------------------------------------------------------------------- */

.ct-scene {
  height: 320vh;
  padding: 0;
  /* a sticky child cannot stick inside an overflow-hidden ancestor */
  overflow: visible;
}

.ct-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;              /* mobile browsers' shrinking viewport */
  display: grid;
  /* EXPLICIT full-width column. Without it the implicit `auto` track sizes to
     the content's max-content and the container collapses to ~660px — which
     silently squashed the board to half its width and crammed all four vias
     into the left of the sheet. `minmax(0, 1fr)` also stops a wide child from
     blowing the track out. */
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
  overflow: hidden;
}

/* `.container` carries `margin: 0 auto`, and AUTO MARGINS ON A GRID ITEM absorb
   the free space instead of stretching it — so even with a full-width track the
   container sized itself to its own content and the board came out at 599px
   instead of 1080. An explicit width restores the stretch; the auto margins and
   the max-width then do their normal job. */
.ct-pin > .container { width: 100%; }

/* Everything inside the pin has to fit ONE viewport, including a 700px-tall
   laptop. The board and the readout are therefore capped against vh as well as
   px — at their fixed sizes the three blocks total ~710px and the last stage's
   paragraph falls off the bottom of a short screen. */
.ct-scene .ct-board { height: min(380px, 36vh); }
.ct-scene .ct-readout { min-height: min(210px, 26vh); }
.ct-scene .section-head { margin-bottom: clamp(12px, 2.4vh, 30px); }

/* --------------------------------------------------------------------------
   The board
   -------------------------------------------------------------------------- */

.ct-board {
  position: relative;
  height: 380px;
  /* the two faint rules at the far edges in the reference — a board outline,
     not a container */
  border-left: 1px solid var(--ct-grid);
  border-right: 1px solid var(--ct-grid);
}

.ct-board::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--ct-grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--ct-grid) 1px, transparent 1px);
  background-size: 58px 58px;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
}

.ct-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* ---- the trace ---- */

.ct-svg .ct-path {
  fill: none;
  stroke: var(--ct-trace);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--p, 0));
}

/* The unrouted remainder, so the route reads as a path that exists and is
   being energised rather than one being invented as you scroll. */
.ct-svg .ct-path-bed {
  fill: none;
  stroke: var(--ct-dim);
  stroke-width: 1;
  stroke-linejoin: round;
}

/* Decorative routing behind the subject. Static, and quiet enough that it
   never competes with the trace it sits behind. */
.ct-svg .ct-ghost {
  fill: none;
  stroke: var(--ct-ghost);
  stroke-width: 1;
  stroke-linejoin: round;
}
.ct-svg .ct-ghost-via { fill: var(--ct-ghost); }

/* ---- vias ---- */

.ct-via-ring {
  fill: var(--surface-canvas);
  stroke: var(--ct-trace);
  stroke-width: 2.5;
  opacity: var(--v, 0);
  transition: opacity 320ms var(--ease-apple);
}
.ct-via-core {
  fill: var(--ct-trace);
  opacity: var(--v, 0);
  transition: opacity 320ms var(--ease-apple), fill 320ms var(--ease-apple);
}

.ct-via.is-live .ct-via-core { fill: var(--ct-live); }
.ct-via.is-live .ct-via-ring { stroke: var(--ct-trace); }

/* The halo only exists on the live via — a powered pad. */
.ct-via-halo {
  fill: none;
  stroke: var(--ct-live);
  stroke-width: 2;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(0.6);
  transition: opacity 420ms var(--ease-apple), transform 420ms var(--ease-apple);
}
.ct-via.is-live .ct-via-halo { opacity: 0.55; transform: scale(1); }

/* The outer bloom — soft, wide and blurred. It is what makes the live pad read
   as emitting rather than as outlined, and it is the difference between a
   powered board and a printed one. */
.ct-via-bloom {
  fill: var(--ct-live);
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(0.5);
  transition: opacity 520ms var(--ease-apple), transform 520ms var(--ease-apple);
}
.ct-via.is-live .ct-via-bloom { opacity: 0.20; transform: scale(1); }

/* GLOW IS DARK-ONLY. A bloom over a white page is grey mud, not light — on
   light the trace is simply ink on paper. */
[data-theme="dark"] .ct-svg .ct-path,
[data-theme="dark"] .ct-via.is-live .ct-via-core,
[data-theme="dark"] .ct-via.is-live .ct-via-bloom { filter: url(#ct-glow); }
[data-theme="light"] .ct-via-bloom,
:root:not([data-theme="dark"]) .ct-via-bloom { opacity: 0 !important; }

.ct-via-label {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.16em;
  fill: var(--mist);
  opacity: var(--v, 0);
  transition: opacity 320ms var(--ease-apple), fill 320ms var(--ease-apple);
}
.ct-via.is-live .ct-via-label { fill: var(--ink); }

/* ---- the status readout ---- */

.ct-status {
  position: absolute;
  top: 14px;
  right: 16px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.15em;
  color: var(--mist);
  opacity: 0;
  transition: opacity 500ms var(--ease-apple);
}
.ct.is-live .ct-status { opacity: 1; }
.ct-status b { font-weight: inherit; color: var(--accent); }

/* --------------------------------------------------------------------------
   The stage copy

   All four blocks are stacked in the same cell; only the live one is shown.
   Stacking rather than swapping innerHTML keeps every stage in the DOM, so the
   section still reads as four steps to a screen reader and to a crawler.
   -------------------------------------------------------------------------- */

.ct-readout {
  display: grid;
  text-align: center;
  padding: 4px 20px 0;
  min-height: 210px;
}

.ct-stage {
  grid-area: 1 / 1;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 420ms var(--ease-apple), transform 420ms var(--ease-apple);
  pointer-events: none;
}
.ct-stage.is-live { opacity: 1; transform: none; pointer-events: auto; }

.ct-stage-tag {
  display: block;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 16px;
}

.ct-stage h3 {
  font-size: clamp(27px, 3.6vw, 44px);
  letter-spacing: -0.026em;
  line-height: 1.06;
  color: var(--ink);
  margin: 0 auto 16px;
  max-width: 18ch;
}

.ct-stage p {
  font-size: var(--text-body);
  line-height: var(--leading-body);
  letter-spacing: var(--tracking-body);
  color: var(--mist);
  margin: 0 auto;
  max-width: 48ch;
}

/* --------------------------------------------------------------------------
   Where it stands down

   A trace that routes across 1180px has nowhere to go on a phone, and the
   readout would show one stage of four with no way to reach the others. Below
   820px js/effects/circuit.js never builds the board and every stage is shown as a
   plain list.
   -------------------------------------------------------------------------- */

@media (max-width: 820px) {
  .ct-board, .ct-status { display: none; }
  .ct-readout { display: block; min-height: 0; padding: 0; text-align: left; }
  .ct-stage {
    opacity: 1;
    transform: none;
    pointer-events: auto;
    padding: 24px 0 26px;
    border-bottom: 1px solid var(--line);
  }
  .ct-stage:last-child { border-bottom: 0; }
  .ct-stage h3, .ct-stage p { margin-left: 0; margin-right: 0; max-width: none; }
  .ct-stage-tag { margin-bottom: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .ct-svg .ct-path { stroke-dashoffset: 0; }
  .ct-via-ring, .ct-via-core, .ct-via-label { opacity: 1; }
  .ct-status { opacity: 1; }
  .ct-stage, .ct-via-ring, .ct-via-core, .ct-via-halo, .ct-via-label {
    transition-duration: 1ms;
  }
}

/* The pin comes off with the board. A section that holds the viewport for
   three screens to show a diagram that is not being drawn is just a section
   you cannot scroll past. */
@media (max-width: 820px) {
  .ct-scene { height: auto; padding: clamp(64px, 8vw, 120px) 0; }
  .ct-pin { position: static; height: auto; display: block; overflow: visible; }
  .ct-scene .ct-readout { min-height: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ct-scene { height: auto; padding: clamp(64px, 8vw, 120px) 0; }
  .ct-pin { position: static; height: auto; display: block; overflow: visible; }

  /* Unpinned, only one stage's copy would ever be reachable — so show them all
     and let the fully-routed board sit above as a diagram. */
  .ct-readout { display: block; min-height: 0; text-align: left; }
  .ct-stage {
    opacity: 1;
    transform: none;
    pointer-events: auto;
    padding: 22px 0 24px;
    border-bottom: 1px solid var(--line);
  }
  .ct-stage:last-child { border-bottom: 0; }
  .ct-stage h3, .ct-stage p { margin-left: 0; margin-right: 0; max-width: none; }
}
