SpiceShelf
v0.1.0 app prototype · pre-launch waitlistA genre-native romantasy book companion for the BookTok crowd — a polished brand, a live landing page that showcases the real product (rendered book spines and in-app mobile screens, not stock art), and a waitlist backend, now extended with a v0.1.0 mobile app prototype: a spine-out wooden bookshelf with a 12-template spine renderer, seven switchable shelf themes that re-skin every book, and a procedural-free / AI-baked-premium 'special editions' monetization model.
- Community
- Brand system
- Mobile app
- Design system
- Next.js
- Monetization
Updated 2026-07-03

Overview
SpiceShelf is a romantasy and spicy-fantasy reader companion built the disciplined way: audience insight and brand first, then a real app behind the waitlist. The public site at spiceshelf.app still gates on a waitlist, but it no longer shows mockups — every screen on the landing page is a captured render from the actual v0.1.0 app: a spine-out bookshelf with a 12-template renderer, seven switchable shelf themes, real reading-progress and dog-ear tracking on a self-hosted backend, and a working free/premium billing model.
The case study is about earning the right to build software by getting the positioning right first, then proving it with a real product instead of a prototype screenshot.
The problem
The romantasy genre is heating up — multiple titles in the film/TV pipeline, BookTok vocabulary (tropes, heat levels, "book hangovers") leaking into mainstream attention. The existing reader tools were built for a different era:
- Goodreads is ad-supported, Amazon-owned, and optimized for catalog scale. The default for everyone, the right tool for almost no one.
- StoryGraph / Fable are closer in spirit but generalist.
- BookTok itself is where the heat-level vocabulary actually lives — but it's a feed, not a place to track or recommend.
The window to be the default companion app for the romantasy reader is open right now. The bet is that "for readers, not advertisers" — purpose-built for the heat-aware, trope-aware way this audience already talks about books — is the right wedge.
Audience
- Romantasy and spicy-fantasy readers, BookTok-adjacent.
- Readers who already think in tropes, heat levels, and book hangovers — not just genres and stars. Reader-insider register, no onboarding-the-genre tone.
What I built
- A complete brand system. Cinzel + Cinzel Decorative for display, Inter
for body. Gold/parchment palette with a five-tier pepper-themed heat ramp
(
#D4A84B → #C41E2A). Logo, motion philosophy (calm hero, no scroll jacking), tagline ("The Ultimate Romantasy & Spicy Fantasy Companion"), brand promise ("We bring the heat"). - A working v0.1.0 app, not just the five pillars as landing-page copy: real shelves with reading-progress and status tracking, a persisted Dog-Ear moment timeline with a spoiler wall (you only see tags for chapters you've reached), a spine-out bookshelf with a 12-template renderer, and seven switchable shelf themes that re-skin every book on the shelf at once.
- A free/premium monetization model, actually wired up. Procedural theme re-skinning is free and instant; "baked" AI special editions — richer, real-material covers and spines generated per book × theme — are the premium unlock. Billing runs through Stripe (test mode) with server-verified entitlements, not a client-side flag.
- A baked-edition production pipeline. fal.ai generation, OCR quarantine to catch bad renders, Pillow color grading, WebP downscaling, and a contact-sheet + acceptance-test gate — 60 baked covers/spines produced across 5 books × 6 themes in the first batch.
- A landing page that shows the real product. The marketing site captures actual screens from the running app (not mockups) and embeds them directly — the bookshelf phone screen in the hero, the book-detail heat/trope/dog-ear screen, and a live spine row in "Show Me Your Shelf."
- Self-hosted backend on PocketBase — waitlist, shelves, dog-ears, entitlements, and Stripe webhook events all live in versioned collections with documented API rules and an admin-UI recovery runbook.
- Transactional + confirmation email through Resend, including a
prefetch-safe double opt-in flow (a real production bug: Gmail's link
prefetcher was silently auto-confirming signups via a side-effecting
GET— fixed by moving confirmation to a POST behind a button). - A marketing channel plan with per-channel cadence, dimensions, and voice notes for Instagram, TikTok, X, and Pinterest.
- Deployment topology — Docker on LXC 201, behind a Cloudflare Tunnel, with a pull-based CI deploy reconciler.
Product decisions
- Brand and audience first, app second — but "second" still means real. The waitlist stayed the only public surface while the actual app got built behind it: real backend-backed shelves, not five pillars of landing-page copy. Audience attention is still the gating resource for launch, but the product risk (can this actually be built well) got retired in parallel instead of deferred.
- The heat scale is the signature mechanic. Visual identity (the pepper ramp) and product (heat-aware search, PepperScale ratings) both hang off the same primitive. The brand and the product point at the same thing, by design.
- Free/premium boundary matches cost-to-serve. Procedural re-skins are ~zero marginal cost and free for everyone; baked AI editions cost real money to generate and are the paid unlock — the pricing line follows the infrastructure line instead of an arbitrary feature gate.
- For readers, not advertisers. Stated as a positioning rule, not a marketing line. Revenue comes from a subscription ("Spiceshelf Gold") and a founding-member lifetime tier, not ads — locked pricing: $99 lifetime, $2.99/mo founder rate rising to $4.99/mo post-beta.
- PocketBase, not a managed BaaS. Same self-host pattern used across the portfolio. Waitlist, shelves, and billing entitlements all run on infrastructure I operate, with documented recovery runbooks.
- Ship the review loop, not just the feature. Later phases (billing, baked editions) were built subagent-driven — implementer, spec-compliance review, code-quality review per task — after earlier phases shipped two production bugs (an unreachable internal-origin redirect, then the Gmail prefetch auto-confirm) that only a live post-merge smoke test caught.
Technical architecture
- Frontend: Next.js, self-hosted via Docker on LXC 201 (
deployment-pve). - Backend: self-hosted PocketBase — waitlist, shelves, dog-ears, entitlements, and Stripe webhook-event collections, schema and API rules versioned in the repo.
- Billing: Stripe in test mode, server-verified entitlements (webhook → PocketBase patch), no client-trusted premium flag.
- Image pipeline: fal.ai generation → OCR quarantine → Pillow color grading → WebP downscale → contact sheet + automated acceptance checks, for the baked-edition catalog.
- Email: Resend, with verified DNS and a double opt-in flow — a
prefetch-safe confirm page (
GET, no side effects) plus a POST-only confirm action, after the original side-effectingGETdesign proved exploitable by email-client link prefetching in production. - Public surface: spiceshelf.app behind Cloudflare Tunnel.
- Deploy: pull-based CI reconciler (
spiceshelf-deploy.sh) that fetches the exact pushed SHA, installs infra files atomically, and only force-recreates PocketBase when migrations actually changed. - Operational layer: waitlist and deploy runbooks cover PocketBase env, admin auth, container health, and known failure modes — the difference between "the site is down" and "the site is down for exactly this reason and here's the recovery."
Design and brand
The visual system reads warm and a little ornate without tipping into kitsch. Cinzel for display headlines, Cinzel Decorative for select accents, Inter carrying all the body weight so the page stays readable. The palette runs parchment to gold to deep crimson; the heat ramp is the palette extension, not a separate system. Motion is deliberately calm — the hero doesn't shout.
The voice is short, sensory, and reader-insider: imperative verbs, pepper / heat / spice metaphors used load-bearingly rather than decoratively.
Current status
- Public surface is still a gated waitlist at spiceshelf.app — but the landing page now shows the real product: captured screens from the running v0.1.0 app, not concept art.
- The app itself (v0.1.0) is built and working in private beta: real shelves, reading progress, dog-ears with a spoiler wall, a 12-template spine renderer, seven shelf themes, and Stripe-test-mode billing with server-verified entitlements.
- Baked-edition catalog seeded: 60 AI-generated covers/spines (5 books × 6 themes) through the fal.ai → color-grade → acceptance-test pipeline.
- Brand system, marketing plan, waitlist backend, double opt-in, and transactional email are all defined and operational.
What I would do next
- Take the private-beta app public and retire the waitlist-only gate — the product no longer needs to hide behind concept art.
- Run the launch / channel plan: Instagram first, then TikTok, with the dimensions and cadence already documented.
- Move billing off Stripe test mode once the founder pricing ($99 lifetime, $2.99/mo) is ready to take real payment.
- Expand the baked-edition catalog beyond the first 5-book batch as real shelves populate with more titles.
- Finish the deployment cutover fully onto Cloudflare Tunnel and close the remaining infra TODOs (health checks, logging strategy).
Proof
- Live site: spiceshelf.app
- Hero and proof imagery on this page are live captures from the running app — the bookshelf home screen, the spine-out shelf with theme switching, and the book-detail heat/trope/dog-ear screen.