cursedbelt 3.0.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/dist/react/components/ListToolbar.d.ts +94 -0
  2. package/dist/react/components/ListToolbar.d.ts.map +1 -0
  3. package/dist/react/components/ListToolbar.js +66 -0
  4. package/dist/react/components/ListToolbar.js.map +1 -0
  5. package/dist/react/file-tree/FileTree.d.ts +282 -3
  6. package/dist/react/file-tree/FileTree.d.ts.map +1 -1
  7. package/dist/react/file-tree/FileTree.js +799 -131
  8. package/dist/react/file-tree/FileTree.js.map +1 -1
  9. package/dist/react/file-tree/fileTree.css +151 -0
  10. package/dist/react/file-tree/fileTreeSelection.d.ts +187 -0
  11. package/dist/react/file-tree/fileTreeSelection.d.ts.map +1 -0
  12. package/dist/react/file-tree/fileTreeSelection.js +264 -0
  13. package/dist/react/file-tree/fileTreeSelection.js.map +1 -0
  14. package/dist/react/file-tree/index.d.ts +1 -0
  15. package/dist/react/file-tree/index.d.ts.map +1 -1
  16. package/dist/react/file-tree/index.js +8 -0
  17. package/dist/react/file-tree/index.js.map +1 -1
  18. package/dist/react/index.d.ts +1 -0
  19. package/dist/react/index.d.ts.map +1 -1
  20. package/dist/react/index.js +1 -0
  21. package/dist/react/index.js.map +1 -1
  22. package/dist/react/lib/form.d.ts +3 -0
  23. package/dist/react/lib/form.d.ts.map +1 -1
  24. package/dist/react/lib/form.js +43 -5
  25. package/dist/react/lib/form.js.map +1 -1
  26. package/dist/react/media/DenseGalleryShell.d.ts +19 -3
  27. package/dist/react/media/DenseGalleryShell.d.ts.map +1 -1
  28. package/dist/react/media/DenseGalleryShell.js +55 -15
  29. package/dist/react/media/DenseGalleryShell.js.map +1 -1
  30. package/dist/react/media/FocusViewer.d.ts.map +1 -1
  31. package/dist/react/media/FocusViewer.js +14 -14
  32. package/dist/react/media/FocusViewer.js.map +1 -1
  33. package/dist/react/media/FrameGrabber.d.ts +23 -0
  34. package/dist/react/media/FrameGrabber.d.ts.map +1 -1
  35. package/dist/react/media/FrameGrabber.js +67 -1
  36. package/dist/react/media/FrameGrabber.js.map +1 -1
  37. package/dist/react/media/MediaResize.d.ts +51 -19
  38. package/dist/react/media/MediaResize.d.ts.map +1 -1
  39. package/dist/react/media/MediaResize.js +20 -13
  40. package/dist/react/media/MediaResize.js.map +1 -1
  41. package/dist/react/media/VideoChapterEditor.d.ts +67 -0
  42. package/dist/react/media/VideoChapterEditor.d.ts.map +1 -0
  43. package/dist/react/media/VideoChapterEditor.js +148 -0
  44. package/dist/react/media/VideoChapterEditor.js.map +1 -0
  45. package/dist/react/media/VideoPlayer.d.ts +46 -4
  46. package/dist/react/media/VideoPlayer.d.ts.map +1 -1
  47. package/dist/react/media/VideoPlayer.js +124 -11
  48. package/dist/react/media/VideoPlayer.js.map +1 -1
  49. package/dist/react/media/VideoTurner.d.ts +15 -2
  50. package/dist/react/media/VideoTurner.d.ts.map +1 -1
  51. package/dist/react/media/VideoTurner.js +29 -2
  52. package/dist/react/media/VideoTurner.js.map +1 -1
  53. package/dist/react/media/denseGallery.css +104 -46
  54. package/dist/react/media/hlsSource.d.ts +57 -0
  55. package/dist/react/media/hlsSource.d.ts.map +1 -1
  56. package/dist/react/media/hlsSource.js +177 -1
  57. package/dist/react/media/hlsSource.js.map +1 -1
  58. package/dist/react/media/index.d.ts +2 -0
  59. package/dist/react/media/index.d.ts.map +1 -1
  60. package/dist/react/media/index.js +6 -0
  61. package/dist/react/media/index.js.map +1 -1
  62. package/dist/react/media/mediaResize.css +127 -54
  63. package/dist/react/media/pictureEditor.css +52 -6
  64. package/dist/react/media/videoChapterEditor.css +203 -0
  65. package/dist/react/media/videoChapters.d.ts +117 -0
  66. package/dist/react/media/videoChapters.d.ts.map +1 -0
  67. package/dist/react/media/videoChapters.js +95 -0
  68. package/dist/react/media/videoChapters.js.map +1 -0
  69. package/dist/react/media-gallery/GalleryTable.d.ts +52 -1
  70. package/dist/react/media-gallery/GalleryTable.d.ts.map +1 -1
  71. package/dist/react/media-gallery/GalleryTable.js +40 -9
  72. package/dist/react/media-gallery/GalleryTable.js.map +1 -1
  73. package/dist/react/media-gallery/MediaGallery.d.ts +107 -4
  74. package/dist/react/media-gallery/MediaGallery.d.ts.map +1 -1
  75. package/dist/react/media-gallery/MediaGallery.js +484 -104
  76. package/dist/react/media-gallery/MediaGallery.js.map +1 -1
  77. package/dist/react/media-gallery/MediaMetaEditor.d.ts +48 -0
  78. package/dist/react/media-gallery/MediaMetaEditor.d.ts.map +1 -0
  79. package/dist/react/media-gallery/MediaMetaEditor.js +66 -0
  80. package/dist/react/media-gallery/MediaMetaEditor.js.map +1 -0
  81. package/dist/react/media-gallery/index.d.ts +2 -0
  82. package/dist/react/media-gallery/index.d.ts.map +1 -1
  83. package/dist/react/media-gallery/index.js +5 -0
  84. package/dist/react/media-gallery/index.js.map +1 -1
  85. package/dist/react/media-gallery/mediaGallery.css +180 -4
  86. package/dist/react/media-gallery/mediaMeta.d.ts +62 -0
  87. package/dist/react/media-gallery/mediaMeta.d.ts.map +1 -0
  88. package/dist/react/media-gallery/mediaMeta.js +56 -0
  89. package/dist/react/media-gallery/mediaMeta.js.map +1 -0
  90. package/dist/react/media-gallery/playbackPreferences.d.ts +77 -0
  91. package/dist/react/media-gallery/playbackPreferences.d.ts.map +1 -1
  92. package/dist/react/media-gallery/playbackPreferences.js +42 -0
  93. package/dist/react/media-gallery/playbackPreferences.js.map +1 -1
  94. package/dist/react/media-gallery/types.d.ts +34 -0
  95. package/dist/react/media-gallery/types.d.ts.map +1 -1
  96. package/dist/scripts/guardrailsEnforce.d.ts +29 -0
  97. package/dist/scripts/guardrailsEnforce.d.ts.map +1 -0
  98. package/dist/styles-areas/activity-bar.css +30 -0
  99. package/dist/styles-areas/analytics.css +672 -0
  100. package/dist/styles-areas/auth.css +154 -0
  101. package/dist/styles-areas/calendar.css +416 -0
  102. package/dist/styles-areas/chart-table.css +41 -0
  103. package/dist/styles-areas/charts.css +89 -0
  104. package/dist/styles-areas/chat.css +364 -0
  105. package/dist/styles-areas/clipboard.css +26 -0
  106. package/dist/styles-areas/code-editor.css +130 -0
  107. package/dist/styles-areas/companion-link.css +70 -0
  108. package/dist/styles-areas/core.css +2503 -0
  109. package/dist/styles-areas/dashboard-grid.css +84 -0
  110. package/dist/styles-areas/data-table.css +657 -0
  111. package/dist/styles-areas/deep-link.css +26 -0
  112. package/dist/styles-areas/diff-viewer.css +30 -0
  113. package/dist/styles-areas/disk-usage.css +262 -0
  114. package/dist/styles-areas/emoji.css +154 -0
  115. package/dist/styles-areas/fields.css +582 -0
  116. package/dist/styles-areas/file-tree.css +33 -0
  117. package/dist/styles-areas/filter-rail.css +235 -0
  118. package/dist/styles-areas/folder-tree.css +219 -0
  119. package/dist/styles-areas/keep-awake.css +26 -0
  120. package/dist/styles-areas/layout-engine.css +239 -0
  121. package/dist/styles-areas/markdown.css +87 -0
  122. package/dist/styles-areas/master-detail.css +239 -0
  123. package/dist/styles-areas/master-lock.css +26 -0
  124. package/dist/styles-areas/media-gallery.css +351 -0
  125. package/dist/styles-areas/media.css +658 -0
  126. package/dist/styles-areas/nav.css +488 -0
  127. package/dist/styles-areas/notifications.css +245 -0
  128. package/dist/styles-areas/overlays.css +133 -0
  129. package/dist/styles-areas/palette.css +140 -0
  130. package/dist/styles-areas/pdf-viewer.css +47 -0
  131. package/dist/styles-areas/problem-detail.css +97 -0
  132. package/dist/styles-areas/rich-text.css +167 -0
  133. package/dist/styles-areas/sharing.css +153 -0
  134. package/dist/styles-areas/spreadsheet.css +37 -0
  135. package/dist/styles-areas/stats.css +281 -0
  136. package/dist/styles-areas/test-report.css +133 -0
  137. package/dist/styles-areas/virtual.css +30 -0
  138. package/dist/styles-areas/wizard.css +381 -0
  139. package/dist/styles-areas/workbench.css +543 -0
  140. package/dist/styles-areas/workbook-viewer.css +44 -0
  141. package/dist/styles-static.css +34 -23
  142. package/dist/styles.css +34 -23
  143. package/package.json +111 -31
  144. package/scripts/checkDistExports.ts +67 -0
  145. package/scripts/cssRules.ts +125 -0
  146. package/scripts/fixtureAppCss.ts +344 -0
  147. package/scripts/generateAreaStyles.ts +253 -0
  148. package/scripts/guardrailsEnforce.spec.ts +62 -0
  149. package/scripts/guardrailsEnforce.ts +67 -3
  150. package/scripts/styleAreas.ts +585 -0
  151. package/scripts/verify.ts +5 -0
  152. package/src/barrelsReachNoOptionalPeer.spec.ts +117 -9
  153. package/src/docsMatchTheSplit.spec.ts +98 -0
  154. package/src/fixtureAppCss.spec.ts +177 -0
  155. package/src/namedSubpathsResolve.spec.ts +35 -0
  156. package/src/publishShape.spec.ts +67 -0
  157. package/src/react/components/ListToolbar.spec.tsx +172 -0
  158. package/src/react/components/ListToolbar.tsx +151 -0
  159. package/src/react/file-tree/FileTree.spec.tsx +1009 -0
  160. package/src/react/file-tree/FileTree.tsx +1459 -309
  161. package/src/react/file-tree/fileTree.css +151 -0
  162. package/src/react/file-tree/fileTreeSelection.spec.ts +327 -0
  163. package/src/react/file-tree/fileTreeSelection.ts +321 -0
  164. package/src/react/file-tree/index.ts +21 -0
  165. package/src/react/index.ts +1 -0
  166. package/src/react/lib/form.ts +51 -8
  167. package/src/react/media/DenseGalleryShell.tsx +108 -36
  168. package/src/react/media/FocusViewer.tsx +15 -8
  169. package/src/react/media/FrameGrabber.spec.tsx +175 -0
  170. package/src/react/media/FrameGrabber.tsx +67 -0
  171. package/src/react/media/MediaResize.spec.tsx +84 -14
  172. package/src/react/media/MediaResize.tsx +51 -19
  173. package/src/react/media/VideoChapterEditor.tsx +428 -0
  174. package/src/react/media/VideoPlayer.spec.tsx +111 -1
  175. package/src/react/media/VideoPlayer.tsx +158 -11
  176. package/src/react/media/VideoTurner.spec.tsx +67 -0
  177. package/src/react/media/VideoTurner.tsx +70 -15
  178. package/src/react/media/denseGallery.css +104 -46
  179. package/src/react/media/hlsSource.recovery.spec.ts +213 -0
  180. package/src/react/media/hlsSource.spec.ts +8 -0
  181. package/src/react/media/hlsSource.ts +189 -1
  182. package/src/react/media/index.ts +14 -0
  183. package/src/react/media/mediaResize.css +127 -54
  184. package/src/react/media/pictureEditor.css +52 -6
  185. package/src/react/media/videoChapterEditor.css +203 -0
  186. package/src/react/media/videoChapters.spec.ts +176 -0
  187. package/src/react/media/videoChapters.ts +181 -0
  188. package/src/react/media-gallery/GalleryTable.tsx +93 -3
  189. package/src/react/media-gallery/MediaGallery.spec.tsx +1156 -10
  190. package/src/react/media-gallery/MediaGallery.tsx +813 -95
  191. package/src/react/media-gallery/MediaMetaEditor.tsx +237 -0
  192. package/src/react/media-gallery/galleryTable.spec.ts +41 -1
  193. package/src/react/media-gallery/index.ts +7 -0
  194. package/src/react/media-gallery/mediaGallery.css +180 -4
  195. package/src/react/media-gallery/mediaMeta.spec.ts +95 -0
  196. package/src/react/media-gallery/mediaMeta.ts +101 -0
  197. package/src/react/media-gallery/playbackPreferences.spec.ts +172 -0
  198. package/src/react/media-gallery/playbackPreferences.ts +100 -0
  199. package/src/react/media-gallery/types.ts +34 -0
  200. package/src/shippedFilesAreTracked.spec.ts +69 -0
  201. package/src/styles-areas/activity-bar.css +30 -0
  202. package/src/styles-areas/analytics.css +672 -0
  203. package/src/styles-areas/auth.css +154 -0
  204. package/src/styles-areas/calendar.css +416 -0
  205. package/src/styles-areas/chart-table.css +41 -0
  206. package/src/styles-areas/charts.css +89 -0
  207. package/src/styles-areas/chat.css +364 -0
  208. package/src/styles-areas/clipboard.css +26 -0
  209. package/src/styles-areas/code-editor.css +130 -0
  210. package/src/styles-areas/companion-link.css +70 -0
  211. package/src/styles-areas/core.css +2503 -0
  212. package/src/styles-areas/dashboard-grid.css +84 -0
  213. package/src/styles-areas/data-table.css +657 -0
  214. package/src/styles-areas/deep-link.css +26 -0
  215. package/src/styles-areas/diff-viewer.css +30 -0
  216. package/src/styles-areas/disk-usage.css +262 -0
  217. package/src/styles-areas/emoji.css +154 -0
  218. package/src/styles-areas/fields.css +582 -0
  219. package/src/styles-areas/file-tree.css +33 -0
  220. package/src/styles-areas/filter-rail.css +235 -0
  221. package/src/styles-areas/folder-tree.css +219 -0
  222. package/src/styles-areas/keep-awake.css +26 -0
  223. package/src/styles-areas/layout-engine.css +239 -0
  224. package/src/styles-areas/markdown.css +87 -0
  225. package/src/styles-areas/master-detail.css +239 -0
  226. package/src/styles-areas/master-lock.css +26 -0
  227. package/src/styles-areas/media-gallery.css +351 -0
  228. package/src/styles-areas/media.css +658 -0
  229. package/src/styles-areas/nav.css +488 -0
  230. package/src/styles-areas/notifications.css +245 -0
  231. package/src/styles-areas/overlays.css +133 -0
  232. package/src/styles-areas/palette.css +140 -0
  233. package/src/styles-areas/pdf-viewer.css +47 -0
  234. package/src/styles-areas/problem-detail.css +97 -0
  235. package/src/styles-areas/rich-text.css +167 -0
  236. package/src/styles-areas/sharing.css +153 -0
  237. package/src/styles-areas/spreadsheet.css +37 -0
  238. package/src/styles-areas/stats.css +281 -0
  239. package/src/styles-areas/test-report.css +133 -0
  240. package/src/styles-areas/virtual.css +30 -0
  241. package/src/styles-areas/wizard.css +381 -0
  242. package/src/styles-areas/workbench.css +543 -0
  243. package/src/styles-areas/workbook-viewer.css +44 -0
  244. package/src/styles-static.css +34 -23
  245. package/src/styles.css +34 -23
  246. package/src/stylesAreas.spec.ts +247 -0
  247. package/src/stylesUtilitiesMatches.spec.ts +6 -77
  248. package/src/testFilesRunInParallel.spec.ts +79 -0
  249. package/src/typecheckCachesAreSeparate.spec.ts +128 -0
  250. package/src/verifyGraph.spec.ts +6 -0
