/* =========================================================
   mbrd - the Timeline: every board change as a step
   Docked along the foot of the window on every width. The
   board ends above it: ui/timeline-view.ts writes the bar's
   height to --dock, which #viewport and the bottom-anchored
   furniture add to their inset (chrome.css and the rest) -
   except while the bar is faded, when the board takes the
   band back (canvas.css, #viewport).
   Drawn after the history bar in Fusion 360: the marks sit
   close on a baseline, the playhead stands in the gap after
   the step shown, and a slim scrollbar of the page's own
   runs above (research/old/done-2026-09-15.md, R1, R2).
   ========================================================= */

#timeline-strip {
  position: fixed;
  z-index: var(--z-chrome);
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  /* The panels' inset at the sides (sidebar.css), so Play stands under the
     sidebar's edge and the gear under the header panel's. */
  padding: 4px max(var(--panel-inset), env(safe-area-inset-right))
           max(4px, env(safe-area-inset-bottom)) max(var(--panel-inset), env(safe-area-inset-left));
  min-height: var(--chrome-button-h);
  border-top: var(--hairline) solid var(--rule-2);
  background: var(--paper-card);
  -webkit-user-select: none;
  user-select: none;
  /* The quick half of the idle fade: coming back (chrome.css). */
  transition: opacity var(--dur-base) var(--ease);
}
#timeline-strip[hidden] { display: none; }

/* Play and the gear share one icon-button shape. */
#timeline-strip :is(.tl-play, .tl-gear) {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: var(--icon-button);
  height: var(--icon-button);
  padding: 0;
  border: 0;
  /* --leaf, not --radius-sm: standalone controls, not segments. */
  border-radius: var(--leaf);
  background: none;
  color: var(--ink-3);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
@media (hover: hover) {
  #timeline-strip :is(.tl-play, .tl-gear):not(:disabled):hover {
    background: var(--paper-2);
    color: var(--accent-deep);
  }
}
#timeline-strip :is(.tl-play, .tl-gear):not(:disabled):active { background: var(--paper-3); }
#timeline-strip :is(.tl-play, .tl-gear):focus-visible {
  background: var(--paper-2);
  color: var(--accent-deep);
}
#timeline-strip .tl-play:disabled { opacity: 0.35; cursor: default; }
#timeline-strip .tl-play[aria-pressed="true"] { color: var(--accent-deep); }
/* Both wear a button's edge, ground and lift. The gear was a bare icon (R33),
   and beside a bordered Play it read as a glyph, not something to press. */
#timeline-strip :is(.tl-play, .tl-gear) {
  border: var(--hairline) solid var(--rule-2);
  background: var(--paper);
  color: var(--ink-2);
  box-shadow: var(--shadow-1);
}
/* 16px, not --icon-glyph's 15: in the 26px inside of the button that leaves 5px
   a side, a whole pixel, and the 16-unit symbols draw one unit to the pixel.
   At 15 the glyph began at half a pixel, Firefox rounds that, and the two thin
   bars of Pause sat off centre. */
#timeline-strip :is(.tl-play, .tl-gear) svg {
  width: 16px;
  height: 16px;
}
/* The triangle's weight sits left of its box, so centred it reads as off to
   the left: one whole pixel right, which keeps it on the pixel grid above.
   Only while it shows Play - the two bars of Pause are centred as drawn. */
#timeline-strip .tl-play[aria-pressed="false"] svg { translate: 1px 0; }

/* Says something only when the history does not match the board. The step
   count it used to show ("5 of 8") went in R33: the playhead says where you
   are, and the marks say how many there are. */
#timeline-strip .tl-where {
  flex: none;
  font-size: var(--t-small);
  color: var(--ink-3);
}
#timeline-strip .tl-where:empty { display: none; }

/* While Play runs the board is read-only, and the tools that edit it are inert
   (paintPlay() in ui/timeline-view.ts). Dimmed, so they read as off. */
:root.is-replaying :is(#toolbar [inert], #history-ctl[inert], #drawer-btn[inert],
  #mobile-header-edit-btn[inert]) {
  opacity: 0.4;
}

/* Track dimensions, named so the rules below can do arithmetic on them. */
#timeline-strip {
  --tl-cell: 24px;     /* one mark's column */
  --tl-mark: 22px;     /* the mark inside it */
  --tl-start: 10px;    /* the start disc */
  --tl-gap: 8px;       /* between marks, and the playhead's room: its flag clears both */
  --tl-foot: 6px;      /* the baseline and its ticks, under the marks */
  --tl-bar: 4px;       /* the scrollbar */
  /* Between the scrollbar and the marks. 4 and not 3 so the rail is 38px, an
     even height: Play and the gear centre on it at a whole pixel, and at 37 the
     half pixel put the bars of Pause a pixel low in Firefox. */
  --tl-bar-gap: 4px;
}

