/* One markup, two shapes. Vertical below 992px (the project's existing
   sidebar/tab-bar breakpoint), horizontal at and above it. */
.journey { padding: .75rem .25rem; }
.journey__note { font-size: .875rem; color: var(--ideal-text-muted); margin-bottom: .75rem; }
/* Amber as TEXT (--ideal-warning on white) is ~1.6:1 — far under WCAG 1.4.3's
   4.5:1, and this is the one sentence telling a provider their invoice is
   stuck. Dark text on the amber tint instead, which is how the rest of the
   project uses the token: as a surface and a border, never as a foreground. */
.journey__hold {
  display: block;
  margin-top: .5rem;
  padding: .5rem .625rem;
  border-left: 3px solid var(--ideal-warning);
  background: var(--ideal-warning-light);
  color: var(--ideal-text-dark);
  font-weight: 600;
}

.journey__steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.journey__step { display: flex; align-items: baseline; gap: .5rem; padding: .25rem 0 .25rem 1.25rem; position: relative; }
.journey__dot { position: absolute; left: 0; top: .35rem; width: .625rem; height: .625rem; border-radius: 50%; background: var(--ideal-gray-medium); }
.journey__step.is-done .journey__dot { background: var(--ideal-teal); }
/* Colour alone can't carry "done" (WCAG 1.4.1) — a tick, not just the fill,
   marks a completed step. Positioned relative to the dot's own box, so it
   stays centred under the horizontal layout's translateX(-50%) on the dot. */
.journey__step.is-done .journey__dot::after {
  content: "\2713";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: .5rem;
  line-height: 1;
  color: var(--ideal-text-dark);
}
.journey__step.is-current .journey__dot { background: #fff; border: 2px solid var(--ideal-teal); box-shadow: 0 0 0 3px rgba(92,189,189,.25); }
.journey__step.is-todo .journey__label { color: var(--ideal-text-muted); }
.journey__date { font-size: .8125rem; color: var(--ideal-text-muted); }

@media (min-width: 992px) {
  .journey__steps { flex-direction: row; }
  .journey__step { flex: 1; flex-direction: column; align-items: center; text-align: center; padding: 1.5rem .5rem 0; }
  .journey__step::before { content: ""; position: absolute; top: .5rem; left: -50%; width: 100%; height: 2px; background: var(--ideal-gray-medium); }
  .journey__step:first-child::before { display: none; }
  .journey__step.is-done::before, .journey__step.is-current::before { background: var(--ideal-teal); }
  .journey__dot { left: 50%; top: .1875rem; transform: translateX(-50%); }
}

/* The timeline arrives over HTTP AFTER the row has already opened, so the
   placeholder has to hold the space it will need. Without a reserved height the
   row snapped open to a thin strip and then jolted taller a fifth of a second
   later, which is the part that read as unsmooth rather than the wait itself.
   Centred for the same reason: a spinner pinned to the far left of a full-width
   row does not look like it belongs to the row it is loading.

   The height matches the horizontal timeline: .journey padding, the step's
   1.5rem top padding, a label line and a date line. This expander only exists
   at >=992px (the button is d-none d-lg-inline-block), which is the same
   breakpoint the horizontal layout starts at, so one figure covers it. */
.journey-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 5.75rem;
  color: var(--ideal-text-muted);
  font-size: .875rem;
}

/* Fade the timeline in rather than letting it pop into the space the spinner
   was holding. Short enough not to feel like a wait of its own. */
.journey { animation: journey-fade .18s ease-out both; }

@keyframes journey-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .journey { animation: none; }
}
