diff --git a/website/README.md b/website/README.md index f77bba01..363acbbd 100644 --- a/website/README.md +++ b/website/README.md @@ -148,25 +148,51 @@ table of contents, code examples, and previous/next navigation. The supplied Scope showreel plays in a framed 16:9 player below the hero calls to action, so the headline stays clean and the footage is -shown without an overlay. The local [video](public/scope-showreel.mp4) -is re-encoded as H.264 at half the original speed (30 seconds instead -of 15), with the audio track removed and metadata moved to the front -for web playback. It loops, is always muted, and plays inline on -mobile. A visually hidden caption describes the scenes it shows. - -[showreel.ts](src/scripts/showreel.ts) starts playback when at least a -quarter of the player is visible. A keyboard-accessible button pauses -or resumes it. Scrolling it out of view or hiding the tab pauses -playback; an explicit user pause persists when returning. The button -overlays the bottom corner of the video, and moves below it on narrow -screens so it does not cover the footage. - -Reduced-motion visitors see the [poster](public/scope-showreel-poster.jpg), -taken from the closing Scope title card, without downloading the video -until they choose to play it. Without JavaScript, the poster remains -visible and the playback button stays hidden. Blocked autoplay offers -manual playback; media failures display a status message and log the -error. Both media URLs use the configured deployment base. +shown without an overlay. It comes in two cuts styled with the landing +tokens: a [dark video](public/scope-showreel-dark.mp4) and a +[light video](public/scope-showreel-light.mp4). Both show the same +scenes and are re-encoded as H.264 at half the original speed (30 +seconds instead of 15), with the audio track removed and metadata moved +to the front for web playback. The player loops, is always muted, and +plays inline on mobile. A visually hidden caption describes the scenes. + +The cut follows the active Starlight theme: the `data-theme` attribute +on ``, which Starlight sets before first paint, including when it +resolves **Auto** from the system color scheme. The +[dark poster](public/scope-showreel-poster-dark.jpg) and +[light poster](public/scope-showreel-poster-light.jpg), taken from the +closing Scope title card, are exposed to CSS as base-aware custom +properties. The frame paints the active theme's poster, and the video +stays transparent over it until it has a frame. Neither the first paint +nor a theme change shows the other cut, and the browser only fetches the +poster it paints. + +[showreel.ts](src/scripts/showreel.ts) keeps both video URLs in data +attributes and assigns the active theme's source only when playback +starts, when at least a quarter of the player is visible. A +keyboard-accessible button pauses or resumes it. Scrolling it below a +quarter visible or hiding the tab pauses playback; an explicit user +pause persists when returning. Selecting Play still starts a player that +is less than a quarter visible, and it keeps playing until it leaves the +viewport. The button overlays the bottom corner of the video, and moves +below it on narrow screens so it does not cover the footage. The +controls and frame use the landing tokens, so they stay readable over +either cut. + +When the theme changes, a `MutationObserver` on `data-theme` swaps a +loaded player to the matching cut at the same position, keeping it +playing or paused. A paused player loads only the frame at that +position. A player that is off screen, or less than a quarter visible +and not started with Play, switches to the new poster at once and keeps +its current source until it is visible again. A player that has not +loaded yet only changes its poster. + +Reduced-motion visitors see the poster for their theme without +downloading either video until they choose to play it. Without +JavaScript, the poster remains visible and the playback button stays +hidden. Blocked autoplay offers manual playback; media failures display +a status message and log the error. All media URLs use the configured +deployment base. ### Interactive example diff --git a/website/public/scope-showreel-dark.mp4 b/website/public/scope-showreel-dark.mp4 new file mode 100644 index 00000000..8dc3fb07 Binary files /dev/null and b/website/public/scope-showreel-dark.mp4 differ diff --git a/website/public/scope-showreel-light.mp4 b/website/public/scope-showreel-light.mp4 new file mode 100644 index 00000000..100df5be Binary files /dev/null and b/website/public/scope-showreel-light.mp4 differ diff --git a/website/public/scope-showreel-poster-dark.jpg b/website/public/scope-showreel-poster-dark.jpg new file mode 100644 index 00000000..ccef540f Binary files /dev/null and b/website/public/scope-showreel-poster-dark.jpg differ diff --git a/website/public/scope-showreel-poster-light.jpg b/website/public/scope-showreel-poster-light.jpg new file mode 100644 index 00000000..3b6de433 Binary files /dev/null and b/website/public/scope-showreel-poster-light.jpg differ diff --git a/website/public/scope-showreel-poster.jpg b/website/public/scope-showreel-poster.jpg deleted file mode 100644 index d687978a..00000000 Binary files a/website/public/scope-showreel-poster.jpg and /dev/null differ diff --git a/website/public/scope-showreel.mp4 b/website/public/scope-showreel.mp4 deleted file mode 100644 index 0ccd31a3..00000000 Binary files a/website/public/scope-showreel.mp4 and /dev/null differ diff --git a/website/src/components/Home.astro b/website/src/components/Home.astro index c99371ce..e25a2412 100644 --- a/website/src/components/Home.astro +++ b/website/src/components/Home.astro @@ -3,6 +3,11 @@ import CommunityTeaser from './community/CommunityTeaser.astro'; import FlowDemo from './FlowDemo.astro'; const base = import.meta.env.BASE_URL.replace(/\/?$/, '/'); +// CSS paints the active theme's poster, so first paint never shows the other theme's cut. +const showreelPosters = { + '--showreel-poster-dark': `url("${base}scope-showreel-poster-dark.jpg")`, + '--showreel-poster-light': `url("${base}scope-showreel-poster-light.jpg")`, +}; const paths = [ { number: '01', @@ -45,11 +50,11 @@ const paths = [

Your tasks. Your criteria. Repeatable experiments.

-
+