@@ -2,10 +2,12 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import '@vidstack/react/player/styles/default/theme.css';
3
3
  import '@vidstack/react/player/styles/default/layouts/video.css';
4
4
  import './videoPlayer.css';
5
- import { Gesture, isHLSProvider, MediaPlayer, MediaProvider, Poster, } from '@vidstack/react';
5
+ import { Gesture, isHLSProvider, MediaPlayer, MediaProvider, Poster, Track, useMediaState, } from '@vidstack/react';
6
6
  import { DefaultVideoLayout, defaultLayoutIcons, } from '@vidstack/react/player/layouts/default';
7
7
  import { useEffect, useMemo, useRef, useState } from 'react';
8
+ import { PLAYER_VOLUME_KEY, readSessionVolume, writeSessionVolume, } from '../media-gallery/playbackPreferences';
8
9
  import { isSurfaceControl } from './surfaceGesture';
10
+ import { chapterSpans } from './videoChapters';
9
11
  /**
10
12
  * Toggle browser fullscreen when a double-click landed on the PICTURE rather than on a
11
13
  * control — the whole of the 2026-09-11 fix, as a free function so it can be asserted
@@ -193,17 +195,39 @@ export const AUTOPLAY_DEFAULT = true;
193
195
  * preference", which is the behavior everything had before this existed.
194
196
  */
