/*
 * WORK IN FLIGHT, in its two marks.
 *
 * `spinner` — ONE element, no SVG: the ring is a circular border at 20% of the
 * ink with its top edge at full strength, an outer diameter of `size` and a
 * stroke an eighth of it (3px at the default 24).
 *
 * `dots` — one keyframe timeline, three dots, one rung of stagger between them.
 * The rest at the end of the cycle is what makes it read as a breath rather than
 * a conveyor, and the gutter is derived from the dot rather than taken from the
 * spacing scale: it is the dot's own proportion (two fifths of it), and a rung
 * would space a 6px dot and a 14px dot identically.
 *
 * `currentColor` is what makes the colour one declaration in either mark: the
 * caller's ink lands on `color`, and the ring, its arc and the dots all mix from
 * there.
 */
@layer theme, base, lotics, components, utilities;
@layer lotics.tokens, lotics.reset, lotics.components;

@layer lotics.components {
  .lotics-activity-indicator {
    color: var(--lotics-activity-indicator-color, var(--lotics-ink-default));
    /* An icon-scale mark never gives way on a row. */
    flex-shrink: 0;
  }

  /* ─── spinner — the ring ───────────────────────────────────────────────── */

  .lotics-activity-indicator[data-variant="spinner"] {
    display: inline-block;
    width: var(--lotics-activity-indicator-size);
    height: var(--lotics-activity-indicator-size);
    border-style: solid;
    border-width: calc(var(--lotics-activity-indicator-size) / 8);
    border-color: color-mix(in srgb, currentColor 20%, transparent);
    border-top-color: currentColor;
    border-radius: var(--lotics-radius-full);
    animation-name: lotics-activity-indicator-spin;
    /* Three rungs of the travelling duration — 720ms a turn, slow enough to read
       as motion rather than as a flicker. */
    animation-duration: calc(var(--lotics-duration-slow) * 3);
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }

  /* ─── dots — the rhythm ────────────────────────────────────────────────── */

  .lotics-activity-indicator[data-variant="dots"] {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: calc(var(--lotics-activity-indicator-size) / 2.5);
  }

  .lotics-activity-indicator__dot {
    display: block;
    width: var(--lotics-activity-indicator-size);
    height: var(--lotics-activity-indicator-size);
    flex-shrink: 0;
    border-radius: var(--lotics-radius-full);
    background: currentColor;
    animation-name: lotics-activity-indicator-bounce;
    /* Ten rungs of the appearing duration — 1800ms, and one rung is the
       stagger, so the whole rhythm moves together if the token does. */
    animation-duration: calc(var(--lotics-duration-base) * 10);
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }

  .lotics-activity-indicator__dot:nth-child(2) {
    animation-delay: var(--lotics-duration-base);
  }

  .lotics-activity-indicator__dot:nth-child(3) {
    animation-delay: calc(var(--lotics-duration-base) * 2);
  }

  /* An INFINITE animation is what the duration tokens cannot retime: collapsed
     to 1ms the mark strobes instead of stopping — see docs/theming.md §2.3. */
  @media (prefers-reduced-motion: reduce) {
    .lotics-activity-indicator[data-variant="spinner"],
    .lotics-activity-indicator__dot {
      animation: none;
    }
  }

  @keyframes lotics-activity-indicator-spin {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
  }

  /* 8px of rise — the dot's own travel, not a gutter. */
  @keyframes lotics-activity-indicator-bounce {
    0% {
      transform: translateY(0);
    }
    16.67% {
      transform: translateY(-8px);
    }
    38.89% {
      transform: translateY(-8px);
    }
    55.56% {
      transform: translateY(0);
    }
    100% {
      transform: translateY(0);
    }
  }
}
