diff --git a/DECISIONS.md b/DECISIONS.md
index 0f003fc..360b62d 100644
--- a/DECISIONS.md
+++ b/DECISIONS.md
@@ -53,3 +53,7 @@
- PR video approach: use Remotion for frame-accurate React motion graphics and `@remotion/player` for in-app preview at `/pr-video` before rendering.
- Remotion dependency policy: keep `remotion`, `@remotion/cli`, and `@remotion/player` on the same exact version to avoid render/runtime mismatches.
- Remotion styling bridge: use `@remotion/tailwind` so Vite preview and Remotion CLI renders share the same Tailwind v3 visual system.
+
+## 2026-06-13
+- Remotion sound design: use `@remotion/sfx` at the same exact Remotion version for predefined motion-graphic SFX cues instead of hand-generating local audio assets.
+- PR video BGM: use a locally generated light musical WAV under `public/audio/pr-video/` with Remotion fade controls, avoiding external music licensing and network-dependent playback.
diff --git a/package.json b/package.json
index 0a5cf7e..c8a15d2 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"@remotion/player": "4.0.475",
+ "@remotion/sfx": "4.0.475",
"@tanstack/react-query": "^5.90.21",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 782b84f..4594c9a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -23,6 +23,9 @@ importers:
'@remotion/player':
specifier: 4.0.475
version: 4.0.475(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ '@remotion/sfx':
+ specifier: 4.0.475
+ version: 4.0.475
'@tanstack/react-query':
specifier: ^5.90.21
version: 5.90.21(react@19.2.4)
@@ -1063,6 +1066,9 @@ packages:
react: '>=16.8.0'
react-dom: '>=16.8.0'
+ '@remotion/sfx@4.0.475':
+ resolution: {integrity: sha512-cs3O5wwuY42hxZkI4xWxPD5WzO4zZeV6fPkDk45MudXqJiwZA3YDEuSWCOOaglAwFyBaJ5foMCZJ8UxpdrFzEA==}
+
'@remotion/streaming@4.0.475':
resolution: {integrity: sha512-wBxed6DczdwybFSNsZqVnmdnkCSWjkg0/Q37eTCfq56bJ6lM5IJ2ZiyEfswE7TfI0OFpp1CWOFWCGf27O7WTDw==}
@@ -3694,6 +3700,8 @@ snapshots:
- bufferutil
- utf-8-validate
+ '@remotion/sfx@4.0.475': {}
+
'@remotion/streaming@4.0.475': {}
'@remotion/studio-server@4.0.475(lightningcss@1.31.1)(postcss@8.5.8)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
diff --git a/public/audio/pr-video/team-po-light-loop.wav b/public/audio/pr-video/team-po-light-loop.wav
new file mode 100644
index 0000000..c3edd47
Binary files /dev/null and b/public/audio/pr-video/team-po-light-loop.wav differ
diff --git a/src/features/pr-video/components/pr-video-player.tsx b/src/features/pr-video/components/pr-video-player.tsx
index 251dbdc..c35db26 100644
--- a/src/features/pr-video/components/pr-video-player.tsx
+++ b/src/features/pr-video/components/pr-video-player.tsx
@@ -7,7 +7,6 @@ export function PrVideoPlayer() {
return (
Math.round(seconds * TEAM_PO_PR_VIDEO.fps);
+
+const sceneStarts = {
+ opening: 0,
+ problem: 5.5,
+ matching: 11,
+ workspace: 20,
+ report: 30,
+ closing: 41,
+ finale: 50,
+} as const;
+
+const atScene = (scene: keyof typeof sceneStarts, seconds: number) =>
+ at(sceneStarts[scene] + seconds);
+
+const soundCues: readonly SoundCue[] = [
+ {
+ id: "opening-prompt-stroke",
+ frame: atScene("opening", 0.12),
+ durationInFrames: 24,
+ src: whoosh,
+ volume: 0.045,
+ playbackRate: 1.08,
+ },
+ {
+ id: "opening-logo-block-one",
+ frame: atScene("opening", 0.45),
+ durationInFrames: 11,
+ src: uiSwitch,
+ volume: 0.05,
+ playbackRate: 0.88,
+ },
+ {
+ id: "opening-logo-block-two",
+ frame: atScene("opening", 0.58),
+ durationInFrames: 11,
+ src: uiSwitch,
+ volume: 0.048,
+ playbackRate: 0.96,
+ },
+ {
+ id: "opening-logo-block-three",
+ frame: atScene("opening", 0.72),
+ durationInFrames: 11,
+ src: uiSwitch,
+ volume: 0.046,
+ playbackRate: 1.04,
+ },
+ {
+ id: "opening-team-word-swipe",
+ frame: atScene("opening", 1.02),
+ durationInFrames: 20,
+ src: whip,
+ volume: 0.068,
+ playbackRate: 0.96,
+ },
+ {
+ id: "opening-ui-cluster-arrives",
+ frame: atScene("opening", 1.65),
+ durationInFrames: 28,
+ src: whoosh,
+ volume: 0.058,
+ playbackRate: 0.98,
+ },
+ {
+ id: "opening-po-resolve",
+ frame: atScene("opening", 1.78),
+ durationInFrames: 18,
+ src: shutterModern,
+ volume: 0.064,
+ playbackRate: 0.78,
+ },
+ {
+ id: "opening-flow-connectors-draw",
+ frame: atScene("opening", 2.35),
+ durationInFrames: 40,
+ src: whoosh,
+ volume: 0.05,
+ playbackRate: 0.9,
+ },
+ {
+ id: "opening-camera-drift",
+ frame: atScene("opening", 4.7),
+ durationInFrames: 34,
+ src: whoosh,
+ volume: 0.042,
+ playbackRate: 0.74,
+ },
+ {
+ id: "problem-reveal-wipe",
+ frame: atScene("problem", 0),
+ durationInFrames: 30,
+ src: whoosh,
+ volume: 0.08,
+ playbackRate: 0.86,
+ },
+ {
+ id: "problem-board-lands",
+ frame: atScene("problem", 0.62),
+ durationInFrames: 20,
+ src: shutterModern,
+ volume: 0.064,
+ playbackRate: 0.84,
+ },
+ {
+ id: "problem-issue-node-cluster-one",
+ frame: atScene("problem", 1),
+ durationInFrames: 14,
+ src: uiSwitch,
+ volume: 0.045,
+ playbackRate: 0.82,
+ },
+ {
+ id: "problem-warning-field",
+ frame: atScene("problem", 1.25),
+ durationInFrames: 22,
+ src: uiSwitch,
+ volume: 0.062,
+ playbackRate: 0.7,
+ },
+ {
+ id: "problem-issue-node-cluster-two",
+ frame: atScene("problem", 1.38),
+ durationInFrames: 14,
+ src: uiSwitch,
+ volume: 0.041,
+ playbackRate: 0.92,
+ },
+ {
+ id: "problem-pressure-build",
+ frame: atScene("problem", 1.82),
+ durationInFrames: 36,
+ src: whoosh,
+ volume: 0.045,
+ playbackRate: 0.78,
+ },
+ {
+ id: "problem-signal-converges",
+ frame: atScene("problem", 2.18),
+ durationInFrames: 28,
+ src: whoosh,
+ volume: 0.066,
+ playbackRate: 0.92,
+ },
+ {
+ id: "problem-signal-bars",
+ frame: atScene("problem", 2.32),
+ durationInFrames: 20,
+ src: mouseClick,
+ volume: 0.038,
+ playbackRate: 0.76,
+ },
+ {
+ id: "problem-bottleneck-lock",
+ frame: atScene("problem", 2.62),
+ durationInFrames: 24,
+ src: shutterModern,
+ volume: 0.078,
+ playbackRate: 0.72,
+ },
+ {
+ id: "problem-pain-point-rail",
+ frame: atScene("problem", 2.9),
+ durationInFrames: 22,
+ src: uiSwitch,
+ volume: 0.048,
+ playbackRate: 0.78,
+ },
+ {
+ id: "problem-bridge-copy",
+ frame: atScene("problem", 4.45),
+ durationInFrames: 24,
+ src: whoosh,
+ volume: 0.044,
+ playbackRate: 1,
+ },
+ {
+ id: "matching-reveal-wipe",
+ frame: atScene("matching", 0),
+ durationInFrames: 30,
+ src: whoosh,
+ volume: 0.082,
+ playbackRate: 0.94,
+ },
+ {
+ id: "matching-window-lands",
+ frame: atScene("matching", 0.7),
+ durationInFrames: 20,
+ src: shutterModern,
+ volume: 0.06,
+ playbackRate: 0.8,
+ },
+ {
+ id: "matching-request-field-role",
+ frame: atScene("matching", 1.05),
+ durationInFrames: 12,
+ src: uiSwitch,
+ volume: 0.042,
+ playbackRate: 0.9,
+ },
+ {
+ id: "matching-request-field-scope",
+ frame: atScene("matching", 1.21),
+ durationInFrames: 12,
+ src: uiSwitch,
+ volume: 0.038,
+ playbackRate: 0.98,
+ },
+ {
+ id: "matching-headline-underline",
+ frame: atScene("matching", 1.35),
+ durationInFrames: 24,
+ src: whoosh,
+ volume: 0.034,
+ playbackRate: 1.08,
+ },
+ {
+ id: "matching-request-button",
+ frame: atScene("matching", 1.86),
+ durationInFrames: 14,
+ src: mouseClick,
+ volume: 0.076,
+ playbackRate: 0.72,
+ },
+ {
+ id: "matching-session-scan",
+ frame: atScene("matching", 2.25),
+ durationInFrames: 30,
+ src: whoosh,
+ volume: 0.056,
+ playbackRate: 1.08,
+ },
+ {
+ id: "matching-profile-selected-one",
+ frame: atScene("matching", 2.45),
+ durationInFrames: 14,
+ src: uiSwitch,
+ volume: 0.052,
+ playbackRate: 0.84,
+ },
+ {
+ id: "matching-profile-selected-two",
+ frame: atScene("matching", 2.63),
+ durationInFrames: 14,
+ src: uiSwitch,
+ volume: 0.054,
+ playbackRate: 0.92,
+ },
+ {
+ id: "matching-team-panel",
+ frame: atScene("matching", 3.2),
+ durationInFrames: 24,
+ src: shutterModern,
+ volume: 0.068,
+ playbackRate: 0.72,
+ },
+ {
+ id: "matching-role-slots-settle",
+ frame: atScene("matching", 3.45),
+ durationInFrames: 22,
+ src: uiSwitch,
+ volume: 0.046,
+ playbackRate: 0.78,
+ },
+ {
+ id: "matching-team-panel-spark",
+ frame: atScene("matching", 3.55),
+ durationInFrames: 18,
+ src: uiSwitch,
+ volume: 0.046,
+ playbackRate: 0.68,
+ },
+ {
+ id: "workspace-reveal-wipe",
+ frame: atScene("workspace", 0),
+ durationInFrames: 30,
+ src: whoosh,
+ volume: 0.076,
+ playbackRate: 0.9,
+ },
+ {
+ id: "workspace-window-lands",
+ frame: atScene("workspace", 0.62),
+ durationInFrames: 20,
+ src: shutterModern,
+ volume: 0.06,
+ playbackRate: 0.78,
+ },
+ {
+ id: "workspace-headline-underline",
+ frame: atScene("workspace", 1.25),
+ durationInFrames: 24,
+ src: whoosh,
+ volume: 0.034,
+ playbackRate: 1.04,
+ },
+ {
+ id: "workspace-stage-forming",
+ frame: atScene("workspace", 1.6),
+ durationInFrames: 12,
+ src: uiSwitch,
+ volume: 0.044,
+ playbackRate: 0.82,
+ },
+ {
+ id: "workspace-stage-progress",
+ frame: atScene("workspace", 2),
+ durationInFrames: 56,
+ src: whoosh,
+ volume: 0.046,
+ playbackRate: 0.86,
+ },
+ {
+ id: "workspace-checklist-first",
+ frame: atScene("workspace", 2.02),
+ durationInFrames: 12,
+ src: mouseClick,
+ volume: 0.046,
+ playbackRate: 0.7,
+ },
+ {
+ id: "workspace-active-stage",
+ frame: atScene("workspace", 2.18),
+ durationInFrames: 14,
+ src: uiSwitch,
+ volume: 0.056,
+ playbackRate: 0.78,
+ },
+ {
+ id: "workspace-contract-lift",
+ frame: atScene("workspace", 2.55),
+ durationInFrames: 26,
+ src: whoosh,
+ volume: 0.052,
+ playbackRate: 1.08,
+ },
+ {
+ id: "workspace-drawer-appears",
+ frame: atScene("workspace", 3.35),
+ durationInFrames: 22,
+ src: shutterModern,
+ volume: 0.064,
+ playbackRate: 0.72,
+ },
+ {
+ id: "workspace-active-confirmed",
+ frame: atScene("workspace", 3.62),
+ durationInFrames: 16,
+ src: uiSwitch,
+ volume: 0.062,
+ playbackRate: 0.68,
+ },
+ {
+ id: "report-reveal-wipe",
+ frame: atScene("report", 0),
+ durationInFrames: 30,
+ src: whoosh,
+ volume: 0.076,
+ playbackRate: 0.9,
+ },
+ {
+ id: "report-window-lands",
+ frame: atScene("report", 0.62),
+ durationInFrames: 20,
+ src: shutterModern,
+ volume: 0.058,
+ playbackRate: 0.78,
+ },
+ {
+ id: "report-headline-underline",
+ frame: atScene("report", 1.22),
+ durationInFrames: 24,
+ src: whoosh,
+ volume: 0.034,
+ playbackRate: 1.04,
+ },
+ {
+ id: "report-activity-rows",
+ frame: atScene("report", 1.55),
+ durationInFrames: 18,
+ src: uiSwitch,
+ volume: 0.044,
+ playbackRate: 0.78,
+ },
+ {
+ id: "report-metrics-count-up",
+ frame: atScene("report", 1.7),
+ durationInFrames: 22,
+ src: uiSwitch,
+ volume: 0.052,
+ playbackRate: 0.72,
+ },
+ {
+ id: "report-chart-line-draw",
+ frame: atScene("report", 1.8),
+ durationInFrames: 42,
+ src: whoosh,
+ volume: 0.056,
+ playbackRate: 0.88,
+ },
+ {
+ id: "report-chart-dot-resolve",
+ frame: atScene("report", 2.72),
+ durationInFrames: 14,
+ src: uiSwitch,
+ volume: 0.058,
+ playbackRate: 0.8,
+ },
+ {
+ id: "report-insight-panel",
+ frame: atScene("report", 3.15),
+ durationInFrames: 24,
+ src: shutterModern,
+ volume: 0.064,
+ playbackRate: 0.74,
+ },
+ {
+ id: "report-next-action-confirmed",
+ frame: atScene("report", 3.62),
+ durationInFrames: 16,
+ src: uiSwitch,
+ volume: 0.06,
+ playbackRate: 0.7,
+ },
+ {
+ id: "closing-reveal-wipe",
+ frame: atScene("closing", 0),
+ durationInFrames: 30,
+ src: whoosh,
+ volume: 0.072,
+ playbackRate: 0.84,
+ },
+ {
+ id: "closing-brand-arrives",
+ frame: atScene("closing", 0.22),
+ durationInFrames: 16,
+ src: uiSwitch,
+ volume: 0.038,
+ playbackRate: 0.76,
+ },
+ {
+ id: "closing-token-matching",
+ frame: atScene("closing", 0.52),
+ durationInFrames: 12,
+ src: uiSwitch,
+ volume: 0.042,
+ playbackRate: 0.68,
+ },
+ {
+ id: "closing-token-workspace",
+ frame: atScene("closing", 0.74),
+ durationInFrames: 12,
+ src: uiSwitch,
+ volume: 0.04,
+ playbackRate: 0.76,
+ },
+ {
+ id: "closing-ribbon-path-draw",
+ frame: atScene("closing", 0.9),
+ durationInFrames: 58,
+ src: whoosh,
+ volume: 0.054,
+ playbackRate: 0.66,
+ },
+ {
+ id: "closing-token-report",
+ frame: atScene("closing", 0.96),
+ durationInFrames: 12,
+ src: uiSwitch,
+ volume: 0.04,
+ playbackRate: 0.82,
+ },
+ {
+ id: "closing-token-shipping",
+ frame: atScene("closing", 1.18),
+ durationInFrames: 12,
+ src: uiSwitch,
+ volume: 0.042,
+ playbackRate: 0.88,
+ },
+ {
+ id: "closing-headline-line-one",
+ frame: atScene("closing", 1.62),
+ durationInFrames: 16,
+ src: shutterModern,
+ volume: 0.046,
+ playbackRate: 0.66,
+ },
+ {
+ id: "closing-headline-line-two",
+ frame: atScene("closing", 1.95),
+ durationInFrames: 16,
+ src: shutterModern,
+ volume: 0.05,
+ playbackRate: 0.7,
+ },
+ {
+ id: "closing-headline-line-three",
+ frame: atScene("closing", 2.32),
+ durationInFrames: 18,
+ src: shutterModern,
+ volume: 0.054,
+ playbackRate: 0.64,
+ },
+ {
+ id: "closing-token-locks",
+ frame: atScene("closing", 2.55),
+ durationInFrames: 22,
+ src: uiSwitch,
+ volume: 0.04,
+ playbackRate: 0.62,
+ },
+ {
+ id: "closing-headline-shine",
+ frame: atScene("closing", 3.18),
+ durationInFrames: 28,
+ src: whip,
+ volume: 0.038,
+ playbackRate: 0.72,
+ },
+ {
+ id: "closing-copy-lock",
+ frame: atScene("closing", 3.36),
+ durationInFrames: 20,
+ src: shutterModern,
+ volume: 0.042,
+ playbackRate: 0.62,
+ },
+ {
+ id: "closing-underline-draw",
+ frame: atScene("closing", 3.58),
+ durationInFrames: 28,
+ src: whoosh,
+ volume: 0.034,
+ playbackRate: 0.9,
+ },
+ {
+ id: "closing-comet-pass",
+ frame: atScene("closing", 4.72),
+ durationInFrames: 50,
+ src: whoosh,
+ volume: 0.058,
+ playbackRate: 0.82,
+ },
+ {
+ id: "closing-feature-ignition",
+ frame: atScene("closing", 5.3),
+ durationInFrames: 20,
+ src: uiSwitch,
+ volume: 0.042,
+ playbackRate: 0.64,
+ },
+ {
+ id: "finale-reveal",
+ frame: atScene("finale", 0),
+ durationInFrames: 30,
+ src: whoosh,
+ volume: 0.082,
+ playbackRate: 0.88,
+ },
+ {
+ id: "finale-prompt-stroke",
+ frame: atScene("finale", 0.22),
+ durationInFrames: 22,
+ src: whoosh,
+ volume: 0.04,
+ playbackRate: 1.02,
+ },
+ {
+ id: "finale-logo-block-one",
+ frame: atScene("finale", 0.46),
+ durationInFrames: 11,
+ src: uiSwitch,
+ volume: 0.048,
+ playbackRate: 0.76,
+ },
+ {
+ id: "finale-logo-block-two",
+ frame: atScene("finale", 0.6),
+ durationInFrames: 11,
+ src: uiSwitch,
+ volume: 0.046,
+ playbackRate: 0.84,
+ },
+ {
+ id: "finale-logo-block-three",
+ frame: atScene("finale", 0.74),
+ durationInFrames: 11,
+ src: uiSwitch,
+ volume: 0.044,
+ playbackRate: 0.92,
+ },
+ {
+ id: "finale-team-word",
+ frame: atScene("finale", 0.9),
+ durationInFrames: 22,
+ src: whip,
+ volume: 0.06,
+ playbackRate: 0.86,
+ },
+ {
+ id: "finale-po-resolve",
+ frame: atScene("finale", 1.36),
+ durationInFrames: 20,
+ src: shutterModern,
+ volume: 0.06,
+ playbackRate: 0.66,
+ },
+ {
+ id: "finale-message-settle",
+ frame: atScene("finale", 1.86),
+ durationInFrames: 24,
+ src: shutterModern,
+ volume: 0.052,
+ playbackRate: 0.68,
+ },
+ {
+ id: "finale-message-underline",
+ frame: atScene("finale", 2.2),
+ durationInFrames: 34,
+ src: whoosh,
+ volume: 0.046,
+ playbackRate: 0.88,
+ },
+ {
+ id: "finale-bottom-pulse",
+ frame: atScene("finale", 4.2),
+ durationInFrames: 20,
+ src: uiSwitch,
+ volume: 0.058,
+ playbackRate: 0.62,
+ },
+];
+
+export function PrVideoSoundDesign() {
+ return (
+ <>
+
+ {soundCues.map((cue) => (
+
+
+
+ ))}
+ >
+ );
+}
+
+function PrVideoBackgroundMusic() {
+ return (
+
+ interpolate(
+ frame,
+ [
+ 0,
+ at(2.4),
+ TEAM_PO_PR_VIDEO.durationInFrames - at(4.2),
+ TEAM_PO_PR_VIDEO.durationInFrames,
+ ],
+ [0, 0.1, 0.1, 0],
+ {
+ extrapolateLeft: "clamp",
+ extrapolateRight: "clamp",
+ },
+ )
+ }
+ />
+ );
+}
diff --git a/src/features/pr-video/components/team-po-pr-video.tsx b/src/features/pr-video/components/team-po-pr-video.tsx
index 3b2b109..f549ad2 100644
--- a/src/features/pr-video/components/team-po-pr-video.tsx
+++ b/src/features/pr-video/components/team-po-pr-video.tsx
@@ -28,6 +28,8 @@ import {
useVideoConfig,
} from "remotion";
+import { PrVideoSoundDesign } from "@/features/pr-video/components/pr-video-sound-design";
+
const EASE_OUT = Easing.bezier(0.16, 1, 0.3, 1);
const EASE_IN_OUT = Easing.bezier(0.45, 0, 0.55, 1);
const OPENING_SCENE_FRAMES = 180;
@@ -431,6 +433,7 @@ export function TeamPoPrVideo() {
>
+
);