/*
 * A control-plane diagram: one vague ask enters on the left, passes through
 * three gated stages, and leaves as verified work. Underneath sits the GitHub
 * toolchain, wired up to the stage each surface actually powers.
 *
 * Deliberately not a stepper — the page already carries Phase Graph, and two
 * horizontal timelines in one document read as the same graphic twice. Here
 * nothing is hidden: every stage and every surface shows its copy at all times,
 * and the interaction only moves emphasis around. That is also why there are no
 * tab stops; there is nothing behind them to reveal.
 *
 * Two colour systems meet. --s1/--s2/--s3 are the fixed stage colours (the same
 * brand ramp Phase Graph samples, so the two graphics look related), and --c is
 * whichever of those an individual element belongs to, set inline.
 *
 * The wire paths in .band are the one measured part of the layout; everything
 * else is flex and grid.
 */

.WQf2o9_s3N45A2GdXQpl {
  /* Overridden inline by the theme props. */
  --bg: #ffffff;
  --surface: #ffffff;
  --ink: #000d30;
  --muted: #4e4e4e;
  --line: #e3e8f1;
  --s1: #0066ff;
  --s2: #4c00ff;
  --s3: #ff00d4;
  --accent: var(--s1);
  --radius: 16px;
  --maxw: 85rem;
  --step: 4.2s;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /*
   * The spine's fixed columns. Everything left over is split three ways between
   * the stages, so these are kept tight: the site's container tops out at
   * 1360px and the stages need ~230px each before the descriptions start
   * breaking badly. Below 78rem the layout stacks instead — see the breakpoint.
   *
   * The intake is wider than the copy alone needs because its note runs at the
   * same 1rem as the rest of the card text; at the old 9.5rem that short line
   * broke into a four-line tower next to stages half its height.
   */
  --intakeW: 11rem;
  --linkW: 3rem;
  --bandH: 82px;
  --flow: 2.6s;

  /*
   * The layout switches on the frame's own width, not the viewport's. A
   * Designer author can drop this into any column, and the component renders in
   * Shadow DOM where the site's breakpoints mean nothing to it either — a
   * viewport media query would go horizontal in a half-width column and stack
   * on a wide one. Everything below queries this container instead.
   */
  container-type: inline-size;

  box-sizing: border-box;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  /* Not switched at the breakpoint: a container cannot query itself, and this
     is the one rule that would need to. Scales on the viewport instead. */
  padding: 1.4rem clamp(1.25rem, 1.4vw, 1.75rem) 1.6rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

.WQf2o9_s3N45A2GdXQpl *,
.WQf2o9_s3N45A2GdXQpl *::before,
.WQf2o9_s3N45A2GdXQpl *::after {
  box-sizing: border-box;
}

.WQf2o9_s3N45A2GdXQpl p,
.WQf2o9_s3N45A2GdXQpl h3,
.WQf2o9_s3N45A2GdXQpl h4 {
  margin: 0;
}

/* ---------- header strip ---------- */

.DM36cwG7qhC2NMh4AWxk {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.9rem;
  padding-bottom: 1.1rem;
  margin-bottom: 1.4rem;
  border-bottom: 1px solid var(--line);
}

.chvjJ4yt4uapegP2a0M6 {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
}

/*
 * The one always-on motion in the graphic. It reads as "this system is
 * running", which is the whole claim, and it costs one composited property.
 */
.ai3LXnS5htrMzoRJzXJc {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  transition: background 0.5s ease;
  animation: iiohWZipxtDiKv3jmNj_ 2.4s ease-in-out infinite;
}

@keyframes iiohWZipxtDiKv3jmNj_ {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.75); }
}

.y5n6RkBAY4asE396_8lA {
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--muted);
}

/* ---------- spine ---------- */

.QDezGzhHaZOUdyRnWpzC {
  display: flex;
  align-items: stretch;
  width: 100%;
}

/*
 * Stage plus its trailing link. Wrapping the pair means the three stages stay
 * equal-width flex siblings — links are fixed-width, so a flat row would make
 * each stage's share depend on how many links happened to precede it.
 */
.GhGEOZ9WbvssLWdMzAh4 {
  display: flex;
  align-items: stretch;
  flex: 1 1 0;
  min-width: 0;
}

/*
 * Centred rather than stretched, unlike the stages. The intake is the thing
 * outside the system; matching the stages' full height would file it as another
 * one of them.
 */
