/* ONE READING, drawn straight or round: title left, caption right, track below; `compact` folds them into
   one row, and the ring puts its header below with the figure inside. The fill is absolute in the track so
   animating it moves nothing else; `width: 0` is the indeterminate rest, since auto would paint a full
   bar. */
@layer theme, base, lotics, components, utilities;
@layer lotics.tokens, lotics.reset, lotics.components;

@layer lotics.components {
  .lotics-progress {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--lotics-space-8);
    min-width: 0;
    /* On the root, so a colour only the tone rules set inherits into a toneless nested meter. */
    --lotics-progress-color: var(--lotics-accent);
    --lotics-progress-complete-color: var(--lotics-tone-green-solid);
    /* One paint channel: the state's colour is decided here; each shape only names the property
       (`background`, `stroke`). */
    --lotics-progress-paint: var(--lotics-progress-color);
  }

  /* At the bound (Base UI's root state), or a quantity to reach at or past it, both indicators swap in one
     rule. */
  .lotics-progress[data-complete],
  .lotics-progress[data-reached] {
    --lotics-progress-paint: var(--lotics-progress-complete-color);
  }

  /* Short of its pass mark — a minimum not yet reached — the fill warns; at or past it, the calm fill. */
  .lotics-progress[data-short] {
    --lotics-progress-paint: var(--lotics-tone-amber-solid);
  }

  .lotics-progress[data-compact] {
    flex-direction: row;
    align-items: center;
    gap: var(--lotics-space-8);
    /* A bar takes the width it is given: auto resolves to min-content in a right-aligned cell and
       max-content with a track floor. */
    align-self: stretch;
    width: 100%;
  }

  /* A line has no width to give, so the track is fixed below. */
  .lotics-progress[data-inline] {
    flex: 0 0 auto;
    align-self: auto;
    /* Stretched in a grid cell, the figure's auto margin pushed it off its track. */
    justify-self: start;
    width: auto;
    gap: var(--lotics-space-4);
  }

  .lotics-progress__header {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    gap: var(--lotics-space-16);
    min-width: 0;
  }

  /* Flex, so the box is the run's line box; a block around inline `Text` adds a strut. */
  .lotics-progress__label {
    display: flex;
    min-width: 0;
  }

  /* Its own margin pushes it to the far edge; it is alone on that side. */
  .lotics-progress__value {
    display: flex;
    margin-inline-start: auto;
  }

  /* A figure is one token with its unit (`860/1,200` over a lone `kg` is two readings); two classes to
     outrank `Text`'s wrapping. */
  .lotics-progress[data-compact] .lotics-progress__caption {
    white-space: nowrap;
  }

  /* A count one digit longer shortens its own track, so the slot is constant down the column — its widest
     figure where measured — and held empty for `caption={null}`, so every track starts and ends at one x.
     A floor, not a clamp. */
  .lotics-progress[data-compact] .lotics-progress__value {
    min-width: var(--lotics-progress-figure, 9ch);
    /* A longer count spends the track, not its unit. */
    flex-shrink: 0;
    /* Digits end at one edge down a column, a meter's and a plain figure's alike; the tracks still start
       and end at one x, the slot being constant. */
    justify-content: flex-end;
  }

  /* 10px reads as a meter, not a hairline; the full-rung radius is the half-height cap. */
  .lotics-progress__track {
    position: relative;
    display: flex;
    flex-direction: row;
    align-items: stretch;
    height: var(--lotics-progress-thickness);
    border-radius: var(--lotics-radius-full);
    background: var(--lotics-progress-track, var(--muted));
    overflow: hidden;
    /* A hairline inner edge makes a groove, not a grey strip. */
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--lotics-shadow-color) 4%, transparent);
  }

  /* The track clips its fill, so the marks belong to the rail, outside the clip. */
  .lotics-progress__rail {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--lotics-space-6);
    min-width: 0;
  }

  .lotics-progress[data-compact] .lotics-progress__rail {
    /* A basis, not a floor: a shrink-to-fit parent leaves `flex: 1` nothing to divide, and a 64 minimum
       could not give way. The figure's slot may not shrink (a cut number is wrong), so the squeeze lands
       here. */
    flex: 1 1 64px;
    min-width: 0;
  }

  /* No groove — an empty track reads as zero — but its room kept, so the figure starts where bounded
     neighbours' do. */
  .lotics-progress[data-compact][data-unbounded] .lotics-progress__track {
    visibility: hidden;
  }

  /* One length per line, so meters compare. */
  .lotics-progress[data-inline] .lotics-progress__rail {
    flex: 0 0 var(--lotics-space-48);
  }

  .lotics-progress__indicator {
    position: absolute;
    top: 0;
    height: 100%;
    width: 0;
    border-radius: var(--lotics-radius-full);
    background: var(--lotics-progress-paint);
    transition-property: width, background-color;
    transition-duration: var(--lotics-duration-base);
    transition-timing-function: var(--lotics-ease-standard);
  }

  /* Two shapes so neither is mistaken for the other at any fill or length; each centred on its share,
     outside the track. */
  .lotics-progress__pace,
  .lotics-progress__gate {
    position: absolute;
    left: var(--lotics-progress-tick);
    translate: -50% 0;
  }

  /* A downward caret in muted ink — a schedule's "today", the mark that moves. */
  .lotics-progress__pace {
    top: calc(var(--lotics-space-6) * -1);
    width: var(--lotics-space-8);
    height: var(--lotics-space-6);
    background: var(--muted-foreground);
    clip-path: polygon(0 0, 100% 0, 50% 100%);
  }

  /* A rule in the page's ink proud of both edges — a bullet graph's target — louder than the pace because
     it does not move. */
  .lotics-progress__gate {
    top: calc(var(--lotics-space-4) * -1);
    width: var(--lotics-space-2);
    height: calc(var(--lotics-progress-thickness) + 2 * var(--lotics-space-4));
    border-radius: var(--lotics-radius-full);
    background: var(--foreground);
  }

  /* Its anchor slides with the mark (left edge at 0, right at 100), so it never overruns the track. */
  .lotics-progress__gate-label {
    display: flex;
    align-self: flex-start;
    margin-left: var(--lotics-progress-tick);
    translate: calc(var(--lotics-progress-tick) * -1) 0;
    /* Its own length; the translate brings it back inside. */
    width: max-content;
    white-space: nowrap;
  }

  /* A toned meter at zero would look like no reading, so the fill floors at the track's thickness — the
     round cap it starts with. */
  .lotics-progress[data-tone][data-shape="bar"] .lotics-progress__indicator {
    min-width: var(--lotics-progress-thickness);
  }

  /* The verdict's fills live here; they move the component's properties, so both shapes follow and an
     inline `color` still wins. */
  .lotics-progress[data-tone="warning"] {
    --lotics-progress-color: var(--lotics-tone-amber-solid);
    --lotics-progress-complete-color: var(--lotics-tone-amber-solid);
  }
  .lotics-progress[data-tone="danger"] {
    --lotics-progress-color: var(--lotics-tone-red-solid);
    --lotics-progress-complete-color: var(--lotics-tone-red-solid);
  }

  /* An allocation is entered, not watched: no transition, since a fading-in red is a late verdict. */
  .lotics-progress[data-verdict] .lotics-progress__indicator {
    transition: none;
  }

  .lotics-progress[data-verdict="exact"] {
    --lotics-progress-paint: var(--lotics-tone-emerald-solid);
  }

  .lotics-progress[data-verdict="over"] {
    --lotics-progress-paint: var(--lotics-tone-red-solid);
  }

  /* Each share is data turned into `flex-grow`; the shortfall paints nothing, showing the track as the
     unfilled tail. */
  .lotics-progress__segment,
  .lotics-progress__remainder {
    flex-grow: var(--lotics-progress-weight);
    flex-basis: 0;
  }

  .lotics-progress__segment {
    background-color: var(--lotics-progress-color);
  }

  /* Header below, figure inside; the track owns the size. */
  .lotics-progress[data-shape="ring"] {
    align-items: center;
    gap: var(--lotics-space-12);
  }

  .lotics-progress[data-shape="ring"] .lotics-progress__track {
    order: 1;
    position: relative;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: var(--lotics-progress-size);
    height: var(--lotics-progress-size);
    border-radius: var(--lotics-radius-full);
    background: none;
    box-shadow: none;
  }

  .lotics-progress[data-shape="ring"] .lotics-progress__header {
    order: 2;
    flex-direction: column;
    align-items: center;
    gap: var(--lotics-space-2);
  }

  .lotics-progress[data-shape="ring"] .lotics-progress__value {
    margin-inline-start: 0;
  }

  .lotics-progress__ring {
    fill: none;
    stroke: var(--lotics-progress-track, var(--muted));
  }

  .lotics-progress[data-shape="ring"] .lotics-progress__indicator {
    position: static;
    width: auto;
    height: auto;
    fill: none;
    stroke: var(--lotics-progress-paint);
    stroke-linecap: round;
  }

  /* On the drawing, so it stays put whatever the arc does. */
  .lotics-progress__figure {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
