/* compare.css — 1 Nov 2026. THE COMPARE page (src/ComparePage.jsx): the chip rows (the Shots page's own .sf-seq-chip chips in
   .sp-reelbar, as on the Prompts page), the picks tally, and one contact-sheet row per shot (its details on the left, every
   frame version side by side, big, each labelled with the route / model that made it). Its own cmp-* classes only. Colours are
   tokens (the separation ladder: a panel is --sep-panel-fill on the page, a card --sep-card-fill, a row --sep-row-fill), so
   every skin repaints it and none resizes it. FIXED SIZES (invariant 20): the chip rows, the tally, the error line and every
   shot row have fixed heights; a pick only changes a ring and a badge.
   2 Nov 2026 rebuild: a row is ONE line that never scrolls sideways (ORIGINAL + one tile per route share the width, a grid of
   --cmp-cols equal columns); every tile is the 21:9 frame and its picture fills it INSIDE its border (the img is absolutely
   placed in the padding box, so the border and the rounded corners stay visible on all four sides); the viewer (an app modal,
   .cmp-modal) stacks every full picture of the shot and shows one by z-index, each on its own layer, so a flick repaints
   nothing. Round 2 (2 Nov 2026): no hover preview; the viewer is the app's own modal, not a full-screen page. */
.view-page.cmp-page { gap: 10px; }

