feat(player): clip mode - mark a range of what is playing and cut it into a download
Both players get a scissors in their control row (Plex: the control row; YouTube: the actions and the docked bar), `c`, and `[` / `]` to mark at the playhead. The clip panel lives in the player, so the watched video is the preview: an overview of the whole item and a zoomed strip around the selection whose ends are sliders (arrows step a tenth, Shift a second), Start / End fields with nudges and "to the playhead", the length, a looping Play selection, a name, Cut. Escape closes the panel before the player and the focus goes back to the scissors. A cut is a toast with a Downloads link plus the usual Ready notification. - ui/RangeTrack + RulerTicks: the shared, domain-free time track (regions, keyboard-steppable handles with a 1.5rem hit area, a playhead, a background slot, over a window of the item). The Downloads editor's cuts moved onto it, so they are keyboard-steppable now. - lib/clipRange holds the marking rules (1 s to 10 min, the server's), lib/timecode the editing timecode the editor's private tc/parseTc became. - keymap: a symbol typed through AltGr answers its bare-symbol row - on the HU layout `[` is AltGr+F, which arrives as Ctrl+Alt; letter and Mod rows still never match Ctrl+Alt. - The YouTube stage sits in a wrapper with the panel, so the maximised stage's blur escape matches at any depth. - media-scope: fields on the always-dark player chrome read white in a light theme too.
This commit is contained in:
+16
-2
@@ -142,6 +142,18 @@
|
||||
border-color: var(--edge-strong);
|
||||
}
|
||||
|
||||
/* A form on the always-dark player chrome (the clip panel's fields): the neutral tokens the field
|
||||
primitives read are re-pointed to white-on-chrome for this subtree, so a light theme's dark text
|
||||
never lands on the dark bar. The accent stays the theme's. */
|
||||
@utility media-scope {
|
||||
--fg: #ffffff;
|
||||
--muted: rgb(255 255 255 / 0.62);
|
||||
--bg: var(--media-chrome);
|
||||
--border: rgb(255 255 255 / 0.16);
|
||||
--edge-strong: rgb(255 255 255 / 0.4);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
/* The reading measure for prose (a synopsis, a biography, a channel's description): ~65 characters
|
||||
a line, inside the 45–75 a reader follows back to the next line's start. A full-width page ran
|
||||
one to 110 (owner: "shorter lines are easier to follow"). Only where the container can
|
||||
@@ -280,6 +292,7 @@
|
||||
a:focus-visible,
|
||||
[role="button"]:focus-visible,
|
||||
[role="tab"]:focus-visible,
|
||||
[role="slider"]:focus-visible,
|
||||
summary:focus-visible {
|
||||
/* Solid accent: the earlier 60% mix all but vanished on the dark glass. */
|
||||
outline: 2px solid var(--accent);
|
||||
@@ -1191,9 +1204,10 @@ html[data-theme="light"] {
|
||||
}
|
||||
/* …and it only fills the viewport while no ancestor has a filter: a `backdrop-filter` makes that
|
||||
ancestor the fixed stage's containing block. The modal's card is a blurred `.glass` panel,
|
||||
so while the stage is maximised the card drops its blur — the stage covers the card anyway. `html `
|
||||
so while the stage is maximised the card drops its blur — the stage covers the card anyway. Any
|
||||
depth: the stage sits in a wrapper with the clip panel. `html `
|
||||
outranks `html[data-theme="dark"] .glass`, which sets the blur again (lib/playerStage.contract.test.ts). */
|
||||
html .glass:has(> .player-stage--max) {
|
||||
html .glass:has(.player-stage--max) {
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user