/* Keep this timeline aligned with the InsightSpace website/slides counterpart.
   Only the container runs an animation. Every descendant samples its inherited
   progress, including fibers restored after a responsive display:none change. */
@property --extraction-progress {
  syntax: "<number>";
  inherits: true;
  initial-value: .85;
}

:is(.extraction-stage, .scan-animation) {
  --extraction-progress: .85;
  animation: extraction-cycle 8s linear infinite;
}

@keyframes extraction-cycle {
  from { --extraction-progress: 0; }
  to { --extraction-progress: 1; }
}

:is(.extraction-stage, .scan-animation) .scan-line {
  --scan-position: clamp(0, (var(--extraction-progress) - .09) / .59, 1);
  top: calc(8px + (100% - 18px) * var(--scan-position));
  opacity: min(clamp(0, (var(--extraction-progress) - .06) / .03, 1), clamp(0, (.72 - var(--extraction-progress)) / .04, 1));
}

/* A feathered strip travels through each fiber's mask. Its start follows the
   scanner down the input page; transit takes 22% of the same eight-second cycle. */
.flow-fiber-pulses .fiber-shimmer {
  --travel: clamp(0, (var(--extraction-progress) - var(--fiber-start)) / .22, 1);
  /* Hide the parked strip until the scanner arrives, then fade in over 40ms. */
  --ignition: clamp(0, (var(--extraction-progress) - var(--fiber-start)) / .005, 1);
  transform: translateX(calc(var(--travel) * 349px));
  opacity: calc(.86 * var(--ignition));
}
.flow-fiber-pulses > g { filter: drop-shadow(0 0 5px rgba(96,165,250,.9)); }
.flow-fiber-mask { fill: none; stroke: white; stroke-width: 3; stroke-linecap: round; }

:is(.extraction-stage, .scan-animation) .flow-stage-panel span {
  --enter: clamp(0, (var(--extraction-progress) - var(--stage-start)) / .03, 1);
  --leave: clamp(0, (var(--extraction-progress) - var(--stage-end)) / .03, 1);
  opacity: calc(var(--enter) - var(--leave));
  transform: translateY(calc((1 - var(--enter) - var(--leave)) * 4px));
}
.flow-stage-read { --stage-start: .08; --stage-end: .27; }
.flow-stage-layout { --stage-start: .30; --stage-end: .49; }
.flow-stage-figures { --stage-start: .52; --stage-end: .71; }

:is(.extraction-stage, .scan-animation) :is(.structured-heading, .structured-text, .structured-block) {
  --enter: clamp(0, (var(--extraction-progress) - var(--reveal-start)) / .04, 1);
  --remaining: calc(1 - var(--enter));
  --ease-out: calc(1 - var(--remaining) * var(--remaining) * var(--remaining));
  --leave: clamp(0, (var(--extraction-progress) - .94) / .04, 1);
  opacity: min(var(--ease-out), calc(1 - var(--leave)));
  transform: translateY(calc((1 - var(--ease-out)) * 4px));
}
.structured-heading { --reveal-start: .34; }
.structured-text { --reveal-start: .44; }
.structured-block.table-block { --reveal-start: .59; }
.structured-block.figure-block { --reveal-start: .74; }

@media (prefers-reduced-motion: reduce) {
  :is(.extraction-stage, .scan-animation) { animation: none; --extraction-progress: .85; }
  :is(.extraction-stage, .scan-animation) :is(.scan-line, .flow-fiber-pulses) { display: none; }
  :is(.extraction-stage, .scan-animation) .flow-stage-panel span { opacity: 0; transform: none; }
  :is(.extraction-stage, .scan-animation) .flow-stage-panel span:last-child { opacity: 1; }
}