.UuuwKZeWtFlJOrxeXt_M {
  display: flex;
  flex: 0 0 var(--intakeW);
  flex-direction: column;
  align-self: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 1rem 1.05rem;
  border: 1px dashed color-mix(in srgb, var(--muted) 45%, transparent);
  border-radius: calc(var(--radius) - 4px);
  /* Reads as the unresolved thing it depicts, against the solid stages. */
  background: repeating-linear-gradient(
    -45deg,
    transparent 0 7px,
    color-mix(in srgb, var(--muted) 5%, transparent) 7px 14px
  );
}

.AkBAaFDYcbRQoetoW7Za {
  font-family: var(--mono);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.GQKmQGWFtjk6GYobe86z {
  font-size: 1.05rem;
  font-weight: 400;
  font-style: italic;
  line-height: 1.35;
  color: var(--ink);
}

.oIVJsgO2YBHHYKyiBx9p {
  font-size: 1rem;
  line-height: 1.5;
  color: var(--muted);
}

/* ---------- links between stages ---------- */

.Hc51fQIMlwIYqE99T1cR {
  position: relative;
  display: flex;
  flex: 0 0 var(--linkW);
  align-items: center;
  justify-content: center;
  gap: 1px;
  color: color-mix(in srgb, var(--muted) 55%, transparent);
  transition: color 0.45s ease;
}

.tqvvjrZZGfT26s4aAPC_ {
  color: var(--accent);
}

/*
 * Set vertically so a word like "decompose" fits a 3rem column without either
 * wrapping or spilling over the neighbouring cards. Reading bottom-to-top is
 * the convention for axis labels and looks intentional here; the stacked layout
 * puts it back horizontal, where there is room.
 */
.WS91XX3im4_fpUQ4YiUm {
  /* Centred with auto margins rather than a translate, leaving `transform`
     free for the flip — combining the two fights over the rotated axis. */
  position: absolute;
  right: 0;
  bottom: calc(50% + 0.8rem);
  left: 0;
  width: max-content;
  margin-inline: auto;
  font-family: var(--mono);
  font-size: 0.56rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  color: currentcolor;
  opacity: 0.85;
}

._8HvKX4tq6aHoxXcCoEW {
  position: relative;
  flex: 1 1 auto;
  height: 2px;
  overflow: hidden;
  background: currentcolor;
  opacity: 0.35;
}

.tqvvjrZZGfT26s4aAPC_ ._8HvKX4tq6aHoxXcCoEW {
  opacity: 1;
}

/* The packet of work moving between gates. */
.HG5L0x6j6v3PL_LsGAJw {
  position: absolute;
  inset: 0 auto 0 0;
  width: 45%;
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--bg) 85%, transparent),
    transparent
  );
  animation: lnuL87Ia1W1KJd1vlUyG var(--flow) linear infinite;
}

@keyframes lnuL87Ia1W1KJd1vlUyG {
  from { transform: translateX(-100%); }
  to { transform: translateX(320%); }
}

.ANCCkePxFzTK4D48iJmi {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  color: currentcolor;
}

/* ---------- stages ---------- */

.s8kRrNqpn1T4iT5LDCRd {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 0.45rem;
  min-width: 0;
  padding: 1.15rem 1.2rem 1.35rem;
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) - 4px);
  background: var(--surface);
  /* Not `all` — transitioning border-color alongside a box-shadow on a hovered
     card is what makes these feel like they settle rather than snap. */
  transition: border-color 0.45s ease, box-shadow 0.45s ease, transform 0.45s ease;
}

.YgGl3KMMYRsddjVtaxYo {
  border-color: color-mix(in srgb, var(--c) 40%, var(--line));
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--ink) 6%, transparent),
    0 14px 30px -18px color-mix(in srgb, var(--c) 55%, transparent);
  transform: translateY(-2px);
}

.eybkjBgfRQqWsKJJPTQK {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--c);
  opacity: 0.55;
  transition: opacity 0.45s ease;
}

.YgGl3KMMYRsddjVtaxYo .eybkjBgfRQqWsKJJPTQK {
  opacity: 1;
}

.t9MppCbj8K2gOc3OrgqI {
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.JUtzLbB7fUZrYn2BRtXj {
  font-size: 1rem;
  line-height: 1.55;
  color: var(--muted);
}

/*
 * The fill bar along the bottom edge. Scaling a full-width element beats
 * animating width: it stays on the compositor, and the 0.5s here is what makes
 * the autoplay cursor feel like it lands rather than blinks.
 */
.WEpcHaPPl8d7PziCZwJn {
  position: absolute;
  right: 1px;
  bottom: 1px;
  left: 1px;
  height: 3px;
  border-radius: 0 0 calc(var(--radius) - 5px) calc(var(--radius) - 5px);
  background: var(--c);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.5s cubic-bezier(0.22, 0.75, 0.3, 1);
}

.YgGl3KMMYRsddjVtaxYo .WEpcHaPPl8d7PziCZwJn {
  transform: scaleX(1);
}

/* ---------- terminal ---------- */

.NTsl0BtMnCZyPwv4SEsL {
  display: flex;
  flex: 0 0 2.25rem;
  align-items: center;
  justify-content: center;
  align-self: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--muted);
  background: var(--surface);
  transition: border-color 0.45s ease, color 0.45s ease, background 0.45s ease;
}