195
197
  /**
196
- * The autoplay decision, as a pure function so it can be asserted without a browser.
198
+ * The autoplay decision — and, since 2026-09-16, how loud the clip opens.
197
199
  *
198
200
  * 🔴 It is extracted rather than inlined because nothing below a real browser can see the
199
201
  * difference: `autoPlay` and `muted` are two props on one JSX element, and swapping them,
200
202
  * dropping the reduced-motion term, or letting `muted` default independently all typecheck
201
203
  * and render identically under happy-dom. The same reasoning `posterFraming.ts` and
202
204
  * `mediaGalleryModel.ts` already apply to their own decisions.
205
+ *
206
+ * ── 🔴 Where `session` sits in the precedence, and why ──────────────────────────────────
207
+ * Owner, `ideas/collections-09-14.md`: *"Keep the media player volume where I set it after
208
+ * changing it during a session except if I refresh or first log in then continue starting it
209
+ * at mute. Then if I unmute it, keep that value as I change to other videos."*
210
+ *
211
+ * · an explicit `muted` prop still wins — an app that says "silent" means silent
212
+ * · then what he set THIS SESSION ({@link readSessionVolume}, `null` until he touches it)
213
+ * · then the old rule: muted follows autoPlay, because an unmuted autoplay is refused
214
+ *
215
+ * A `null` session is therefore byte-for-byte the behavior every consumer had before this
216
+ * existed, which is what makes "a refresh starts at mute" true rather than merely intended:
217
+ * a fresh tab has no session entry, so a fresh tab takes the third line.
218
+ *
219
+ * `volume` is returned separately from `muted` on purpose — see {@link SessionVolume}. A mute
220
+ * stored as `volume: 0` would make the control bar's unmute button return to silence, and
221
+ * *"if I unmute it, keep that value"* is the sentence that forbids it.
203
222
  */
