/* Figure: tabs, each holding a slideshow of static images.
   Behaviour and the image manifest live in static/js/tab-slideshow.js;
   markup is <d-figure id="tab-slideshow-figure"> in src/index.html. */

/* Colours come from the shared theme (static/js/theme.js), which also handles
   the light/dark switch; the literals here are only fallbacks for if it fails
   to load. */
.tsl {
  --tsl-surface: var(--vx-surface, #fcfcfb);
  --tsl-ink: var(--vx-ink, #16160f);
  --tsl-muted: var(--vx-muted, #6b6a63);
  --tsl-rule: var(--vx-rule, #d8d7cf);
  --tsl-block: var(--vx-block, #ebeae2);
  --tsl-accent: var(--vx-accent, #eb6834);
  margin: 2rem 0 2.5rem;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif;
}

/* The article's figures sit in the text column (~648px), which is room for two
   slides at 314px each (see MIN_SLIDE_WIDTH in the JS). These are UI screenshots
   rather than diagrams, so if they read too small — the portrait pose shots are
   scaled to about a fifth of native at that size — uncomment this and raise
   MAX_IMAGE_HEIGHT in the JS; a pair then gets 580px each. Nothing else needs to
   change: the row re-measures and each slide sizes itself from the room it is
   given. */
/*
d-figure#tab-slideshow-figure {
  grid-column: page;
}
*/

/* ---- tabs ---- */
/* The strip scrolls rather than wraps: the tabs are one row of choices, and a
   wrapped second row reads as a second group. */
.tsl-tabs {
  display: flex;
  overflow-x: auto;
  border-bottom: 1px solid var(--tsl-rule);
  scrollbar-width: none;
}
.tsl-tabs::-webkit-scrollbar {
  display: none;
}

.tsl-tab {
  font: inherit;
  font-size: 13px;
  line-height: 1;
  flex: none;
  padding: 9px 14px;
  color: var(--tsl-muted);
  background: transparent;
  border: none;
  /* The selected underline sits *on* the strip's own rule, so switching tabs
     moves one mark instead of thickening the border. */
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
  white-space: nowrap;
}
.tsl-tab:hover {
  color: var(--tsl-ink);
}
.tsl-tab.is-active {
  color: var(--tsl-ink);
  font-weight: 700;
  border-bottom-color: var(--tsl-accent);
}
.tsl-tab:focus-visible {
  outline: 2px solid var(--tsl-ink);
  outline-offset: -2px;
  border-radius: 3px 3px 0 0;
}

/* ---- panel ---- */
.tsl-panel {
  padding-top: 12px;
}
.tsl-panel:focus {
  outline: none;
}
.tsl-panel:focus-visible {
  outline: 2px solid var(--tsl-ink);
  outline-offset: 4px;
  border-radius: 3px;
}

.tsl-note {
  margin: 0 0 10px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--tsl-muted);
}

/* The row of slides: one or two of them, the count decided in the JS by
   measuring this element (--tsl-cols is written back out from there). Centred,
   and aligned at the top so a pair whose captions run to different lengths still
   starts on one line. */
.tsl-frame {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: var(--tsl-gap, 20px);
}

/* Every slot takes an equal share of the row *including* on the last page of an
   odd-length tab, where only one of the two is filled: the lone slide is then
   drawn at the size its neighbours were, and centred, rather than swelling to the
   full column and reading as a different figure. */
.tsl-slot {
  min-width: 0;
  flex: 0 1 calc((100% - (var(--tsl-cols, 1) - 1) * var(--tsl-gap, 20px)) / var(--tsl-cols, 1));
}

/* A stage the slide is centred on, not a window it is cropped to. The stage is
   always its slot's full width; its *height* is reserved by the JS to fit the
   tallest slide in the open tab (see reserveHeight), so stepping through a tab
   never pushes the page around, whatever mix of shapes it holds, and both halves
   of a pair sit on one baseline. The value below is only the floor, for before
   anything has been measured. */
.tsl-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 160px;
}

/* Every slide keeps its own aspect ratio — nothing is cropped or stretched. The
   image shrinks to fit the column and the --tsl-max-h cap (portrait screenshots
   are why that cap exists), and by default stops at its natural size, since
   upscaling a 256px render to a 648px column is visibly blurry. `ALLOW_UPSCALE`
   in the JS lifts that last limit; object-fit keeps the ratio either way. */
.tsl-img {
  display: block;
  max-width: 100%;
  max-height: var(--tsl-max-h, 560px);
  width: auto;
  height: auto;
  object-fit: contain;
  border: 1px solid var(--tsl-rule);
  border-radius: 3px;
  background: var(--tsl-block);
  opacity: 0;
}
.tsl.is-upscale .tsl-img {
  width: 100%;
}

/* A missing or mistyped src reads as "not here yet", not as a broken image, and
   shows the path it tried so the fix is obvious. */
.tsl-missing {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 12px;
  text-align: center;
  border: 1px solid var(--tsl-rule);
  border-radius: 3px;
  background: repeating-linear-gradient(45deg, transparent 0 5px, var(--tsl-rule) 5px 7px);
}
.tsl-stage.is-missing .tsl-missing {
  display: flex;
}
.tsl-missing span {
  font-size: 11px;
  font-family: "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--tsl-muted);
  background: var(--tsl-surface);
  padding: 3px 7px;
  border-radius: 3px;
  overflow-wrap: anywhere;
}

/* One caption per slide, under its own slide, so a pair reads as two examples
   rather than one picture with a note. */
.tsl-caption {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--tsl-muted);
  font-variant-numeric: tabular-nums;
}

/* ---- back / forward bar ---- */
.tsl-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}

.tsl-btn {
  font: inherit;
  font-size: 12px;
  line-height: 1;
  flex: none;
  padding: 6px 12px;
  color: inherit;
  background: transparent;
  border: 1px solid var(--tsl-rule);
  border-radius: 4px;
  cursor: pointer;
}
.tsl-btn:hover:not([disabled]) {
  border-color: var(--tsl-muted);
}
/* Disabled at the ends rather than wrapping around, so the ladder has a felt
   beginning and end. */
.tsl-btn[disabled] {
  opacity: 0.4;
  cursor: default;
}

/* The dots take the middle, which keeps back and forward at a fixed distance
   from the frame's edges as the count changes. */
.tsl-dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  flex: 1 1 auto;
}
.tsl-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--tsl-muted);
  background: transparent;
  cursor: pointer;
}
.tsl-dot.is-current {
  background: var(--tsl-accent);
  border-color: var(--tsl-accent);
}

/* Wide enough for a two-slide page — "1–2 / 6" — so the dots beside it do not
   shift when the row goes from one slide to two. */
.tsl-counter {
  flex: none;
  font-size: 12px;
  color: var(--tsl-muted);
  font-variant-numeric: tabular-nums;
  min-width: 5em;
  text-align: right;
}

@media screen and (max-width: 600px) {
  /* The counter says the same thing as the dots; at this width the buttons need
     the room more. */
  .tsl-counter {
    display: none;
  }
}
