/*
 * ONE ANATOMY, TWO AXES. A step is a gutter (the marker between two spine
 * segments) beside its content; horizontally the same three boxes lie on their
 * side, so `data-orientation` turns the run rather than forking it.
 *
 * The spine is TWO segments per step because the marker centres on the content's
 * FIRST ROW, not on the top of the box: the upper segment fills the band above
 * the node, so the line is continuous from the first marker to the last.
 *
 * `--lotics-stepper-node` is the one number the geometry derives from — the
 * marker's diameter, and deliberately `Checkbox`'s own box.
 */
@layer theme, base, lotics, components, utilities;
@layer lotics.tokens, lotics.reset, lotics.components;

@layer lotics.components {
  .lotics-stepper,
  .lotics-stepper__marker {
    --lotics-stepper-node: 24px;
  }

  .lotics-stepper {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-width: 0;
    list-style: none;
  }

  .lotics-stepper[data-orientation="horizontal"] {
    flex-direction: row;
  }

  .lotics-stepper__step {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-width: 0;
  }

  .lotics-stepper__step[data-orientation="horizontal"] {
    flex: 1;
  }

  .lotics-stepper__item {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    /* 6 — the gap between a marker and the words it belongs to. */
    gap: var(--lotics-space-6);
    min-width: 0;
  }

  /* Each step rises + fades in on mount, so a streamed feed reads as steps
     APPEARING rather than popping in. */
  .lotics-stepper__step[data-orientation="vertical"] .lotics-stepper__item {
    animation: lotics-stepper-step-in var(--lotics-duration-slow) var(--lotics-ease-standard);
  }

  @keyframes lotics-stepper-step-in {
    from {
      opacity: 0;
      transform: translateY(6px);
    }
    to {
      opacity: 1;
      transform: none;
    }
  }

  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__item {
    flex-direction: column;
    align-items: center;
    gap: var(--lotics-space-8);
    width: 100%;
  }

  .lotics-stepper__gutter {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex-shrink: 0;
    width: var(--lotics-stepper-node);
  }

  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__gutter {
    flex-direction: row;
    width: 100%;
  }

  .lotics-stepper__spine {
    flex-shrink: 0;
    background: transparent;
  }

  .lotics-stepper__spine[data-line] {
    background: var(--border);
  }

  .lotics-stepper__step[data-orientation="vertical"] .lotics-stepper__spine {
    width: 1.5px;
    border-radius: var(--lotics-radius-full);
  }

  /* The band above the node, exactly as tall as the offset that centres the
     marker on the content's first row. */
  .lotics-stepper__step[data-orientation="vertical"] .lotics-stepper__spine[data-before] {
    height: var(--lotics-stepper-marker-offset);
  }

  /* No top margin: the segment starts AT the marker, or the line detaches from
     the node it is supposed to leave. */
  .lotics-stepper__step[data-orientation="vertical"] .lotics-stepper__spine:not([data-before]) {
    flex: 1;
    min-height: 14px;
  }

  .lotics-stepper__step[data-orientation="vertical"] .lotics-stepper__spine[data-line][data-filled] {
    background: var(--lotics-wash-control-press);
  }

  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__spine {
    flex: 1;
    height: 2px;
  }

  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__spine[data-filled] {
    background: var(--lotics-stepper-color, var(--primary));
  }

  .lotics-stepper__marker {
    position: relative;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: var(--lotics-stepper-node);
    height: var(--lotics-stepper-node);
    border: 0 solid transparent;
    border-radius: var(--lotics-radius-full);
    background: var(--card);
    /* The glyph inside strokes the node's own ink. */
    color: var(--lotics-white);
  }

  /* What's ahead: a faint ring on the card ground. */
  .lotics-stepper__marker[data-status="upcoming"] {
    border-width: 1.5px;
    border-color: var(--input);
  }

  /* WHERE YOU ARE — a ring in the run's own ink, thicker than the faint one
     every stage ahead of it wears, and the one thing on the run painted at full
     contrast. Not a solid disc: a walk of identical discs makes the eye find the
     current stage by its MISSING check. */
  .lotics-stepper__marker[data-status="current"] {
    border-width: 2.5px;
    border-color: var(--lotics-stepper-color, var(--primary));
  }

  /* TICKED: the filled disc a checked box makes, for a run whose passed steps
     are a track behind the reader. */
  .lotics-stepper__marker[data-status="done"] {
    background: var(--lotics-stepper-color, var(--primary));
  }

  /* PASSED, REPORTED — a ring spending its ink on the check instead of a fill,
     and the terminal "Done". What a run that only REPORTS wears behind the
     reader, so the history does not outweigh the stage the record is in. */
  .lotics-stepper__marker[data-status="complete"] {
    border-width: 2px;
    border-color: var(--primary);
    color: var(--lotics-ink-default);
  }

  .lotics-stepper__marker[data-status="warning"] {
    background: var(--lotics-tone-amber-solid);
  }

  /* A decided negative: the done disc's shape in the kit's danger hue, so only
     the colour says which way it went. */
  .lotics-stepper__marker[data-status="fail"] {
    background: var(--lotics-tone-red-solid);
  }

  /* The slot a real control sits in — a `Checkbox`, in either shape, draws its
     own face, so the node keeps only the box that holds the column's rhythm. */
  .lotics-stepper__marker[data-control] {
    border-width: 0;
    background: transparent;
  }

  .lotics-stepper__pulse {
    position: absolute;
    width: var(--lotics-stepper-node);
    height: var(--lotics-stepper-node);
    border: 2px solid var(--lotics-stepper-color, var(--primary));
    border-radius: var(--lotics-radius-full);
    pointer-events: none;
    animation-name: lotics-stepper-pulse;
    /* A 1500ms breath — six and a quarter rungs of the slow duration, so the
       whole rhythm moves if the token does. */
    animation-duration: calc(var(--lotics-duration-slow) * 6.25);
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }

  /* An INFINITE animation is what the duration tokens cannot retime: collapsed to
     1ms the halo strobes instead of stopping — see docs/theming.md §2.3. */
  @media (prefers-reduced-motion: reduce) {
    .lotics-stepper__pulse {
      animation: none;
    }
  }

  @keyframes lotics-stepper-pulse {
    from {
      transform: scale(1);
      opacity: 0.35;
    }
    to {
      transform: scale(2.2);
      opacity: 0;
    }
  }

  .lotics-stepper__bar {
    width: 8px;
    height: 2px;
    border-radius: var(--lotics-radius-full);
    background: currentColor;
  }

  .lotics-stepper__content {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    flex: 1;
    min-width: 0;
    /* The gap BETWEEN steps of a vertical run, overridable through the same
       property `Stepper`'s `gap` writes inline. It has to beat the spacing
       INSIDE a step, or the groups stop reading as groups. */
    --lotics-stepper-gap: var(--lotics-space-16);
  }

  .lotics-stepper__step[data-orientation="vertical"]:not([data-last]) .lotics-stepper__content {
    padding-bottom: var(--lotics-stepper-gap);
  }

  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__content {
    align-items: center;
    flex: 0 0 auto;
  }

  .lotics-stepper__press {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-width: 0;
    border: 0 solid transparent;
    border-radius: calc(var(--lotics-radius-control) - var(--lotics-space-2));
    background: transparent;
    background-image: none;
    appearance: none;
    color: var(--lotics-ink-default);
    font-family: var(--font-sans);
    font-size: var(--lotics-text-sm);
    line-height: var(--lotics-leading-sm);
    letter-spacing: var(--lotics-tracking-sm);
    font-weight: var(--lotics-weight-regular);
    font-feature-settings: var(--lotics-font-features);
    text-align: start;
    /* The ARROW: a step is a button wrapped around DATA, and its text is read. */
    cursor: auto;
    touch-action: manipulation;
    transition: background-color var(--lotics-duration-fast) var(--lotics-ease-standard);
  }

  /* ONE box carries the wash in every state — the press horizontally, the row
     vertically. `data-active` rides every part of the step and the wash tokens
     are translucent, so a nested pair composites to twice the strength. */
  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__press:not([data-active]):hover {
    background: var(--lotics-wash-hover);
  }

  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__press[data-active] {
    background: var(--lotics-wash-selected);
  }

  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__press:active {
    background: var(--lotics-wash-press);
  }

  .lotics-stepper__press:focus-visible {
    outline: var(--lotics-ring-width) solid var(--ring);
    outline-offset: 0;
  }

  /* The wash bleeds a row inset outward, so a pressed row highlights past its
     text while the text keeps the run's own left edge. */
  .lotics-stepper__step[data-orientation="vertical"] .lotics-stepper__press {
    margin-inline: calc(var(--lotics-space-10) * -1);
  }

  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__press {
    width: 100%;
    padding-block: var(--lotics-space-4);
  }

  .lotics-stepper__row {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-width: 0;
    border-radius: calc(var(--lotics-radius-control) - var(--lotics-space-2));
    /* 10 and 2 — the row box's own inset, which is what puts a step's text on
       `STEP_TEXT_COLUMN`, and the sliver above its first line. */
    padding-inline: var(--lotics-space-10);
    padding-block: var(--lotics-space-2);
    background: transparent;
  }

  /* The inset exists for the hover/active WASH, so a markerless row — a group
     heading, which shows no wash — pays nothing for it. */
  .lotics-stepper__row:not([data-marker]) {
    padding-inline: 0;
  }

  .lotics-stepper__step[data-orientation="vertical"]
    .lotics-stepper__press:hover
    .lotics-stepper__row:not([data-active]) {
    background: var(--lotics-wash-hover);
  }

  .lotics-stepper__step[data-orientation="vertical"] .lotics-stepper__row[data-active] {
    background: var(--lotics-wash-selected);
  }

  .lotics-stepper__step[data-orientation="vertical"] .lotics-stepper__press:active
    .lotics-stepper__row {
    background: var(--lotics-wash-press);
  }

  .lotics-stepper__step[data-orientation="horizontal"] .lotics-stepper__row {
    padding: 0;
    border-radius: 0;
  }
}
