Skip to content
Code by Pawpu

2026

Lumina

Daily motivation dashboard with a Gemini coach and optional spoken voice.

Lab · Solo founder · product & engineering (Momentra Labs)

Written by Al Beltran (Al Andrew Paul Beltran), Software Engineering Lead.

Desktop, tablet, and iPhone 16

01 · The problem

Most AI chat UIs dump you into a blank prompt. Lumina needed a calmer first moment, on-device intro memory, and a coach API that never ships secrets in the browser bundle.

Lumina is a personal daily motivation dashboard Al Andrew Paul Beltran (Al Beltran) designed and developed as founder of Momentra Labs. It opens with a quiet check-in — warm, not clinical — then a Gemini-backed coach and optional spoken voice. API keys stay on the server. The public app is at lumina-momentra-labs.vercel.app.

02 · My role

Solo founder · product & engineering (Momentra Labs)

03 · The result

Shipped a React + Vite + Tailwind dashboard with Framer Motion, a Vercel serverless POST /api/coach (Gemini generateContent), and optional POST /api/lumina-tts (ElevenLabs) with Web Speech fallback. Preferred name lives in localStorage; copy is grounding, not therapy.

04 · Architecture

  1. 01

    React + Vite SPA with Tailwind CSS and Framer Motion

  2. 02

    Vercel serverless /api/coach (Gemini) and /api/lumina-tts (ElevenLabs)

  3. 03

    API keys stay in server env — never VITE_-prefixed into the client bundle

  4. 04

    Optional Open-Meteo weather widgets; intro handshake in localStorage

The story

The constraints
Gemini and ElevenLabs keys must never ship in the Vite bundle. Copy stays grounding, not therapy.
The hard part
SPA + serverless /api only works if rewrites keep /api/* off the index.html fallback.
The trade-off
A quiet first visit costs an extra handshake. A blank prompt would have shipped faster and felt worse.
What broke
The failure mode to avoid was leaking keys via VITE_ prefixes. That is a design constraint, not a war story.
What changed
Coach and optional voice are live. Preferred name stays in localStorage.
What I would do differently
Same split: keys on the server, intro data local. I would add an explicit privacy line on the first screen sooner.

Diagram

Sanitized architecture. Hover is optional — tap or focus a box.

Visitor

Purpose
Check-in, then the daily board.
Trade-off
Name lives on-device.
Scale
No account.

Implementation

  • Soft first-visit handshake, then a daily motivation dashboard
  • Gemini coach via POST /api/coach with keys server-side only
  • Optional Lumina Voice (ElevenLabs) with Web Speech fallback
  • Public demo at lumina-momentra-labs.vercel.app

Challenges & outcomes

Challenges

  • Keeping Gemini and ElevenLabs keys off the client while deploying a Vite SPA on Vercel
  • Writing check-in copy that stays warm without sounding like therapy

Outcomes

  • Public app live at https://lumina-momentra-labs.vercel.app/
  • Shipped as a founder-owned Momentra Labs product, not a client case study

Lessons

  • SPA + serverless /api routes only work if rewrites keep /api/* off the index.html fallback
  • Voice and coach features need a privacy-honest story: keys server-side, intro data local

Related writing