.OvnLudhYckvSXn61Tcge {
  border-color: transparent;
  color: #ffffff;
  background: var(--s3);
}

.SlamzFwBBDt_TZYzNms2 {
  width: 15px;
  height: 15px;
}

/* ---------- wiring band ---------- */

.TZqeAkiuhkdtwBFKQWwD {
  position: relative;
  width: 100%;
  height: var(--bandH);
}

.O8o6L9RW4cAwukBKCsOz {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.OQuaWm4Uro_Q_YQS7dvw {
  fill: none;
  stroke: var(--muted);
  stroke-width: 1.25;
  stroke-linecap: round;
  opacity: 0.3;
  transition: opacity 0.45s ease, stroke 0.45s ease, stroke-width 0.45s ease;
}

._ogrJNdMevnbH9JmgGP9 {
  stroke: var(--c);
  stroke-width: 1.75;
  opacity: 1;
  /* Dash length is deliberately long against a short gap: it reads as one
     current running up the wire, not as a dotted line. */
  stroke-dasharray: 7 5;
  animation: jnHrr8y8XChViAeoEGhc 1.1s linear infinite;
  animation-delay: var(--d);
}

@keyframes jnHrr8y8XChViAeoEGhc {
  to { stroke-dashoffset: -12; }
}

/* ---------- rail ---------- */

/* Mirrors .head at the foot of the frame, so the rail is bracketed the same way
   the spine is rather than looking like a caption that drifted loose. */
.FSUfYxRFTscrZgONcX7A {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.2rem 0.6rem;
  padding-top: 1.05rem;
  margin-top: 1.25rem;
  border-top: 1px solid var(--line);
  line-height: 1.5;
}

.R4ISfHbGmkt7ccWesIHl {
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
}

.JDDJTBG8LSnn8e_TWYF3 {
  font-size: 0.82rem;
  color: var(--muted);
}

.ts2IIWCF0Nfp80sakdo2 {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  gap: 0.75rem;
}

.Osz8zCCtexKRCyHctPK7 {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  min-width: 0;
  padding: 0.95rem 1rem 0.85rem;
  border: 1px solid var(--line);
  border-top: 2px solid color-mix(in srgb, var(--c) 30%, var(--line));
  border-radius: calc(var(--radius) - 6px);
  background: var(--surface);
  transition: border-color 0.45s ease, background 0.45s ease, transform 0.45s ease;
}

.VClKN7iXE4BNjRkFQm1y {
  border-color: color-mix(in srgb, var(--c) 22%, var(--line));
  border-top-color: var(--c);
  background: color-mix(in srgb, var(--c) 4%, var(--surface));
  transform: translateY(-2px);
}

.JXQx65Mwb9Dp96Sfiz4v {
  font-size: 1.06rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
}

.BsRtGHvykw7Fj8LYyMg5 {
  flex: 1 1 auto;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--muted);
}

.L19__MDWQWn50LvZApUR {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.15rem;
  font-family: var(--mono);
  font-size: 0.56rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.rukWQismdxxnJ8vj6ZEV {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c);
  opacity: 0.45;
  transition: opacity 0.45s ease;
}

.VClKN7iXE4BNjRkFQm1y .rukWQismdxxnJ8vj6ZEV {
  opacity: 1;
}

/*
 * The wire says which stage a chip feeds, so on desktop the text would repeat
 * it. Below the breakpoint the wires are gone and the text is the only carrier,
 * which is why it is hidden here rather than simply not rendered.
 */
@container (min-width: 78rem) {
  .GqViGn6bZz8Ga1C7Vy6U {
    display: none;
  }
}

/* ---------- dimming ---------- */

/*
 * Only while something is hovered. Under autoplay alone the unlit cards stay at
 * full strength — a graphic that pulses its own contrast every few seconds is
 * hard to read next to.
 */
.Dh9Af_MloVziQTjX6Dyg .s8kRrNqpn1T4iT5LDCRd:not(.YgGl3KMMYRsddjVtaxYo),
.Dh9Af_MloVziQTjX6Dyg .Osz8zCCtexKRCyHctPK7:not(.VClKN7iXE4BNjRkFQm1y) {
  opacity: 0.5;
}

