/*
 * Lab explainer player — v1
 *
 * Ships the chrome for every interactive explainer: play/pause, speed, the
 * clickable step track, and the step caption. Explainers declare scenes only;
 * they never implement playback themselves.
 *
 * Everything is namespaced `sl-` and themeable through the custom properties
 * below, so an explainer can restyle the controls without forking the player.
 */

sl-explainer {
  --sl-accent: var(--purple, #7C3AED);
  --sl-accent-soft: var(--purple-soft, #F1E9FE);
  --sl-ink: var(--ink, #1A1622);
  --sl-muted: var(--muted, #6B6577);
  --sl-border: var(--card-border, #EAE8EE);
  --sl-surface: #FFFFFF;
  --sl-track: var(--track-bg, #EDEBF2);
  --sl-fade: .55s;

  display: block;
}

/* --------------------------------------------------------------------------
 * Scenes
 *
 * Bare scenes swap instantly. Wrapping them in <sl-stage> stacks them in one
 * grid cell so they cross-fade and the stage sizes to the tallest scene.
 * ----------------------------------------------------------------------- */

sl-stage {
  display: grid;
  position: relative;
}

sl-scene {
  display: block;
}

sl-scene:not([active]) {
  display: none;
}

sl-stage > sl-scene {
  grid-area: 1 / 1;
  display: block;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--sl-fade) ease, visibility var(--sl-fade) ease;
}

sl-stage > sl-scene[active] {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  z-index: 2;
}

/*
 * Before the player boots, show the first scene only. Without this the page
 * paints every scene at once, and if the script fails to load the explainer
 * still renders as a sensible static image of step 1.
 */
sl-explainer:not([data-sl-ready]) sl-scene:first-of-type {
  display: block;
  opacity: 1;
  visibility: visible;
}

/* --------------------------------------------------------------------------
 * Controls: play/pause + speed
 * ----------------------------------------------------------------------- */

sl-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.sl-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
  margin: 0;
  padding: 10px 18px;
  border: 1px solid var(--sl-border);
  border-radius: 11px;
  background: var(--sl-surface);
  color: var(--sl-ink);
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  box-shadow: 0 1px 2px rgba(20, 16, 30, .05);
  cursor: pointer;
}

.sl-toggle:hover {
  border-color: #DAD6E4;
}

.sl-toggle__icon {
  font-size: 11px;
  letter-spacing: 1px;
  line-height: 1;
}

.sl-speed {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--sl-border);
  border-radius: 11px;
  background: var(--sl-surface);
  box-shadow: 0 1px 2px rgba(20, 16, 30, .05);
}

.sl-speed__label {
  padding: 0 6px 0 8px;
  color: var(--sl-muted);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.sl-speed__btn {
  min-width: 38px;
  height: 30px;
  margin: 0;
  padding: 0 6px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--sl-muted);
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  cursor: pointer;
}

.sl-speed__btn:hover {
  background: var(--sl-accent-soft);
  color: var(--sl-accent);
}

.sl-speed__btn[aria-pressed="true"] {
  background: var(--sl-accent);
  color: #fff;
}

/* --------------------------------------------------------------------------
 * Progress track + caption
 * ----------------------------------------------------------------------- */

sl-progress {
  display: block;
}

.sl-track {
  display: flex;
  gap: 6px;
  margin: 20px 0 14px;
}

.sl-seg {
  flex: 1;
  height: 5px;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: var(--sl-track);
  overflow: hidden;
  cursor: pointer;
  transition: transform .16s ease, box-shadow .16s ease;
}

.sl-seg:hover,
.sl-seg:focus-visible {
  transform: translateY(-1px);
  box-shadow: 0 0 0 3px rgba(124, 58, 237, .12);
  outline: none;
}

.sl-seg__fill {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 3px;
  background: var(--sl-accent);
  transform: scaleX(0);
  transform-origin: left center;
}

.sl-seg[data-state="past"] .sl-seg__fill {
  transform: scaleX(1);
}

/*
 * The fill animation doubles as the playback clock: the player advances on
 * `animationend`, so pausing the animation pauses the step. Duration is set
 * inline from the scene's dwell and the current speed.
 */
.sl-seg[data-state="current"] .sl-seg__fill {
  animation: sl-fill linear forwards;
  animation-duration: var(--sl-step-duration, 2600ms);
}

sl-explainer[data-sl-paused] .sl-seg__fill {
  animation-play-state: paused;
}

@keyframes sl-fill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.sl-caption {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0;
  font-size: 13.5px;
}

.sl-caption__num {
  flex-shrink: 0;
  color: var(--sl-accent);
  font-weight: 800;
}

.sl-caption__text {
  color: var(--sl-ink);
  font-weight: 500;
}

/* --------------------------------------------------------------------------
 * Reduced motion
 *
 * No cross-fade, no animated fill. The player also skips autoplay and falls
 * back to a timer-based clock, since `animationend` will not fire here.
 * ----------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  sl-stage > sl-scene {
    transition: none;
  }

  .sl-seg[data-state="current"] .sl-seg__fill {
    animation: none;
    transform: scaleX(1);
  }

  .sl-seg:hover,
  .sl-seg:focus-visible {
    transform: none;
  }
}