/* The rail: the scrollbar over the track, and the playhead across both. */
#timeline-strip .tl-rail {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* The scrollbar, drawn by the page (paintScroll() in ui/timeline-view.ts).
   It keeps its room with nothing to scroll, so the bar's height, and with
   it --dock, holds still as steps arrive. */
#timeline-strip .tl-scroll {
  position: relative;
  flex: none;
  height: var(--tl-bar);
  margin-bottom: var(--tl-bar-gap);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  cursor: pointer;
}
/* A taller target than the line it draws. */
#timeline-strip .tl-scroll::before {
  content: '';
  position: absolute;
  inset: -4px 0 -3px;
}
#timeline-strip .tl-scroll.is-idle { visibility: hidden; }
#timeline-strip .tl-thumb {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--ink) 30%, transparent);
  touch-action: none;
  transition: background var(--dur-fast) var(--ease);
}
@media (hover: hover) {
  #timeline-strip .tl-scroll:hover .tl-thumb { background: color-mix(in srgb, var(--ink) 46%, transparent); }
}
#timeline-strip .tl-thumb.is-dragging { background: var(--accent); }

/* The track: one line of steps, scrolled by the bar above. The system's own
   scrollbar is hidden. */
#timeline-strip .tl-track {
  flex: none;
  display: flex;
  align-items: flex-start;
  gap: var(--tl-gap);
  /* Room after the newest step for the playhead that stands behind it. */
  padding: 0 var(--tl-gap) 0 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  /* By whole steps: ui/timeline-view.ts sizes the track to whole steps and
     scrolls it by them, and the snap holds a finger's pan to the same. */
  scroll-snap-type: x mandatory;
}
#timeline-strip .tl-track::-webkit-scrollbar { display: none; }

/* The playhead: in the gap after the step the board stands on, from the
   scrollbar down to the baseline, with a flag at the top to take hold of. */
#timeline-strip .tl-marker {
  position: absolute;
  top: calc(var(--tl-bar) + var(--tl-bar-gap) - 1px);
  bottom: 0;
  width: 10px;
  margin-left: -5px;
  /* A hand, not resize arrows: the playhead is a thing to pick up and move,
     and nothing about it changes size (R33). */
  cursor: grab;
  touch-action: none;
  z-index: 1;
}
#timeline-strip .tl-marker[hidden] { display: none; }
#timeline-strip .tl-marker::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 0;
  width: 6px;
  height: 5px;
  border-radius: 0 0 4px 4px;
  background: var(--accent);
}
#timeline-strip .tl-marker::after {
  content: '';
  position: absolute;
  left: 4px;
  top: 4px;
  bottom: 0;
  width: 2px;
  border-radius: 1px;
  background: var(--accent);
}
#timeline-strip .tl-marker.is-dragging { cursor: grabbing; }
#timeline-strip .tl-marker.is-dragging::before,
#timeline-strip .tl-marker.is-dragging::after { background: var(--accent-deep); }

/* One step: its mark above the baseline, and a tick down onto it. */
#timeline-strip .tl-step {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: var(--tl-cell);
  height: calc(var(--tl-cell) + var(--tl-foot));
  padding: calc((var(--tl-cell) - var(--tl-mark)) / 2) 0 0;
  border: 0;
  background: none;
  color: var(--ink-3);
  cursor: pointer;
  scroll-snap-align: start;
}
/* The baseline: a segment per step that meets its neighbours' in the gaps,
   so it scrolls with the marks. It starts and ends under the outer marks. */
#timeline-strip .tl-step::before {
  content: '';
  position: absolute;
  bottom: 0;
  left: calc(var(--tl-gap) / -2);
  right: calc(var(--tl-gap) / -2);
  height: var(--hairline);
  background: var(--rule-2);
}
#timeline-strip .tl-step:first-child::before { left: 50%; }
#timeline-strip .tl-step:last-child::before { right: 50%; }
/* The tick: one per step, standing on the baseline under its mark. */
#timeline-strip .tl-step::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  width: var(--hairline);
  height: calc(var(--tl-foot) - 2px);
  transform: translateX(-50%);
  background: var(--ink-3);
}
/* The arrow keys walk the steps from a focused mark (stepKeys()). */
#timeline-strip .tl-step:focus-visible { outline: none; }
#timeline-strip .tl-step:focus-visible .tl-dot {
  outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
  /* Inside the 1px the cell leaves above the mark, for the clip R34 names. */
  outline-offset: -1px;
}
#timeline-strip .tl-step.is-ahead::after { opacity: 0.42; }
#timeline-strip .tl-step.is-at::after { background: var(--ink-2); }

