/* RF Timeline widget — Reloadux Addons
 * All variables scoped to .rftimeline-root.
 */

/* ---------- Tokens (scoped) ---------- */
.rftimeline-root {
  --rf-bg-section: #dcedff;
  --rf-bg-far: #e8f3fe;
  --rf-bg-near: #ffffff;
  --rf-bg-active: #1882ec;
  --rf-bg-body-default: #f7f7f7;
  --rf-bg-body-on-color: #ffffff;

  --rf-text-default: #2f2f2f;
  --rf-text-on-active: #ffffff;
  --rf-text-muted-opacity: 0.6;
  --rf-text-body-opacity: 0.9;

  --rf-dot-ring: #c8c8c8;
  --rf-dot-near: #51bc51;
  --rf-dot-far: #1882ec;

  --rf-line-color: rgba(0, 0, 0, 0.3);

  --rf-slide-width: 459px;
  --rf-slide-gap: 56px;
  --rf-slide-stride: calc(var(--rf-slide-width) + var(--rf-slide-gap));

  --rf-year-row-h: 30px;
  --rf-year-line-gap: 24px;
  --rf-dot-size: 28px;
  --rf-dot-inner-size: 18px;
  --rf-card-radius: 32px;
  --rf-line-y: 17px;

  --rf-card-header-pt: 32px;
  --rf-card-header-pb: 8px;
  --rf-card-body-margin: 16px;
  --rf-card-body-px: 32px;
  --rf-card-body-py: 16px;

  --rf-section-pad-top: 64px;
  --rf-section-pad-bottom: 80px;
  --rf-section-pad-x: 24px;

  --rf-header-bottom-gap: 56px;
  --rf-header-gap: 8px;

  --rf-transition-slide: transform 700ms cubic-bezier(0.4, 0, 0.2, 1);
  --rf-transition-state: background-color 500ms ease, color 500ms ease,
    border-color 500ms ease, opacity 500ms ease, transform 500ms ease;
}

/* ---------- Box-sizing reset for our subtree only ---------- */
.rftimeline-root *,
.rftimeline-root *::before,
.rftimeline-root *::after {
  box-sizing: border-box;
}

/* ---------- Scroll-pin frame ----------
 * Sticky pin. The scroller is taller than the viewport by exactly
 * --rf-pin-distance (set inline by PHP from (N-1) × scrollPerSlide vh),
 * plus 100vh for the sticky child itself. The sticky child fills the
 * viewport for the entire runway, with the section centred inside it.
 *
 * Effects:
 *  • The page literally has to scroll through `--rf-pin-distance` of
 *    runway to leave the section, so a fast flick can't skip past it.
 *  • Cards are advanced via scroll-position → index mapping in JS, so
 *    they only start advancing once the section is pinned/centred —
 *    never while the user is mid-scroll into or out of the section.
 *  • Below 1024px and under prefers-reduced-motion both wrappers
 *    collapse to `display: contents` (see media queries below), letting
 *    the section flow normally and the carousel runtime take over.
 */
.rftimeline-root--pinned .rftimeline-scroller {
  position: relative;
  height: calc(var(--rf-pin-distance, 0vh) + 100vh);
}

.rftimeline-root--pinned .rftimeline-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.rftimeline-root--pinned .rftimeline-sticky > .timeline-section {
  width: 100%;
}

/* Pin mode adds NUM_CLONES (=2) decorative clones at each end on boot,
 * so once JS runs the first real slide sits at visualIndex 2 — which
 * conveniently matches the carousel-mode default --active-index: 2.
 * Nothing extra to override here; the default already produces the
 * correct first paint after clones are inserted. */

/* Track transitions remain stylesheet-owned so the pinned card-snap and
 * the mobile / reduced-motion carousel fallback share the same animation. */

/* ---------- Section frame ---------- */
.rftimeline-root .timeline-section__inner {
  max-width: 1440px;
  margin: 0 auto;
  background: var(--rf-bg-section);
  border-radius: 16px;
  padding: var(--rf-section-pad-top) var(--rf-section-pad-x) var(--rf-section-pad-bottom);
  overflow: clip;
}

.rftimeline-root .timeline-section__header {
  max-width: 750px;
  margin: 0 auto var(--rf-header-bottom-gap);
  text-align: center;
}

.rftimeline-root .timeline-section__title {
  margin: 0 0 var(--rf-header-gap);
  font-size: 48px;
  line-height: 54px;
  letter-spacing: -0.96px;
  font-weight: 400;
  color: #000;
}

.rftimeline-root .timeline-section__subtitle {
  margin: 0;
  font-size: 20px;
  line-height: 28px;
  font-weight: 400;
  color: var(--rf-text-default);
}

/* ---------- Timeline ----------
 * Extend the carousel outward by the inner section padding so the
 * dotted line and slide track reach the rounded edges of the blue
 * background. Header above stays inside the padding for normal
 * margins. The negative margin is exactly cancelled by the inner
 * padding, so the timeline is bounded by the section bg, not larger.
 */
.rftimeline-root .timeline {
  position: relative;
  margin: 0 calc(var(--rf-section-pad-x) * -1);
}

