| # UI_SPEC.md — The Radio |
| |
| Off Brand badge bar: "pushes past the default Gradio look." The interface IS |
| a radio. No visible Gradio chrome in the primary experience. |
| |
| ## Implementation approach |
| |
| - `gr.Server` custom frontend: single HTML/CSS/JS page served by the Space, |
| talking to Gradio API routes (`/api/broadcast`, `/api/transcribe`, |
| SSE/stream endpoint for StageEvents). |
| - No frontend framework — vanilla JS + CSS. One file each. (Fast to build, |
| nothing to bundle, trivially auditable for judges reading the repo.) |
| - Keep a minimal fallback `gr.Blocks` UI mounted at `/plain` — REQ-02 |
| insurance (interface must be a Gradio app) and judge-accessibility if the |
| custom UI breaks on someone's browser. |
| |
| ## Visual design |
| |
| - **The object**: a 1940s wooden tabletop radio, drawn in CSS (rounded |
| walnut cabinet, brass trim, fabric speaker grille, glass dial window). |
| Centered, ~720px wide desktop; full-bleed mobile. |
| - **Palette**: walnut #4a2f1d, brass #c9a86a, cream dial #f3e9d2, amber |
| glow #ffb84d, off-black room background with soft vignette. |
| - **Type**: dial numerals + station idents in a condensed retro sans |
| (e.g. "Oswald"); body text in a humanist serif. Title card "MIDNIGHT |
| STATIC" in deco lettering. |
| - **Texture restraint**: one wood grain, one fabric weave, subtle noise on |
| background. No skeuomorphic overload — it should look art-directed, |
| not clip-art. |
| |
| ## Components & states |
| |
| 1. **Genre dial** — horizontal tuning band, 6 station marks (KNOX, WEIRD, |
| GOLD, HEART, LAFF, RAAT). Drag or click; needle animates with slight |
| overshoot; soft static-burst audio blip (<0.3s, pre-loaded) on station |
| change. Selected station label glows amber. |
| 2. **Premise input** — a "telegram slip" beneath the radio: single text |
| field, placeholder rotates through 3 example premises. 300 char max. |
| 3. **CALL IN button** — brass push-button with red lamp. Press → hold-to- |
| record (MediaRecorder) → release → transcript appears on the telegram |
| slip for confirm/edit (never auto-submit ASR output). |
| 4. **ON AIR sequence** — submit → dial window becomes frequency scanner: |
| needle sweeps, station idents fade through per StageEvent |
| (87.9 WRITING… → 91.5 CASTING… → 94.7 FOLEY… → 98.3 SCORING… → |
| 101.1 ON AIR). Amber "ON AIR" lamp lights on completion. The sweep is |
| driven by real events, not a fake timer — if a stage stalls, the needle |
| hovers (honest latency theater). |
| 5. **Playback** — speaker grille pulses subtly with audio amplitude |
| (analyser node). Below the radio, the **script teleprinter**: lines |
| type out karaoke-synced to playback (we know exact line timestamps from |
| the mixer). Cast names in small caps, deliveries as stage directions. |
| 6. **After the show** — three brass controls: ⬇ KEEP (download MP3), |
| ↻ ANOTHER STATION (same premise, re-pick genre — one click), |
| ⤴ SHARE (copies link + poster if FLUX stretch landed). |
| 7. **Showcase reruns** — on first load, dial window shows "NOW PLAYING: |
| reruns" with 3 pre-cached broadcasts playable instantly. A judge must |
| hear audio within 10 seconds of landing (SPEC quality bar). |
| |
| ## Mobile (judges will open it on phones) |
| |
| - Radio scales to viewport width; dial becomes swipeable. |
| - Hold-to-record needs touch events + iOS Safari mic permission flow tested. |
| - Teleprinter collapses to current-line-only marquee. |
| |
| ## Loading/error voice |
| |
| All system text stays in-fiction: |
| - quota exhausted → "The station is at capacity — enjoy a rerun." |
| - pipeline fallback → "Our writer spilled coffee on page two. Improvising." |
| - mic denied → "The call-in line seems to be down. Type your premise." |
| |
| ## Asset budget |
| |
| Static assets <600KB total (textures as CSS gradients where possible, |
| station blip + needle sounds as short OGGs). The Space must feel instant |
| even before any model loads. |
| |
| ## Build order (Day 3) |
| |
| 1. Static radio render + dial interaction (2h) |
| 2. Wire /api/broadcast + StageEvent scanner (1.5h) |
| 3. Playback + teleprinter sync (1.5h) |
| 4. CALL IN + mobile pass (1.5h) |
| 5. Polish: lamp glows, needle physics, AUTHENTIC_AM toggle (1h) |
| Fallback rule: if behind schedule, ship 1–3 polished and cut 4; a flawless |
| mouse demo beats a buggy mic demo. |
|
|