/* ShredMentor shared Playback Volume fader (SM-142) -- extracted VERBATIM from the Player
   app's own fader (templates/player.html + static/css/player.css + static/js/player.js).
   Same image assets (static/images/ui/gpmachine/fader-track.png, fader.png -- referenced by
   the SAME URL below, never duplicated), same CSS rules (.fader-panel/.fader-label/
   .fader-track-container/.fader-handle/.fader-handle:active are byte-identical property
   values to player.css's own -- diff against player.css's "FADER STYLES" block to confirm),
   same "Playback Volume" label text (templates/_playback_volume_fader.html). /app/player
   itself is UNCHANGED by this task -- see ops/agent-tasks/blocked/
   PROPOSED-player-fader-shared-partial.md for the follow-up that points it at this shared
   partial instead of its own inline copy.

   .pv-fader-widget is NEW (does not exist in player.css) -- a page-wide fixed-position
   wrapper, since this partial is dropped into three different page layouts (exercise/
   routine/chain viewers) rather than living inside Player's own flex sidebar column. It
   introduces NO new colors; all visible styling comes from the copied rules below.

   SM-166 (2026-07-24): fixes two production defects Jason reported after SM-142 shipped --
   (a) the fader overlapped page content (buttons/text/labels) at most non-phone widths
   because nothing reserved space for it; (b) it was unresponsive to touch on iPad. See the
   two new sections at the END of this file (after the verbatim-copied block) for both
   fixes -- neither one touches the 5 rules above, which stay byte-identical to player.css
   (Sm142SharedAssetContentTests.test_fader_css_rules_are_byte_identical_to_player_css keeps
   passing unmodified). */

.pv-fader-widget {
  position: fixed;
  right: 14px;
  top: calc(var(--nav-h, 54px) + 24px);
  z-index: 500;
}

/* SM-270 global phone rule (Jason, 2026-08-05): "PHONES DON'T NEED THE FADER AT
   ALL EVER." The established 760px breakpoint comes from this component's own SM-166
   lineage, Exercise Viewer's mobile rules, and mobile-view.js. .pv-fader-widget covers
   the page-wide partial; .pv-fader-mount is added by the shared JS to EVERY mount() and
   mountInline() host. Hiding the host (not merely its panel) reclaims flex/grid gaps and
   columns completely. !important deliberately beats consumer styling such as
   .msq-fader-host { display:inline-flex } that can load later in the cascade. */
@media (max-width: 760px) {
  .pv-fader-widget,
  .pv-fader-mount {
    display: none !important;
  }
}

/* ---- Everything below is copied VERBATIM from static/css/player.css's FADER STYLES
   block (.fader-panel through .fader-handle:active) -- same class names, same property
   values, so a rule-by-rule diff against player.css is exact. ---- */

.fader-panel {
  background: #222;
  border: 2px solid #444;
  padding: 5px;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.1);
  width: 80px;
  display: inline-block;
  text-align: center;
}

.fader-label {
  font-size: 14px;
  margin-bottom: 20px;
  display: block;
  font-family: "Archivo Narrow", sans-serif;
  font-optical-sizing: auto;
  font-weight: bold;
  font-style: normal;
}

.fader-track-container {
  position: relative;
  width: 20px;
  height: 200px;
  margin: 0 auto;
  background: url("/app/static/images/ui/gpmachine/fader-track.png") no-repeat center;
  background-size: contain;
}

.fader-handle {
  position: absolute;
  width: 20px;
  height: 60px;
  background: url("/app/static/images/ui/gpmachine/fader.png") no-repeat center;
  background-size: contain;
  top: 70px;
  left: 50%;
  transform: translateX(-50%);
  cursor: grab;
}

.fader-handle:active {
  cursor: grabbing;
}

