/* fx.css · layout/timeline, milestones light up along a line as you scroll · owner: Lizzy East · all rights reserved */

/* The list carries the line (data-fx-timeline); each milestone is its own block. The
   finished look is a full line with every dot lit. With the core, a milestone still
   to come waits with its dot unlit and its words low, then arrives; where CSS scroll
   timelines exist, the lit part of the line grows with the scroll, its tip at the
   middle of the screen. Without them, or with motion off, the whole line is lit. */
[data-fx-timeline] {
  position: relative;
  display: grid;
  gap: var(--fx-tl-gap, clamp(2.5rem, 6vw, 4.5rem));
  margin: 0;
  max-width: var(--fx-tl-max, 46rem);
  padding: 0 0 0 var(--fx-tl-inset, clamp(2.5rem, 6vw, 4rem));
  list-style: none;
}
[data-fx-timeline]::before,
[data-fx-timeline]::after {
  content: "";
  position: absolute;
  top: 0.5rem;
  bottom: 0.5rem;
  left: calc(var(--fx-tl-x, 0.75rem) - 1px);
  width: 2px;
  border-radius: 2px;
  background: var(--fx-tl-line, #c7ccd8);
}
[data-fx-timeline]::after { background: var(--fx-tl-accent, #2340ff); transform-origin: 50% 0; }
[data-fx-timeline] > [data-fx~="layout/timeline"] {
  --fx-tl-wait: calc(var(--fx-delay, 0ms) + var(--fx-i, 0) * var(--fx-stagger));
  position: relative;
  display: grid;
  gap: 0.5rem;
}
[data-fx-timeline] > [data-fx~="layout/timeline"] > * { margin: 0; }
/* The dot: a ring on the line, and the light inside it. */
[data-fx-timeline] > [data-fx~="layout/timeline"]::before,
[data-fx-timeline] > [data-fx~="layout/timeline"]::after {
  content: "";
  position: absolute;
  z-index: 1;
  top: 0.1rem;
  left: calc(var(--fx-tl-x, 0.75rem) - var(--fx-tl-inset, clamp(2.5rem, 6vw, 4rem)) - 0.6rem);
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 50%;
}
[data-fx-timeline] > [data-fx~="layout/timeline"]::before {
  background: var(--fx-tl-paper, #f4f5f7);
  box-shadow: inset 0 0 0 2px var(--fx-tl-accent, #2340ff);
}
[data-fx-timeline] > [data-fx~="layout/timeline"]::after {
  background: var(--fx-tl-accent, #2340ff);
  scale: 0.5;
}

/* Arriving: the words rise into place, then the dot lights. */
html.fx-armed [data-fx-timeline] > [data-fx~="layout/timeline"].is-pending > * {
  opacity: 0;
  translate: 0 var(--fx-distance);
}
html.fx-armed [data-fx-timeline] > [data-fx~="layout/timeline"].is-pending::after { scale: 0; }
html.fx-armed [data-fx-timeline] > [data-fx~="layout/timeline"].is-in > * {
  transition: opacity var(--fx-dur) var(--fx-ease), translate var(--fx-dur) var(--fx-ease);
  transition-delay: var(--fx-tl-wait);
}
html.fx-armed [data-fx-timeline] > [data-fx~="layout/timeline"].is-in::after {
  transition: scale calc(var(--fx-dur) * 0.75) cubic-bezier(0.3, 1.6, 0.5, 1);
  transition-delay: calc(var(--fx-tl-wait) + 160ms);
}

/* The lit line follows the scroll: its tip is always at the middle of the screen. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    html:not(.fx-still) [data-fx-timeline] { view-timeline-name: --fx-timeline; }
    html:not(.fx-still) [data-fx-timeline]::after {
      animation: fx-timeline-draw linear both;
      animation-timeline: --fx-timeline;
      animation-range: cover 50vh cover calc(100% - 50vh);
    }
  }
}
@keyframes fx-timeline-draw {
  from { scale: 1 0; }
  to { scale: 1 1; }
}