/* The mark: glyph for what was done, --tl-mark size. Round, and square at
   Harsh: --leaf left the 22px mark a pixel short of a circle at Middle. */
#timeline-strip .tl-step .tl-dot {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--tl-mark);
  height: var(--tl-mark);
  border-radius: var(--radius-pill);
  background: var(--paper-card);
  color: var(--ink-3);
  transition: color var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}
#timeline-strip .tl-step .tl-dot .ico { width: 14px; height: 14px; }
/* Ink veil on hover rather than paper step -- the mark fills with
   accent when current, so paper wash would add a fourth ground. */
@media (hover: hover) {
  /* No scale: the track clips above its marks (a scroller cannot overflow
     one way only), so a grown mark lost its top edge (R34). */
  #timeline-strip .tl-step:hover .tl-dot {
    background: color-mix(in srgb, var(--ink) 8%, transparent);
    color: var(--ink);
  }
}

/* Start of the board -- a plain disc, no glyph, level with the marks. */
#timeline-strip .tl-step:first-child .tl-dot {
  background: none;
  box-shadow: inset 0 0 0 5px var(--ink-3);
  border-radius: 50%;
  width: var(--tl-start);
  height: var(--tl-start);
  margin-top: calc((var(--tl-mark) - var(--tl-start)) / 2);
}
@media (hover: hover) {
  #timeline-strip .tl-step:first-child:hover .tl-dot {
    box-shadow: inset 0 0 0 5px var(--ink);
    background: none;
  }
}

/* Ahead of the playhead: present but faded -- a redo you can see. */
#timeline-strip .tl-step.is-ahead .tl-dot { opacity: 0.42; }

/* Current position: a grey ground, no accent. The playhead beside it is what
   says "here" in colour, and a second accent mark next to it only competed
   (R31, R33). No scale either: a grown mark reached into the gap the
   playhead stands in. */
#timeline-strip .tl-step.is-at .tl-dot,
#timeline-strip .tl-step.is-at:hover .tl-dot {
  background: color-mix(in srgb, var(--ink) 12%, var(--paper-card));
  color: var(--ink);
  box-shadow: none;
  transform: none;
}

/* Ruled (editable) step wears a ring. Most steps are sealed, so the
   strip stays quiet and the few editable ones stand out. */
#timeline-strip .tl-step.is-ruled .tl-dot {
  box-shadow: 0 0 0 var(--hairline) color-mix(in srgb, var(--accent-text) 55%, transparent);
}

/* Broken: references a card no longer present. */
#timeline-strip .tl-step.is-broken .tl-dot {
  color: var(--danger);
  box-shadow: 0 0 0 var(--hairline) var(--danger);
}

/* Named step: a pip under the mark for landmarks in a long history. */
#timeline-strip .tl-step.is-named .tl-dot { color: var(--ink); }
#timeline-strip .tl-step.is-named .tl-dot::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -1px;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--accent);
}

/* Stale history: steps do not add up to the current board. */
#timeline-strip.is-stale .tl-track { opacity: 0.4; pointer-events: none; }
#timeline-strip.is-stale .tl-where { color: var(--danger); }

/* A phone keeps the steps and the controls, and drops the count. */
@media (max-width: 520px) {
  #timeline-strip .tl-where { display: none; }
  #timeline-strip { gap: 4px; }
}

/* Fallback without color-mix() -- see tokens.css section 7. */
@supports not (color: color-mix(in srgb, red, blue)) {
  #timeline-strip .tl-step:hover .tl-dot { background: rgb(var(--ink-c) / 8%); }
  #timeline-strip .tl-step.is-ruled .tl-dot {
    box-shadow: 0 0 0 var(--hairline) rgb(var(--accent-c) / 55%);
  }
  #timeline-strip .tl-step.is-at .tl-dot,
  #timeline-strip .tl-step.is-at:hover .tl-dot { background: rgb(var(--ink-c) / 12%); }
  #timeline-strip .tl-scroll { background: rgb(var(--ink-c) / 7%); }
  #timeline-strip .tl-thumb { background: rgb(var(--ink-c) / 30%); }
}
