/* The issue timeline: the Timeline view a series hub AND a list page draw.
 * Rows are months of issues in publication order; columns are lanes of
 * editions, each a bar spanning the rows it collects. Extracted from
 * series.css, where it lived while only the series hub had the view -- a
 * list page never loads series.css (it has no hub banner, facts or pills to
 * style), so its Timeline rendered as raw markup: every cover at natural
 * size, stacked one per line, no rail, no lanes. index.html loads this
 * sheet for exactly the kinds that include _series_issue_timeline.html.
 *
 * Token-only colours, like series.css: every bar is the brand token mixed
 * into the surface, so there is no dark-mode block to keep in step. */

/* ---- The issue timeline (the series hub's Timeline view) --------------------
   Rows are months of issues in publication order; columns are lanes of editions,
   each a bar spanning the rows it collects. One CSS grid — a sticky rail column
   plus --sit-lanes equal lane columns — with every Alpine row `display:
   contents`, so the grid places rail and cells directly while each <template
   x-for> keeps one root element.

   Rows are `minmax(row height, auto)`: the row a bar starts on grows to fit its
   cover, which is what lets two books follow each other in one lane with no
   gap and nothing overlapping. Covers are in flow, never absolutely positioned
   over the rows beneath. */
.series-issue-timeline { margin: 0 0 18px; }
.series-issue-timeline__note {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px;
  margin: 0 0 14px; color: var(--text-muted); font-size: 14px;
}
.series-issue-timeline__retry {
  padding: 3px 12px; border: 1px solid var(--border-strong); border-radius: 999px;
  background: var(--surface); color: var(--text);
  font-size: 12px; font-weight: 600; letter-spacing: .01em; cursor: pointer;
}
.series-issue-timeline__retry:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brand) 55%, transparent); outline-offset: 1px;
}

.sit {
  --sit-rail-w: 176px; --sit-lane-w: 76px; --sit-lane-max: 84px;
  --sit-row-h: 44px; --sit-cover-w: 44px;
  /* Every bar is the brand token mixed into the surface; the six tint classes
     rotate that hue on the bar's pseudo-element, so adjacent books read apart
     without a single literal colour — this file is a raw-colour-free owner,
     and the audit counts every colour function, comments included. Fills
     only: no words are set on a tint; the badge and the rail carry their ink
     on token surfaces. The token is already solved per theme, so there is no
     dark override to keep in step. */
  --sit-tint: var(--brand);
}
.sit-tint-1::before { filter: hue-rotate(60deg); }
.sit-tint-2::before { filter: hue-rotate(120deg); }
.sit-tint-3::before { filter: hue-rotate(180deg); }
.sit-tint-4::before { filter: hue-rotate(240deg); }
.sit-tint-5::before { filter: hue-rotate(300deg); }

.sit-summary {
  display: flex; flex-wrap: wrap; gap: 4px 10px;
  margin: 0 0 10px; color: var(--text-muted); font-size: 13px;
}
.sit-summary__hint { color: var(--text-dim); }

/* The selected bar's card overlays `.sit-frame`, OUTSIDE `.sit-viewport`.
   The viewport must keep overflow-x:auto for multi-lane charts, and browsers
   resolve its other overflow axis to auto too; any descendant panel is
   therefore clipped on both axes. JS measures the tapped cell and supplies
   frame-relative top/left coordinates clamped to the visual viewport.

   Two rows at every width: cover, text and close, then the action spanning
   under them. One flex row left the text ~47px between the cover, the
   nowrap pill and the close button, so a title wrapped a word a line
   (GH-1104). 320px on a wide screen gives the text column ~200px. */
