What's new

Changelog

Recent updates across HiveJournal, Graphene, and write.cafe. Curated, not auto-generated — only the changes worth knowing about. New entries land near the top.

Graphene FMJune 7, 2026

Tagline reverted to “Written. Spoken. Yours.”

Network brand pairing settles. "It will not be televised." was promoted from motto to headline in May (see the entry below) — strong as a single line of brand kit, but in practice cold visitors saw it as enigmatic before they had any context for what we are. Reverted to "Written. Spoken. Yours." everywhere the tagline reads: hero h1, layout metadata title, OG share card, mobile slate header, podcast RSS itunes:subtitle. The GRAPHENE.tagline constant + GRAPHENE.subhead pairing stays the same shape (posture + format) — just a different posture. Network display name also standardized as "Graphene FM" across page titles, JSON-LD, oEmbed, PWA manifest (#507).

Graphene FMMay 18, 2026

Tagline shift — “it will not be televised.” is now the headline

The motto graduates to tagline. "Serialized fiction. Audio-first." was an accurate category descriptor but interchangeable with any rival that ships tomorrow — a label, not a posture. "It will not be televised." was already living as a small italic line beneath the wordmark and is the only string in the brand kit that sounds like nobody else could have written it; promoting it puts the posture in the headline slot (hero h1, layout metadata title, OG share card, mobile slate header, podcast RSS itunes:subtitle). A new GRAPHENE.subhead — "Audio fiction. Weekly chapters. Listener letters bend the story." — picks up the category-descriptor work the old tagline did (footer blurb, PWA manifest description). The GRAPHENE.motto constant is retired; the homepage hero no longer doubles up since the h1 is the tagline now.

Graphene FMMay 16, 2026

Writer engine v2.0 — per-season craft framework selection

Until today the engine broadcast all three structural frameworks (Save the Cat, McKee, Hero's Journey) at every chapter in parallel — a literary novella was getting told to inject "Fun and Games" energy into prose that should be tightening pressure. v2.0 moves the framework choice upstream to design time: the planner picks one based on premise/genre/mode, the choice stamps the season row, and all four prompt sites inject ONLY that framework's beats. New super-admin tools to drive it: a 🎯 bulk-pick button (~$0.0005/season) on /dashboard/admin/quality-signals migrates the existing catalog off legacy 'auto' in batches of 50; a 📋 preview tool on /dashboard/admin/seasons shows the actual prompt strings GPT will see; a ↻ Regenerate to v2.0 banner on each season's /read page brings chapters up through the full critic pipeline. Pairs with a status chip in the /read header showing whether the season is at v2.0 or still has chapters behind.

PlatformMay 16, 2026

Pipeline + cron failures now auto-record to /dashboard/admin/errors

Observability sweep — pre-this-ship, pipeline failures (audio render, script gen, trailer, generate-chapter, improve-all-behind, etc.) only landed in the per-season runs feed; cron failures only landed in /admin/system-health. Daily /errors triage was missing both. Now: EventTracker.failWithError() writes to both surfaces in one call (20 sites swept in story-seasons.ts), and recordHeartbeat with status='error' auto-bridges to service_errors so every cron's failure path picks this up with zero opt-in (24+ sites). New service-filter chips on /dashboard/admin/errors let triage narrow to cron-* or season-pipeline-* in one click. Net: every backend pipeline + every backend cron now surfaces in the daily triage table.

PlatformMay 16, 2026

Anonymous engagement + listener feedback no longer silently 401

Per-:id ownership middleware on the story-seasons router 401'd all anonymous POST/PATCH/DELETE — but seven public-by-design endpoints (engagement beacons, listener letters, in-line comments, segment feedback, listener ratings, per-episode listen events, timelines branch state) were designed to accept signed-out visitors. They'd been quietly dropping site-wide for any reader without a session. New PUBLIC_MUTATION_PATTERNS allowlist in the guard fixes all seven at once while still gating on the season being published or platform-owned (private drafts stay hidden).

Graphene FMMay 16, 2026

It will not be televised. — motto under the Graphene wordmark

Small italic indigo line beneath the GRAPHENE hex-mark on the /graphene homepage hero. Reads as a network signature, not a marketing claim — the existing tagline "Serialized fiction. Audio-first." carries the marketing. Pulled into the GRAPHENE.motto constant so future edits hit a single source of truth.

Admin toolsMay 16, 2026

Daily-quote chip on /dashboard/stream replaces the wall-of-italics

The daily quote card was eating half the mobile viewport on every load and re-appearing on a 5-second auto-show timer mid-entry. Now it starts as a tiny pulsing chip near the top ("✦ Today's quote — Author"); tap to expand the full card with the existing 10s auto-fade back to the pulse, or use the new ▴ collapse affordance to dismiss without waiting. Stream surface stays clean by default.

Admin toolsMay 11, 2026

🎭 takes-count chip on the admin seasons list

Discovery affordance for the takes layer. A 14-day audit found only 2 seasons used takes because the feature was invisible from the admin list — admins had to drill into a season to find out it already had alternate cuts. Each row now shows a cyan-when-drafts-exist '🎭 N · Md' chip. Click jumps to the season page where the existing 🎭 Takes button lives. Backend batch-loads counts on the existing seasons fetch (no N+1).

Admin toolsMay 11, 2026

Stale draft takes auto-archive after 14 days

Daily cron flips season_script_takes rows from 'draft' to 'rejected' when they've sat unreviewed for >14 days. Audit found 3 stale drafts accumulating; without cleanup the diff UI gets cluttered with takes the admin already moved past. 'rejected' is the existing terminal state per the migration — rows stay queryable for cost analytics, not deleted. Heartbeat-tracked as stale_takes_archive_tick.

Graphene FMMay 11, 2026

Trailer auto-renders when audio finishes

The 2026-04-28 trailer audit found only 25% of audio-rendered seasons had a trailer because the manual admin button rarely got clicked. After renderSeasonAudio successfully writes audio_url, a fire-and-forget block now kicks renderSeasonTrailer for any non-novel-mode season without an existing trailer. Idempotent, non-blocking (the audio response returns before the ~35s trailer pipeline finishes), errors logged but never propagate.

Graphene FMMay 11, 2026

Trailer drawtext now sanitizes + falls back to textless tag

Two narrow trailer-render fixes driven by an ffmpeg drawtext failure observed in the same audit. Title sanitizer now strips every control char ffmpeg's filter grammar treats specially (not just :'"\\). The tag-card render is wrapped in a try/catch that retries once without text overlays so a future ffmpeg quirk degrades to a darkened-poster card instead of failing the whole trailer.

JournalingMay 11, 2026

Year heatmap on /dashboard/me/stats

GitHub-style 365-day grid below the 12-month sparkline. Each cell is a day; column is a Sun-anchored week. Tint comes from that day's dominant mood (same palette as the streak strip + /dashboard/calendar); opacity scales by entry count so a busy day reads as stronger color. Month labels run along the top so the strip is scannable. Together the sparkline gives monthly totals and the heatmap gives day-level texture.

JournalingMay 11, 2026

Streak widget strip now mood-tinted

The 30-day strip on the writing-streak widget used to be binary fill — one streak-tier color for filled, gray for empty. Each filled cell now picks its color from the day's dominant mood (highest-frequency mood across that day's entries), matching the /dashboard/calendar palette. Days without a tagged mood fall back to the streak-tier color; tooltip now reads 'mostly grateful' / 'mostly tired' instead of bare 'wrote'.

PlatformMay 11, 2026

Cmd-K + ? cheat sheet now work on every page

Both shortcuts were previously gated inside the dashboard layout, so they did nothing on /graphene, /seasons/[id], /write-cafe, the landing page, etc. Lifted to the app-root mount so ⌘K opens the palette and ? opens the keyboard cheat sheet from anywhere. The palette's recent-entries / capsules / highlights / notebooks fetches all catch 401 silently, so anonymous visitors who press ⌘K see just the Quick actions + Pages groups instead of an error.

Admin toolsMay 11, 2026

🎲 Re-bootstrap any user-managed universe without re-typing the prompt

Admin/creator universes that were originally LLM-generated (via description / random / inspired_by / from_journal) now have a Re-bootstrap button in the edit modal that replays the row's saved bootstrap_input against the same endpoint. Replaces the LLM-generated fields in place (label, description, prompt directive, canon) while preserving the row's identity (key, generated_via, source notebook, etc). Save still requires a click — no auto-PATCH. Includes a dirty-edit guard (window.confirm if the admin has unsaved manual edits) and a small 🎲 {mode} badge on creator-list cards so the affordance is discoverable from outside the editor too.

PlatformMay 11, 2026

Cmd-K theme toggle + random-notebook + dead-end fallback

Three more entries in the Cmd-K quick-actions row. ☀️/🌙 'Switch to {dark|light} mode' flips the theme without leaving the palette (label adapts so you see what the click will do, and the palette stays open so the swap is verifiable). 🎲 'Open a random notebook' rounds out the surprise-me family — pure client-side pick from the notebook list the palette already loads. And when a query has zero matches, the 'Nothing matching' dead-end now sprouts a 'Write a new entry starting with «query»' CTA that routes to the composer with your text pre-filled as the first line.

PlatformMay 11, 2026

Right-edge FAB column now center-aligned (no more stagger)

The three bottom-right buttons (JQ chatbot orb, QuickEntry pencil, ActionButton checkmark) shared right:24px so their right edges lined up — but their widths differed (64 / 56 / 19 px) so the centers staggered leftward as the buttons shrank. Re-anchored each to share an x-center 56 px from the right edge (matching the JQ orb's center) so the column reads as a clean vertical stack. ActionButton's hover-grow handlers also adjust the right value so the center stays pinned during the size animation.

lovioMay 11, 2026

👀 Preview as recipient now works on DRAFT capsules too

Authors could already preview sealed capsules (open the public unlock URL in a new tab) but drafts had no preview — the recipient view was a black box until you sealed. New owner-only route /dashboard/lovio/[id]/preview renders the exact recipient UI for unsealed capsules, with a sticky amber 'PREVIEW' banner so the author-context is unmistakable. Audio block adapts: 'audio renders at seal time' when nothing's been generated yet. Author opens don't stamp the recipient's first-open timestamp.

JournalingMay 11, 2026

Inline 💌 lovio-flag on dashboard entry cards

Symmetric to the 📌 pin button. Flag any entry for a future lovio capsule with one click from the /dashboard stream — same as pinning. The lovio pile strip on /dashboard/lovio listens for the toggle event and refreshes its count instantly, no reload required.

PlatformMay 11, 2026

Notebooks are now searchable in Cmd-K

Sixth result group in the global command palette. Type a notebook name and jump straight to /dashboard/notebooks/[id] from anywhere. The empty-query default surface seeds 5 notebooks right after Pages (notebooks read more like navigation than content). Cached on first open like the other groups so re-opens are instant.

JournalingMay 11, 2026

Inline filter on /dashboard/notebooks

Same pattern as the highlights wall filter. Once you have more than 6 notebooks (work / dreams / projects / lovio drafts / project logs / …) the grid becomes a sea of cards. Substring match across name + description, 'N of M' count while filtering, dedicated empty-state with clear-filter button. Surfaces only when there are 7+ notebooks so smaller libraries stay uncluttered.

PlatformMay 11, 2026

Last-7-days net change on the Drift wallet

The wallet showed balance + lifetime earned / spent + recent transactions but no trend signal — you couldn't tell at a glance whether you were earning faster, spending faster, or stagnating right now. New strip on the headline summarizes the trailing 7 days: +earned in emerald, −spent in rose, net delta in amber. Computed client-side from transactions already loaded.

Graphene FMMay 11, 2026

🎲 Try another on the season page

Users who land on a season via Cmd-K's 'random Graphene show' or the catalog 🎲 pill and don't connect with it now have a 'Try another' link in the season header (next to '← All shows'). Re-rolls without bouncing back through the catalog. 3-retry guard against the API picking the current season on thin catalogs.

JournalingMay 11, 2026

Inline 📌 pin / unpin on dashboard entry cards

Pinning an entry to surface in the 'Pinned' widget at the top of /dashboard used to mean opening the entry, finding the pin button, clicking it — three navigation hops for a one-click intent. Now each journal entry card on /dashboard has a 📌 button next to the delete button. Amber-tinted when pinned, gray otherwise. Optimistic toggle with revert on error, and the Pinned widget refreshes instantly via a window event so the entry pops up there without a reload.

lovioMay 11, 2026

👀 Preview as recipient on sealed capsules

Authors who've sealed a lovio capsule had no way to see what the recipient actually receives until the delivery email landed. A new 'Preview as recipient' link on the capsule detail page (sealed + non-revoked only) opens /lovio/unlock/<delivery_token> in a new tab — the exact same URL the recipient gets emailed. Byte-for-byte preview of what'll be delivered.

PlatformMay 11, 2026

🎲 Surprise me — random Graphene show + 🎲 in the catalog header

Fourth sibling in the Cmd-K surprise-me family (random journal entry, random highlight, random writing prompt, now random Graphene show). Same backend endpoint also powers a small 🎲 Surprise me pill in /graphene's catalog header so cold visitors landing on the show slate get a one-tap 'pick one for me' affordance instead of having to choose where to start.

PlatformMay 11, 2026

? keyboard shortcut cheat sheet

Press ? from anywhere outside an input to open a modal listing every global shortcut — ⌘K, ⌘+Shift+E, the in-palette navigation keys, on-dashboard letter shortcuts (s / n / ⌥F), Esc. Discovery surface for power users who didn't know what was available beyond the navbar's ⌘K hint. A small ? button next to ⌘K in the navbar opens the same overlay for mouse + touch users.

PlatformMay 11, 2026

/dashboard/stream gets full content filters via a floating bubble

The horizontal stream had only meta filters (age / MBTI / note-type / AI). Now it reaches parity with /dashboard's vertical stream — a second floating bubble next to the existing meta-filter bubble houses the same search + recency + notebook + tag + @person + mood filters. Same shared EntryContentFilterStrip component on both surfaces, so adding a new filter dimension lands in one file instead of three.

PlatformMay 11, 2026

Dashboard widget rail packs into a responsive grid

The eight reflective widgets at the top of /dashboard (Milestone, Pinned entries, Highlight of the day, Writing streak, Daily comic, On this day, Today's prompt, Mood snapshot) used to stack vertically — a long scroll past widgets you'd already seen before reaching the actual stream. Now they pack into a 1 / 2 / 3 column grid by viewport, with null-returning widgets contributing no empty cells.

PlatformMay 10, 2026

Cmd-K now searches your highlights too

The global command palette already surfaced pages, recent entries, and lovio capsules. Now it pulls in your last 60 saved highlights too — fuzzy-search by any phrase in a pull-quote and jump straight to the source entry. The empty-query default also seeds three recent highlights below the recent capsules so they're discoverable without typing. One more way the most memorable lines from your journal stay one keypress away.

JournalingMay 10, 2026

🎲 Surprise me — random journal entry jump

Tap 'Surprise me' from the Cmd-K command palette (now the top item with no query typed) OR from the header of /dashboard/me/stats to jump to a random old journal entry. Drives self-discovery by surfacing forgotten moments — like Wikipedia's random-article button but for your own writing. Skips side-stream synthetic rows (mood/action/sleep quick logs) so the jump always lands on a 'real' entry.

JournalingMay 10, 2026

Sunday weekly recap email (opt-in)

Opt-in cron sends a content-rich summary of your writing week every Sunday morning UTC: entry count + word count + days written + top mood + top 3 @mentions + a featured highlight from this week (or a random older one as a callback). Reflective rather than prescriptive — different vibe from the daily prompt nudge. Empty weeks fire a single 'you didn't write' nudge then go quiet. Toggle on /dashboard/settings.

JournalingMay 10, 2026

Share highlights as image cards (1200×630 PNG)

Every highlight now has a 'Share' button (on /dashboard/highlights wall cards + on the entry-detail highlights section). Opens a modal with a live preview of a 1200×630 PNG share card — gradient background tinted by the highlight's color tier, the quote in serif italic, optional note + entry attribution + a small 'hivejournal.com' mark. Two actions: Download (PNG file) or Copy image (Clipboard API). Pure client-side canvas rendering — no third-party dependency, no server round-trip, no privacy implications.

PlatformMay 10, 2026

Cmd/Ctrl+K command palette

A global fuzzy-search overlay on every authed dashboard page. Cmd/Ctrl+K opens; ↑↓ navigates; Enter goes; Esc closes. Three groups: Pages (hardcoded nav destinations), recent entries (last 20), and your sealed lovio capsules. First-open fetches once + caches for the session. Mounted in DashboardLayout so it's available everywhere a user might want to jump somewhere else fast.

JournalingMay 10, 2026

"Highlight of the day" widget on /dashboard

Closes the loop on yesterday's highlights primitive. A new dashboard widget surfaces one of your saved passages, picked deterministically by UTC day-of-year — same one all day, rotates at midnight. Keeps captured pull-quotes alive in your daily view instead of letting them gather dust on the wall page. Self-hides when you have no highlights yet so the dashboard stays quiet.

JournalingMay 10, 2026

Journal entry highlights — pull-quote passages worth keeping

A new highlights primitive. On any entry detail page, tap '+ Highlight a passage' → paste the passage, add an optional note, pick a color tier (amber/rose/emerald/sky/purple). Each entry shows its highlights as styled blockquote cards in the bottom section. /dashboard/highlights is a wall view of every highlight across your whole journal, newest-first — like Kindle highlights but for your own writing. text_snapshot is captured at save time so the highlight survives later entry edits.

JournalingMay 10, 2026

Notebook-level mood snapshot on /dashboard/notebooks/[id]

The mood snapshot widget now drills in. /api/journal/mood-stats accepts an optional ?notebook_id query param, and the MoodSnapshotWidget grew a notebookId prop + a days prop. Notebook detail pages render a 365-day mood rollup scoped to just that notebook — see the emotional shape of your work notebook vs. your relationship one. Self-hides on notebooks with fewer than 3 tagged entries.

Graphene FMMay 10, 2026

Email-on-new-show for writer follows

Closes yesterday's writer-follow loop. When a writer publishes a new season to Graphene, an hourly cron emails every follower of that writer with a Graphene-branded email (poster + premise + one-tap link to the show). Migration 224 adds story_seasons.writer_followers_notified_at as the idempotency gate. List-Unsubscribe header + a /unsubscribe/writer page wire one-click opt-out same as chapter notifications. Heartbeat-tracked as writer_publish_notify_tick.

Graphene FMMay 10, 2026

Follow writers, not just shows

A 'Follow writer' button on /writers/[handle] lets listeners subscribe to a creator across their whole catalog instead of just one show. Sibling to season-follows: that one is 'tell me about new chapters on this show'; this is 'tell me about anything new from this writer.' Migration 223 mirrors the season_follows shape — PK (follower, writer), unique unsubscribe_token at insert, no-self-follow CHECK. Public follower count surfaces alongside; anonymous taps route to signup. Notification cron lands in a follow-up.

Graphene FMMay 10, 2026

"More from this writer" strip on /seasons/[id]

Cross-promotion on every season detail page. When the show has a public-handled owner, a new strip surfaces their other published shows as a 6-up poster grid below the main content. Reuses the existing GET /api/writers/:handle endpoint — no schema or backend changes. Sits above the existing platform-wide 'Other shows' strip so writer-scoped discovery comes first.

JournalingMay 10, 2026

Milestone celebration widget on /dashboard

A small dashboard widget that surfaces when you cross a notable point — first entry, one week, one month, 100/250/500/1000 entries, year anniversaries (1y / 2y / 5y / 10y). Renders only when a milestone is fresh (within ~5 entries or 7 days of the date) and dismissible per-milestone via localStorage so it doesn't nag. Reuses the existing profile-stats endpoint — no backend changes.

JournalingMay 10, 2026

Quick-entry FAB — jot a journal entry from anywhere

A floating ✏️ button in the bottom-right corner of every authed dashboard page opens a slim modal: title + textarea + save. Save creates the entry and drops you onto its detail page so you can keep editing if needed. Keyboard shortcuts: Cmd/Ctrl+Shift+E to open from any page; Cmd/Ctrl+Enter to save; Esc to close. Self-hides on /dashboard/entries/new so the composer isn't doubled up.

JournalingMay 10, 2026

Pin journal entries to keep them within reach

A 📌 button on every entry detail page pins the entry to a new 'Pinned' strip at the top of /dashboard, regardless of date. Distinct from the lovio flag (which is 'save for a future capsule') — pinning is 'I want this always within reach.' Self-hides when the user has nothing pinned. Capped at 12 entries (the strip won't render more than 6, with a + N more indicator).

Graphene FMMay 10, 2026

Personal Drift wallet at /dashboard/drift

The Drift coin economy now has a personal ledger page. Current balance + lifetime earned/spent headline, recent transactions list with reason-coded badges (🎁 treasure / 🌀 fork / 🔓 chapter / 💸 coin tip / 💰 purchase) and season-title hydration (so 'Tipped Iron Hour Ch 3' shows instead of a UUID). Reuses existing /api/drift/wallet endpoints — no schema or backend changes.

JournalingMay 10, 2026

Daily writing-prompt nudge email (opt-in)

An hourly cron sends one email per day to opted-in users with today's writing prompt + a one-tap link to the composer. Skipped automatically on days the user has already written — it's a nudge, not a guilt-trip. Fires only inside the 09-23 UTC waking-hours window so US/EU users get it during the day. Opt-in lives on /dashboard/settings under a new 'Daily nudges' card; default off.

PlatformMay 10, 2026

Personal activity feed at /dashboard/activity

What's-happening-for-you across the platform on one page: lovio capsule opens (the emotional payoff of writing for someone in the future), new followers on your shows, and recent creator earnings. Rolling 60-day window, newest first, capped at 50. No persisted notification log — recomputed from authoritative tables on each load so the feed stays honest.

Graphene FMMay 10, 2026

Surface analytics from /dashboard/creator + /seasons/[id]

Discoverability for yesterday's per-show analytics. The /dashboard/creator landing now lists every show the creator owns with poster + publish-state + a one-tap "📊 Analytics" link per show. The public /seasons/[id] page also surfaces an "📊 Analytics" text-link inline with the follow button, owner-only.

Graphene FMMay 10, 2026

Per-show writer analytics at /dashboard/seasons/[id]/analytics

Owner-only analytics page that rolls up followers, readers, chapter publishing state, and earnings into one view. Headline cards (followers / readers / chapters / 30d to you) + per-source revenue breakdown (tips, drift coin, subscription pool, sponsorship, manual grants) + a most-recent-followers list + interleaved activity feed (follows / reader sessions / earnings). Single backend endpoint runs all the counter queries in parallel using head:true so no row payloads ship for the cheap counters.

Graphene FMMay 10, 2026

One-click unsubscribe in chapter notification emails

CAN-SPAM polish for the new-chapter emails. Each follow row now has a server-minted unsubscribe_token (24-char base64url) generated at follow time + backfilled for existing rows. Emails include an inline Unsubscribe link in the footer + a List-Unsubscribe RFC 8058 header so Gmail surfaces a one-click unsubscribe button alongside. /unsubscribe/season?token=X is a public confirmation page that calls the unsubscribe endpoint and shows a styled 'you're unsubscribed' state.

Graphene FMMay 10, 2026

Email-on-new-chapter for followed shows

Closes the follow → return-when-new loop. Hourly cron scans story_episodes for chapters with rendered audio + null followers_notified_at, hydrates the parent season, fetches all followers via the season_follows table, sends a styled email per recipient via Resend (Graphene branding, poster image, premise, one-tap link to the chapter), then stamps the column so re-runs are no-ops. Heartbeat-tracked as chapter_followers_notify_tick; bounded at 10 chapters per tick so a backfill can't blow Resend rate limits.

Graphene FMMay 10, 2026

Follow Graphene shows — bookmark without starting

A new follow button on /seasons/[id] lets listeners bookmark a show without needing to start reading first (the existing progress tracking only kicks in once you scroll past chapter 1, paragraph 3). Public follower count surfaces alongside; anonymous taps route to signup. A new 'Following · N' row on /dashboard/listening shows the followed shows as a poster grid. Natural audience for future email-on-new-chapter notifications.

PlatformMay 10, 2026

PWA install — add HiveJournal / Graphene / write.cafe to your homescreen

Every brand (hivejournal.com / graphene.fm / write.cafe) now ships a Web App Manifest at /api/manifest with the right name, theme color, start URL, and icon for that brand. Combined with apple-web-app meta in the layout, listeners + writers can 'Add to Home Screen' on iOS / install on Android and get a real-feeling app tile that opens directly to the brand's home surface.

lovioMay 10, 2026

/lovio/demo — preview the recipient experience without signing up

A standalone demo page that mirrors the real /lovio/unlock/[token] flow with hardcoded sample content — sender's name, recipient name, intro message, four sample entries written in a parent-to-child voice spanning seventeen years. Conveys what receiving a capsule feels like before a visitor has to sign up + clone their voice + create + seal a capsule. CTA at the bottom routes to the waitlist or the owner dashboard. New "See a sample capsule →" button on the /lovio hero links here.

lovioMay 10, 2026

Quarterly-reminder opt-out toggle on /dashboard/settings

The opt-out column on profiles existed since the reminder cron shipped — this commit wires the UI. A new 'lovio' card on /dashboard/settings has a single toggle for the quarterly reminder emails. Opt-out is optimistic (flips instantly, reverts on API failure) and only affects the founder-side reminder cadence; recipient delivery emails are unaffected.

Graphene FMMay 10, 2026

Cross-device progress visible on /graphene + season reader

Yesterday's server-side progress sync now drives the first surfaces a listener hits: the Continue-listening row on /graphene merges server progress with localStorage (server wins ties), and the ResumeReadingPill on /seasons/[id]/read falls back to the server when this device has no local position — so a show started on your phone instantly shows the resume pill on your laptop with zero scroll required.

Graphene FMMay 10, 2026

Cross-device listening progress (server-side sync)

Signed-in listeners' reading positions now sync across devices. ResumeReadingPill mirrors the currently-visible paragraph to a new user_season_progress table every 30s and on tab-hide/page-leave. /dashboard/listening merges server progress with localStorage and prefers whichever timestamp is newer per show — so start a show on your phone, finish it on your laptop. Anonymous listeners still get the localStorage-only path; no behavior change.

Graphene FMMay 10, 2026

/dashboard/listening — every show you've started

A permanent personal history page that lists every Graphene show with an in-progress position on this device. Groups by recency (Today / This week / This month / Earlier) and links each card to /seasons/[id]/read for one-tap resume. Reads the same localStorage entries the /graphene Continue-listening row uses; self-hides shows whose IDs no longer exist in the public slate (deleted or unpublished). Cross-device progress is flagged as a future ship.

JournalingMay 10, 2026

Your numbers at /dashboard/me/stats

Personal stats page that reflects your HiveJournal data back to you: total entries / words / days written / avg-per-entry headline; 12-month entry sparkline; top 5 moods + tags + @mentions ranked by frequency; day-of-week + hour-of-day bar charts ("you write most on Sundays around 10pm"). Pure self-knowledge, no comparison surface. Rolls up over the trailing 5,000 entries.

Admin toolsMay 10, 2026

Super-admin lovio overview at /dashboard/admin/lovio

Founder-level rollup of the lovio side-product: voice clones (active/retired/last-30d), capsules by state (drafts/sealed-queued/delivered/revoked + 30d throughput + notebook-bound), waitlist + reminder cron status, and an interleaved recent-activity feed (voice clones / seals / deliveries / reminders / signups) so the founder can spot anomalies + track growth at a glance.

JournalingMay 10, 2026

Voice-first journal entries (record → transcribe → edit → save)

A new /dashboard/entries/voice page lets you talk through a journal entry instead of typing it. MediaRecorder captures audio in-browser, the audio uploads to a new POST /api/journal/voice-transcribe endpoint that calls OpenAI Whisper, and the transcript prefills an editable composer with an auto-derived title. Combined with the just-shipped "hear in my voice" feature, the full audio loop is now possible: speak it → see it → save it → hear it back in your cloned voice → seal it into a future lovio capsule.

lovioMay 10, 2026

Hear any journal entry read in your own voice

Once you've set up your lovio voice clone, a 🎙️ button on every entry detail page renders that entry as MP3 in your own voice (via ElevenLabs TTS) and plays it inline in a fixed-bottom audio dock. Cached on the entry row keyed by a content+voice hash so re-plays are instant + free; edits or voice changes automatically invalidate. Button state surfaces: 🎙️ (never rendered), 🎧 (cached + fresh), ↻ (stale — entry edited or voice changed), ⏳ (rendering). Makes the voice clone valuable from day one — not just for capsules 18 years out.

lovioMay 10, 2026

Flag entries for your lovio pile

A 💌 button on every entry detail page flags it for a future lovio capsule (toggles via PUT /api/lovio/entries/:id/flag). Flagged entries are surfaced first in the capsule entry-picker drawer with a 💌 badge so you can build a capsule from your pile without scrolling through all your entries. A new strip on /dashboard/lovio shows your pile count + expands to a preview of recent flags.

lovioMay 10, 2026

Owner controls: share link, manual resend, owner-fallback

Sealed capsule detail page now exposes the recipient's unlock URL with copy + 'Open as recipient' buttons, plus 'Send now to recipient' and 'Send a preview to me' actions. When a capsule has no recipient_email, the delivery cron now sends the link to the OWNER with a forward-this-manually template (instead of silently sitting forever). Status line shows queued / sent / opened with timestamps.

lovioMay 10, 2026

Delivery cron + /lovio/unlock recipient page

Sealed capsules now actually deliver. Hourly cron finds capsules whose unlock_at has passed and emails the recipient via Resend with a one-tap link to /lovio/unlock/[token]. The public recipient page renders the sender greeting, intro message, audio player (in the cloned voice), and the entries as readable prose underneath — designed to feel like opening a letter, not a SaaS page. Setting unlocked_at on first open is idempotent. Revoked capsules return 410 Gone with a polite message.

lovioMay 10, 2026

Quarterly reminder emails for sealed-but-future capsules

A daily cron now sends one styled email roughly every 90 days to users who have sealed lovio capsules waiting to deliver more than 30 days from now. The email groups all of the user's pending capsules into one message ("you have N capsules in flight; here's when they open") with a one-tap link back to /dashboard/lovio. Per-user opt-out is on profiles.lovio_reminders_opted_out_at. Heartbeat-tracked as lovio_reminder_tick.

lovioMay 10, 2026

Dedicate a whole notebook to a capsule

Capsules can now be bound to an entire notebook instead of (or in addition to) hand-picking entries. Bind a notebook once, write into it normally over the years, and at seal time we materialize every entry from that notebook into the capsule's snapshot. New 'Dedicate a whole notebook' tile on the new-capsule form. Bound capsules surface the notebook on the detail page with a one-tap link back to it.

lovioMay 10, 2026

Capsule sealing — render the audio, lock the delivery

A 'Seal capsule' button on the capsule detail page is live. Sealing locks the entries, renders the full capsule (intro + each entry's title + content) as one MP3 in your cloned voice via ElevenLabs, uploads to storage, mints a one-time delivery token, and queues for delivery on the unlock date. Sealed capsules surface an inline audio preview so you can hear what the recipient will hear. Revoke before unlock works too.

lovioMay 10, 2026

Voice cloning live — record once, narrate every capsule

Browser MediaRecorder UI on /dashboard/lovio/voice-setup walks you through a one-sentence consent recording + a sixty-second sample reading. Both upload to the backend; ElevenLabs Instant Voice Cloning creates the clone; we render a preview clip so you can hear your own voice come back at you. Voice status strip on /dashboard/lovio shows whether your clone is active. Consent audio is kept forever as proof of opt-in. Sealing capsules with the cloned voice ships next.

lovioMay 10, 2026

lovio capsule builder UI in /dashboard

Owner-side capsule builder shipped: /dashboard/lovio lists your capsules grouped by status (drafts / sealed / delivered) with an inline new-capsule form, and /dashboard/lovio/[id] opens the per-capsule editor with an entry picker drawer that surfaces your last 30 journal entries with one-tap add. Drafts are fully editable; sealing depends on the voice-cloning ship still pending. Nav entry under Journal → Lovio.

lovioMay 10, 2026

lovio v1 — schema + marketing page + waitlist

A side-feature of HiveJournal: time-locked journal entries narrated in your own voice, delivered to a recipient on a future date. v1 lands the schema (capsules, voice clones, capsule entries) + waitlist + a marketing page at /lovio explaining the concept. Voice cloning + capsule builder UI + scheduled delivery ship in a follow-up. v1 trigger types: date only — death-trigger ("opened after you pass, executor-verified") arrives with our legacy partner network in 2027.

JournalingMay 10, 2026

Month calendar view at /dashboard/calendar

A full month-grid view of your journal entries with each day cell colored by the dominant mood you wrote in. Multi-entry days get a count badge. Click any day to see its entries inline. Linked from the writing-streak widget's 30-day heatmap as "Open calendar →".

Graphene FMMay 10, 2026

Sleep timer on chapter audio

A 💤 button on the now-playing pill opens a 15 / 30 / 45 / 60-minute menu — the player auto-pauses when the timer ends. Wall-clock based so backgrounded tabs and locked phones still pause on time. While running, the button shows the remaining minutes.

Graphene FMMay 10, 2026

"Continue listening" row on /graphene

Returning listeners now see a row at the top of /graphene with the top 3 shows they were in the middle of (episode number + poster), each linking straight back to the resume position. Reads the same localStorage entries the read-page resume pill writes — so anonymous listeners get the same drop-back-in benefit without signing up.

JournalingMay 10, 2026

Mood-adaptive daily prompts

Today's prompt now reads your last 7 days of mood tags — when one mood is clearly dominant, the card swaps to a prompt tuned to where you actually are (anxious, tired, sad, grateful, etc.) and recolors itself to match. Caption flips to "For where you've been · <mood>" so the personalization is visible. Falls back to the day-of-year rotation otherwise.

JournalingMay 10, 2026

Mood snapshot + click-to-filter

A 30-day mood distribution widget on the journal dashboard renders as a stacked color-tinted bar with an emoji legend — "Mostly 😴 tired (43%)" at a glance. Each segment + chip is a button that filters the entries list to that mood; click again to clear. A removable rose pill shows what's active.

Graphene FMMay 10, 2026

Drift explainer page

New /drift marketing surface walks visitors through the listener-economy loop: find treasures hidden in chapter prose to earn coins, spend coins on tipping writers or unlocking single chapters, 90% of every coin reaches the writer's ledger. Coin bundles + writer-side mechanics in their own sections.

Admin toolsMay 10, 2026

Daily admin digest in your inbox

Hourly cron sends a single styled email each morning summarizing the last 24 hours: gift activity, tip revenue, new subscribers, new Timelines walks, and recent walk highlights. Skips empty days; subject line scans in inbox preview.

Graphene FMMay 10, 2026

Live network activity pill

Small pulsing indicator on the Graphene and Timelines hero showing walks-this-week + chapter drops + signup-list size. Public, server-cached 5min, self-hides on cold network.

Admin toolsMay 10, 2026

Daily activity standup page at /dashboard/admin/today

Single page that rolls up the last 24h (or 3d / 7d) across every system: gift purchases + redemptions, tip + sub revenue, Timelines walks, recent walk highlights with leaf badges. One URL replaces five admin tab visits.

Admin toolsMay 9, 2026

Cross-season Timelines health dashboard

Aggregate view at /dashboard/admin/timelines — every Timelines season with chapter progress, reader counts, finish rates, top-walked leaves. Stat cards on top show total seasons, published count, total readers, finished walks, launch signups.

Admin toolsMay 9, 2026

Preview-before-send + signup list view for launch emails

Notify launch list button now shows a preview confirm with recipient counts before firing. New /dashboard/admin/timelines-signups page lists every email captured by the /timelines signup form, with by-source breakdown + copy-as-CSV.

Gift Graphene+May 9, 2026

Tabbed Sent / Received view on My Gifts

/dashboard/my-gifts now has both sides of the gift system: gifts you've sent (with resend + copy-link actions) and gifts you've received (with status + expiry). Default tab is whichever has data.

TimelinesMay 9, 2026

Per-chapter audio resume

Closed-tab-then-reopened-tab no longer loses your audio position. localStorage-backed; works for any chapter length; path-aware so the four leaves' chapters don't collide.

TimelinesMay 8, 2026

Cross-promotion + reader analytics + per-leaf posters

Ending screen now surfaces 'More timelines' (same-universe first). New 📊 Reader Analytics admin panel shows funnel buckets, choice 1 vote share, leaf distribution. Each leaf gets its own DALL-E poster keyed off its climax beat.

TimelinesMay 8, 2026

Per-leaf social-share OG cards + share button

After walking a leaf, listeners can share their timeline. The og:image is a per-leaf rich card composed with the leaf poster + 'I just walked one of four endings.' Native share sheet on mobile, clipboard fallback on desktop.

TimelinesMay 8, 2026

Tipping parity on the Timelines reader

End-of-chapter tip prompts + end-of-walk tip CTA. Same Stripe + Drift coin flows as the standard reader. Real revenue gap closed.

TimelinesMay 7, 2026

Novel → Timelines converter

One-click clone any novel-mode season into a Timelines variant. AA targets the closest faithful adaptation; AB/BA/BB diverge into new tonal verdicts. Original season stays untouched.

Gift Graphene+May 7, 2026

Pre-expiry conversion reminders + funnel dashboard

Hourly cron sends 30d / 7d / 1d reminder emails as gift recipients approach expiry. Admin monetization dashboard shows the conversion funnel — reminders sent vs recipients now subscribed.

Gift Graphene+May 7, 2026

Gift Graphene+ — $60 buys 12 months for someone else

Pre-paid sub credit, not a recurring subscription. Anonymous-friendly buy form, recipient redeems by email, gift entitlement displays on /dashboard/subscription. Buyer can resend the email if it bounced + copy the redemption link as fallback.

TimelinesMay 6, 2026

Timelines — branching seasons with 4 endings

A new sibling story format alongside journal-driven dramas and linear novels. Two binary choices send the listener down one of four engineered-equal endings. Characters in each timeline have dreams of events from parallel timelines — on rewind, listeners realize the dreams were the other paths' reality.

MonetizationMay 5, 2026

Cancel-flow retention: switch to annual

Subscribers in the cancel flow get a 'Switch to $48/yr (save $12)' option alongside the existing free-month coupon. Stripe prorates the swap. Logged distinctly so the dashboard separates annual conversions from coupon takers.

MonetizationMay 5, 2026

End-of-chapter tip prompt

Floating prompt appears when a chapter audio finishes — peak emotional intensity for tip conversion. Two CTAs: Tip in coins (no checkout) and Tip the team (Stripe). One per chapter per session.

Changelog · HiveJournal | HiveJournal