diff --git a/.github/workflows/render.yml b/.github/workflows/render.yml new file mode 100644 index 0000000..efbe34f --- /dev/null +++ b/.github/workflows/render.yml @@ -0,0 +1,95 @@ +name: Render launch film + +# Re-renders the v0.3 launch film from source and commits the finished LFS media +# (MP4 + the synthesized music.mp3) back. This closes the loop for environments +# that can't push Git LFS objects: the source lands via PR, CI produces and +# commits the binaries. Triggers only on source changes (never on the media it +# writes, so it can't loop) and on manual dispatch. + +on: + push: + branches: [main] + paths: + - 'v0.3/src/index.html' + - 'v0.3/src/animations.jsx' + - 'v0.3/src/render.mjs' + - 'v0.3/src/vendor/**' + - 'v0.3/src/fonts/**' + - 'v0.3/src/shots/**' + - 'v0.3/src/clips/**' + - 'v0.3/src/scripts/synth-music.mjs' + - '.github/workflows/render.yml' + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: render-v03 + cancel-in-progress: true + +jobs: + render: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + lfs: true + + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install ffmpeg + run: sudo apt-get update && sudo apt-get install -y ffmpeg + + - name: Install Chrome + id: chrome + uses: browser-actions/setup-chrome@v1 + with: + chrome-version: stable + + - name: Install puppeteer-core + working-directory: v0.3/src + run: npm install --no-save puppeteer-core@23 + + - name: Regenerate music (deterministic synth) + working-directory: v0.3/src + run: | + node scripts/synth-music.mjs music.wav + ffmpeg -y -i music.wav \ + -af "highpass=f=30,lowpass=f=15800,alimiter=limit=0.97:level=false" \ + -c:a libmp3lame -b:a 192k music.mp3 + rm -f music.wav + + - name: Render frames + working-directory: v0.3/src + env: + CHROME: ${{ steps.chrome.outputs.chrome-path }} + run: | + rm -rf frames && mkdir -p frames + node render.mjs + + - name: Encode MP4 + working-directory: v0.3/src + run: | + DUR=$(cat render-duration.txt) + FADE=$(awk "BEGIN{printf \"%.3f\", $DUR - 1}") + echo "duration=$DUR fade_start=$FADE" + ffmpeg -y -framerate 30 -i frames/f%05d.png -i music.mp3 \ + -vf "scale=1920:1080:flags=lanczos,format=yuv420p" \ + -c:v libx264 -profile:v high -preset slow -crf 16 \ + -c:a aac -b:a 192k -af "afade=out:st=${FADE}:d=1" \ + -t "$DUR" -movflags +faststart ../chmonitor-v03-design-launch.mp4 + + - name: Commit rendered media + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add v0.3/chmonitor-v03-design-launch.mp4 v0.3/src/music.mp3 + if git diff --cached --quiet; then + echo "No media changes — nothing to commit." + exit 0 + fi + git commit -m "chore(v0.3): re-render launch film from source [ci]" + git push diff --git a/.gitignore b/.gitignore index 3e67e3b..d491e2f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,8 @@ node_modules/ frames/ renders/work-*/ .DS_Store + +# render/encode scratch +render-duration.txt +music.wav +package-lock.json diff --git a/CLAUDE.md b/CLAUDE.md index 5b950de..56355a6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -274,7 +274,24 @@ Auto-deployed on every push to `main` via `.github/workflows/pages.yml`. To add a new release to the landing page, copy the `.vcard` block in `index.html` and update `data-src`, `href`, version chip, title, and description. -## Known outstanding items (v0.3) - -- End card reads `github.com/duyet/clickhouse-monitoring` (pre-rebrand). Fix in `EndScene` in `v0.3/src/index.html` before next render. -- AI Agent and Topology scenes use static screenshots — replace with live recordings when `agent.mov` and `topology.mov` are available. +## Redesign notes (v0.3, current cut) + +The v0.3 film was redesigned to a flat "instrument / editorial" language — grid +ground (no breathing glow), numbered cues with ruled kickers + mask-revealed +titles, flat monospace "spec" tags (`Tag`) instead of glass pills, a hairline +product window (`Window`, no traffic-light chrome), a persistent `FilmRail`, and +an original synthesized score. Durable changes worth knowing before the next cut: + +- **Self-contained runtime, no CDN.** React / ReactDOM / Babel are vendored under + `v0.3/src/vendor/`, fonts under `v0.3/src/fonts/`. The render is fully offline. + Babel **7** standalone is required (Babel 8 broke the in-browser `text/babel` + runner). The Lottie pulse-ring dependency was removed. +- **Data-driven timeline.** Scene order/durations live in `buildCues()`; start/end + times and the total are derived (0.15s overlaps), exposed as `window.__duration`. + `render.mjs` reads it and takes the Chrome path from `$CHROME`. +- **Original score.** `music.mp3` is synthesized deterministically (no stock/AI + track). Regenerate with the Node synth described in `v0.3/README.md` § Music. +- End card now reads `github.com/chmonitor/chmonitor` (pre-rebrand URL fixed). +- Most feature scenes use static screenshots (`Frame`); Alerts is a fully-rendered + card (no screenshot). Replace AI Agent / Topology stills with live recordings + when `agent.mov` / `topology.mov` are available. diff --git a/README.md b/README.md index c15b090..9ec29b2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ source needed to re-render or edit them. | Version | Folder | Highlights | |---------|--------|------------| -| v0.3 | [`v0.3/`](v0.3/) | Full rebuild launch film — TanStack Start dashboard, AI agent, query monitoring, data explorer, topology & health, self-host. | +| v0.3 | [`v0.3/`](v0.3/) | Full rebuild launch film (redesigned cut) — TanStack Start, AI agent, query monitoring, SQL console, AI insights, alerts, topology & health, self-host. Editorial redesign + original score. | ## Conventions diff --git a/index.html b/index.html index 67b0749..32a248e 100644 --- a/index.html +++ b/index.html @@ -201,13 +201,13 @@
v0.3
-
0:28
+
0:31