@property --t {
  syntax: '<number>';
  inherits: false;
  initial-value: 0;
}

:root {
  color-scheme: light dark;
}

body {
  margin: 0;
  min-height: 100vh;
  display: grid;
  place-items: center;
  font-family: system-ui, sans-serif;
}

.hello {
  --hop: .5;       /* seconds per hop */
  --stagger: .4;   /* seconds between dots */
  --pause: 1;      /* seconds of rest after the last dot */
  --height: 2px;   /* jump height */
  --sharp: 1.5;    /* peak sharpness: 2 = parabola, 1 = triangle, lower = pointier */
  --dots: 3;
  --loop: calc((var(--dots) - 1) * var(--stagger) + var(--hop) + var(--pause));

  font-size: 32px;
  font-weight: 500;
  display: flex;
  align-items: baseline;
}

.dot {
  display: inline-block;
  animation: run calc(var(--loop) * 1s) linear infinite;
  --p: clamp(0, calc((var(--t) * var(--loop) - var(--i) * var(--stagger)) / var(--hop)), 1);
  transform: translateY(calc((1 - pow(abs(var(--p) * 2 - 1), var(--sharp))) * var(--height) * -1));
  will-change: transform;
}

@keyframes run {
  from { --t: 0; }
  to   { --t: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .dot {
    animation: none;
    transform: none;
    will-change: auto;
  }
}