/* ── the chip rows and the tally ── */
.cmp-bars { flex: none; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cmp-barrow { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cmp-bar-label {
  flex: none; width: 76px;
  font-size: var(--fs-10); font-weight: var(--fw-bold); letter-spacing: var(--track-12); text-transform: uppercase;
  color: var(--sep-panel-ink-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cmp-bar.sp-reelbar { flex: 1 1 auto; min-width: 0; padding: 0 0 2px; }

.cmp-tally { display: flex; align-items: center; gap: 10px; height: 34px; min-width: 0; }
.cmp-tally-list { flex: 1 1 auto; display: flex; align-items: center; gap: 6px; min-width: 0; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.cmp-tally-list::-webkit-scrollbar { display: none; }
.cmp-tally-chip {
  flex: none; display: inline-flex; align-items: center; gap: 8px; height: 28px; padding: 0 10px;
  border-radius: var(--r-md);
  background: var(--sep-card-fill);
  box-shadow: 0 0 0 var(--hairline-w) color-mix(in srgb, var(--card-border) 55%, transparent);
}
.cmp-tally-chip.is-lead { box-shadow: 0 0 0 var(--ring-w) var(--leaf); }
.cmp-tally-route { font-size: var(--fs-12); font-weight: var(--fw-semi); color: var(--ink); white-space: nowrap; }
.cmp-tally-n { font-family: var(--font-display); font-size: var(--fs-14); letter-spacing: var(--track-005); color: var(--ink); }
.cmp-tally-none { font-size: var(--fs-12); color: var(--sep-panel-ink-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmp-tally-sum { flex: none; font-size: var(--fs-12); color: var(--sep-panel-ink-muted); white-space: nowrap; }
.cmp-pick-err { height: 16px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--fs-12); line-height: 16px; color: var(--danger); visibility: hidden; }
.cmp-pick-err.is-on { visibility: visible; }

/* ── the body: scrolls inside itself, the chip rows stay ── */
.cmp-body { flex: 1 1 0; min-height: 0; min-width: 0; overflow-y: auto; padding: 2px 2px 28px; display: flex; flex-direction: column; gap: 10px; scrollbar-width: thin; }
.cmp-empty { padding: 36px 12px; text-align: center; font-size: var(--fs-13); line-height: 1.5; color: var(--sep-panel-ink-muted); }
.cmp-empty--err { color: var(--danger); }

/* ── a shot's row: details on the left (a click opens the viewer), then ORIGINAL + one tile per route, one line ── */
.cmp-row {
  flex: none; display: grid; grid-template-columns: 168px minmax(0, 1fr); gap: 12px; min-width: 0;
  padding: 10px 12px;
  border-radius: var(--r-md);
  background: var(--sep-panel-fill);
  box-shadow: 0 0 0 var(--hairline-w) color-mix(in srgb, var(--card-border) 55%, transparent);
}
.cmp-row-meta {
  display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 6px 8px; margin: 0;
  border: 0; border-radius: var(--r-md); background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
  transition: background var(--dur-0) ease;
}
.cmp-row-meta:hover { background: var(--sep-row-fill); }
.cmp-row-meta:focus-visible { outline: none; box-shadow: 0 0 0 var(--ring-w) var(--leaf); }
.cmp-row-top { display: flex; align-items: center; gap: 6px; height: 20px; min-width: 0; }
.cmp-row-code { flex: none; font-family: var(--font-display); font-size: var(--fs-14); letter-spacing: var(--track-005); color: var(--ink); }
.cmp-row-tag {
  flex: none; padding: 1px 6px; border-radius: var(--r-xs);
  font-size: var(--fs-10); font-weight: var(--fw-bold); letter-spacing: var(--track-04); text-transform: uppercase; line-height: 14px;
  color: var(--sep-panel-ink-muted);
  background: var(--sep-row-fill);
}
.cmp-row-title {
  height: calc(3 * 1.4em); overflow: hidden; font-size: var(--fs-13); font-weight: var(--fw-semi); line-height: 1.4; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
}
.cmp-row-count { height: 16px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--fs-11); line-height: 16px; color: var(--sep-panel-ink-muted); }
/* round 3: a click waits for its first full picture; past 400 ms this quiet spinner turns in the row (always in the
   layout, only shown, so nothing moves) */
.cmp-row-wait {
  flex: none; width: 14px; height: 14px; margin-left: auto; border-radius: 50%; box-sizing: border-box;
  border: var(--ring-w) solid color-mix(in srgb, var(--sep-panel-ink-muted) 35%, transparent); border-top-color: var(--leaf);
  visibility: hidden;
}
.cmp-row-wait.is-on { visibility: visible; animation: cmp-wait-spin 0.9s linear infinite; }
@keyframes cmp-wait-spin { to { transform: rotate(360deg); } }
.cmp-row-pick {
  height: calc(2 * 1.4em); overflow: hidden; font-size: var(--fs-12); line-height: 1.4; color: var(--sep-panel-ink-muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.cmp-row-pick.is-set { color: var(--ink); font-weight: var(--fw-semi); }

.cmp-strip { display: grid; grid-template-columns: repeat(var(--cmp-cols, 6), minmax(0, 1fr)); gap: 8px; min-width: 0; align-items: start; }

/* ── one tile: the 21:9 picture INSIDE its border, then what made it ── */
.cmp-tile {
  display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 0; margin: 0;
  border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.cmp-tile.is-empty { cursor: default; }
.cmp-tile-pic {
  position: relative; display: block; width: 100%; aspect-ratio: 21 / 9; overflow: hidden;
  border: var(--hairline-w) solid color-mix(in srgb, var(--card-border) 70%, transparent);
  border-radius: var(--r-md);
  background: var(--sep-row-fill);
  transition: border-color var(--dur-0) ease, box-shadow var(--dur-0) ease;
}
.cmp-tile-img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }
.cmp-tile:not(.is-empty):hover .cmp-tile-pic { border-color: var(--leaf); }
.cmp-tile.is-picked .cmp-tile-pic { border-color: var(--leaf); box-shadow: 0 0 0 var(--ring-w) var(--leaf); }
.cmp-tile.is-orig .cmp-tile-pic { border-color: color-mix(in srgb, var(--ink) 45%, transparent); }
.cmp-tile:focus-visible { outline: none; }
.cmp-tile:focus-visible .cmp-tile-pic { box-shadow: 0 0 0 var(--ring-w) var(--leaf); }
.cmp-tile.is-empty .cmp-tile-pic { border-style: dashed; background: none; }
.cmp-tile-none { position: absolute; inset: 0; display: grid; place-items: center; font-size: var(--fs-11); color: var(--sep-panel-ink-muted); }
.cmp-tile-badge {
  position: absolute; top: 6px; left: 6px; height: 18px; padding: 0 7px; border-radius: var(--r-xs);
  font-size: var(--fs-10); font-weight: var(--fw-bold); letter-spacing: var(--track-04); text-transform: uppercase; line-height: 18px;
  color: var(--ink);
  background: color-mix(in srgb, var(--sep-card-fill) 88%, transparent);
}
.cmp-tile-badge:empty { visibility: hidden; }
.cmp-tile.is-picked .cmp-tile-badge, .cmp-view-tile.is-picked .cmp-tile-badge { color: var(--cta-ink); background: var(--cta-bg); }
.cmp-tile-cap { display: flex; align-items: baseline; gap: 6px; height: 20px; min-width: 0; padding: 0 2px; }
.cmp-tile-route { flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--fs-13); font-weight: var(--fw-bold); line-height: 20px; color: var(--ink); }
.cmp-tile-route.is-derived { font-weight: var(--fw-semi); color: var(--sep-panel-ink-muted); }
.cmp-tile-route.is-orig { letter-spacing: var(--track-04); text-transform: uppercase; }
.cmp-tile-ver { flex: none; font-size: var(--fs-11); line-height: 20px; color: var(--sep-panel-ink-muted); }

/* ── the viewer = an app MODAL (round 2, 2 Nov 2026): the shot window's own .modal-backdrop / .modal-card.glass /
   .modal-close-btn / .modal-header / .modal-hero-image, sized to HUG the picture + the strip (no empty bands). The sum:
   the picture box may be --cmp-hero-h tall (92vh minus the card's fixed rows: padding 26 + 22, header 62, two gaps 14,
   the strip row 144), the card is that box's width at the shot's ratio (--cmp-ar, set by ComparePage on the backdrop)
   plus its 2 x 28px padding, never wider than the screen. The box has the card's inner width at --cmp-ar, so it is
   exactly the picture's shape. Every row has a fixed height: a flick, a pick or a note never moves anything. ── */
.cmp-modal-backdrop {
  --cmp-st-h: 120px;                                   /* a strip thumbnail's picture height */
  --cmp-hero-h: calc(92vh - 282px);
  --cmp-card-w: min(98vw, max(900px, calc(var(--cmp-hero-h) * var(--cmp-ar, 2.3333) + 56px)));
}
.modal-card.cmp-modal {
  width: var(--cmp-card-w); max-width: none; max-height: 96vh;
  overflow: hidden; scrollbar-gutter: auto;
  padding: 26px 28px 22px; gap: 14px;
}
/* review 2 Nov 2026: the card is the shot window's own (.modal-card--shot: the same fill in every skin); its X sits where the
   shot window's does (24px in: that window keeps a 10px scrollbar gutter), and its 46vh picture cap does not apply here */
.modal-card.cmp-modal > .modal-close-btn { right: 24px; }
.modal-card.cmp-modal > .modal-hero-image.cmp-modal-hero { max-height: none; }
.modal-header.cmp-modal-head { height: 62px; gap: 4px; min-width: 0; }
.cmp-modal-idrow { display: flex; align-items: baseline; gap: 16px; height: 36px; min-width: 0; }
.cmp-modal-idrow .md-id { flex: none; }
.cmp-modal-now { flex: 0 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--fs-16); font-weight: var(--fw-bold); color: var(--ink); }
.cmp-modal-pos { flex: none; margin-left: auto; font-size: var(--fs-13); color: var(--sep-panel-ink-muted); }
.md-frame.cmp-modal-title { height: 22px; line-height: 22px; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* the picture box: the shot's own ratio, rounded like the shot window's hero; every picture stacked, one on top */
.modal-hero-image.cmp-modal-hero {
  aspect-ratio: var(--cmp-ar, 21 / 9);
  width: min(100%, calc(var(--cmp-hero-h) * var(--cmp-ar, 2.3333)));
  margin-inline: auto;
  border-radius: var(--r-md);
  background: var(--shade-53);
}
/* every layer is opaque and on its own compositor layer: the one on top is the one shown; a flick changes a z-index only */
.cmp-view-layer { position: absolute; inset: 0; z-index: 0; background: var(--shade-53); will-change: transform; }
.cmp-view-layer.is-on { z-index: 1; }
.cmp-view-img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: contain; }
/* round 3 (2 Nov 2026): the big picture never shows a thumbnail. A layer holds only its full, decoded picture; a flick to
   one still decoding keeps the current picture up and marks the asked tile (is-want) until it switches */

/* the strip row: every picture of the shot, labelled, then the pick at its right end */
.cmp-modal-foot { display: flex; align-items: stretch; gap: 16px; height: 144px; min-width: 0; }
.cmp-modal-strip { flex: 1 1 auto; display: flex; justify-content: flex-start; gap: 10px; min-width: 0; }
.cmp-view-tile {
  position: relative; flex: 0 1 calc(var(--cmp-st-h) * var(--cmp-ar, 2.3333)); display: flex; flex-direction: column; gap: 4px;
  min-width: 0; padding: 0; margin: 0;
  border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.cmp-view-tile .cmp-tile-pic { aspect-ratio: auto; height: var(--cmp-st-h); }
.cmp-view-tile:hover .cmp-tile-pic { border-color: color-mix(in srgb, var(--leaf) 60%, transparent); }
.cmp-view-tile.is-picked .cmp-tile-pic { border-color: var(--cta-bg); }
.cmp-view-tile.is-want .cmp-tile-pic { border-color: color-mix(in srgb, var(--leaf) 70%, transparent); }
.cmp-view-tile.is-on .cmp-tile-pic { border-color: var(--leaf); box-shadow: 0 0 0 var(--ring-w) var(--leaf); }
.cmp-view-tile.is-orig .cmp-tile-pic { background: var(--shade-53); }
.cmp-view-tile:focus-visible { outline: none; }
.cmp-view-tile:focus-visible .cmp-tile-pic { box-shadow: 0 0 0 var(--ring-w) var(--leaf); }

.cmp-modal-pick { flex: none; width: 250px; display: flex; flex-direction: column; justify-content: center; gap: 8px; min-width: 0; }
.cmp-modal-pickbtn {
  height: 42px; padding: 0 14px; border-radius: var(--r-md); cursor: pointer;
  font: inherit; font-size: var(--fs-14); font-weight: var(--fw-bold);
  color: var(--cta-ink); background: var(--cta-bg);
  border: var(--hairline-w) solid transparent;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cmp-modal-pickbtn:hover:not(:disabled) { filter: brightness(1.08); }
.cmp-modal-pickbtn:focus-visible { outline: none; box-shadow: 0 0 0 var(--ring-w) var(--leaf); }
.cmp-modal-pickbtn:disabled { opacity: 0.45; cursor: default; }
.cmp-modal-pickbtn.is-picked:disabled { opacity: 1; color: var(--ink); background: none; border-color: var(--cta-bg); }
.cmp-modal-pickstate {
  height: calc(2 * 1.4em); overflow: hidden; font-size: var(--fs-12); line-height: 1.4; color: var(--sep-panel-ink-muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.cmp-modal-pickstate.is-set { color: var(--ink); font-weight: var(--fw-semi); }

/* the phone: the details go above the frames */
@media (max-width: 760px) {
  .cmp-row { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 10px; }
  .cmp-row-title { height: calc(2 * 1.4em); -webkit-line-clamp: 2; }
  .cmp-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cmp-tally-sum { display: none; }
  .modal-card.cmp-modal { width: 100%; }
  .cmp-modal-now { display: none; }
  .cmp-modal-foot { height: auto; flex-direction: column; }
  .cmp-modal-strip { overflow-x: auto; }
  .cmp-modal-pick { width: auto; }
}
