/* ---------------------------------------------------------------------------
   stage-rail.css — the eight pipeline segments across the top.
   ---------------------------------------------------------------------------
   The rail is the only element that shows the WHOLE pipeline at once, so it
   never collapses a stage and never hides one that has not started. Every state
   is carried by BOTH a colour and a word ("Running", "Blocked"), because a
   console read on a bad monitor by a colour-blind operator still has to work.
--------------------------------------------------------------------------- */

.stage-rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--s-2);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  padding-bottom: var(--s-1);
}

.stage {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  min-width: 0;
  min-height: var(--h-rail);
  padding: var(--s-2) var(--s-3) var(--s-3) calc(var(--s-3) + var(--s-1));
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  scroll-snap-align: start;
  transition: border-color var(--m-base) var(--m-ease),
              background var(--m-base) var(--m-ease),
              box-shadow var(--m-base) var(--m-ease);
}

/* The state spine. A 3px bar reads at a glance from across a desk in a way a
   border tint does not. */
.stage::before {
  content: '';
  position: absolute;
  inset: var(--s-2) auto var(--s-2) var(--s-2);
  width: 3px;
  border-radius: var(--r-pill);
  background: var(--c-idle);
  transition: background var(--m-base) var(--m-ease);
}

.stage__top {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  min-width: 0;
}

.stage__idx {
  flex: none;
  font-family: var(--f-mono);
  font-size: var(--t-xs);
  color: var(--c-fg-faint);
}

.stage__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--t-md);
  font-weight: var(--fw-semi);
  color: var(--c-fg);
}

.stage__state {
  margin-left: auto;
  flex: none;
  font-size: var(--t-xs);
  font-weight: var(--fw-semi);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--c-fg-faint);
}

.stage__sub {
  font-size: var(--t-xs);
  color: var(--c-fg-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.stage__counts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1) var(--s-2);
  margin-top: auto;
  font-size: var(--t-xs);
  font-family: var(--f-mono);
}
.stage__count { color: var(--c-fg-muted); }
.stage__count[hidden] { display: none; }
.stage__count--pass { color: var(--c-ok-ink); }
.stage__count--drop { color: var(--c-drop); }

.stage__bar {
  position: relative;
  overflow: hidden;
  height: 3px;
  border-radius: var(--r-pill);
  background: var(--c-idle-soft);
}
.stage__bar-fill {
  display: block;
  width: 0;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--c-idle);
  transition: width var(--m-base) var(--m-ease), background var(--m-base) var(--m-ease);
}

/* ---- states -------------------------------------------------------------- */
.stage[data-state="idle"] { background: var(--c-surface-2); }
.stage[data-state="idle"] .stage__label { color: var(--c-fg-muted); font-weight: var(--fw-medium); }

.stage[data-state="active"] {
  border-color: var(--c-primary);
  box-shadow: var(--sh-2);
}
.stage[data-state="active"]::before { background: var(--c-primary); }
.stage[data-state="active"] .stage__state { color: var(--c-primary); }
.stage[data-state="active"] .stage__bar-fill { background: var(--c-primary); }

.stage[data-state="done"] { border-color: var(--c-ok-soft); }
.stage[data-state="done"]::before { background: var(--c-ok); }
.stage[data-state="done"] .stage__state { color: var(--c-ok-ink); }
.stage[data-state="done"] .stage__bar-fill { background: var(--c-ok); }

.stage[data-state="blocked"] {
  background: var(--c-warn-soft);
  border-color: var(--c-warn);
}
.stage[data-state="blocked"]::before { background: var(--c-warn); }
.stage[data-state="blocked"] .stage__state { color: var(--c-warn-ink); }
.stage[data-state="blocked"] .stage__label,
.stage[data-state="blocked"] .stage__sub { color: var(--c-warn-ink); }
.stage[data-state="blocked"] .stage__bar-fill { background: var(--c-warn); }

.stage[data-state="failed"] {
  background: var(--c-danger-soft);
  border-color: var(--c-danger);
}
.stage[data-state="failed"]::before { background: var(--c-danger); }
.stage[data-state="failed"] .stage__state { color: var(--c-danger-ink); }
.stage[data-state="failed"] .stage__label,
.stage[data-state="failed"] .stage__sub { color: var(--c-danger-ink); }
.stage[data-state="failed"] .stage__bar-fill { background: var(--c-danger); }

/* A scrape can run for ten minutes with no count to report. The indeterminate
   sweep is what says "still working" rather than "hung". */
.stage[data-state="active"][data-progress="indeterminate"] .stage__bar::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 35%;
  border-radius: var(--r-pill);
  background: var(--c-primary);
  animation: rail-sweep 1.4s var(--m-ease) infinite;
}
@keyframes rail-sweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(340%); }
}

/* ---- narrow: scroll instead of squeeze ---------------------------------- */
@media (max-width: 1023px) {
  .stage-rail { grid-auto-columns: minmax(148px, 44%); }
}
@media (max-width: 600px) {
  .stage-rail { grid-auto-columns: minmax(146px, 62%); }
  .stage { min-height: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .stage[data-state="active"][data-progress="indeterminate"] .stage__bar::after {
    animation: none;
    width: 100%;
    opacity: .35;
  }
}
