Marty asked why banners still show "running" with 0 left. They genuinely are
running — banners on this network have no cap. The counter runs past the
purchase and the ad keeps rotating until its 365-day expiry, so a
fully-delivered banner is still serving. #2707 is at ~6,129 on a 2,500 buy.
"running / LEFT 0" reads as broken though, so the row now says "delivered —
still serving as a bonus, Stop to end it", and the footnote explains it once:
the extra costs nothing further against their allowance, and Stop actually
ends it on the network.
Worth flagging what this does NOT do: nothing auto-stops a banner at its
purchased amount. Members get free over-delivery, which is fine on our own
inventory, but it means every banner ever launched keeps rotating for a year
unless someone stops it. If that becomes noisy, the fix is a scheduled job
that deactivates ads once served >= bought — deliberately not built now,
since it needs a cron and the over-delivery currently costs nothing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Marty asked why they start muted. Browsers only permit autoplay when a video
is muted, so "expand and play" necessarily meant "expand and play silently" —
and for these that is the wrong trade, because the narration IS the training.
A member's first visit was showing them a silent walkthrough.
So the panel now opens paused with the play button showing. Pressing it is a
user gesture, which means it plays with sound, every time. preload stays
'none' until the panel opens, then goes to 'metadata' so an open panel shows
a real first frame instead of a black rectangle.
Each bar now also carries its runtime ("· 71 sec"), so nobody has to guess
whether they are committing to one minute or ten.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Twelve narrated walkthroughs, one per Suite tool, in Marty's cloned voice.
No screen recording involved: Playwright drives and records the real UI,
ElevenLabs narrates, ffmpeg muxes. Pipeline lives outside this repo at
../video-pipeline.
Placement (Marty's call): TOP of each tool page but COLLAPSED — a one-line
"Watch the walkthrough" bar that auto-opens on a member's first visit to that
specific tool and stays shut after. A video in a separate library never gets
watched; an embedded player pushes the tool below the fold on mobile for every
returning member. First-visit autoplay is muted, so it is never a surprise
noise, and every localStorage access is guarded because it throws outright in
private windows.
Served from the data volume via /tv/<slug>.mp4, NOT from public/. That
directory is already 199MB and another 33MB of MP4 would ride along on every
deploy forever; this way a video can also be re-cut and dropped in without a
rebuild. The route implements HTTP range requests — without them the scrub bar
renders but cannot seek, which looks broken in a way people rarely report.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Text placements out-perform banners on this network — 357 text ads average
~171 clicks each against ~150 for banners, on far less inventory — so
members can now run them too.
The format is measured, not guessed. Across 60 live text ads: Subject caps
at 20 characters and Body is ALWAYS exactly three <br>-joined lines of at
most 24 characters. Every ad in the sample obeyed it.
Emoji: the NAS columns are latin1, but so is the connection, so UTF-8 bytes
pass through and render — which is how the existing emoji ads got there. The
bridge's clean() would have deleted every emoji via iconv //TRANSLIT//IGNORE,
so text copy now uses clean_ad_text(), which preserves them and strips angle
brackets instead. The bridge builds the <br> separators itself from a lines[]
array, so a member can never inject markup.
The engine writes plain text to a tight budget and we apply emoji ourselves:
models cannot count characters, least of all with emoji, so decoration is
arithmetic we control. It also lets the emoji rotate independently of the
copy. The palette carries no money emoji — the network is full of them, but
implying earnings outranks matching the neighbours.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three fixes from live testing of the Traffic Desk:
- /p/<id> with no page built now 302s to /join/<id> instead of returning
raw JSON 404. Any /p/ link already on a banner, flyer, or in a DM must
always land somewhere useful.
- The personal-page ad destination is only offered (client) and only
accepted (server) once a page actually exists; otherwise the member is
pointed at the Page Builder.
- Members can stop a running banner and get the unserved impressions back
in their monthly balance. Counters are read before deactivation, since
deactivating zeroes `remaining` and would look fully served.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>