/* ---------------------------------------------------------------------------
   Video player (.vp-*) -- the control bar videoPlayer.js builds. Video only --
   an image renders the same .viewer-media it always did, with no wrapper.

   LOADED LAST in both documents: after main.css in index.html, after review.css
   in review.html. That is the decision, not an accident. `.vp-row .vp-btn` is a
   descendant selector written to stay clear of `.viewer-panel button`, and the
   client-facing page has its own rules for buttons and inputs inside the
   lightbox. Coming last means none of them can repaint a transport control,
   whatever gets added to them later.

   MARK (stage 6b): `.viewer-panel button` no longer exists -- the viewer's
   action row moved onto .k-btn--ghost and the rule on the tag was removed. The
   descendant form named above is a leftover of it. Kept, not simplified: these
   selectors belong to the player and were out of that stage's scope. Nothing
   else in this paragraph is affected -- loading last is about the OTHER
   stylesheets, which still have their own button rules.

   The tokens used here (--k-accent, --k-text-3) are declared in krgxion.css,
   which both documents also load. Custom properties resolve at computed-value
   time, so the order between these two files does not matter -- only that
   krgxion.css is linked at all.

   The studio-only rules -- the in..out region, its two marks, the speed
   <select>, and the fullscreen rule for .viewer-media -- stay in main.css.
   videoPlayer.js does not build those nodes when it is attached with
   controls: "client", so their absence here leaves nothing unstyled.

   .vp-root takes the flex:1 1 0 that .viewer-media used to hold in the panel,
   and hands it back to .viewer-media inside itself, so the picture still fills
   the leftover height and the bar sits under it. min-height:0 is the usual
   flex-item escape: without it a child cannot shrink below its content and the
   bar gets pushed out of the panel.

   The bar is a SIBLING of .viewer-media, not a child, on purpose: wireZoom's
   wheel listener is on .viewer-media, so a control inside it would zoom the
   picture when the user rolled the wheel over the scrub bar or the volume
   slider. Being outside also keeps it clear of the zoom transform, which is
   applied to the <video> itself.

   NOTE, and do not "tidy" it: .vp-play, .vp-mute, .vp-full, .vp-step-back and
   .vp-step-fwd have NO rules here on purpose. They are the handles
   videoPlayer.js looks the elements up by -- a behaviour contract, not styling
   -- and their appearance comes from .vp-btn. Deleting one as "unused CSS"
   would silently break a control. The six studio-only handles are documented in
   main.css, beside the rules that remain there.
   ------------------------------------------------------------------------- */

.vp-root {
  display: flex;
  flex-direction: column;
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
  gap: 8px;
}

/* Focus is what routes the keyboard to ONE of the two Generation viewers, so it
   has to be visible -- an invisible focus ring here means the user cannot tell
   which player their Space bar is about to reach. */
/* OUTSIDE the border box, which is what carrying no outline-offset means. It
   was inset by -2px until the ring turned out to be invisible along the top:
   .vp-root has no padding, .viewer-media touches its inner edge, and a child
   painted over an inset ring hides it. A ring drawn outside has nothing in
   front of it.
   What it rings is the whole player -- picture and control bar together -- and
   that is the point rather than a side effect: .vp-root is the element that
   takes focus, so .vp-root is the element the ring belongs to.
   THE COST, accepted: on the client-facing page .vp-root sits flush against the
   left edge of the window, so on that side the 2px fall outside the viewport
   and do not show; the other three sides do. In the five studio rooms the box
   around the frame carries 16px of padding on every side -- measured -- so
   neither .media-viewer-box nor .viewer-panel, both overflow: hidden, comes
   near it. */
.vp-root:focus-visible {
  outline: 2px solid var(--k-accent);
}

.vp-root:fullscreen {
  background: #000;
  gap: 0;
  padding: 0;
}

/* Over the picture rather than under it in fullscreen: the video takes the
   whole screen there, and a bar in the flow would letterbox it further. */
.vp-root:fullscreen .vp-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(15, 17, 22, 0.86);
  padding: 10px 16px 14px;
}

.vp-bar {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  flex-shrink: 0;
}

/* A photo gets no player, so the bar stays an empty element -- and an empty
   flex item still counts for .vp-root's gap, which put 8px of nothing under
   every picture. Removing the box removes the gap beside it. The gap itself
   is not touched: a video needs it. */
.vp-bar:empty {
  display: none;
}

/* Explicit flex on a row of mixed elements (buttons, a select, a range input, a
   couple of text spans) rather than fighting each one's width: the readouts are
   the only items allowed to grow, everything else keeps its natural size. */
.vp-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
}

.vp-spacer {
  flex: 1 1 0;
}

/* Not `.viewer-panel button`: that rule paints every button in the panel the
   destructive red of Delete. These are transport controls.

   MARK (stage 6b). Two separate things, and they happened at different times:

   -- The red named above left in stage 6a, onto the Delete button alone. From
      that stage on, the sentence described a rule that no longer did what it
      says. That error predates 6b and was not caused by it -- 6b only found it.

   -- The rule itself was removed in 6b. So the reason for writing this as a
      descendant is gone too, and the form is now a leftover. Kept on purpose:
      the player's selectors were not that stage's to change. */
.vp-row .vp-btn {
  flex: 0 0 auto;
  min-width: 28px;
  height: 28px;
  padding: 0 7px;
  border: 1px solid #333844;
  border-radius: 6px;
  background: #0f1116;
  color: #e6e6e6;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}

.vp-row .vp-btn:hover {
  border-color: #4a5162;
}

/* The "engaged" look for a toggle (loop, fullscreen). A separate class from the
   hover/active pseudo-states because it is state, not interaction. */
.vp-row .vp-btn.vp-on {
  border-color: var(--k-accent);
  color: var(--k-accent);
}

.vp-time,
.vp-frames {
  flex: 0 0 auto;
  font-family: var(--k-mono);
  font-size: 12px;
  color: #e6e6e6;
  white-space: nowrap;
}

.vp-frames {
  color: #8b909a;
}

.vp-row .vp-volume {
  flex: 0 1 72px;
  min-width: 48px;
  accent-color: var(--k-accent);
}

/* --- scrub bar --- */
/* Padded vertically so the pointer target is comfortable while the visible
   track stays thin. */
.vp-scrub {
  position: relative;
  width: 100%;
  padding: 7px 0;
  cursor: pointer;
  touch-action: none;
}

.vp-scrub-track {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: #262b36;
}

.vp-scrub-played {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  border-radius: 3px;
  background: var(--k-text-3);
}

.vp-scrub-head {
  position: absolute;
  top: 50%;
  width: 10px;
  height: 10px;
  margin-left: -5px;
  border-radius: 50%;
  background: #e6e6e6;
  transform: translateY(-50%);
  pointer-events: none;
}

.vp-scrub-tip {
  position: absolute;
  bottom: 100%;
  transform: translateX(-50%);
  padding: 2px 6px;
  border-radius: 4px;
  background: #1b1f27;
  border: 1px solid #333844;
  color: #e6e6e6;
  font-family: var(--k-mono);
  font-size: 11px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
}

.vp-scrub:hover .vp-scrub-tip {
  opacity: 1;
}
