/* transport.css — the scroll transport, and the viewport unit it stands on.
 *
 * Shared by the two long-form pages, journey.html and gjader-3d.html. They had
 * a byte-identical copy each: same pill, same fold, same manners, and the same
 * fix applied twice by hand every time one was touched — the 44px touch pass
 * was reconciled in both files in one commit, differently. One sheet now.
 *
 * The pages keep what is genuinely theirs:
 *   --tp-z    the stacking order (the journey rides over its own topbar at 170;
 *             gjader-3d has nothing to clear, so it keeps the default)
 *   --tp-pad  how much bottom strip the page reserves for the bar. It is a page
 *             question, not a transport one: the journey lifts step cards out of
 *             the way, gjader-3d instead indents its credit line. Declared here
 *             only as the 0 a no-script reader gets.
 *
 * The [data-state="wait"] rules are the journey's clip gate (the bar waits for a
 * voice note to finish). gjader-3d never enters that state and the selectors
 * simply never match there — cheaper than forking the sheet for three rules.
 *
 * `bundle.js` rewrites <link rel=stylesheet> into <style> when it builds a
 * page's self-contained download, and tools/make_standalone.mjs observes
 * subresources, so neither delivery path needs to know this file exists.
 */

:root {
  /* The pinned-stage height. 100vh on a phone is the height with the browser
     chrome RETRACTED, so a sticky stage sized from it hangs below the fold and
     the fixed overlays are pushed off it; worse, the chrome sliding in and out
     re-fires resize and re-measures the scroll track under the reader's thumb.
     svh is the small viewport — it does not move. */
  --vh: 100vh;
  /* the strip the bar occupies along the bottom edge. 0 until the transport
     actually mounts (JS sets html[data-transport]), so a no-script reader loses
     nothing; each page raises it to whatever its own layout needs. */
  --tp-pad: 0px;
  --tp-z: 10;
}
@supports (height: 100svh) { :root { --vh: 100svh; } }

/* ---- the bar --------------------------------------------------------------
   At rest it is one quiet button in the corner; hover, keyboard focus or a tap
   unfolds the rest of the transport leftwards. */
#transport {
  position: fixed; right: 16px; bottom: 16px; z-index: var(--tp-z);
  display: flex; align-items: center; padding: 4px; border-radius: 999px;
  /* the journey's coda, credits and share panels are PAPER, not night: a mostly
     glass pill turned grey and illegible over them, so the chip carries its own
     dark ground and the blur only softens what shows through the last 10%. */
  border: 1px solid var(--hair); background: color-mix(in srgb, var(--night) 90%, transparent);
  backdrop-filter: blur(16px) saturate(0.9);
  -webkit-backdrop-filter: blur(16px) saturate(0.9);
  opacity: 0.45; transition: opacity 0.3s ease;
}
/* driving: present enough to find, quiet enough to read past */
#transport[data-state="play"], #transport[data-state="wait"] { opacity: 0.62; }
#transport:hover, #transport.open { opacity: 1; }

/* the fold. max-width rather than display, so it can animate — 300px is a
   ceiling the content never reaches, not a measured width. */
.tp-more {
  display: flex; align-items: center; overflow: hidden; max-width: 0; opacity: 0;
  pointer-events: none; transition: max-width 0.32s ease, opacity 0.2s ease;
}
#transport:hover .tp-more, #transport.open .tp-more {
  max-width: 300px; opacity: 1; pointer-events: auto;
}
/* keyboard focus holds it open; a MOUSE click must not, or the bar would stay
   unfolded for as long as the play button kept focus. Hence :focus-visible, and
   hence its own rule — an unsupported :has() would take the hover rule with it. */
#transport:has(:focus-visible) { opacity: 1; }
#transport:has(:focus-visible) .tp-more { max-width: 300px; opacity: 1; pointer-events: auto; }

.tp-b {
  width: 34px; height: 34px; padding: 0; border: 0; border-radius: 50%; background: none;
  display: grid; place-items: center; cursor: pointer; color: var(--night-sub); transition: color 0.2s ease;
}
.tp-b:hover, .tp-b:focus-visible { color: var(--bi-cyan); outline: none; }
.tp-b svg { width: 16px; height: 16px; fill: currentColor; }
.tp-play { flex: none; }
.tp-play svg { width: 20px; height: 20px; }
#transport[data-state="play"] .tp-play, #transport[data-state="wait"] .tp-play { color: var(--bi-cyan); }

/* fixed width, centred text: the label runs from "1x" to "0.75x", and a chip
   that resized as it cycled would move under the cursor clicking it */
.tp-rate {
  flex: none; width: 44px; margin: 0 6px 0 2px; padding: 5px 0; text-align: center;
  border: 1px solid var(--hair); border-radius: 999px; background: none; cursor: pointer;
  color: var(--night-sub); transition: color 0.2s ease, border-color 0.2s ease;
  font: 700 10px/1 var(--sans); letter-spacing: 0.04em; font-variant-numeric: tabular-nums;
}
.tp-rate:hover, .tp-rate:focus-visible { color: var(--bi-cyan); border-color: var(--bi-cyan); outline: none; }

.tp-stat {
  flex: none; width: 9em; margin: 0 4px 0 8px; overflow: hidden; white-space: nowrap;
  text-overflow: ellipsis; font: 600 9.5px var(--sans); letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--night-mute);
}
#transport[data-state="wait"] .tp-stat { color: var(--bi-cyan); }

@media (max-width: 760px) {
  #transport { right: 10px; bottom: 10px; padding: 3px; }
  .tp-stat { display: none; }
}
@media print { #transport { display: none; } }

/* ---- touch floor ----------------------------------------------------------
   A 30px button is a comfortable mouse target and a poor thumb one. Keyed on
   the pointer, not the width, so a touch laptop gets it too; only the box
   grows, the glyphs are unchanged. This block comes after the width query
   above deliberately — they set the same properties at the same specificity,
   so source order is what decides, and the pointer has to win. */
@media (pointer: coarse) {
  #transport { opacity: 0.72; padding: 4px; }
  /* the resting state came UP to 0.72, so the playing state has to come up with
     it — [data-state] out-specifies a bare #transport, and left at 0.62 the bar
     was dimmer while running than while stopped */
  #transport[data-state="play"], #transport[data-state="wait"] { opacity: 0.85; }
  .tp-b { width: 44px; height: 44px; }
  .tp-rate { width: 52px; padding: 16px 0; }
}