/* ────────────────────────────────────────────────────────────────────────────
   SM-166 (a) -- LANE: reserve a REAL layout lane down the right edge of every
   page that includes this partial, at every width where the fader can show, so
   content never renders under/behind it (Jason: "carve a lane... basically a
   thin sidebar that's the width of the fader DIV"). This is padding-right on
   `.ev-page` -- the one content wrapper exercise_viewer.html/routine_viewer.html/
   chain_viewer.html all already use -- not z-index.

   `.ev-page`'s own inline `style="...padding:24px 20px 80px;"` (set directly in
   those three templates) already wins over a plain external rule for the SAME
   longhand property, so this is `!important` -- the SAME established technique
   this exact element already uses at the OPPOSITE (mobile) breakpoint, see
   static/exercise-viewer/exercise-viewer.css's own
   `.ev-page { max-width: none !important; margin: 0 !important; padding: 0 !important; }`
   inside its `@media (max-width: 760px), (max-height: 480px)` block.

   `html body` is prepended purely to WIN CSS specificity over that same mobile
   rule in the one edge case where both conditions can be true at once:
   exercise-viewer.css's rule ALSO fires on `(max-height: 480px)` alone,
   independent of width (e.g. a landscape phone, iPhone XR 896x414 -- width 896
   is comfortably > 760 so THIS widget's own hide rule above does NOT hide it,
   but the mobile full-bleed player rule still zeroes .ev-page's padding on all
   four sides there). Boosting specificity to (0,1,2) beats exercise-viewer.css's
   bare `.ev-page` at (0,1,0) DETERMINISTICALLY regardless of <link> declaration
   order, so in that landscape-phone edge case the OTHER three sides stay
   full-bleed (matching the mobile player's intended layout) while the right
   side still reserves the lane, because the widget genuinely is still showing
   there. exercise-viewer.css itself is untouched (forbidden path).

   VALUE (130px), decomposed:
     20px -- .ev-page's own original right gutter/padding, preserved as-is
     14px -- .pv-fader-widget's own `right` offset (unchanged, see above)
     84px -- .fader-panel's rendered width: its own `width: 80px` declaration
             above IS already its full outer width (theme.css's sitewide
             `*, *::before, *::after { box-sizing: border-box; }` reset means
             padding/border are carved OUT of that 80px, not added on top),
             +4px safety margin for the few px of shrink-to-fit inline-block
             whitespace .pv-fader-widget (auto width, no own padding/border)
             computes around its single .fader-panel child
     12px -- extra breathing room so content never touches the fader's edge
             pixel-for-pixel
     = 130px total.

   Proof this clears the fader at EVERY width >= 761px (not just spot-checked
   ones), not just this one value: see the SM-166 completion report for the
   full algebraic derivation (content's right edge stays >= 32px clear of the
   fader's left edge at the narrowest qualifying width, 761px, and the margin
   only grows from there as natural centering takes over above ~1100px). */
@media (min-width: 761px) {
  html body .ev-page {
    padding-right: 130px !important;
  }
}

/* SM-814: a page whose fader was mounted by ensurePageFader() (a blog post,
   announcement or lesson carrying embedded players) reserves the same 130px
   right lane on its content, so the one page fader stays OUT of the content
   container. Phones hide the fader, so the lane only exists where it shows. */
@media (min-width: 761px) {
  body.pv-page-fader-auto .sm-content {
    padding-right: 130px;
  }
}

/* ────────────────────────────────────────────────────────────────────────────
   SM-166 (b) -- TOUCH: dragging the fader handle must never scroll the page on
   a touch device (iPad-class). `touch-action: none` on both the handle (the
   actual drag target) and its track container (so a finger landing just off
   the handle, still within the track's hit area, doesn't trigger a page pan
   before Pointer Events even get a chance to call preventDefault()). Belt-and-
   suspenders alongside the JS's own `e.preventDefault()` in its pointerdown
   handler (see playback-volume-fader.js) -- touch-action is the CSS-level
   guarantee some browsers require for touch specifically, since preventDefault
   on a pointerdown/pointermove is not universally honored for scroll
   suppression the way it is for mouse. */
.fader-track-container,
.fader-handle {
  touch-action: none;
}
