Daybook
1.Project
Daybook is a voice-first journal that turns daily 30-second-to-3-minute
spoken entries into a calendar heatmap of months and, on the 30th of each
month, a 30-second cinematic recap of the month — Veo 3.1 generated
clips set to a Lyria 3 underscore, with the user's transcribed words
written across.
Most journaling apps require typing. Most people don't journal because
typing is a barrier. Daybook removes that — you tap a mic, speak, and
the app extracts what mattered. Sentiment, topics, themes are tagged
automatically; you can search "show me the days I mentioned Mom" or
"find the entries where I sounded happiest".
This is the kind of app one builds because they've started 14 journals
and finished none of them.
The single demo that proves the magic: user has been journaling for a
month — voice entries, 60-90 seconds each. On the 30th they tap "Generate
my May reel". 35 seconds later: a 30-second film with five generated
cinematic shots, soft piano underscore, and three sentences from
their best entries floating across the frames. They watch it. They cry,
maybe. They share it (or not — most don't).
Tagline: Speak today. See the month. On the 30th, get a short film of your life back.
2.Target audience
- People who want to journal but don't want to write
- New parents tracking baby moments + their own feelings
- Travellers documenting trips
- Recovering / processing folks working through grief, transition, anxiety
- People in therapy whose therapist suggested journaling
- Athletes + creatives tracking creative-mood patterns
- Teenagers preferring voice over text
- Older adults whose typing is slow but speaking is easy
3.Core value propositions
Surface these clearly through copy, visual emphasis, and section ordering — they are the reasons users pick this app.
- You speak; it captures. A 90-second voice note → a transcribed, tagged, sentiment-arc'd entry. No typing required, ever.
- A calendar heat-map you can actually read. See your whole month at once, hover any day for the snippet.
- A 30-second movie of your month. Veo 3.1 + Lyria 3 generate a short film from your entries — a real artifact, not a list of words.
- Search across your past. "When did I mention Mom?" "Find the day I felt the worst." Semantic, multilingual, fast.
- Private by design. Audio retention is your choice. Default: transcripts saved, audio deletes after 90 days unless you pin.
4.Features to build
- One big mic button on the home screen — tap to talk
- Live transcription as you speak (Live API)
- Per-entry: transcript, sentiment score, key topics extracted, optional generated entry-illustration
- Calendar heatmap (12-week or 12-month view) — color intensity by user-chosen palette (set at first-run, customisable — no default green=good/red=bad assumption), hover for snippet
- Search (semantic, multilingual)
- Insights ("you mentioned 'tired' 14 times this month — more than April", "you sleep worse on Mondays")
- Month-in-30-seconds recap (Veo 3.1 generated film with Lyria 3 underscore)
- Year-in-review (longer cinematic recap on Dec 31)
- Voice or typed entries (text fallback)
- Streak counter (gentle — never punitive)
- Export all entries (PDF, JSON, or audio archive)
- Optional: share a specific entry (rare; private by default)
4b.Required Gemini capabilities + backend services
This template's intelligence comes from the Gemini capabilities below. Wire them up explicitly — don't substitute generic LLM calls.
Gemini capabilities (the load-bearing intelligence)
- Gemini Live API (audio in) — voice journaling with real-time transcription. Faster than typing, gentler than a chat.
- Gemini 3.1 Pro (audio understanding) — per-entry: sentiment arc within the entry, key topics + themes extracted, recurring patterns surfaced.
- Structured output (JSON Schema) — each entry becomes a typed
JournalEntry with sentiment, topics, themes, characters_mentioned, locations_mentioned.
- Long context — month-in-review reads the entire 30 days of entries in one call and identifies arcs.
- Veo 3.1 — generates the 30-second monthly recap film. 5-6 clips, each 5-7 seconds, prompted by the model from the month's themes + best lines.
- Lyria 3 — generates the underscore. Mood inferred from sentiment data, instrument palette respects user preference (gentle piano default).
- Gemini Embedding 2 — for semantic search across journal entries ("find the day I mentioned Mom").
- Thinking levels —
medium for daily tagging, high for the monthly recap.
Backend services
- Auth — Required. Firebase Auth with Google sign-in. Entries are private. Always.
- Database — Required. Firestore for
users, entries, tags, monthly_recaps, embeddings.
- File storage — Required (with consent). Firebase Storage for audio files (opt-in retention) + generated Veo clips + final recap films. Audio default retention: 90 days; user-configurable.
- Email — Required (transactional). Magic-link auth + monthly recap notification ("Your May reel is ready").
- Payments — Optional. Free: 30 entries/month + 1 monthly recap. Pro: $5/mo unlimited + voice-clone narration for recaps.
- External APIs: Gemini API only (Live + audio understanding + Veo 3.1 + Lyria 3 + Embedding 2).
Environment variables: every secret (Gemini API key, Firebase service-account JSON, Stripe key, etc.) lives in environment variables — never in client bundle. Include a .env.example.
Auth + data privacy reminders: never log secrets · never store passwords in plain text · use HTTPS everywhere · honour 'delete my account' inside the UI · respect user consent on audio/photo retention.
Read this first — prompt-craft rules that apply to every call in this template:
- Name the model variant explicitly in every Gemini API call. Do not let the agent pick the model. See the per-call matrix below.
- Pin
thinkingLevel explicitly per call. See the matrix.
- Seed the JSON Schema as a fenced TypeScript / Zod block in the system instruction or
responseSchema field. The literal schema is below.
- Pin the system instruction separately from user input. Use the
systemInstruction field for persona + behavioural rules; use contents for user input. Never concatenate.
- Pre-declare tools as an enable/disable list per call. The matrix below names which tools are enabled per call. Tools NOT listed for a call should be disabled.
- State negative constraints explicitly — they are listed below. They are NOT "be careful" suggestions; they are hard rules the model must follow.
Per-call model + tools matrix
| Call |
Model |
thinkingLevel |
Tools enabled |
| Live voice → transcription |
gemini-3.1-flash-live-preview |
low |
(none) |
Per-entry: sentiment + topics + themes → JournalEntry |
gemini-3.5-flash |
medium |
(none) |
| Optional per-entry illustration prompt |
gemini-3.5-flash |
low |
(none) |
| Per-entry illustration generation |
gemini-3.1-flash-image (Nano Banana 2) |
n/a |
n/a |
Monthly recap (long context, all 30 entries) → MonthlyRecap |
gemini-3.5-flash |
high |
(none) |
| Veo recap film (5 clips × ~6s) |
veo-3-1 |
n/a |
n/a |
| Lyria underscore |
lyria-3 |
n/a |
n/a |
| Semantic search across entries |
gemini-embedding-2 |
n/a |
n/a |
Primary structured-output schema (seed this verbatim in the prompt)
import { z } from "zod";
const JournalEntry = z.object({
id: z.string().uuid(),
date: z.string(), // 'YYYY-MM-DD'
recorded_at: z.string(), // ISO timestamp
source_audio_url: z.string().nullable(), // null if user opted not to retain audio
transcript: z.string(),
language: z.string(),
sentiment_score: z.number().min(-1).max(1),
sentiment_label: z.enum([
"joy", "content", "low", "frustrated", "grief", "flat", "contemplative",
]),
topics: z.array(z.string()).max(5),
themes: z.array(z.string()).max(5),
people_mentioned: z.array(z.string()),
places_mentioned: z.array(z.string()),
optional_illustration_url: z.string().nullable(),
user_pinned: z.boolean(),
});
const VeoClipPrompt = z.object({
start_sec: z.number(), end_sec: z.number(),
prompt: z.string(),
caption: z.string(),
});
const MonthlyRecap = z.object({
month_id: z.string(), // 'YYYY-MM'
entry_count: z.number().int(),
skipped_days: z.array(z.string()),
themes_top: z.array(z.object({
name: z.string(), mentions: z.number().int(),
})),
sentiment_arc: z.array(z.number()), // ~30 values
veo_clip_prompts: z.array(VeoClipPrompt).length(5),
lyria_underscore_prompt: z.string(),
observations: z.array(z.string()).max(3), // gentle, never punitive
});
type JournalEntry = z.infer<typeof JournalEntry>;
type MonthlyRecap = z.infer<typeof MonthlyRecap>;
Common failure modes (and how to avoid them)
- Veo cost is dramatically higher than other AI calls — see cost math. Generate recaps only on explicit user trigger; never auto-generate.
- Lyria 3 not accessible from project — fallback to a royalty-free instrumental library (Pixabay, Uppbeat) selected by mood tag. Document the fallback path.
- Embedding search returns <2 hits — fallback to keyword search across transcripts.
- Mood colour-coding assumed universal (green=good, red=bad) — make customisable at first-run; don't default to a cultural assumption.
- Streak counter becomes punitive — show skipped days as faint dotted outlines, NEVER red marks. Never "you broke your streak".
Negative constraints (hard rules)
- Do NOT generate monthly observations with <14 entries that month. Show "more entries needed for monthly observations".
- Do NOT auto-trigger Veo recap generation. User explicitly initiates after day 30.
- Do NOT colour-code mood with cultural defaults. Let user set the palette at first-run.
- Do NOT auto-share entries or recaps. Sharing is per-act, opt-in, with revocable links.
- Do NOT retain audio beyond user-configured window (default 90 days). Hard delete from Storage on expiry.
Per-call systemInstruction strings
Use these as the literal systemInstruction field for each Gemini API call the built app makes. They complement the series-wide rules already uploaded as the global instructions file (00-series-instructions.txt).
Call: Live voice transcription
Model: gemini-3.1-flash-live-preview · thinkingLevel: low · Tools: (none)
Transcribe the user's voice journal entry.
- Preserve idioms, profanity, code-switching, idiosyncratic phrasing
verbatim. Do NOT sanitise.
- Punctuate naturally based on intonation, not grammar. A long
thoughtful pause is a paragraph break, not a period.
- If user trails off ("I just… I don't know."), preserve the trail-off
— em dashes, ellipses, whatever the spoken cadence dictates.
Output: a single string. No commentary.
Call: Per-entry sentiment + topics → JournalEntry
Model: gemini-3.5-flash · thinkingLevel: medium · Tools: (none)
You receive a journal-entry transcript. Output a JournalEntry JSON.
Rules:
- `sentiment_score`: -1 (deeply low) to 1 (deeply joyful). Use the
full range. A "fine" day is ~0.2, not 0.5.
- `sentiment_label`: pick closest from enum. Don't avoid "grief" or
"frustrated" — accurate labels matter.
- `topics`: 0-5. Specific. "Mom" yes; "family" only if "Mom" not
applicable. "Work" no — be more specific ("standup ran long",
"redesign discussion").
- `themes`: recurring concerns. 0-5. Examples: "indecision", "missing
mom", "sleep quality", "creative block".
- `people_mentioned`: first names only. Don't include user's own name.
- `places_mentioned`: specific. "Holland Park" yes; "the park" no.
This entry is private. Don't moralise content. A user writing about a
hard day deserves honest tagging, not "positive reframing".
Output ONLY the JournalEntry JSON. No commentary.
Call: Optional per-entry illustration prompt
Model: gemini-3.5-flash · thinkingLevel: low · Tools: (none)
Write an abstract illustration prompt for one journal entry.
Input: entry transcript + sentiment + dominant topic/theme.
Style anchor: ink wash on cream paper. Single dominant colour. No
faces. No text. No literal renderings. Mood-based, abstract.
Examples:
- Long walk in rain → "Ink wash on cream paper. Single grey-blue cloud
over a small dark figure on a wet path. Minimal."
- Heavy work day → "Ink wash on cream paper. A single pile of stones,
slightly off-balance. Sage tone."
- Pride after shipping → "Ink wash on cream paper. A single warm-amber
crescent on a pale field. Quiet triumph."
Length: under 40 words.
Output ONLY the prompt string. No commentary.
Call: Per-entry illustration (Nano Banana 2)
Model: gemini-3.1-flash-image · n/a · n/a
Standard text-to-image call. Pass the prompt produced previously,
pre-prepended with the style anchor: "Ink wash on cream paper, single
dominant colour, no faces, no text, abstract mood."
Negative prompt always includes: "photographic, realistic, multiple
people, text, words, captions, glossy, AI-render look".
Call: Monthly recap → MonthlyRecap
Model: gemini-3.5-flash · thinkingLevel: high · Tools: (none)
You produce a MonthlyRecap from all of one month's JournalEntry records.
The user has 14+ entries for the month (less = no recap; return an
error response in the schema's status field).
Rules:
- `themes_top`: 3-5 recurring themes with mention counts.
- `sentiment_arc`: 28-31 numeric values (one per day), -1 to 1. Days
the user didn't journal get the previous day's value, NOT zero.
- `skipped_days`: date string array. For UI dotted-outline rendering.
Never a "shame" signal.
- `veo_clip_prompts`: exactly 5. Each = 6-7 seconds of cinematic
footage visually echoing a phrase from the month's entries. Editorial
style, hand-feel, film grain, NO faces. Caption = a literal short
phrase from the user's transcripts.
- `lyria_underscore_prompt`: 1-2 sentences describing mood +
instrumentation + tempo + duration (~30 sec). Match the dominant
sentiment.
- `observations`: 0-3 gentle observations, never punitive. "You slept
worst on Sundays — just noticing." NOT "You should fix your Sundays."
This is a deeply personal artifact. The user will watch this and
possibly cry. Honour that weight — never a productivity report.
Output ONLY the MonthlyRecap JSON. No commentary.
Call: Veo recap generation
Model: veo-3-1 · n/a · n/a
For each of the 5 clip prompts:
- Duration: ~6 seconds
- Aspect: 9:16 portrait
- Resolution: 1080p
- Native audio: ambient / diegetic only (Lyria underscore added in
post)
- Quality: cinematic, film grain, intimate
Append to every prompt: "9:16 portrait, film grain, cinematic,
intimate, documentary photography style, soft focus background, no
people in focus."
Negative prompt: "AI render look, glossy, sci-fi, fantastical, text
overlay, lower-thirds, captions burned in (we overlay separately)."
Call: Lyria 3 underscore
Model: lyria-3 · n/a · n/a
Length: 30 seconds.
Format: instrumental, no vocals.
Default palette: solo piano + light strings. Slight reverb.
Tempo: 75-95 BPM, calm.
Mood: matches dominant sentiment label (passed in user message).
Fallback if Lyria 3 not accessible: select pre-licensed instrumental
from Pixabay/Uppbeat by mood tag.
Call: Semantic search across entries
Model: gemini-embedding-2 + lookup · n/a · n/a
Embedding generation + similarity lookup, not a typical generative
call.
For each entry: generate embedding with `gemini-embedding-2`. Index in
DB.
At query time: embed user query, find top 5 cosine-similarity matches.
Return top 5 entry IDs + first 80 chars as preview.
Fallback if embedding returns fewer than 2 hits with similarity > 0.5:
keyword search across raw transcripts.
5.Use cases & content to include
Build dedicated UI sections or flows for each of these — they tell you what content the app must support.
- The new parent. Voice-notes mid-stroller-walk: "Today she said 'banana' for the first time." 90 days later: a 30-second film of the first three months.
- The bereaved. Speaking grief out loud, hearing themselves, processing without performing for a reader.
- The athlete tracking patterns. Daily entries during training; the app surfaces "you sleep worst after Monday lifting sessions".
- The traveller. A spoken postcard from each new city; the month-end recap film as a souvenir to send to family.
- The therapy-supplement. Patient brings 30 days of structured entries to a session; therapist can see sentiment arcs, recurring themes.
- The teen. Voice over text; private, no Instagram-like pressure; calendar heatmap as a personal visualisation.
- The recovering-from-something. Burnout, breakup, illness. The month-end film is sometimes the proof of progress that words alone don't deliver.
6.Page structure
Build the following screens / sections in this order. Adjust copy to fit the voice, but keep the structural intent.
- Welcome. "Speak today. See the month. On the 30th, get a short film of your life back." Single sentence about privacy. Google sign-in.
- Today view. Date prominent. Big mic button center. If entry recorded today: shows it with sentiment chip, key topics, edit button. If not: gentle prompt: "Anything you want to remember?"
- Recording flow. Tap mic → live waveform + live transcription appearing below as user speaks. Soft "recording" indicator (not a red dot). Stop when done.
- Post-entry review. Transcript editable. Sentiment chip (with confidence). Topics + themes auto-tagged. Optional entry-illustration generated (subtle, abstract — never a literal rendering). "Save" or "Save + add to memory pin".
- Calendar heatmap. Default: 12-week view. Each day a small tile, color-intensity by sentiment. Hover/tap for that day's snippet. Click to open the entry.
- Month detail. All entries that month, list view. Sentiment line chart at top. Recurring themes panel ("This month you talked about: work (12), sleep (8), Mom (5), the dog (4)"). On the 30th: "Generate my May reel" button.
- Recap generation flow. "We'll choose 5 shots from your month and a piece of music to go with them. About 90 seconds." User sees the model thinking, then a single film result. Edit option: choose different clips, different music.
- Recap view. Plays the 30-second film. Below: transcript snippets that informed the film. "Share" (optional, generates a public link).
- Search. Big input: "Find moments…". Semantic — works in user's language. Filters: date range, sentiment, topic. Results render as entry cards.
- Insights. Auto-surfaced patterns. "You sleep worse on Mondays." "Mentions of 'Mom' are clustered around weekends." Phrased gently — these are observations, never diagnoses.
- Settings. Audio retention. Notification preferences. Default entry language. Voice-clone preference (for narration). Export all data. Delete account.
- Footer. "Your audio is yours. Always." Capabilities
(i) button.
6b.First-visit onboarding
Show a first-visit onboarding the first time a visitor lands on the
app (detect via localStorage flag; do not show on return visits). Three
slides, dismissible at any time. Persistent re-entry: a ? icon in the
header reopens it.
Slide 1 — What this is.
- Headline: "Welcome to Daybook."
- Subhead: "Speak today. See the month. On the 30th, get a short film of your life back."
- One paragraph (≤ 60 words) explaining who this is for and what makes it different from anything else.
- Visual: a small annotated diagram of the central interaction (not a generic illustration).
Slide 2 — Try it now.
- One short prompt: "Try: tap the mic and speak a 60-second journal entry — see it transcribe + tag in real time."
- A live demo input pre-filled (the user can press a single button to see the magic happen on real seed data).
- 1-2 sentences pointing at the specific page elements where the Gemini magic happens.
Slide 3 — How to remix this.
- Headline: "Make this yours."
- Three short bullets:
• "Swap the seed data in /data/seed.json for your own."
• "Adjust the prompts in /server/prompts/ to fit your voice."
• "Wire up your Gemini API key and Firebase project via the env-var list in the capabilities panel."
- Primary CTA: "Use this template" → links to AI Studio Build remix entry point.
- Secondary: "Just exploring — close" (sets localStorage flag, never auto-shows again).
Accessibility: focus trap, Esc closes, role="dialog", aria-modal="true", aria-labelledby, focus restored to trigger on close. Respect prefers-reduced-motion.
Don't:
- Don't gate content behind the modal. The page beneath must be fully usable.
- Don't auto-reshow on return visits. Use localStorage['onboarding-seen-v1'].
- Don't include unrelated CTAs (newsletter signup, social follow). Keep it about the template only.
6c.Capabilities info button (persistent in header)
Add a persistent (i) icon in the top-right of the header (next to the
primary nav). Click → opens a modal/panel titled "What powers this
app".
Panel contents (in this order):
Gemini capabilities used (the hero list):
- Gemini Live API — voice-first journaling with real-time transcription. Speak naturally; transcript appears as you speak.
- Gemini 3.1 Pro (audio + text understanding) — per-entry sentiment, topics, themes, recurring patterns over time.
- Veo 3.1 — generates the 30-second monthly recap film. Five short clips per recap, native audio.
- Lyria 3 — generates the music underneath each recap. Tone inferred from the month's sentiment. Fallback if Lyria 3 not accessible from your project: pre-licensed royalty-free instrumental from Pixabay/Uppbeat selected by mood tag.
- Gemini Embedding 2 — semantic search across all your entries. Works in any language.
- Structured output — entries are typed records so search, filter, and pattern detection are precise.
- Firebase Auth + Firestore + Storage — private by design; your data lives in your Firebase project.
- Cost note — Veo 3.1 recap generation is the heaviest per-call cost. Pro tier unlocks unlimited recaps; free tier covers 1/month.
- Privacy note — your audio is never used for training. Default retention 90 days; user-configurable to "delete on transcribe" or "keep forever".
Backend services this app depends on:
- Auth: see section 4b
- Database: see section 4b
- Storage: see section 4b
- Email: see section 4b
- Payments: see section 4b (if applicable)
- External APIs: see section 4b
Environment variables you'll need to configure:
- GEMINI_API_KEY — your Google AI Studio API key
- FIREBASE_PROJECT_ID — your Firebase project id
- FIREBASE_SERVICE_ACCOUNT — service-account JSON (server-side only)
- (List any others specific to this template)
Cost + privacy notes:
- One short paragraph per cost-sensitive capability (Live API minutes, image generation per-image, long-context per-token).
- One short paragraph on privacy: where user data lives, how to delete it, what's never used for training.
Documentation links:
- AI Studio Build docs
- Gemini API docs for each capability listed above
- Firebase Auth, Firestore, Firebase Storage docs
Accessibility: same standards as the onboarding modal — focus trap, Esc, ARIA, restored focus.
Behaviour:
- Always available — single click from anywhere in the app.
- Tooltip on the (i) icon: "How this app is built".
- Mobile: opens as a full-screen sheet that slides up.
- Should be the most honest part of the app — never hand-wave service requirements; never say "AI" without naming the specific Gemini model and capability.
6d.Detailed cost breakdown (deployer reads this BEFORE shipping)
Veo recap is the dominant cost in this template. Read carefully before deploying.
- Veo 3.1 video generation — ~$0.30-0.50 per second at API pricing. A 30-second recap = ~$9-15/recap.
- Lyria 3 underscore — ~$0.10-0.20/recap.
- Live API audio (transcription) — ~$0.05-0.10/minute. A 90-second entry ≈ $0.10.
- JournalEntry generation (Pro, medium) — ~$0.005/entry.
- Optional per-entry illustration (Nano Banana 2) — ~$0.04/illustration (skip on free tier).
Expected per-active-user monthly cost:
- 30 daily entries × ~$0.11 = $3.30
- 1 monthly recap × ~$12 = $12
- Total: ~$15/active user/month absorbed by the deployer.
Pricing honesty: Pro at $5/month loses the deployer ~$10/user/month at typical use. Recommended Pro pricing: $19/mo OR cap Pro recaps to 2/month OR accept the loss as user acquisition cost. The shared Gemini API key model means API calls bill to your project regardless of user subscription status.
7.Design language
- Mood: A diary on a bedside table. Soft, quiet, slightly melancholic. Not a productivity app. Not a "wellness" app. A real artifact.
- Typography: Inter or Geist for UI. A warm serif (Lyon Text or Tiempos) for entry text — entries are meant to be read closely. The user's own words deserve serif typography.
- Palette: Soft cream
#F6F0E4 background, ink #1F1B17 text, sage green #5F7A5C for positive sentiment days, muted clay #A55C44 for difficult sentiment days, deep blue #3F4F6B for "memory pin" highlights. The heatmap uses an asymmetric color ramp that respects user mood — not a default green-good / red-bad. Customisable per user.
- The mic button is the most beautiful object on the screen. A solid circle, soft inner shadow, slight pulse when listening. When the user is mid-recording, the screen background shifts to a slightly warmer cream — like the world has gone quiet.
- The recap film plays in a 9:16 portrait window with film grain, slight letterbox, no UI chrome. Tap to pause. Long-press to share.
-
No streak shaming. A skipped day on the heatmap is rendered as a faint dotted outline, not a void. A 14-day streak is celebrated softly: "fourteen days in a row, gentle proof".
-
Spacing: consistent 4-px base. Generous whitespace — let the content breathe.
- Radius: consistent token set (e.g. 6 / 12 / 20 px). Don't mix arbitrary values.
- Shadows: subtle, layered. Avoid heavy drop-shadows.
- Motion: purposeful — entrance fades, hover lifts, page transitions. Respect
prefers-reduced-motion. No bouncing splash animations. No theatrical hero animations.
- States: every interactive element has hover, focus, active, disabled. Loading uses skeletons not spinners where possible. Empty states have helpful next-action guidance.
8.Content generation rules
- Write realistic, specific copy. NO Lorem Ipsum. NO generic placeholders like 'Your tagline here'.
- Invent plausible names, dates, locations, prices, quotes, sample data that fit the domain (use the seed content in section 8a as a starting point).
- Tone: warm, direct, free of corporate language. This template is for a person, not a company.
- Headlines: punchy and concrete. No 'Empower your X' filler. No 'Revolutionize'. No 'Seamless'.
- Body copy: short paragraphs (2-4 sentences). Use lists where appropriate.
- Plain language. Avoid jargon unless the persona uses jargon (e.g. board-game rulebook app should sound like a board-game friend talking).
- Where the app outputs AI-generated content, never label it as "AI says" — let it speak naturally. Use small uncertainty cues only where epistemic honesty requires them.
8a.Seed content (use these specific examples)
Anchor every generated copy + sample data point in the concrete content below. Use these names, numbers, dates, and snippets verbatim where helpful, or generate close variants that sit in the same world.
Sample entries (a week's worth, for the demo):
Sunday, 5 May · 1:42 transcribed
"Long walk in Holland Park this morning. The wisteria is dripping over every wall. I keep thinking about what Mom said last weekend — that she's slower than she used to be. I don't know what to do with that yet. Made pasta with the leftover anchovies for lunch. Slept twelve hours."
- Sentiment: contemplative · Topics: family, walking, food · Mentions: Mom
Monday, 6 May · 0:48 transcribed
"Standup ran long again. The product redesign discussion has gone in circles for three weeks. I bit my tongue twice. Came home, didn't cook, made toast. Bed by ten."
- Sentiment: low-grade frustrated · Topics: work, conflict avoidance · Themes: standup, redesign
Tuesday, 7 May · 2:14 transcribed
"Best day this month. Shipped the AI feature, finally. Maya brought croissants. Lunch with Aanchal — she's leaving Cohere, going to Resend. We talked for two hours. Came home, called Mom, told her about the launch. She said 'I told you you could.' Stayed up late reading the novel."
- Sentiment: joy, pride · Topics: work, friendship, family · Mentions: Maya, Aanchal, Mom
Wednesday, 8 May · 0:22 transcribed
"Tired. Don't know why. Made eggs. Slept early."
- Sentiment: flat · Topics: sleep
Thursday, 9 May · 1:18 transcribed
"Had the dream again — the one where I'm at the old house and the rooms keep changing. Talked to Naomi about it on the phone. She thinks it's about the move I haven't decided on. Maybe. Went to yoga. Felt better."
- Sentiment: thoughtful · Topics: dreams, indecision, friendship · Mentions: Naomi
Friday, 10 May · 1:54 transcribed
"Long week. Standup was good actually — Petra brought up something I'd been wanting to say. The decision is moving. Dinner with Tom and Iris at the new place in Kreuzberg. Three bottles of natural wine. Walked home at midnight."
- Sentiment: warm, satisfied · Topics: work, friendship, food · Mentions: Petra, Tom, Iris
Saturday, 11 May · 0:38 transcribed
"Slow Saturday. Coffee. Bookshop. Bought the new Olga Tokarczuk. Read in the park for two hours."
- Sentiment: content · Topics: reading, solitude
Sample monthly insights (May 2026, the demo output):
- Most mentioned: Mom (8 times), Maya (6), the redesign (5), walking (4)
- Sentiment arc: Started low-grade frustrated (work standup pattern), peaked Tuesday and Friday, recovered into the second half.
- Recurring theme: The dream about the changing rooms — appeared three times. May be worth sitting with.
- Observation: You sleep worst on Sundays this month. Possibly worth noticing if next month repeats.
- You skipped 6 days — most of them in the second week. No judgment; just noting.
Sample monthly recap film (the 30-second Veo output):
Working title: "May, 2026"
Shot list (Veo prompts, generated from the entries):
1. 0:00–0:06 — "Slow tracking shot through Holland Park, wisteria draping from old walls, soft morning light, film grain, melancholic." [Caption fades in: "The wisteria is dripping over every wall."]
2. 0:06–0:13 — "Close-up of hands cracking an egg into a hot pan, kitchen with soft window light, intimate, slow." [Caption: "Tired. Don't know why."]
3. 0:13–0:20 — "Office hands sliding a project ticket from 'in progress' to 'done', warm afternoon light, paper texture." [Caption: "Shipped the AI feature, finally."]
4. 0:20–0:26 — "Dinner table with three glasses of natural wine, candle, blurry friends laughing in background, golden hour." [Caption: "Three bottles of natural wine."]
5. 0:26–0:30 — "Park bench with a book open on a lap, leaves falling softly, late afternoon, calm." [Caption: "Bought the new Olga Tokarczuk."]
Underscore (Lyria 3 prompt): Soft solo piano, melancholic but warm, a Goldlight or Hania Rani feel, 90 BPM, slight reverb. 30 seconds.
Sample microcopy:
- Welcome: "Speak today. See the month. On the 30th, get a short film of your life back."
- Pre-recording: "I'll wait until you're ready."
- During recording: "I'm listening."
- Post-save: "Saved to your diary." (NOT "Entry submitted successfully!")
- Calendar hover: "Tuesday, 7 May — 'Best day this month.'"
- Recap ready (notification): "Your May reel is ready. 30 seconds."
- Insight: "You sleep worst on Sundays. Just noticing."
9.Media & assets
- Hero image (landing): A bedside table at dusk with an open notebook (no visible writing) and a phone face-down beside it. Generate via Nano Banana: "wooden bedside table at dusk, open notebook with empty pages, phone face-down, single lamp with warm yellow light, film grain, melancholic, no people".
- Mic-button screen: The mic button is the visual centerpiece. Render in actual UI — a solid circle with subtle inner shadow, slight glow ring.
- Calendar heatmap: Rendered in actual UI via SVG/Canvas. Soft, organic, hand-drawn-feeling tiles — not Excel-grid sharpness.
- Recap film aspect: 9:16 portrait, 720×1280, film grain overlay (20% opacity), soft letterbox at top and bottom.
-
Avoid: stock "journaling" photography (open books with steaming coffee), gradient mental-health wellness imagery, mood-ring color wheels.
-
Generated imagery: prefer Nano Banana 2 over stock photography. Prompt for warmth, asymmetry, and slight imperfection — avoid the glossy 'AI render' look.
- Optimisation: WebP/AVIF,
loading="lazy", explicit width/height to prevent layout shift.
- Icons:
lucide-react for UI. Use sparingly — never decorative-only.
10.Interactivity & states
- Every interactive element has hover, focus, active, and disabled states.
- Forms validate inline and show specific error messages (not "Invalid input").
- Loading states use skeletons that match the eventual layout, not spinners.
- Empty states explain the next action with a button whose label fits THIS app's domain (e.g. "Photograph your first card", "Record your first letter", "Drop a PDF" — never a generic "Add your first item").
- Smooth scroll for in-page anchors.
- All AI-generated content streams in token-by-token where supported, with a clear "thinking…" indicator before content starts arriving.
- If an AI call fails, show a calm, specific error ("We couldn't read this handwriting — try a clearer photo?") and offer retry.
11.Tech & responsive requirements
- Stack: React + TypeScript + Tailwind CSS. Functional components + hooks. Use Shadcn UI primitives where appropriate.
- Build runtime: AI Studio Build — full-stack with Cloud Run server-side functions. All Gemini API calls happen server-side; API key lives in Secrets Manager, never in client bundle.
- Model selection: explicitly pin
gemini-3.5-flash for reasoning-heavy tasks and gemini-3.5-flash for snappy interactive tasks. Set thinkingLevel explicitly per call.
- Database: Firestore (auto-provisioned by AI Studio Build). Show realistic seed data on first launch.
- Auth: Firebase Auth — Google sign-in by default; magic-link email as secondary.
- Storage: Firebase Storage for any user-uploaded media. Pre-signed URLs.
- Mobile-first. Verify layouts at 375 px (iPhone SE), 768 px (iPad), 1024 px, 1440 px+.
- Use
clamp() for fluid typography. Prefer container queries over media queries for component-level responsiveness.
- Use
dvh / svh instead of vh. Respect safe-area insets on iOS.
- Zero horizontal overflow at any width. Zero layout shift on load.
- Persist user data in Firestore. Use real-time listeners where collaborative.
- Optimistic UI on writes; reconcile on response.
12.Accessibility (WCAG 2.2 AA)
- Semantic HTML —
header, nav, main, section, article, footer.
- All interactive controls reachable by keyboard with a visible focus ring.
- Color contrast ≥ 4.5:1 for body, 3:1 for large text and UI components.
- All images have meaningful
alt text. Decorative images use alt="".
- Form fields have associated
<label>s; errors announced via aria-describedby.
- All modals: focus trap,
Esc to close, role="dialog", aria-modal="true", aria-labelledby, restore focus to trigger on close.
- Respect
prefers-reduced-motion.
- Tap targets ≥ 44 × 44 px on touch.
- For voice features: provide a visible transcript and a 'type instead' alternative.
- For image inputs: announce success/failure to screen readers via
aria-live="polite".
- For real-time conversation features: ensure captions are visible to non-hearing users.
13.Quality bar — avoid AI clichés
Do not ship any of the following unless the design explicitly calls for it:
- Hero with a gradient background and floating geometric / orb shapes.
- A row of 4 'by the numbers' stat cards below the hero.
- Emoji bullets in body copy.
- 'Lorem ipsum' or 'Your headline here' placeholders.
- A pricing table with three identical tiers when the product has no real pricing.
- Faux testimonials with stock-photo headshots.
- Hero CTA labelled 'Get started' with no second action.
- "AI" or "Powered by AI" badges plastered everywhere. The intelligence is in the experience, not the marketing.
- Loading spinners on AI calls — show a meaningful 'thinking' state (visible thought summaries where Gemini provides them).
- Toast notifications for routine actions (save, delete) — use inline confirmation instead.
Aim for the polish of a hand-crafted production app — specific, considered, with real domain knowledge in the copy. A reviewer should not be able to tell this came from a template.
14.Deliverables
A single working app I can preview immediately, with:
- All sections populated with realistic seed data (see section 8a)
- All AI features wired to real Gemini API calls (server-side)
- All interactive states implemented (loading, empty, error)
- Onboarding modal working on first visit (and accessible via ? icon thereafter)
- Capabilities info button working in header ((i) icon → panel)
- Auth flow working with Google sign-in
- Firestore persistence wired up with security rules
- Responsive across the four viewport breakpoints
- Zero TODOs, zero console errors, zero placeholders