204
223
  export function resolveAutoplay(opts) {
205
224
  const autoPlay = (opts.autoPlay ?? AUTOPLAY_DEFAULT) && !opts.reducedMotion;
206
- return { autoPlay, muted: opts.muted ?? autoPlay };
225
+ const session = opts.session ?? null;
226
+ return {
227
+ autoPlay,
228
+ muted: opts.muted ?? session?.muted ?? autoPlay,
229
+ volume: session?.volume ?? 1,
230
+ };
207
231
  }
208
232
  /**
209
233
  * 🔴 Make the picture follow the scrub bar WHILE it is dragged, not only on release.
@@ -315,22 +339,36 @@ export function usePrefersReducedMotion() {
315
339
  });
316
340
  return reduced;
317
341
  }
318
- export function VideoPlayer({ video, autoPlay, muted, className, aspectRatio = DEFAULT_VIDEO_ASPECT_RATIO, onEnded, loop, liveScrub = true, smallLayoutWhen = isSmallVideoLayout, onStep, canStep = true, fullscreenOnDoubleClick = true, }) {
342
+ export function VideoPlayer({ video, autoPlay, muted, volumeKey = PLAYER_VOLUME_KEY, className, aspectRatio = DEFAULT_VIDEO_ASPECT_RATIO, onEnded, loop, liveScrub = true, smallLayoutWhen = isSmallVideoLayout, onStep, canStep = true, fullscreenOnDoubleClick = true, }) {
319
343
  // Prefer the adaptive HLS master; fall back to the progressive Range source.
320
344
  const src = video.hlsUrl
321
345
  ? { src: video.hlsUrl, type: 'application/x-mpegurl' }
322
346
  : video.streamUrl;
323
347
  // See AUTOPLAY_DEFAULT. `muted` follows `autoPlay` because an unmuted autoplay is refused
324
- // by every browser and the refusal LOOKS like the spinner this batch removed.
348
+ // by every browser and the refusal LOOKS like the spinner this batch removed — unless he
349
+ // has already set a level on this surface this session, which is what `session` carries.
325
350
  const reducedMotion = usePrefersReducedMotion();
326
- const { autoPlay: shouldAutoPlay, muted: shouldMute } = resolveAutoplay({
327
- autoPlay,
328
- muted,
329
- reducedMotion,
330
- });
351
+ // 🔴 Read ONCE, on mount, and never again: this is a starting value handed to a player that
352
+ // owns its own volume state from then on. Re-reading it on a later render would fight the
353
+ // control bar he is holding, and stepping to the next clip remounts this component anyway,
354
+ // which is exactly when the remembered level is supposed to be applied.
355
+ const [session] = useState(() => readSessionVolume(volumeKey));
356
+ const { autoPlay: shouldAutoPlay, muted: shouldMute, volume: startVolume, } = resolveAutoplay({ autoPlay, muted, reducedMotion, session });
331
357
  const hostRef = useRef(null);
332
358
  const playerRef = useRef(null);
333
359
  useLiveScrub(hostRef, playerRef, liveScrub);
360
+ /*
361
+ * 🔴 What is on the element right now, so the RESTORE is not mistaken for a change.
362
+ *
363
+ * Applying `volume`/`muted` above makes the element fire `volumechange` like any other
364
+ * change, so a naive listener writes the starting value straight back — minting a remembered
365
+ * preference for a person who has touched nothing, on every player that mounts. That
366
+ * quietly turns "he has not set a volume" into "he set it to the default", which is the one
367
+ * distinction `readSessionVolume` returns `null` to preserve.
368
+ */
369
+ const applied = useRef({ volume: startVolume, muted: shouldMute });
370
+ /** A mute the BROWSER forced on us — see `onAutoPlayFail` below. Never his choice, so never stored. */
371
+ const forcedMute = useRef(false);
334
372
  const status = video.processingStatus;
335
373
  const showProcessing = status != null && status !== 'ready';
336
374
  // Memoized because `slots` holds React elements: a fresh object every render remounts
@@ -346,10 +384,45 @@ export function VideoPlayer({ video, autoPlay, muted, className, aspectRatio = D
346
384
  // `preferBundledHls` — without it an adaptive ladder depends on a third-party CDN
347
385
  // and fails as a permanent spinner when that CDN is unreachable.
348
386
  onProviderChange: preferBundledHls, title: video.name, poster: video.posterUrl, crossOrigin: true, playsInline: true, autoPlay: shouldAutoPlay, muted: shouldMute,
387
+ // 🔴 The level he set this session, restored on the element — see `resolveAutoplay`
388
+ // and `SessionVolume`. Both values are constant for the life of this mount, so
389
+ // Vidstack's own volume state is never overwritten while he is using the control bar;
390
+ // the next clip is a fresh mount, which is when the restore is meant to happen.
391
+ volume: startVolume,
392
+ /* 🔴 Read off the PLAYER, not off a React slider: he changes this in Vidstack's own
393
+ control bar (or with ↑/↓), which no React-side state can see. `volume-change` fires
394
+ for both facts at once, which is the shape `SessionVolume` stores. */
395
+ onVolumeChange: (detail) => {
396
+ // The echo of our own restore is not a change he made. See `applied`.
397
+ if (detail.volume === applied.current.volume && detail.muted === applied.current.muted)
398
+ return;
399
+ applied.current = { volume: detail.volume, muted: detail.muted };
400
+ if (forcedMute.current) {
401
+ // The browser's refusal, not his preference — leave the stored level alone so
402
+ // unmuting still returns to it.
403
+ forcedMute.current = false;
404
+ return;
405
+ }
406
+ writeSessionVolume(volumeKey, applied.current);
407
+ },
408
+ /* 🔴 A restored volume must not be able to break the slideshow.
409
+ `playbackRun.ts` drives whole folders by mounting the next clip with `autoPlay`,
410
+ and a browser refuses an unmuted autoplay without a prior gesture — so a session
411
+ that remembers "unmuted" could, on the first clip after a restore, leave the run
412
+ sitting on frame one. Falling back to a muted play keeps the run running; the level
413
+ stays on the element, so one press of unmute is still HIS level rather than full. */
414
+ onAutoPlayFail: (detail) => {
415
+ const player = playerRef.current;
416
+ if (!player || detail.muted)
417
+ return;
418
+ forcedMute.current = true;
419
+ player.muted = true;
420
+ void player.play().catch(() => { });
421
+ },
349
422
  // Load eagerly rather than on-visible: the watch surface can size to a
350
423
  // zero-height box during iOS Safari's container-query resolution, so a
351
424
  // `visible` gate never fired and the player sat on a perpetual spinner.
352
- load: 'eager', viewType: 'video', aspectRatio: aspectRatio, className: className, style: { width: '100%', height: '100%', maxHeight: '100%' }, loop: loop, onEnded: onEnded, children: [_jsxs(MediaProvider, { children: [video.posterUrl ? (_jsx(Poster, { className: 'vds-poster', src: video.posterUrl, alt: video.name })) : null, _jsx(Gesture, { className: 'vds-gesture', event: 'pointerup', action: 'toggle:paused' })] }), _jsx(DefaultVideoLayout, { icons: defaultLayoutIcons, thumbnails: video.vttUrl,
425
+ load: 'eager', viewType: 'video', aspectRatio: aspectRatio, className: className, style: { width: '100%', height: '100%', maxHeight: '100%' }, loop: loop, onEnded: onEnded, children: [_jsxs(MediaProvider, { children: [video.posterUrl ? (_jsx(Poster, { className: 'vds-poster', src: video.posterUrl, alt: video.name })) : null, _jsx(Gesture, { className: 'vds-gesture', event: 'pointerup', action: 'toggle:paused' }), _jsx(ChaptersTrack, { chapters: video.chapters })] }), _jsx(DefaultVideoLayout, { icons: defaultLayoutIcons, thumbnails: video.vttUrl,
353
426
  // See SMALL_LAYOUT_WHEN: below this, the play button and the time readout are not
354
427
  // styled differently — they are GONE, and a dialog-sized player tripped Vidstack's
355
428
  // phone-shaped default.
@@ -360,6 +433,46 @@ export function VideoPlayer({ video, autoPlay, muted, className, aspectRatio = D
360
433
  // clip. The default five steps cover neither end.
361
434
  playbackRates: PLAYBACK_RATES, ...(slots ? { slots } : {}) })] }), showProcessing ? (_jsx(ProcessingIndicator, { status: status, progress: video.processingProgress })) : null] }));
362
435
  }