.rftimeline-root .timeline__viewport {
  position: relative;
  overflow: hidden;
}

.rftimeline-root .timeline__line {
  position: absolute;
  top: var(--rf-line-y);
  left: 0;
  right: 0;
  height: 1px;
  background-image: linear-gradient(
    to right,
    var(--rf-line-color) 50%,
    transparent 50%
  );
  background-size: 8px 1px;
  background-repeat: repeat-x;
  z-index: 1;
  pointer-events: none;
}

.rftimeline-root .timeline__track {
  --active-index: 2;
  list-style: none;
  margin: 0;
  padding: 0 calc(50% - (var(--rf-slide-width) / 2));
  display: flex;
  gap: var(--rf-slide-gap);
  transform: translateX(
    calc(var(--active-index) * var(--rf-slide-stride) * -1)
  );
  transition: var(--rf-transition-slide);
  position: relative;
  z-index: 2;
  align-items: stretch;
  will-change: transform;
}

/* Used while we instantly snap from a clone slide back to its real twin */
.rftimeline-root .timeline__track.is-snapping {
  transition: none;
}

.rftimeline-root .timeline__slide {
  flex: 0 0 var(--rf-slide-width);
  width: var(--rf-slide-width);
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  cursor: pointer;
  transition: var(--rf-transition-state);
}

.rftimeline-root .timeline__slide:focus-visible {
  outline: none;
}

.rftimeline-root .timeline__slide:focus-visible .timeline__card {
  outline: 2px solid var(--rf-bg-active);
  outline-offset: 4px;
}

/* ---------- Year ---------- */
.rftimeline-root .timeline__year {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--rf-year-row-h);
  padding: 0;
  background: var(--rf-bg-section);
  position: relative;
  z-index: 4;
  font-size: 24px;
  font-weight: 500;
  line-height: 30px;
  color: #000;
  user-select: none;
  transition: var(--rf-transition-state);
}

/* ---------- Dot ---------- */
.rftimeline-root .timeline__dot {
  position: relative;
  z-index: 3;
  width: var(--rf-dot-size);
  height: var(--rf-dot-size);
  margin-top: var(--rf-year-line-gap);
  border-radius: 50%;
  background: #ffffff;
  border: 1px solid var(--rf-dot-ring);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--rf-transition-state);
}

.rftimeline-root .timeline__dot-inner {
  width: var(--rf-dot-inner-size);
  height: var(--rf-dot-inner-size);
  border-radius: 50%;
  background: var(--rf-dot-far);
  transition: var(--rf-transition-state);
}

/* ---------- Card ---------- */
.rftimeline-root .timeline__card {
  width: 100%;
  margin-top: calc(var(--rf-dot-size) / -2);
  border-radius: var(--rf-card-radius);
  background: var(--rf-bg-near);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  overflow: hidden;
  flex: 1;
  transition: var(--rf-transition-state);
}

.rftimeline-root .timeline__card-header {
  padding: var(--rf-card-header-pt) 16px var(--rf-card-header-pb);
  text-align: center;
}

.rftimeline-root .timeline__card-title {
  margin: 0;
  font-size: 30px;
  line-height: 36px;
  font-weight: 500;
  color: var(--rf-text-default);
  opacity: var(--rf-text-muted-opacity);
  transition: var(--rf-transition-state);
}

.rftimeline-root .timeline__card-body {
  margin: 8px var(--rf-card-body-margin) var(--rf-card-body-margin);
  padding: var(--rf-card-body-py) var(--rf-card-body-px);
  background: var(--rf-bg-body-default);
  border-radius: 16px;
  text-align: center;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--rf-transition-state);
}

.rftimeline-root .timeline__card-body p {
  margin: 0;
  font-size: 18px;
  line-height: 26px;
  color: var(--rf-text-default);
  opacity: var(--rf-text-body-opacity);
}

/* ---------- Distance-based states ---------- */
.rftimeline-root .timeline__slide.is-far .timeline__card {
  background: var(--rf-bg-far);
}
.rftimeline-root .timeline__slide.is-far .timeline__card-body {
  background: var(--rf-bg-body-on-color);
}
.rftimeline-root .timeline__slide.is-far .timeline__dot-inner {
  background: var(--rf-dot-far);
}

.rftimeline-root .timeline__slide.is-near .timeline__card {
  background: var(--rf-bg-near);
}
.rftimeline-root .timeline__slide.is-near .timeline__card-body {
  background: var(--rf-bg-body-default);
}
.rftimeline-root .timeline__slide.is-near .timeline__dot-inner {
  background: var(--rf-dot-near);
}

.rftimeline-root .timeline__slide.is-active .timeline__card {
  background: var(--rf-bg-active);
}
.rftimeline-root .timeline__slide.is-active .timeline__card-title {
  color: var(--rf-text-on-active);
  opacity: 1;
}
.rftimeline-root .timeline__slide.is-active .timeline__card-body {
  background: var(--rf-bg-body-on-color);
}
.rftimeline-root .timeline__slide.is-active .timeline__dot-inner {
  background: var(--rf-dot-near);
}

