.track-viewport {
  position: fixed;
  inset: 0;
  overflow: hidden;
}

.track {
  height: 100%;
  display: flex;
  flex-direction: row;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.track::-webkit-scrollbar { display: none; }

.connector-layer {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}

.slide {
  position: relative;
  flex: 0 0 100vw;
  width: 100vw;
  height: 100%;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-5) var(--space-4);
  z-index: 1;
  opacity: 0.3;
  transform: scale(0.92) translateY(18px);
  filter: blur(2px);
  transition: opacity 800ms cubic-bezier(0.16, 1, 0.3, 1),
              transform 800ms cubic-bezier(0.16, 1, 0.3, 1),
              filter 800ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform, filter;
}

.slide.is-active {
  opacity: 1;
  transform: scale(1) translateY(0);
  filter: blur(0);
}

.slide-inner {
  width: min(1040px, 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  text-align: center;
}

.slide-inner.align-left { align-items: flex-start; text-align: left; }

/* ---------- title slide reveal (letters like handwriting / opening a letter) ---------- */
@keyframes letter-in {
  0% { opacity: 0; transform: translateY(16px) rotate(3deg); filter: blur(2px); }
  100% { opacity: 1; transform: translateY(0) rotate(0); filter: blur(0); }
}
.letter-in {
  display: inline-block;
  animation: letter-in 620ms cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(260ms + var(--i) * 26ms);
}
@keyframes reveal-block {
  0% { opacity: 0; transform: translateY(10px); }
  100% { opacity: 1; transform: translateY(0); }
}
.reveal-block {
  opacity: 0;
  animation: reveal-block 700ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* ---------- title slide ---------- */
.title-slide .eyebrow { margin-bottom: var(--space-2); }
.title-slide h1 {
  font-size: clamp(3rem, 9vw, 6.4rem);
  line-height: 0.98;
}
.title-slide .subtitle {
  font-family: var(--font-script);
  font-style: italic;
  font-size: clamp(1.15rem, 2.4vw, 1.6rem);
  color: var(--ink-secondary);
  margin-top: var(--space-2);
}
.title-slide .signature {
  margin-top: var(--space-5);
  font-size: 1rem;
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
}
/* De: (her, pink) / Para: (him, blue) -- same rule reused on the closing slide */
.signature .script:first-child { color: var(--her); }
.signature .script:last-child { color: var(--him); }
.title-slide .date {
  margin-top: var(--space-2);
  font-family: var(--font-body);
  font-size: 0.85rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* ---------- closing slide ---------- */
.closing-slide .slide-inner {
  position: relative;
  z-index: 1;
}
.closing-heart {
  font-size: clamp(4.5rem, 14vw, 8.5rem);
  margin-bottom: var(--space-2);
  filter: drop-shadow(0 6px 18px rgba(204, 86, 181, 0.35));
}
.closing-slide h2 {
  font-size: clamp(2.2rem, 6vw, 3.4rem);
}
.closing-slide .subtitle {
  font-family: var(--font-script);
  font-style: italic;
  font-size: clamp(1.1rem, 2.2vw, 1.4rem);
  color: var(--ink-secondary);
  max-width: 42ch;
}

/* heart confetti: bursts from the top, falls, piles at the bottom, then sways gently */
.confetti-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.confetti-particle {
  position: absolute;
  top: 6%;
  left: 50%;
  opacity: 0;
}
.confetti-layer.is-playing .confetti-particle {
  animation: confetti-fall var(--dur, 2.2s) var(--delay, 0s) cubic-bezier(0.32, 0, 0.67, 0) forwards;
}
.confetti-inner {
  display: block;
  animation: confetti-sway 3.2s ease-in-out infinite;
  animation-delay: var(--dur, 2.2s);
  transform-origin: center;
}
@keyframes confetti-fall {
  0% { opacity: 0; transform: translate(-50%, 0) scale(0.5) rotate(0deg); }
  8% { opacity: 1; }
  24% { transform: translate(calc(-50% + var(--bx)), var(--by)) scale(1) rotate(var(--rot)); }
  100% { transform: translate(calc(-50% + var(--lx)), var(--ly)) scale(0.9) rotate(var(--rot)); }
}
@keyframes confetti-sway {
  0%, 100% { transform: rotate(-7deg); }
  50% { transform: rotate(7deg); }
}

/* ---------- generic chart slide chrome ---------- */
.slide-heading {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  gap: 6px;
  margin: 0 auto var(--space-2);
  text-align: center;
}
.slide-heading h2 {
  font-size: clamp(1.7rem, 3.6vw, 2.6rem);
}
.slide-heading .lede {
  color: var(--ink-secondary);
  font-size: 1rem;
  max-width: 46ch;
}
.slide-caveat {
  font-size: 0.78rem;
  color: var(--ink-muted);
  max-width: 52ch;
  margin-top: var(--space-2);
}

.chart-slot {
  width: 100%;
  position: relative;
}

/* ---------- scroll affordance ---------- */
.scroll-hint {
  position: fixed;
  bottom: var(--space-3);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  z-index: 5;
  opacity: 0.8;
  animation: hint-pulse 2.4s ease-in-out infinite;
}
@keyframes hint-pulse {
  0%, 100% { opacity: 0.4; transform: translate(-50%, 0); }
  50% { opacity: 0.9; transform: translate(-50%, 4px); }
}
.scroll-hint.is-hidden { display: none; }

.progress-rail {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--her), var(--him));
  z-index: 6;
  transition: width 300ms ease-out;
}

.dots {
  position: fixed;
  right: var(--space-2);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 6;
}
.dots button {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: none;
  background: var(--gridline);
  cursor: pointer;
  padding: 0;
  transition: background 200ms, transform 200ms;
}
.dots button.is-active {
  background: var(--him);
  transform: scale(1.5);
}

@media (max-width: 640px) {
  .slide { padding: var(--space-4) var(--space-2); }
  .dots { right: 6px; }
}
