/* The player screen: the pointer surface, the peripheral marks, and the
 * auto-hiding chrome (top bar, seek bar, bottom bar).
 *
 * Stacking inside #player (its own context, above the picture, below the
 * library): surface 1 < periphery 2 < panels 3 (overlay.css) < chrome 4 <
 * diagnostics 5 < shortcuts 6.  The chrome stays above a panel's scrim so
 * Back and the bar keep working over it.  Settings (40) and toasts (50)
 * sit above everything. */

:root {
  --chrome-inset: var(--s-6);
  --periph-rise: 96px;
  --icon-scrim: drop-shadow(0 1px 2px var(--scrim)) drop-shadow(0 0 6px var(--scrim));
}

#player {
  position: fixed;
  inset: 0;
  z-index: 10;
  isolation: isolate;
  color: var(--star);
  user-select: none;
}
body.browsing #player { display: none; }

#player [hidden] { display: none !important; }
/* Focus parks on the player itself when it is taken back from youtube's
   iframe (app.js); a container holding focus draws no ring. */
#player:focus { outline: none; }

/* -- the surface ---------------------------------------------------- */

#surface {
  position: absolute;
  inset: 0;
  z-index: 1;
  touch-action: none;   /* a drag looks around; it never scrolls */
}
body.dragging #surface { cursor: grabbing; }
body.chrome-asleep #surface, body.chrome-asleep #player { cursor: none; }

/* The skip-ad hole.  youtube draws "Skip ad" inside its own iframe, under
   this layer; while the chrome is awake the surface stops taking the
   pointer over that spot (the right 24%, 9%–26% up from the bottom) so ads
   stay skippable.  Relative positions survive embed.js's layout scale.
   Trade-off: a click in the hole reaches youtube instead (its own
   play/pause, outside our click and drag handling), and a pointer resting
   there is invisible to us, so the chrome may fall asleep over it; the
   next movement anywhere closes the hole and wakes it. */
body.embedded:not(.chrome-asleep) #surface {
  clip-path: polygon(0 0, 100% 0, 100% 74%, 76% 74%, 76% 91%, 100% 91%, 100% 100%, 0 100%);
}

/* -- the peripheral layer ------------------------------------------- */

#periphery {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
}

/* Buffering: a lamp hairline sliding along the very top edge. */
.periph-buffer {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  overflow: hidden;
  opacity: 0;
  transition: opacity var(--t-base) var(--ease-out);
}
.periph-buffer::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 30%;
  background: linear-gradient(90deg, transparent, var(--lamp) 30%, var(--lamp) 70%, transparent);
  transform: translateX(-100%);
}
.periph-buffer.on { opacity: 1; }
.periph-buffer.on::before { animation: periph-slide 1.2s linear infinite; }
@keyframes periph-slide {
  from { transform: translateX(-100%); }
  to { transform: translateX(334%); }
}

/* One glyph and one word at bottom centre, clear of the bottom bar.  The
   three marks are mutually exclusive states, so they share the spot. */
.periph-mark {
  position: absolute;
  bottom: var(--periph-rise);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font: var(--t-label);
  letter-spacing: var(--track-label);
  white-space: nowrap;
  color: var(--star);
  text-shadow: var(--text-scrim);
  opacity: 0;
  /* Hidden, not just transparent, so screen readers hear only the live one. */
  visibility: hidden;
  transition: opacity var(--t-base) var(--ease-out), visibility 0s var(--t-base);
}
.periph-mark .icon { width: 18px; height: 18px; filter: var(--icon-scrim); }
.periph-mark.on { opacity: 1; visibility: visible; transition: opacity var(--t-base) var(--ease-out), visibility 0s; }
.periph-warn { color: var(--ember); }

/* Acquiring: a small lamp breathing, so the viewer knows the camera is
   being read without being asked to do anything. */
.periph-pulse .pulse {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--lamp);
  box-shadow: 0 0 0 1px var(--scrim);
}
.periph-pulse.on .pulse { animation: periph-breathe 1.6s ease-in-out infinite; }
@keyframes periph-breathe {
  0%, 100% { opacity: 0.35; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1); }
}

/* -- the chrome ------------------------------------------------------ */