.sit-selected {
  box-sizing: border-box;
  position: absolute; top: 0; left: 0; z-index: 5;
  width: min(320px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px); overflow-y: auto;
  display: grid; grid-template-columns: auto minmax(0, 1fr) 44px;
  gap: 8px 10px; align-items: center;
  margin: 0; padding: 8px 12px;
  border: 1px solid var(--border-strong); border-radius: 12px;
  background: var(--surface); box-shadow: var(--shadow-md);
}
.sit-selected.is-positioning { visibility: hidden; }
.sit-selected:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brand) 55%, transparent); outline-offset: 2px;
}
.sit-selected__cover {
  grid-column: 1; grid-row: 1 / span 2;
  width: 32px; aspect-ratio: 2 / 3; object-fit: cover; border-radius: 3px;
}
.sit-selected__text { grid-column: 2; grid-row: 1; min-width: 0; }
.sit-selected__title { font-size: 14px; font-weight: 600; line-height: 1.25; color: var(--text); }
.sit-selected__meta { margin-top: 2px; font-size: 12.5px; color: var(--text-muted); }
.sit-selected__open {
  grid-column: 2 / 4; grid-row: 2; width: 100%; min-height: 44px; padding: 4px 12px;
  border: 1px solid var(--border-strong); border-radius: 999px;
  background: var(--surface-2); color: var(--text);
  font-size: 12px; font-weight: 600; letter-spacing: .01em; white-space: nowrap; cursor: pointer;
}
.sit-selected__close {
  grid-column: 3; grid-row: 1; min-width: 44px; min-height: 44px;
  border: 0; background: transparent; color: var(--text-muted);
  font-size: 20px; line-height: 1; padding: 0 4px; cursor: pointer;
}
.sit-selected__open:focus-visible, .sit-selected__close:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brand) 55%, transparent); outline-offset: 1px;
  border-radius: 999px;
}

/* The frame hugs its lanes — four lanes need not span a 1200px column — and
   caps at the column, past which the viewport scrolls sideways. Lanes grow a
   little on a wide screen but never past --sit-lane-max: a bar is a marker
   with a cover on it, not a column of its own. */
.sit-frame { position: relative; overflow: visible; }
.sit-viewport {
  width: fit-content; max-width: 100%;
  overflow-x: auto; border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface);
}
.sit-grid {
  display: grid;
  grid-template-columns:
    var(--sit-rail-w)
    repeat(var(--sit-lanes, 1), minmax(var(--sit-lane-w), var(--sit-lane-max)));
  /* Explicit rows keep the layout deterministic across engines; auto rows are
     the fallback if a stale payload supplies a short count. */
  grid-template-rows: repeat(var(--sit-rows, 1), minmax(var(--sit-row-h), auto));
  grid-auto-rows: minmax(var(--sit-row-h), auto);
  min-width: max-content;
}
.sit-row { display: contents; }

/* The format header row: the lanes are packed one format at a time, so each
   format owns a contiguous block of columns and this names it. Rendered only
   where the chart holds more than one format. */
.sit-fmt-rail { border-bottom: 1px solid var(--border-strong); }
/* Short labels (TPB, Complete, Omnibus) because a lane is 48px on a phone;
   the full name is on the cell's `title`. Clipped rather than ellipsised:
   `text-overflow` needs a block container, and this one centres its label. */
.sit-fmt {
  display: flex; align-items: center; justify-content: center;
  min-width: 0; padding: 5px 6px;
  overflow: hidden; white-space: nowrap;
  background: var(--surface-2); color: var(--text-muted);
  border-bottom: 1px solid var(--border-strong);
  border-left: 1px solid var(--border);
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}

/* The rail: month eyebrow where the month changes, then one line per run the
   month carries -- the run name and its numbers side by side. The name gives
   way (ellipsis; the whole part is on the title) before the numbers do,
   because the numbers are what locates the row. Stacking name over numbers
   cost every row a third line, and the rail, not the bars, is what set the
   chart's height. */
