- Created `capture-alert.mjs` to generate alert loop video for the about page claim "Get Notified About Searches." - Added `CountrySpread` widget for a ranked bar display of member distribution by country. - Implemented `StatBand` component for live platform statistics on the about page. - Introduced template rendering script (`render-search-alert.tsx`) for generating search alert email visuals. - Updated documentation and improved workflows for media creation, video rendering, and data integration.
Compass — Social Media Videos
A standalone Remotion studio for producing Compass promo/social videos (Instagram Reels, TikTok, YouTube Shorts). Videos are defined in React and rendered to MP4.
⚠️ Deliberately isolated from the monorepo
This folder is not a yarn workspace and is not installed by the repo-root yarn install. It has its
own dependency tree so the web app and API never pull Remotion (and its bundled headless browser) by accident.
- Root
package.jsonworkspacesis an explicit list — this folder is intentionally left out. - Install and run it only from inside
media-creator/, using npm (not yarn), so it never touches the rootnode_modulesoryarn.lock. node_modules/,out/, and.remotion/are gitignored.
Setup
cd media-creator
npm install # first time only — also downloads a headless browser for rendering
Preview (interactive studio)
npm run studio # opens the Remotion Studio at http://localhost:3000
Render to MP4
The same intro renders into two Instagram-ready formats:
npm run render:post # -> out/compass-intro-post.mp4 4:5 (1080×1350) — feed post
npm run render:story # -> out/compass-intro-story.mp4 9:16 (1080×1920) — story / reel
npm run render # alias for render:post (the primary format)
Both are 30fps H.264, ready to upload.
| Format | Composition id | Ratio | Pixels | Use |
|---|---|---|---|---|
| Post | IntroPost |
4:5 | 1080×1350 | Instagram feed post — tallest ratio allowed in-feed (primary) |
| Story | IntroStory |
9:16 | 1080×1920 | Instagram Story / Reel, TikTok, YouTube Shorts (secondary) |
Videos
Intro (IntroPost / IntroStory)
The brand intro — what Compass is and why. Content sourced from the About page and FAQ.
Profile tour (ProfileTourStory / ProfileTourPost)
A ~30s section-by-section walk through a real profile page: header → details → interests → personality → bio → photos → compatibility prompts → links → CTA. Story is the primary format here (it's a Reel).
npm run render:tour # -> out/compass-profile-tour-story.mp4 9:16 (primary)
npm run render:tour:post # -> out/compass-profile-tour-post.mp4 4:5
Every shot is a screenshot of the live app, not a mock-up, so the video can never drift from what the product actually looks like. Regenerate the artwork whenever the profile UI changes:
yarn dev # from the repo root — needs http://localhost:3000
npm run capture:profile # -> public/profile/*.png
npm run capture:profile -- http://localhost:3000/SomeoneElse
scripts/capture-profile.mjs shoots the page at 430×932 CSS px @ DPR 2 (so the PNGs are 2× and stay
crisp on the 1080-wide canvas), hides fixed chrome and the Next.js dev badge, and clips one image per
card. It borrows Playwright from the monorepo root by absolute path, deliberately — this package
stays Remotion-only.
Compatibility Prompts and Endorsements only render for a signed-in viewer. Firebase keeps its auth
in IndexedDB, which Playwright's storageState does not carry, so the script uses a persistent browser
profile you sign into by hand, once:
npm run capture:profile -- --login # opens a real window; sign in yourself
npm run capture:profile # later runs reuse the session, headless
The session lives in .auth-profile/ (gitignored — it is a real login). Without it those two cards are
simply skipped, with a warning, and the rest still captures.
Sign in as someone other than the profile's owner. Viewing your own profile renders the prompts card in its editing form; a different account gives the visitor view ("Important to …", "Answer yourself"), which is what someone watching the reel would actually see.
The scene scales each shot by width and pans the ones taller than the frame. If a card's height changes substantially, update its entry in
SHOTSat the top ofsrc/scenes/ProfileTour.tsx— the pan maths reads those dimensions.
Both formats share the same scenes; the taller Features scene compacts automatically on the shorter 4:5
canvas. Formats are defined in src/theme.ts (FORMATS) and registered in src/Root.tsx.
Don't post the 9:16 story as a feed post — Instagram crops it to ~4:5. Use
IntroPostfor the feed.
Structure
media-creator/
├── package.json standalone deps (npm)
├── remotion.config.ts render settings (codec, quality)
├── public/logo.svg Compass logo (copied from web/public/favicon.svg)
└── src/
├── index.ts registerRoot
├── Root.tsx composition registry
├── theme.ts brand colors / fonts / output FORMATS
├── components/ Background, Logo, reusable animations
└── scenes/Intro.tsx the intro video (shared by both formats)
Adding another video
- Build a component under
src/scenes/. - Register a
<Composition>for it insrc/Root.tsx(one per format if it needs both aspect ratios — read the canvas withuseVideoConfig()to adapt the layout, as the Features scene does). npm run studioto preview, thennpx remotion render <id> out/<name>.mp4.
Keeping the brand in sync
src/theme.ts and public/logo.svg mirror the web app (web/styles/globals.css,
web/public/favicon.svg). If the web palette or logo changes, update them here too.
Content in the intro is sourced from the app's About page and FAQ (web/pages/about.tsx,
web/public/md/faq.md).