#chrome {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  text-shadow: var(--text-scrim);
  opacity: 1;
  visibility: visible;
  transition: opacity 200ms var(--ease-out), visibility 0s;
}
body.chrome-asleep #chrome {
  opacity: 0;
  visibility: hidden;
  transition: opacity 200ms var(--ease-out), visibility 0s 200ms;
}
#chrome .icon { filter: var(--icon-scrim); }

/* The two dome washes the chrome stands on; they leave with it. */
#chrome::before, #chrome::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  z-index: -1;
  pointer-events: none;
}
#chrome::before {
  top: 0;
  height: 168px;
  background: linear-gradient(180deg, rgba(6, 8, 20, 0.62), rgba(6, 8, 20, 0.28) 45%, transparent);
}
#chrome::after {
  bottom: 0;
  height: 260px;
  background: linear-gradient(0deg, rgba(6, 8, 20, 0.74), rgba(6, 8, 20, 0.62) 38%, rgba(6, 8, 20, 0.26) 68%, transparent);
}

.topbar {
  position: absolute;
  top: var(--s-4);
  left: var(--s-4);
  right: var(--chrome-inset);
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
.ptitle {
  min-width: 0;
  font: var(--t-title);
  font-size: 1rem;
  color: var(--star);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bottom {
  position: absolute;
  left: var(--chrome-inset);
  right: var(--chrome-inset);
  bottom: var(--s-2);
}

.bottombar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  height: 48px;
}
.bar-group {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  min-width: 0;
}

/* A chrome button: no ground, Star glyph, Lamp under the pointer; 40px hit. */
.pbtn {
  position: relative;
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  flex: none;
  min-width: var(--control);
  height: var(--control);
  padding: 0;
  border: 0;
  border-radius: var(--r-sm);
  background: none;
  color: var(--star);
  font: var(--t-title);
  transition: color var(--t-base) var(--ease-out), transform var(--t-fast) var(--ease-out);
}
.pbtn .icon { width: 22px; height: 22px; }
.pbtn:hover { color: var(--lamp); }
.pbtn:active { transform: translateY(1px); }
.pbtn.labeled { padding: 0 var(--s-3) 0 var(--s-2); }

/* The tracking button speaks in tone: a Star Dim glyph when off or busy
   (the word stays Star, so it reads over a bright picture), the whole
   button Ember when the face is lost. */
#trackbtn[data-tone="busy"] .icon, #trackbtn[data-tone="off"] .icon { color: var(--star-dim); }
#trackbtn[data-tone="warn"] { color: var(--ember); }
#trackbtn:hover, #trackbtn:hover .icon { color: var(--lamp); }

.clock {
  margin-left: var(--s-2);
  font: var(--t-title);
  white-space: nowrap;
  color: var(--star);
}

/* Volume: the slider opens beside the mute button on hover or focus. */
.volume {
  display: flex;
  align-items: center;
  pointer-events: auto;
}
.volume input[type="range"] {
  height: var(--control);   /* the 40px hit band; the track stays 2px, centred */
  width: 0;
  opacity: 0;
  margin: 0;
  transition: width var(--t-base) var(--ease-out), opacity var(--t-base) var(--ease-out),
              margin var(--t-base) var(--ease-out);
}
.volume:hover input[type="range"],
.volume:focus-within input[type="range"],
.volume.open input[type="range"] {
  width: 72px;
  opacity: 1;
  margin: 0 var(--s-2) 0 var(--s-1);
}
.volume input[type="range"]::-webkit-slider-thumb { width: 12px; height: 12px; margin-top: -5px; }

/* -- tooltips: the control's name and its key ------------------------ */

[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + var(--s-2));
  left: 50%;
  transform: translateX(-50%);
  padding: var(--s-1) var(--s-2);
  border: 1px solid var(--rail);
  border-radius: var(--r-xs);
  background: var(--seat);
  color: var(--star);
  font: var(--t-label);
  letter-spacing: var(--track-label);
  white-space: nowrap;
  text-shadow: none;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--t-fast) var(--ease-out), visibility 0s var(--t-fast);
}
[data-tip]:hover::after, [data-tip]:focus-visible::after {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--t-fast) var(--ease-out) 350ms, visibility 0s 350ms;
}
/* One tip at a time: the pointer's wins over the keyboard's, which comes
   back when the pointer leaves. */
