fix(embedded-mpv): make slider track and thumb visible

The timeline and volume sliders were rendering invisibly because:

- --embedded-mpv-accent resolved to var(--mat-sys-primary) with no
  fallback. If the Material 3 theme tokens did not cascade into the
  component scope, the variable was empty and both the thumb and the
  Firefox progress fill rendered with no color.
- The track contrast was 22% of var(--mat-sys-on-surface) which has the
  same scoping fragility on top of being subtle even when it does
  resolve.
- The thumb had no border, so even when accent was present it could
  blend into similarly-toned popover backgrounds.
- The played portion of the timeline had no fill in Chromium because
  ::-webkit-slider-runnable-track does not support a native progress
  state.

Fixes:

- Add hard fallbacks on every theme-token reference (accent falls back to
  #7dd3fc, surface to #0f1620, outline-variant to a translucent white).
- Add --embedded-mpv-track and --embedded-mpv-thumb-ring as theme-
  independent CSS variables so the slider stays legible regardless of
  the parent theme provider.
- Give the thumb a 2 px white ring border + a stronger drop shadow so it
  reads on any background (panel glass, dark backdrop, accent-coloured
  area).
- Implement played-progress fill via a linear-gradient on
  ::-webkit-slider-runnable-track keyed off a CSS variable
  --slider-progress, set per-slider from the template based on the
  current playback position / volume. Firefox uses native
  ::-moz-range-progress.
- Tidy disabled state styling so live-stream timelines (no duration)
  are dim but still visible.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: f957cd9849e0
This commit is contained in:
4grayandClaude Opus 4.7 committed 2026-05-05 10:33:18 +02:00
1 parent 9424dedafc
commit b5dbc33e62
2 files changed
+48 -23

No files matched your search

@@ -128,6 +128,13 @@
<div class="embedded-mpv-player__timeline">
<input
class="embedded-mpv-player__slider"
[style.--slider-progress.%]="
canSeek()
? (timelineValue() /
((session()?.durationSeconds ?? 0) || 1)) *
100
: 0
"
type="range"
min="0"
[max]="session()?.durationSeconds ?? 0"
@@ -185,6 +192,7 @@
>
<input
class="embedded-mpv-player__slider embedded-mpv-player__slider--volume"
[style.--slider-progress.%]="volume() * 100"
type="range"
min="0"
max="1"
@@ -4,13 +4,18 @@
}
.embedded-mpv-player {
--embedded-mpv-accent: var(--mat-sys-primary);
--embedded-mpv-accent: var(--mat-sys-primary, #7dd3fc);
--embedded-mpv-track: rgba(255, 255, 255, 0.28);
--embedded-mpv-thumb-ring: rgba(255, 255, 255, 0.95);
--embedded-mpv-glass: color-mix(
in srgb,
var(--mat-sys-surface) 78%,
var(--mat-sys-surface, #0f1620) 78%,
transparent
);
--embedded-mpv-border: var(--mat-sys-outline-variant);
--embedded-mpv-border: var(
--mat-sys-outline-variant,
rgba(255, 255, 255, 0.16)
);
--embedded-mpv-controls-height: 64px;
position: relative;
@@ -252,9 +257,11 @@
}
.embedded-mpv-player__slider {
--slider-progress: 0%;
width: 100%;
height: 18px;
appearance: none;
-webkit-appearance: none;
background: transparent;
cursor: pointer;
}
@@ -265,26 +272,27 @@
border-radius: 4px;
}
/* WebKit / Chromium */
/* WebKit / Chromium — track shows played portion via linear-gradient. */
.embedded-mpv-player__slider::-webkit-slider-runnable-track {
height: 4px;
border-radius: 999px;
background: color-mix(
in srgb,
var(--mat-sys-on-surface) 22%,
transparent
background: linear-gradient(
to right,
var(--embedded-mpv-accent) var(--slider-progress),
var(--embedded-mpv-track) var(--slider-progress)
);
}
.embedded-mpv-player__slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 14px;
height: 14px;
margin-top: -5px;
border: 0;
border: 2px solid var(--embedded-mpv-thumb-ring);
border-radius: 50%;
background: var(--embedded-mpv-accent);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
transition: transform 120ms ease-out;
}
@@ -293,33 +301,36 @@
transform: scale(1.18);
}
.embedded-mpv-player__slider:disabled::-webkit-slider-runnable-track {
background: var(--embedded-mpv-track);
}
.embedded-mpv-player__slider:disabled::-webkit-slider-thumb {
background: color-mix(
in srgb,
var(--mat-sys-on-surface) 32%,
transparent
);
background: rgba(255, 255, 255, 0.45);
border-color: rgba(255, 255, 255, 0.6);
box-shadow: none;
}
/* Firefox */
/* Firefox — native ::-moz-range-progress for played portion. */
.embedded-mpv-player__slider::-moz-range-track {
height: 4px;
border-radius: 999px;
background: color-mix(
in srgb,
var(--mat-sys-on-surface) 22%,
transparent
);
background: var(--embedded-mpv-track);
}
.embedded-mpv-player__slider::-moz-range-progress {
height: 4px;
border-radius: 999px;
background: var(--embedded-mpv-accent);
}
.embedded-mpv-player__slider::-moz-range-thumb {
width: 14px;
height: 14px;
border: 0;
border: 2px solid var(--embedded-mpv-thumb-ring);
border-radius: 50%;
background: var(--embedded-mpv-accent);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
transition: transform 120ms ease-out;
}
@@ -328,6 +339,12 @@
transform: scale(1.18);
}
.embedded-mpv-player__slider:disabled::-moz-range-thumb {
background: rgba(255, 255, 255, 0.45);
border-color: rgba(255, 255, 255, 0.6);
box-shadow: none;
}
.embedded-mpv-player__control-panel {
min-width: 0;
color: var(--mat-sys-on-surface);