File size: 4,228 Bytes
fc9b7e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# 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.