/* ─────────────────────────────────────────────────────────────────────────
   flow.css — the horizontal workflow strip.

   Green on pure white. A dashed rail runs through the steps, and each card
   hangs off it on a short spoke. A green packet rides the rail — always
   clear of the cards, never occluded — and every card it reaches lights up
   and STAYS lit, so the run fills in behind the current.

   Icons sit on one side of the card, text beside them. Nothing on this page
   animates on a loop of its own: the packet is the only thing moving, and
   it is moving because it is carrying information.

   Two modes, set by orbit.js from MEASURED WIDTH:
     strip  — one horizontal row     (≥720 px: a full-width panel)
     ladder — stacked rows on a rail (the hero column, phones)
   ───────────────────────────────────────────────────────────────────────── */

.orbit { position: relative; --rail-y: 46px; --spoke: 24px; }

.orbit-stage {
  display: flex;
  align-items: flex-start;
  gap: var(--s4);
}

/* ── the rail and the packet ───────────────────────────────────────────── */

.orbit-track { position: relative; flex: 1 1 auto; min-width: 0; }

.orbit-rail {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--rail-y);
  height: 0;
  border-top: 1.5px dashed var(--leaf-30);
}

.orbit-packet {
  position: absolute;
  left: -7px;
  top: -7px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  z-index: 3;
  will-change: transform;
  background: radial-gradient(circle at 36% 30%, var(--leaf-hot), var(--leaf) 55%, var(--leaf-ink));
  box-shadow:
    0 0 0 3px var(--leaf-14),
    0 1px 4px rgba(18, 24, 21, 0.25);
}

/* ── step cards: icon on one side, revealed on arrival, then kept ─────── */

.orbit-steps {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
  padding-top: calc(var(--rail-y) + var(--spoke));
}

.orbit-card {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 9px;
  padding: 11px 11px 12px;
  border-radius: 13px;
  background: #fff;
  border: 1px solid #EAECEA;
  /* Neutral shadows: green belongs to the current, never to a shadow. */
  box-shadow: 0 6px 16px rgba(18, 24, 21, 0.05);
  transition: border-color 300ms var(--ease-out), box-shadow 300ms var(--ease-out);
}

/* The spoke from the rail down to the card, and its junction on the rail. */
.orbit-card::before {
  content: '';
  position: absolute;
  left: 50%;
  top: calc(var(--spoke) * -1);
  height: var(--spoke);
  border-left: 1.5px dashed var(--leaf-30);
}

.orbit-card::after {
  content: '';
  position: absolute;
  left: 50%;
  top: calc((var(--spoke) + 3.5px) * -1);
  width: 7px;
  height: 7px;
  margin-left: -3.5px;
  border-radius: 50%;
  background: #fff;
  border: 1.5px solid var(--leaf-30);
  transition: background 300ms var(--ease-out), border-color 300ms var(--ease-out);
}

.orbit-icon {
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: #A8AFAB;
  background: #F4F6F4;
  box-shadow: inset 0 0 0 1px rgba(18, 24, 21, 0.04);
  transition: background 320ms var(--ease-out), color 320ms var(--ease-out),
              box-shadow 320ms var(--ease-out);
}

.orbit-icon svg { width: 19px; height: 19px; }

.orbit-text { min-width: 0; }

.orbit-num {
  display: block;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: #A8AFAB;
  transition: color 320ms var(--ease-out);
}

.orbit-title {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  line-height: 1.2;
  color: #9AA19D;
  margin: 2px 0 0;
  transition: color 320ms var(--ease-out);
}

/* The line reveals on arrival and is KEPT: the visitor can read the whole
   story so far without waiting for the loop to come round again.

   ITS SPACE IS ALWAYS RESERVED. Animating max-height changed each row's
   height as the current reached it, which reflowed the whole document below
   the workflow — the hero grew by 3px mid-loop and every section under it
   moved. Only opacity animates now, so the layout is fixed the moment the
   component mounts. */
.orbit-sub {
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--ink-60);
  margin: 3px 0 0;
  opacity: 0;
  transition: opacity 300ms var(--ease-out);
}

