/*
 * A DAY AT A TIME. The day head sits on the list's own left edge and the stops
 * run under it — no column headings, no fit budget. What the eye is given
 * instead is ONE RIGHT EDGE: the figure is the LAST track of a stop's first line
 * and is right-aligned, so every day's figures, every day total and the closing
 * total end on the container's own edge.
 *
 * ONE STOP IS TWO LINES, AT EVERY WIDTH — the title with its figure, then the
 * muted qualifiers. TWO, NEVER THREE: the muted line holds one line at every
 * width, and the caption is the one run that gives way (composition.md § "Type
 * and space at the call site").
 *
 * THE SPINE IS A VARIANT, not a second device: it inserts one leading track and
 * changes nothing else. Its anatomy is `ReorderItem`'s rail.
 */
@layer theme, base, lotics, components, utilities;
@layer lotics.tokens, lotics.reset, lotics.components;

@layer lotics.components {
  .lotics-itinerary {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-width: 0;
  }

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

  /* Air BETWEEN days, never above the first: one floating under the section
     heading reads as a second heading. */
  .lotics-itinerary__day + .lotics-itinerary__day {
    margin-top: var(--lotics-space-16);
  }

  .lotics-itinerary__dayhead {
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-shrink: 0;
    min-width: 0;
    gap: var(--lotics-space-8);
    min-height: var(--lotics-register-row);
  }

  /* THE DATE NEVER GIVES WAY: it is the run's whole subject. */
  .lotics-itinerary__date {
    flex-shrink: 0;
  }

  /* THE COUNT TAKES THE SLACK, so the verb and the day's own total land on the
     right edge without either of them owning a `margin-left: auto`. */
  .lotics-itinerary__count {
    flex: 1;
    min-width: 0;
  }

  .lotics-itinerary__add {
    flex-shrink: 0;
  }

  /* The day's sum ends on the same edge its stops' figures do. */
  .lotics-itinerary__daytotal {
    display: block;
    flex-shrink: 0;
    white-space: nowrap;
  }

  .lotics-itinerary__rows {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    flex-shrink: 0;
    min-width: 0;
    gap: var(--lotics-space-4);
  }

  /* NO GAP UNDER A SPINE, because the line has to arrive at the next stop's
     leading segment with nothing between them. The band a two-line item stands
     in is what separates one stop from the next, and no stop pads its own bottom
     to buy the gap back (a sheet reading the register band states no height of
     its own, `css_contract.test.ts`). */
  .lotics-itinerary__rows[data-spine] {
    gap: 0;
  }

  /* TWO CLASSES DEEP, because a stop is a `PressableRow` when it opens something
   *  and a plain box when it does not: the pressable's own rule lays a flex row
   *  out at one class, and a tie between two component sheets is decided by
   *  whichever the bundler emitted first. */
  .lotics-itinerary .lotics-itinerary__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "title figure"
      "meta meta";
    /* BASELINE, not centre: the figure shares the title's FIRST line, and two
       boxes of different height centred in one grid row share no baseline. */
    align-items: baseline;
    /* CENTRED rather than stretched: grid's default hands each auto row half the
       slack, which pushes the qualifiers away from the title. */
    align-content: center;
    column-gap: var(--lotics-space-12);
    row-gap: var(--lotics-space-2);
    /* THE BAND, composed from the tokens. It is the box's own height rather than
       padding, so the wash a `PressableRow` draws covers the whole item — and a
       register states no band of its own (`css_contract.test.ts` §
       register-band). */
    min-height: calc(var(--lotics-register-row) + var(--lotics-space-24));
  }

  /* ONE TRACK MORE and nothing else. The track is RESERVED and the rail is laid
     over it, because a grid item's box is its grid AREA — the centred two-line
     block, which is shorter than the band the stop stands in, so a rail inside
     it would stop short of the next stop. */
  .lotics-itinerary .lotics-itinerary__row[data-spine] {
    position: relative;
    grid-template-columns: 12px minmax(0, 1fr) auto;
    grid-template-areas:
      "rail title figure"
      "rail meta meta";
  }

  /* THE CONTINUATION MARK — not a stop: no band, no figure, no door. */
  .lotics-itinerary .lotics-itinerary__row[data-continues] {
    align-items: center;
    min-height: var(--lotics-space-24);
  }

  /* ─── the spine ────────────────────────────────────────────────────────── */

  .lotics-itinerary__rail {
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 12px;
  }

  .lotics-itinerary__segment {
    flex-shrink: 0;
    width: 1px;
    background: var(--border);
  }

  /* THE MIDDLE OF THE BAND, LESS HALF A LINE — where the title's first line
     sits. A fixed offset rather than the content's own, so a title that wraps to
     two lines does not drag its node down with it. */
  .lotics-itinerary__segment[data-position="lead"] {
    height: calc((var(--lotics-register-row) + var(--lotics-space-16)) / 2 - var(--lotics-space-10));
  }

  /* Fills the rest of the stop, INCLUDING its bottom padding, so the line
     reaches the next stop's leading segment. */
  .lotics-itinerary__segment[data-position="fill"] {
    flex: 1;
    min-width: 0;
  }

  /* A STAY, RUNNING ON — wider than the line, because it says the stop is still
     happening rather than that another one follows. */
  .lotics-itinerary__segment[data-running] {
    width: 3px;
    background: var(--lotics-itinerary-node, var(--lotics-tone-zinc-solid));
  }

  /* The ends are TRANSPARENT rather than absent: every stop then keeps one
     geometry and the nodes stay on one x. A bar that runs on keeps its ink. */
  .lotics-itinerary__row:first-child .lotics-itinerary__segment[data-position="lead"]:not([data-running]),
  .lotics-itinerary__row:last-child .lotics-itinerary__segment[data-position="fill"]:not([data-running]) {
    background: transparent;
  }

  .lotics-itinerary__dot {
    flex-shrink: 0;
    width: 7px;
    height: 7px;
    border-radius: var(--lotics-radius-full);
    background: var(--lotics-itinerary-node, var(--lotics-tone-zinc-solid));
  }

  /* A STOP THAT DID NOT HAPPEN reads as an outline: filled, the node claims the
     trip passed through it. The colour stays — the kind is still true. */
  .lotics-itinerary__dot[data-hollow] {
    background: var(--background);
    box-shadow: inset 0 0 0 2px var(--lotics-itinerary-node, var(--lotics-tone-zinc-solid));
  }

  /* ─── the stop's two lines ─────────────────────────────────────────────── */

  /* NOT CLAMPED, and free to wrap: the title is what the stop IS. */
  .lotics-itinerary__title {
    grid-area: title;
    min-width: 0;
  }

  /* THE CONTINUATION'S ONE LINE, in the title's own track — the name is the only
     thing on it that can give. */
  .lotics-itinerary__continues {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    grid-area: title;
    min-width: 0;
    gap: var(--lotics-space-4);
  }

  /* The name gives: it is stated in full on the stop one row up. */
  .lotics-itinerary__stay {
    min-width: 0;
  }

  /* ...AND THE WORD DOES NOT: a name alone under a stop reads as the stay
     happening twice. */
  .lotics-itinerary__running {
    flex-shrink: 0;
    white-space: nowrap;
  }

  /* THE SECOND LINE, ONE LINE at every width: the caption is the only run that
     gives way. Clipped rather than spilling, because an itinerary that scrolls
     horizontally has stopped being a list. */
  .lotics-itinerary__meta {
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    grid-area: meta;
    min-width: 0;
    overflow: hidden;
    gap: var(--lotics-space-8);
  }

  /* THE TIME LEADS, because a day's run is scanned by WHEN — but holds no
     column: an UNTIMED stop's empty box would still take the gutter and indent
     its qualifiers against the timed ones. The figures are tabular already
     (`reset.css`), so the times stack with no track to hold them. */
  .lotics-itinerary__slot {
    flex-shrink: 0;
  }

  .lotics-itinerary__slot:empty {
    display: none;
  }

  .lotics-itinerary__kind {
    flex-shrink: 0;
  }

  /* THE RUN THAT GIVES WAY — the decision the line's one-line rule rests on. */
  .lotics-itinerary__caption {
    flex-shrink: 1;
    min-width: 0;
  }

  .lotics-itinerary__stage {
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-shrink: 0;
    min-width: 0;
    gap: var(--lotics-space-6);
  }

  /* THE QUIET STAGE'S MARK — the size the kit's status dot is. */
  .lotics-itinerary__stage-mark {
    flex-shrink: 0;
    width: 6px;
    height: 6px;
    border-radius: var(--lotics-radius-full);
    background: var(--lotics-itinerary-mark, var(--lotics-tone-zinc-solid));
  }

  /* The booking code is quoted, so it never breaks across lines. */
  .lotics-itinerary__reference {
    flex-shrink: 0;
    white-space: nowrap;
  }

  /* MONEY NEVER WRAPS: a figure broken across two lines stops being one
     number. */
  .lotics-itinerary__figure {
    grid-area: figure;
    white-space: nowrap;
  }

  .lotics-itinerary__more {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
    min-width: 0;
    gap: var(--lotics-space-12);
    margin-top: var(--lotics-space-12);
  }

  /* The closing line lands on the SAME edge every figure ends on. */
  .lotics-itinerary__total {
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-shrink: 0;
    min-width: 0;
    gap: var(--lotics-space-12);
    margin-top: var(--lotics-space-12);
    /* The band, from the token — the closing line is a row of the list. */
    min-height: var(--lotics-register-row);
    border-top: 1px solid var(--border);
  }

  .lotics-itinerary__total-label {
    display: block;
    flex: 1;
    min-width: 0;
  }

  .lotics-itinerary__total-value {
    display: block;
    flex-shrink: 0;
    white-space: nowrap;
  }
}