436
+ /**
437
+ * The named sections, as the `kind='chapters'` text track Vidstack's default layout is already
438
+ * looking for.
439
+ *
440
+ * ── 🔴 Why this is a component and not three lines inside the player ──────────────────
441
+ * Because a chapter cue needs an END, and the only place the clip's real length is known is
442
+ * INSIDE the player. `PlayableVideo.durationSeconds` is optional and frequently absent — and
443
+ * where it is present it is whatever the app's catalogue recorded, which is routinely rounded
444
+ * to the second. Building the cues from that would put every divider a fraction out on the one
445
+ * surface where they are compared against the picture, and would draw nothing at all for the
446
+ * ordinary video whose row has no duration on it. `useMediaState('duration')` is the decoder's
447
+ * own number, and it only reads it from a component mounted within the player's context —
448
+ * which is what this one is.
449
+ *
450
+ * Handed `content` rather than a `src`, so no URL has to be minted, served, signed or revoked
451
+ * for a list of strings the browser already has. Vidstack's `type='json'` parser takes the cue
452
+ * objects directly.
453
+ *
454
+ * Renders nothing until there is a real duration and at least one section: an empty chapters
455
+ * track is not neutral, it makes the layout draw a chapter title area and a menu entry for a
456
+ * video that has no chapters.
457
+ */
458
+ function ChaptersTrack({ chapters }) {
459
+ const duration = useMediaState('duration');
460
+ const content = useMemo(() => {
461
+ const spans = chapterSpans(chapters ?? [], duration);
462
+ if (spans.length === 0)
463
+ return null;
464
+ return {
465
+ cues: spans.map((span) => ({
466
+ startTime: span.startSeconds,
467
+ endTime: span.endSeconds,
468
+ text: span.title,
469
+ })),
470
+ };
471
+ }, [chapters, duration]);
472
+ if (!content)
473
+ return null;
474
+ return _jsx(Track, { content: content, type: 'json', kind: 'chapters', label: 'Chapters', default: true });
475
+ }
363
476
  /**
364
477
  * The processing state for a video surface: a thin progress bar pinned across the bottom edge
365
478
  * while derivatives build (indeterminate shimmer until real progress arrives), or a compact
@@ -1 +1 @@
1
- {"version":3,"file":"VideoPlayer.js","sourceRoot":"","sources":["../../../src/react/media/VideoPlayer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VideoPlayer.js","sourceRoot":"","sources":["../../../src/react/media/VideoPlayer.tsx"],"names":[],"mappings":"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"}
@@ -7,10 +7,23 @@ export interface MediaOrientation {
7
7
  flipY?: boolean;
8
8
  }
9
9
  export interface VideoTurnerProps {
10
- /** The clip to turn. Plays muted in the dialog so the preview is the real footage. */
10
+ /**
11
+ * The clip to turn. Plays muted in the dialog so the preview is the real footage.
12
+ *
13
+ * 🔴 The RESOLVED source, not whatever URL field an item happens to carry — see
14
+ * `MediaGallery`'s `TurnVideoDialog`, where handing over an empty string was the whole of
15
+ * the owner's *"I see a black screen"*. An empty string here is now a stated reason rather
16
+ * than a black rectangle, but it is still nothing to preview.
17
+ */
11
18
  src: string;
12
19
  /** Shown until the first frame decodes — a black box reads as a broken player. */
13
20
  posterUrl?: string;
21
+ /**
22
+ * True while the app is still finding the source (a signed URL being minted, bytes being
23
+ * fetched). It is the difference between "on its way" and "cannot be shown", and only the
24
+ * caller knows which.
25
+ */
26
+ resolving?: boolean;
14
27
  name?: string;
15
28
  /** What is stored today, so re-opening the dialog starts from the current state. */
16
29
  orientation?: MediaOrientation | undefined;