#chrome:has([data-tip]:hover) [data-tip]:focus-visible:not(:hover)::after {
  opacity: 0;
  visibility: hidden;
  transition: none;
}
.topbar [data-tip]::after { bottom: auto; top: calc(100% + var(--s-2)); left: 0; transform: none; }
[data-tip-end]::after { left: auto; right: 0; transform: none; }
body.chrome-asleep [data-tip]::after { display: none; }

/* -- the seek bar ---------------------------------------------------- */

.seek {
  position: relative;
  pointer-events: auto;
  height: 20px;
  margin: 0 var(--s-2);
  cursor: pointer;
  touch-action: none;
  --played: 0%;
  --buffered: 0%;
  --hover: 0%;
}
.seek:focus-visible { outline-offset: 4px; }
/* The hit band: 40px tall around the 20px bar, without moving the layout,
   the tip or the focus ring.  The bar's buttons come later and keep the
   clicks where the band reaches over them. */
.seek::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -10px;
  bottom: -10px;
}
.seek-rail {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 4px;
  /* Drawn at its hover thickness and scaled down at rest: growing it is a
     transform, not a relayout of the bar on every hover. */
  transform: translateY(-50%) scaleY(0.5);
  border-radius: var(--r-round);
  background: var(--brass-dim);
  box-shadow: 0 1px 2px var(--scrim);
  transition: transform var(--t-fast) var(--ease-out);
}
.seek:hover .seek-rail, .seek.active .seek-rail, .seek:focus-visible .seek-rail { transform: translateY(-50%) scaleY(1); }
.seek-buffered, .seek-hover, .seek-played {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: inherit;
}
.seek-buffered { width: var(--buffered); background: color-mix(in srgb, var(--star-dim) 45%, transparent); }
.seek-hover { width: var(--hover); background: color-mix(in srgb, var(--star) 22%, transparent); opacity: 0; }
.seek:hover .seek-hover { opacity: 1; }
.seek-played { width: var(--played); background: var(--lamp); }
.seek-thumb {
  position: absolute;
  top: 50%;
  left: var(--played);
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  background: var(--lamp);
  box-shadow: 0 0 0 1px var(--scrim);
  transform: scale(0);
  transition: transform var(--t-fast) var(--ease-out);
}
.seek:hover .seek-thumb, .seek.active .seek-thumb, .seek:focus-visible .seek-thumb { transform: scale(1); }
.seek-tip {
  position: absolute;
  bottom: calc(100% + var(--s-1));
  left: var(--hover);
  transform: translateX(-50%);
  padding: 2px 6px;
  border: 1px solid var(--rail);
  border-radius: var(--r-xs);
  background: var(--seat);
  font: var(--t-label);
  letter-spacing: var(--track-label);
  text-shadow: none;
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--t-fast) var(--ease-out);
}
.seek:hover .seek-tip, .seek.active .seek-tip { opacity: 1; }
.seek.unknown { cursor: default; }
.seek.unknown .seek-tip, .seek.unknown .seek-thumb { display: none; }

/* -- diagnostics: the one ground, bottom left, shown with or without the
      chrome (it is for whoever is debugging the steering) --------------- */

.diagnostics {
  position: absolute;
  z-index: 5;
  left: var(--chrome-inset);
  bottom: 120px;
  min-width: 200px;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--rail);
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--seat) 80%, transparent);
  font: var(--t-label);
  letter-spacing: var(--track-label);
  pointer-events: none;
}
.diagnostics .row {
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
}
.diagnostics .key { color: var(--brass); }
.diagnostics .val { color: var(--star); white-space: nowrap; }
.diagnostics .val[data-tone="warn"] { color: var(--ember); opacity: 0.85; }
.diagnostics .val[data-tone="bad"] { color: var(--ember); }

/* -- narrow windows: labels go, icons stay ---------------------------- */

@media (max-width: 640px) {
  /* Hidden from sight, not from the accessibility tree: the words still
     name (or, for tracking, describe) the buttons. */
  .pbtn.labeled span {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
  .pbtn.labeled { padding: 0; }
  .clock { margin-left: 0; font-size: 0.75rem; }
}

@media (prefers-reduced-motion: reduce) {
  .periph-buffer.on::before { animation: none; width: 100%; transform: none; }
  .periph-pulse.on .pulse { animation: none; opacity: 1; transform: none; }
}