/* Reached — and it stays this way until the loop wraps. */
.orbit-card.is-on { border-color: #D8EFE2; }

.orbit-card.is-on::after { background: var(--leaf); border-color: var(--leaf); }

.orbit-card.is-on .orbit-icon {
  background: radial-gradient(circle at 34% 28%, var(--leaf-hot), var(--leaf));
  color: #fff;
  box-shadow: none;
}

.orbit-card.is-on .orbit-num { color: var(--leaf-ink); }
.orbit-card.is-on .orbit-title { color: var(--ink); }

.orbit-card.is-on .orbit-sub { opacity: 1; }

/* The step the current is ON right now. */
.orbit-card.is-live {
  border-color: var(--leaf);
  box-shadow: 0 10px 26px rgba(18, 24, 21, 0.10), 0 0 0 1px var(--leaf);
}

/* ── caption under the strip ───────────────────────────────────────────── */

.orbit-caption {
  display: flex;
  gap: var(--s2);
  align-items: baseline;
  border-top: var(--hairline);
  padding-top: var(--s2);
  margin-top: var(--s4);
  min-height: 2.2em;
  letter-spacing: 0.05em;
}

.orbit-caption .n { color: var(--leaf-ink); }
.orbit-caption .n::before { content: 'STEP '; color: var(--ink-60); }
.orbit-caption .s { color: var(--ink); text-transform: uppercase; }

/* ── ladder mode: the hero column and phones ───────────────────────────── */

.orbit[data-mode='ladder'] { --rail-y: 0px; }

.orbit[data-mode='ladder'] .orbit-stage {
  display: block;
}

/* The rail turns vertical and runs down the left margin. */
.orbit[data-mode='ladder'] .orbit-rail {
  left: 21px;
  right: auto;
  top: 14px;
  bottom: 14px;
  width: 0;
  height: auto;
  border-top: 0;
  border-left: 1.5px dashed var(--leaf-30);
}

.orbit[data-mode='ladder'] .orbit-steps {
  display: flex;
  flex-direction: column;
  /* stretch, not flex-start: down a column, flex-start sizes each card to
     its own text and the right edge comes out ragged. */
  align-items: stretch;
  gap: 7px;
  padding-top: 0;
  padding-left: 44px;
}

/* Down a column, flex-grow would stretch card HEIGHTS to fill. */
.orbit[data-mode='ladder'] .orbit-card { flex: 0 0 auto; }

/* Compact rows: this mode runs inside the hero's right column, so every
   row must earn its height. Titles stay visible on unreached steps — an
   icon-only chip is a guessing game. */
.orbit[data-mode='ladder'] .orbit-card {
  padding: 7px 10px;
  border-radius: 11px;
  gap: 8px;
  grid-template-columns: 30px minmax(0, 1fr);
}

.orbit[data-mode='ladder'] .orbit-icon { width: 30px; height: 30px; }
.orbit[data-mode='ladder'] .orbit-icon svg { width: 17px; height: 17px; }
.orbit[data-mode='ladder'] .orbit-title { font-size: 12.5px; }
.orbit[data-mode='ladder'] .orbit-sub { font-size: 11px; }

/* Spoke and junction rotate to meet the vertical rail. */
.orbit[data-mode='ladder'] .orbit-card::before {
  left: -23px;
  top: 22px;
  height: 0;
  width: 23px;
  border-left: 0;
  border-top: 1.5px dashed var(--leaf-30);
}

.orbit[data-mode='ladder'] .orbit-card::after {
  left: -26px;
  top: 18.5px;
  margin-left: 0;
}

/* ── reduced motion ────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .orbit-card, .orbit-sub, .orbit-num, .orbit-title,
  .orbit-icon, .orbit-card::after { transition: none; }
}

.hero-stepper {
  margin-top: var(--s3);
  background: none;
  border: var(--hairline);
  color: var(--ink);
  padding: 10px var(--s3);
  min-height: 44px;
  cursor: pointer;
  letter-spacing: 0.10em;
}

.hero-stepper:hover { border-color: var(--leaf-ink); color: var(--leaf-ink); }