@@ -38,5 +51,5 @@ export interface VideoTurnerProps {
38
51
  * either lies or silently drops what somebody asked for — the failure this dialog's sibling had
39
52
  * to apologize for in prose.
40
53
  */
41
- export declare function VideoTurner({ src, posterUrl, name, orientation, open, onClose, onSave, }: VideoTurnerProps): React.JSX.Element;
54
+ export declare function VideoTurner({ src, posterUrl, resolving, name, orientation, open, onClose, onSave, }: VideoTurnerProps): React.JSX.Element;
42
55
  //# sourceMappingURL=VideoTurner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VideoTurner.d.ts","sourceRoot":"","sources":["../../../src/react/media/VideoTurner.tsx"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,oGAAoG;AACpG,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,sFAAsF;IACtF,GAAG,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,WAAW,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC3C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,2FAA2F;IAC3F,MAAM,EAAE,CAAC,WAAW,EAAE,gBAAgB,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,SAAS,EACT,IAAI,EACJ,WAAW,EACX,IAAW,EACX,OAAO,EACP,MAAM,GACP,EAAE,gBAAgB,qBA6JlB"}
1
+ {"version":3,"file":"VideoTurner.d.ts","sourceRoot":"","sources":["../../../src/react/media/VideoTurner.tsx"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,oGAAoG;AACpG,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,WAAW,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC3C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,2FAA2F;IAC3F,MAAM,EAAE,CAAC,WAAW,EAAE,gBAAgB,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,SAAS,EACT,SAAiB,EACjB,IAAI,EACJ,WAAW,EACX,IAAW,EACX,OAAO,EACP,MAAM,GACP,EAAE,gBAAgB,qBAsMlB"}
@@ -25,7 +25,7 @@ import { Tooltip } from '../components/Tooltip';
25
25
  * either lies or silently drops what somebody asked for — the failure this dialog's sibling had
26
26
  * to apologize for in prose.
27
27
  */
28
- export function VideoTurner({ src, posterUrl, name, orientation, open = true, onClose, onSave, }) {
28
+ export function VideoTurner({ src, posterUrl, resolving = false, name, orientation, open = true, onClose, onSave, }) {
29
29
  const initial = React.useMemo(() => ({
30
30
  ...NO_EDIT,
31
31
  turns: orientation?.turns ?? 0,
@@ -35,6 +35,29 @@ export function VideoTurner({ src, posterUrl, name, orientation, open = true, on
35
35
  const [edit, setEdit] = React.useState(initial);
36
36
  const [saving, setSaving] = React.useState(false);
37
37
  const [error, setError] = React.useState(null);
38
+ // A source that changes is a fresh attempt: it must not inherit the previous one's failure,
39
+ // the same rule the gallery's own `ThumbImg` keeps.
40
+ const [failedSrc, setFailedSrc] = React.useState(null);
41
+ /**
42
+ * Why there is no moving picture — `null` when there is one.
43
+ *
44
+ * 🔴 The dialog SAYS this instead of rendering black, which is the whole of the owner's
45
+ * report: *"When I click the turn the video button I see a black screen."* He could not tell
46
+ * a broken dialog from a dark frame, and neither could anyone reading a bug report about it.
47
+ * Each reason also says what is still true — the turn is three integers on a row, so it can
48
+ * be set and saved with no preview at all, and refusing to let him would turn a preview
49
+ * failure into a lost capability.
50
+ */
51
+ const cannotShow = resolving
52
+ ? 'Finding this film…'
53
+ : !src
54
+ ? 'This file has no video source to play here, so there is nothing to preview. The turn is stored beside the film rather than encoded into it, so you can still set it and save.'
55
+ : failedSrc === src
56
+ ? 'The film could not be loaded, so there is nothing to preview. The turn is stored beside the film rather than encoded into it, so you can still set it and save.'
57
+ : null;
58
+ // A poster is the next best picture of the film, and it turns with the same transform — so a
59
+ // clip that will not play is still something to aim a turn at rather than a blank panel.
60
+ const posterStandsIn = cannotShow !== null && !resolving && Boolean(posterUrl);
38
61
  const dirty = edit.turns !== initial.turns || edit.flipX !== initial.flipX || edit.flipY !== initial.flipY;
39
62
  const save = async () => {
40
63
  setSaving(true);
@@ -55,7 +78,11 @@ export function VideoTurner({ src, posterUrl, name, orientation, open = true, on
55
78
  setSaving(false);
56
79
  }
57
80
  };
58
- return (_jsx(Modal, { open: open, onClose: onClose, size: 'lg', title: 'Turn this video', isDirty: dirty, footer: _jsx(ActionBar, { secondary: _jsx(Button, { variant: 'ghost', onClick: onClose, disabled: saving, tooltip: 'Close without saving', children: "Cancel" }), primary: _jsx(Button, { variant: 'primary', disabled: !dirty || saving, onClick: () => void save(), tooltip: 'Store which way up this clip plays \u2014 the file itself is never re-encoded', children: saving ? 'Saving…' : 'Save the turn' }) }), children: _jsxs("div", { className: 'cbpe', children: [_jsx("div", { className: 'cbpe-frame cbpe-frame-film', "data-turned": swapsAxes(edit.turns) ? 'true' : undefined, children: _jsx("video", { src: src, poster: posterUrl, muted: true, loop: true, autoPlay: true, playsInline: true, controls: false, style: { transform: previewTransform(edit) } }) }), _jsxs("div", { className: 'cbpe-row', children: [_jsx("span", { className: 'cbpe-label', children: "Turn" }), _jsx(Tooltip, { content: 'A quarter turn anticlockwise', children: _jsx("button", {
81
+ return (_jsx(Modal, { open: open, onClose: onClose, size: 'lg', title: 'Turn this video', isDirty: dirty, footer: _jsx(ActionBar, { secondary: _jsx(Button, { variant: 'ghost', onClick: onClose, disabled: saving, tooltip: 'Close without saving', children: "Cancel" }), primary: _jsx(Button, { variant: 'primary', disabled: !dirty || saving, onClick: () => void save(), tooltip: 'Store which way up this clip plays \u2014 the file itself is never re-encoded', children: saving ? 'Saving…' : 'Save the turn' }) }), children: _jsxs("div", { className: 'cbpe', children: [_jsxs("div", { className: 'cbpe-frame cbpe-frame-film', "data-turned": swapsAxes(edit.turns) ? 'true' : undefined, children: [cannotShow === null ? (_jsx("video", { src: src, poster: posterUrl, muted: true, loop: true, autoPlay: true, playsInline: true, controls: false,
82
+ // 🔴 `metadata` at least. `preload='none'` would leave the element with nothing
83
+ // decoded and nothing drawn until something pressed play, which is a black frame
84
+ // wearing the same face as a broken source.
85
+ preload: 'metadata', onError: () => setFailedSrc(src), style: { transform: previewTransform(edit) } }, src)) : posterStandsIn ? (_jsx("img", { src: posterUrl, alt: name ?? 'The film', style: { transform: previewTransform(edit) } })) : null, cannotShow ? (_jsx("p", { className: 'cbpe-frame-note', role: 'status', children: cannotShow })) : null] }), _jsxs("div", { className: 'cbpe-row', children: [_jsx("span", { className: 'cbpe-label', children: "Turn" }), _jsx(Tooltip, { content: 'A quarter turn anticlockwise', children: _jsx("button", {
59
86
  // guardrails-ignore no-raw-action-button: toolbar pill styled by this module's own
60
87
  // plain CSS, matching the picture editor's `.cbpe-btn` neighbours.
61
88
  type: 'button', className: 'cbpe-btn', onClick: () => setEdit((e) => rotate(e, -1)), children: "\u21BA Left" }) }), _jsx(Tooltip, { content: 'A quarter turn clockwise', children: _jsx("button", {
@@ -1 +1 @@
1
- {"version":3,"file":"VideoTurner.js","sourceRoot":"","sources":["../../../src/react/media/VideoTurner.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VideoTurner.js","sourceRoot":"","sources":["../../../src/react/media/VideoTurner.tsx"],"names":[],"mappings":"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"}
@@ -71,6 +71,39 @@
71
71
  color: var(--accent-solid-foreground);
72
72
  }
73
73
 
74
+ /* ── Icon-only pills ───────────────────────────────────────────────────────────────────
75
+ *
76
+ * Owner, `ideas/collections-09-14.md`: *"Make it have icons only, instead of words in the
77
+ * strip of tools … Hovering over the tooltip can show the words."* Every pill in that strip
78
+ * already carried a `Tooltip` and most an `aria-label`, so the words were the redundant
79
+ * half — what this adds is the BOX an iconless pill needs.
80
+ *
81
+ * 🔴 The tap floor is the thing an icon-only strip loses first, and it is lost on the WIDTH,
82
+ * not the height. `.cbgd-order-btn` above only ever set `min-height`, because a pill with a
83
+ * word in it is wide by construction; strip the word and `padding-inline` is all that is
84
+ * left, which on a coarse pointer is a 42px-wide target under a 44px rule. So `min-width`
85
+ * is declared in all three places `min-height` is — see the two media queries at the foot of
86
+ * this file — and `e2e/touch-targets.spec.ts` measures the rendered rectangles rather than
87
+ * trusting this comment. cursedbelt has shipped this exact defect once already
88
+ * (`Checkbox`, task 69).
89
+ *
90
+ * `svg` rather than a class on the glyph: the pill is handed a lucide element by the gallery
91
+ * and by any consumer filling `detailActions`, and lucide sizes itself with width/height
92
+ * ATTRIBUTES (24 by default) that a CSS rule overrides. Sizing here is therefore the one
93
+ * place that cannot be forgotten at a call site. */
94
+ .cbgd-order-btn.is-icon {
95
+ min-width: 28px;
96
+ padding-inline: 7px;
97
+ justify-content: center;
98
+ }
99
+ .cbgd-order-btn svg {
100
+ width: 15px;
101
+ height: 15px;
102
+ /* A glyph must never be the thing that shrinks when the row runs out of room — the pill
103
+ is the flex item that gives way, and a squashed icon is unreadable rather than tight. */
104
+ flex: none;
105
+ }
106
+
74
107
  /* ── The slideshow speed control ────────────────────────────────────────────────────────
75
108
  *
76
109
  * A `<label>` wrapping a `<select>`, shaped as one more action pill so the actions row stays
@@ -99,6 +132,14 @@
99
132
  .cbgd-dwell-label {
100
133
  line-height: 1;
101
134
  }
135
+ /* The label is an hourglass now rather than the word "Hold" (2026-09-16) — same 15px as the
136
+ pills beside it, and `block` so the line box does not add a descender's worth of slack
137
+ under a glyph that has none. The VALUE (`5s`) stays as text in the select. */
138
+ .cbgd-dwell-label svg {
139
+ width: 15px;
140
+ height: 15px;
141
+ display: block;
142
+ }
102
143
  .cbgd-dwell-select {
103
144
  min-height: 24px;
104
145
  padding: 0 4px;
@@ -408,56 +449,51 @@
408
449
  height: var(--cbgd-stage-h, var(--cbgd-stage-fit, var(--cbgd-stage-default)));
409
450
  max-width: calc(var(--cbgd-stage-h, var(--cbgd-stage-fit, var(--cbgd-stage-default))) * 16 / 9);
410
451
  margin: 0 auto;
411
- /* The anchor for the chrome that rides ON the frame — today that is the resize grip
412
- (`.cbmr-corner`). It must be positioned against the FRAME, which is constant, and
413
- never against the picture, which is not.
414
- HISTORY: the big overlay ⟨ ⟩ step arrows used to hang here too. They were removed on
415
- 2026-08-25 — owner: *"Remove the big previous and next buttons off the sides of the
416
- video."* Stepping moved into `.cbgd-watch-step` in the titlebar, and for video into
417
- the player's own control bar. Do not put them back on the frame. */
452
+ /* 🔴 Nothing of OURS rides on the frame any more, and that is the 2026-09-14 fix.
453
+ `position: relative` stays because a stage may be a player that positions its own
454
+ layers against it, and because `.cbgd-stage-img` letterboxes inside it.
455
+ HISTORY: the big overlay ⟨ ⟩ step arrows hung here until 2026-08-25 — owner: *"Remove
456
+ the big previous and next buttons off the sides of the video."* Stepping moved into
457
+ `.cbgd-watch-step` in the titlebar, and for video into the player's own control bar.
458
+ The resize grip (`.cbmr-corner`) hung here until 2026-09-16 — owner: *"It should only
459
+ be draggable when my mouse pointer is at the bottom right corner … just like mac
460
+ windows"* — and is now in `.cbmr-rail`, a sibling BELOW this box. Do not put either
461
+ back on the frame: everything drawn here competes with whatever the stage is, and for
462
+ a video that is a full-bleed control bar. */
418
463
  position: relative;
419
464
  }
420
465
  /* Whatever the stage turns out to be — a player, a letterboxed picture, a document
421
- panel, an audio card, the loading placeholder — it is exactly the frame. */
422
- /* Every STAGE fills the frame — but the resize grip is chrome ON the frame, not a stage, and
423
- a `height: 100%` grip is a 44px control stretched over the whole picture, swallowing every
424
- click meant for the video under it. Excluded by name rather than left to stylesheet order,
425
- which is what was deciding it. */
426
- .cbgd-watch-player-box > *:not(.cbmr-corner) {
466
+ panel, an audio card, the loading placeholder — it is exactly the frame. Nothing but
467
+ the stage is in this box now: the resize grip left it on 2026-09-16 for the rail
468
+ below (`mediaResize.css`), which is why this no longer excludes `.cbmr-corner`. */
469
+ .cbgd-watch-player-box > * {
427
470
  height: 100%;
428
471
  min-height: 0;
429
472
  }
430
473
 
431
- /* ── Where the video's own controls may NOT lay out ──────────────────────────
432
- * Owner, 2026-08-25: *"make the corner expansion grabbable area bigger … for some
433
- * reason it's hard to grab, possibly the previous/next buttons are overlapping it."*
474
+ /* ── 🔴 The control bar reserves NOTHING, and that is the 2026-09-14 fix ──────
475
+ * There was a gutter here — `padding-inline-end: var(--cbmr-corner-size)` on the
476
+ * player's last two `.vds-controls-group`s — so the buttons would not lay out under a
477
+ * 64px grip that hung inside this frame's bottom-right corner. It is deleted, along
478
+ * with the overlay that needed it.
434
479
  *
435
- * 🔴 It was not the arrows. Measured against `@vidstack/react` 1.15's own theme:
436
- * `[data-view-type='video'] .vds-controls` is `position:absolute; inset:0;
437
- * z-index:10`, and `[data-media-player]` sets only `contain: style`, which is NOT one
438
- * of the containment values that opens a stacking context. So the player's control
439
- * layer competes DIRECTLY with `.cbmr-corner` in this frame's stacking context and
440
- * wins on 10 > 3. Its bottom `.vds-controls-group` is `width:100%` with
441
- * `pointer-events:auto`, so the whole bottom strip of the frame — including the empty
442
- * space between the cog and the frame's edge — swallowed the grip's pointer events.
443
- * And it does so only when the bar is SHOWING, i.e. on hover, i.e. at the exact
444
- * moment somebody reaches for the corner. That is the whole of the report.
480
+ * Owner, `ideas/collections-09-14.md`: *"Fix the drag to resize area to no longer
481
+ * overlap part of the horizontal play timeline area that shows what part of the video
482
+ * is playing."*
445
483
  *
446
- * Raising the grip alone would have covered the player's own last button (fullscreen)
447
- * with a 64px slider, so the fix is symmetrical: the grip goes above the bar (see
448
- * `mediaResize.css`) AND the bar is told to stop short of the corner it now shares a
449
- * frame with. `padding-inline-end` rather than a narrower width because Vidstack's
450
- * groups are `width:100%` flex rows — the padding is what actually moves the buttons.
484
+ * 🔴 The gutter was not the bug — measured, in a browser, before it was touched: with
485
+ * it in place the corner's rect really did clear `.vds-time-slider`'s. What it could
486
+ * not do was reach `.cbmr-bar`, which ran the full width UNDER the slider rather than
487
+ * beside it; and it can only ever shorten a control bar this package styles, which a
488
+ * `nativeVideoStage` gallery's `<video controls>` is not. It also cost 64px of scrub
489
+ * bar to buy a corner, which is the other half of the sentence above.
451
490
  *
452
- * 🔴 Scoped to a player that is NOT fullscreen. In fullscreen the media element is the
453
- * top-level box and the gallery's frame — grip included — is not in its tree at all,
454
- * so reserving a corner there would be a permanent empty gutter beside the cog with
455
- * nothing in it.
491
+ * So the grips moved out of the frame instead (`mediaResize.css`) and the slider gets
492
+ * its full width back. `e2e/resize-grip-rail.spec.ts` measures every drag surface
493
+ * against the frame and against the slider, in a real player, and fails if any of them
494
+ * touches either; do not reintroduce a gutter here to "make room" for something drawn
495
+ * on the picture — put the something in the rail.
456
496
  */
457
- .cbgd-watch-player-box [data-media-player]:not([data-fullscreen]) .vds-controls-group:last-child,
458
- .cbgd-watch-player-box [data-media-player]:not([data-fullscreen]) .vds-controls-group:nth-last-child(2) {
459
- padding-inline-end: var(--cbmr-corner-size, 64px);
460
- }
461
497
 
462
498
  /* ── Stepping in the titlebar ────────────────────────────────────────────────
463
499
  * The ⟨ ⟩ overlay pills that used to sit on the left and right edges of the frame are
@@ -471,7 +507,9 @@
471
507
  gap: 2px;
472
508
  margin-inline-end: 4px;
473
509
  }
474
- /* The glyph is a single chevron and would otherwise sit in a pill sized for a word. */
510
+ /* The glyph is a single chevron and would otherwise sit in a pill sized for a word. Wider
511
+ than `.is-icon`'s 28px because these two are the pair a reader hits over and over while
512
+ walking a folder, and they are the only pills whose job is repetition. */
475
513
  .cbgd-watch-step .cbgd-order-btn {
476
514
  min-width: 34px;
477
515
  padding-inline: 8px;
@@ -637,6 +675,11 @@
637
675
  min-height: 44px;
638
676
  padding: 4px 14px;
639
677
  }
678
+ /* The width half of the same floor — see `.is-icon` at the top of this file. */
679
+ .cbgd-order-btn.is-icon {
680
+ min-width: 44px;
681
+ padding-inline: 10px;
682
+ }
640
683
  .cbgd-dwell {
641
684
  min-height: 44px;
642
685
  }
@@ -662,6 +705,18 @@
662
705
  .cbgd-order-btn {
663
706
  min-height: 44px;
664
707
  }
708
+ /* 🔴 The width, which is what an icon-only pill is missing — a 15px glyph in 2×7px of
709
+ padding is a 29px target on a phone however tall the pill is. */
710
+ .cbgd-order-btn.is-icon {
711
+ min-width: 44px;
712
+ padding-inline: 10px;
713
+ }
714
+ /* Bigger glyph to match the bigger target: 15px reads as a speck at arm's length. */
715
+ .cbgd-order-btn svg,
716
+ .cbgd-dwell-label svg {
717
+ width: 18px;
718
+ height: 18px;
719
+ }
665
720
  .cbgd-search {
666
721
  min-height: 44px;
667
722
  }
@@ -673,12 +728,15 @@
673
728
  }
674
729
  }
675
730
 
676
- /* ── The stage resize grips ──────────────────────────────────────────────────
677
- * They are `mediaResize.css`'s (`.cbmr-corner` on the frame, `.cbmr-bar` under it),
678
- * shared with the focus viewer since 2026-08-25 — the day a handle that existed only
679
- * here was reported as a feature that did not exist. Only the BAR's width is this
680
- * module's business, because only this module knows the frame is 16:9-capped. */
681
- .cbgd-watch-player > .cbmr-bar {
731
+ /* ── The stage resize rail ───────────────────────────────────────────────────
732
+ * It is `mediaResize.css`'s (`.cbmr-rail`, holding the corner grip and — on coarse
733
+ * pointers — the bar), shared with the focus viewer since 2026-08-25, the day a handle
734
+ * that existed only here was reported as a feature that did not exist. Only its WIDTH is
735
+ * this module's business, because only this module knows the frame is 16:9-capped: the
736
+ * rail has to end exactly where the picture does, or its bottom-right corner is not the
737
+ * picture's bottom-right corner and *"the bottom right corner of the video player"* stops
738
+ * being true. */
739
+ .cbgd-watch-player > .cbmr-rail {
682
740
  max-width: calc(var(--cbgd-stage-h, var(--cbgd-stage-fit, var(--cbgd-stage-default))) * 16 / 9);
683
741
  margin-inline: auto;
684
742
  }