.sit-rail {
  position: sticky; left: 0; z-index: 2;
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  min-width: 0; padding: 5px 12px;
  background: var(--surface);
  border-right: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.sit-row.is-lit > .sit-rail { background: var(--surface-2); }
.sit-row.is-month > .sit-rail,
.sit-row.is-month > .sit-cell { border-top: 1px solid var(--border-strong); }
/* A banded chart (an umbrella hub's concurrent series, one group at a time):
   the band's first row carries its name in the rail and a heavier rule across
   every lane, so where one series ends and the next begins reads at a glance. */
.sit-row.is-band > .sit-rail,
.sit-row.is-band > .sit-cell { border-top: 2px solid var(--border-strong); }
.sit-row.is-band > .sit-rail { padding-top: 8px; }
/* Wraps rather than ellipsising: on a phone's 132px rail "Absolute Wonder
   Woman" is the whole point of the heading. */
.sit-band {
  overflow-wrap: anywhere;
  font-size: 13px; font-weight: 700; line-height: 1.3; color: var(--text);
}
.sit-month {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-dim);
}
.sit-part { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.sit-run {
  flex: 0 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 11.5px; line-height: 1.3; color: var(--text-muted);
}
/* Never wraps: an en dash is a break opportunity, and "#1–" over "7" is what
   a shrinking label drew. A label longer than the rail (six parts and "+N
   more") ellipsises; the part's title still carries it whole. */
.sit-nums {
  flex: none; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; font-weight: 600; line-height: 1.3; font-variant-numeric: tabular-nums; color: var(--text);
}

/* Cells: a bar segment (carry), a continuation with nothing collected
   (thread), or nothing. The bar is a pseudo-element inset from the lane
   edges, so two adjacent lanes never read as one wide bar. */
.sit-cell { position: relative; border-bottom: 1px solid var(--border); }
.sit-carry { cursor: pointer; }
.sit-carry::before {
  content: ""; position: absolute; inset: 0 10px;
  background: color-mix(in srgb, var(--sit-tint, var(--text-muted)) 26%, var(--surface));
  border-left: 3px solid var(--sit-tint, var(--text-muted));
}
.sit-carry.is-first::before { top: 4px; border-radius: 6px 6px 0 0; }
.sit-carry.is-last::before { bottom: 4px; border-radius: 0 0 6px 6px; }
.sit-carry.is-first.is-last::before { border-radius: 6px; }
.sit-carry:hover::before,
.sit-carry.is-lit::before {
  background: color-mix(in srgb, var(--sit-tint, var(--text-muted)) 44%, var(--surface));
}
.sit-carry:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brand) 55%, transparent);
  outline-offset: -2px; border-radius: 6px;
}
.sit-thread::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 11px;
  border-left: 2px dotted var(--sit-tint, var(--text-muted)); opacity: .7;
}
.sit-thread.is-lit::before { opacity: 1; border-left-style: solid; }

/* The head of a bar: its cover in flow, the short format badge laid over the
   cover's foot. Stacked under the cover the badge made every head row ~107px
   and a book-per-row hub a staircase; overlapping it saves a line a head. */
.sit-head {
  position: relative; z-index: 1; pointer-events: none;
  display: flex; flex-direction: column; align-items: center;
  padding: 6px 0 12px;
}
.sit-cover {
  display: block; width: var(--sit-cover-w); aspect-ratio: 2 / 3; object-fit: cover;
  border-radius: 3px; background: var(--surface-2); box-shadow: var(--shadow-sm);
}
.sit-cover--none { border: 1px dashed var(--border-strong); }
.sit-badge {
  position: absolute; bottom: 3px; left: 50%; transform: translateX(-50%);
  max-width: calc(100% - 4px); overflow: hidden; text-overflow: ellipsis;
  padding: 1px 6px; border: 1px solid var(--border-strong); border-radius: 999px;
  background: var(--surface); color: var(--text);
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  white-space: nowrap;
}

@media (prefers-reduced-motion: no-preference) {
  .sit-carry::before { transition: background-color .12s; }
}

/* A phone: a narrower rail and lanes, so five lanes fit a 390px screen beside
   the rail with no sideways scroll; more lanes scroll inside the frame while
   the rail stays put. The badge goes — at 48px a lane has room for the cover
   alone, and the caption names the format on tap. */
@media (max-width: 640px) {
  .sit {
    --sit-rail-w: 132px; --sit-lane-w: 48px; --sit-lane-max: 64px;
    --sit-row-h: 40px; --sit-cover-w: 34px;
  }
  .sit-carry::before { inset: 0 6px; }
  .sit-thread::before { left: 7px; }
  .sit-run { font-size: 10.5px; }
  .sit-nums { font-size: 12.5px; }
  .sit-badge { display: none; }
  .sit-head { padding: 6px 0 4px; }
  .sit-selected { width: min(280px, calc(100vw - 32px)); }
}