/* ---------- Visually hidden live region ---------- */
.rftimeline-root .timeline__live {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Tablet ----------
   Carousel slide-width 459px is wider than iPad portrait. Drop it to
   380px so 1.5–2.5 slides are visible and neighbour states read
   correctly. Typography scaled to suit the narrower viewport.
   At ≤1024px scroll-pinning is also disabled — touch scrolling into a
   horizontal pinned track fights the user's gesture, so we let the JS
   fall back to the standard tap/swipe carousel. */
@media (max-width: 1024px) {
  /* Collapse the pin-mode wrappers out of layout entirely so the
   * section sits in the DOM as if it were a direct child of
   * .rftimeline-root. */
  .rftimeline-root--pinned .rftimeline-scroller,
  .rftimeline-root--pinned .rftimeline-sticky {
    display: contents;
  }

  .rftimeline-root {
    --rf-slide-width: 380px;
    --rf-slide-gap: 32px;

    --rf-section-pad-top: 48px;
    --rf-section-pad-bottom: 60px;
    --rf-section-pad-x: 24px;

    --rf-card-header-pt: 24px;
    --rf-card-body-px: 24px;
  }

  .rftimeline-root .timeline-section__header {
    max-width: 540px;
  }

  .rftimeline-root .timeline-section__title {
    font-size: 36px;
    line-height: 44px;
    letter-spacing: -0.5px;
  }

  .rftimeline-root .timeline-section__subtitle {
    font-size: 16px;
    line-height: 22px;
  }

  .rftimeline-root .timeline__year {
    font-size: 22px;
    line-height: 28px;
  }

  .rftimeline-root .timeline__card-title {
    font-size: 24px;
    line-height: 30px;
  }

  .rftimeline-root .timeline__card-body p {
    font-size: 16px;
    line-height: 24px;
  }
}

/* ---------- Phone ----------
   Capped at 600px (not 768px) so the 322px header cap and the
   viewport-derived slide width inside this block — both sized for
   phone viewports — don't engage at iPad portrait. */
@media (max-width: 600px) {
  /* Edge-to-edge blue card on phones — drop the inner radius so the
     blue background runs to the screen edges. */
  .rftimeline-root .timeline-section__inner {
    border-radius: 0 !important;
  }

  .rftimeline-root {
    /* Mobile shows ~2% peek of the previous + next cards on each side
     * of the active slide. Derived from the carousel geometry:
     *   visible peek = (viewport - slide - 2*gap) / 2
     * Solving for 2% peek (visible = 0.02 * slide):
     *   slide_width = (viewport - 2 * gap) / 1.04
     * Peek scales with viewport width across all phone sizes. */
    --rf-slide-width: calc((100vw - 2 * var(--rf-slide-gap)) / 1.04);
    --rf-slide-gap: 16px;

    --rf-year-row-h: 25px;
    --rf-year-line-gap: 8px;
    --rf-dot-size: 16px;
    --rf-dot-inner-size: 10px;
    --rf-card-radius: 24px;

    --rf-card-header-pt: 16px;
    --rf-card-header-pb: 8px;
    --rf-card-body-margin: 8px;
    --rf-card-body-px: 16px;
    --rf-card-body-py: 16px;

    --rf-section-pad-top: 32px;
    --rf-section-pad-bottom: 56px;
    --rf-section-pad-x: 0px;

    --rf-header-bottom-gap: 40px;
    --rf-header-gap: 16px;
  }

  .rftimeline-root .timeline-section__header {
    max-width: 322px;
  }

  .rftimeline-root .timeline-section__title {
    font-size: 32px;
    line-height: 40px;
    letter-spacing: -0.32px;
  }

  .rftimeline-root .timeline-section__subtitle {
    font-size: 14px;
    line-height: 20px;
  }

  .rftimeline-root .timeline__year {
    font-size: 16px;
    line-height: 25px;
  }

  /* Mobile uses solid black titles + full-opacity body text instead
     of the muted desktop variant. */
  .rftimeline-root .timeline__card-title {
    color: #000;
    opacity: 1;
    font-size: 18px;
    line-height: 26px;
  }
  .rftimeline-root .timeline__slide.is-active .timeline__card-title {
    color: var(--rf-text-on-active);
  }
  .rftimeline-root .timeline__card-body p {
    opacity: 1;
    font-size: 14px;
    line-height: 20px;
  }
}

/* ---------- Reduced motion ----------
 * Also disengages scroll-pinning entirely so the section behaves like a
 * normal page-flow carousel that the user can navigate without forced
 * scroll capture. */
@media (prefers-reduced-motion: reduce) {
  .rftimeline-root .timeline__track {
    transition: none;
  }
  .rftimeline-root .timeline__slide,
  .rftimeline-root .timeline__card,
  .rftimeline-root .timeline__card-title,
  .rftimeline-root .timeline__card-body,
  .rftimeline-root .timeline__dot,
  .rftimeline-root .timeline__dot-inner,
  .rftimeline-root .timeline__year {
    transition: none;
  }

  .rftimeline-root--pinned .rftimeline-scroller,
  .rftimeline-root--pinned .rftimeline-sticky {
    display: contents;
  }

}