.Dh9Af_MloVziQTjX6Dyg .s8kRrNqpn1T4iT5LDCRd,
.Dh9Af_MloVziQTjX6Dyg .Osz8zCCtexKRCyHctPK7 {
  transition: opacity 0.35s ease, border-color 0.45s ease, background 0.45s ease,
    box-shadow 0.45s ease, transform 0.45s ease;
}

/* ---------- stacked layout ---------- */

/*
 * Under 78rem of frame width the three stages drop below ~220px each, where the
 * descriptions stop holding a readable line, so the spine turns vertical and
 * each chip states its stage in words instead of drawing it. DOM order never
 * changes, so nothing is duplicated for the small layout.
 *
 * This threshold is set by the card type size, not by the geometry: at the old
 * 0.8rem copy the horizontal layout still read at 66rem, but 1rem needs the
 * extra width to keep the descriptions off ~18-character lines. Change the card
 * font sizes and this number has to move with them.
 */
@container (max-width: 77.99rem) {
  .QDezGzhHaZOUdyRnWpzC,
  .GhGEOZ9WbvssLWdMzAh4 {
    flex-direction: column;
  }

  .UuuwKZeWtFlJOrxeXt_M,
  .GhGEOZ9WbvssLWdMzAh4 {
    flex: 0 0 auto;
  }

  /* Full width here — the centring that sets the intake apart from the stages
     only reads when they sit in a row. */
  .UuuwKZeWtFlJOrxeXt_M {
    align-self: stretch;
  }

  /*
   * The card goes full width but the sentence should not: stacked at 1248px
   * that is a 140-character line, which is as hard to read as the cramped
   * column the breakpoint exists to avoid. The card keeps its full width so
   * the borders and the stage bar still span the frame.
   */
  .JUtzLbB7fUZrYn2BRtXj,
  .BsRtGHvykw7Fj8LYyMg5 {
    max-width: 68ch;
  }

  .Hc51fQIMlwIYqE99T1cR {
    flex: 0 0 auto;
    flex-direction: column;
    gap: 0;
    height: 3.4rem;
  }

  /*
   * Still a column flex child, so flex-basis governs height and the explicit
   * width holds. Leaving the horizontal `flex: 1 1 auto` in place is what
   * stretched this into a grey slab across the card.
   */
  ._8HvKX4tq6aHoxXcCoEW {
    flex: 1 1 auto;
    width: 2px;
    height: auto;
  }

  .HG5L0x6j6v3PL_LsGAJw {
    inset: 0 0 auto 0;
    width: auto;
    height: 45%;
    background: linear-gradient(
      180deg,
      transparent,
      color-mix(in srgb, var(--bg) 85%, transparent),
      transparent
    );
    animation-name: h8qvHk4nikaK8Z9Yw98n;
  }

  @keyframes h8qvHk4nikaK8Z9Yw98n {
    from { transform: translateY(-100%); }
    to { transform: translateY(320%); }
  }

  .ANCCkePxFzTK4D48iJmi {
    transform: rotate(90deg);
  }

  /* Back to horizontal and set beside the connector: the vertical treatment
     exists only to survive the 3rem column of the wide layout. */
  .WS91XX3im4_fpUQ4YiUm {
    right: auto;
    bottom: auto;
    top: 50%;
    left: 50%;
    margin-inline: 0;
    writing-mode: horizontal-tb;
    transform: translate(0.7rem, -50%);
  }

  .TZqeAkiuhkdtwBFKQWwD {
    display: none;
  }

  .ts2IIWCF0Nfp80sakdo2 {
    grid-template-columns: minmax(0, 1fr);
    margin-top: 1.5rem;
  }
}

@container (min-width: 30rem) and (max-width: 77.99rem) {
  .ts2IIWCF0Nfp80sakdo2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---------- motion ---------- */

.lrrfLT4liazekirmWmkw .HG5L0x6j6v3PL_LsGAJw {
  animation-play-state: paused;
}

.YdHLfxcAjG65CbKv4Pre .ai3LXnS5htrMzoRJzXJc,
.YdHLfxcAjG65CbKv4Pre .HG5L0x6j6v3PL_LsGAJw,
.YdHLfxcAjG65CbKv4Pre ._ogrJNdMevnbH9JmgGP9 {
  animation: none;
}

.YdHLfxcAjG65CbKv4Pre ._ogrJNdMevnbH9JmgGP9 {
  stroke-dasharray: none;
}

@media (prefers-reduced-motion: reduce) {
  .WQf2o9_s3N45A2GdXQpl *,
  .WQf2o9_s3N45A2GdXQpl *::before,
  .WQf2o9_s3N45A2GdXQpl *::after {
    animation: none !important;
    transition-duration: 0.01ms !important;
  }
}

