- snippet generation moved to a j2 template; per-host pb_root flag - cms.mozimo.in emits 'redir / /_/' before reverse_proxy (pattern from overlord's Caddyfile); other hosts unchanged - snippets now update in place (blockinfile idempotency) instead of skipping when the desired block changed
Mozimo — The Art of Chocolate, Made in India
A full luxury-editorial redesign of mozimo.in, implementing the proposed "Enter the world of Mozimo" flow: ivory, deep cacao, champagne gold, restrained puce — editorial, European, slightly mysterious.
Built with TanStack Start (React 19 + Vite), Tailwind CSS 4, and zero animation dependencies (hand-rolled CSS + IntersectionObserver).
Design language
- Palette — ivory
#faf6ee, deep cacao#140a06, champagne gold#c2a06e, brand puce#703133 - Type — Fraunces (display serif), Renner* (brand geometric sans), Samantha Signature (script accents)
- Motifs — arched image masks, paper-grain texture, champagne hairlines, marquee tickers, cursor-trailing index previews, staggered line reveals
Site map
| Route | Contents |
|---|---|
/ |
Announcement bar → hero ("Chocolate, perfected.") → brand statement → Shop by Experience → The Mozimo Edit → Signatures → Made by Hand (film) → Ingredient Story → The Art of Giving → Seasonal Edit → Experiences → Journal → Press → Instagram |
/chocolate |
Collection index (Bars → Gifting) with 3-image hover carousels + The Pantry |
/collections/[handle] |
A Shopify collection as a first-party page (also powers /gifting CTAs) |
/products/[handle] |
Product page — gallery, price, description, buy (Shopify checkout) |
/gifting |
Who is it for (price-wise tiles) → hampers → Seasonal Edit |
/experiences |
Chef's Table, Tastings, Private Events, Collaborations, Pop-ups, Mozimo at Home |
/bespoke |
Made for Your Moment — corporate, weddings, collaborations, events, custom packaging + bulk/bespoke enquiry form |
/contact |
Contact form + atelier details |
/our-world |
Story · Chocolate · Craft · Ingredients · People (+ /about redirects here) |
/journal (+3 essays) |
The Mozimo Journal — The Art of Tempering; Why Dark Chocolate Tastes Different; The Story Behind Our Signature Box |
Headless commerce & CMS
The site renders commerce itself; Shopify runs headless behind it.
- Shopify Storefront API (
src/lib/shopify.ts) — products, prices, collections. Server-side, cached ~60s; auth via a staticSHOPIFY_STOREFRONT_ACCESS_TOKENor, withSHOPIFY_CLIENT_ID+SHOPIFY_CLIENT_SECRET, the client auto-mints a storefront token (client-credentials → Admin REST) and self-heals if it is ever revoked. Checkout stays on Shopify's hosted page until Phase 2 (in-container cart,unauthenticated_write_checkoutsscope already granted). - PocketBase (
src/lib/cms.ts, running in the same container on :8090, published ascms.mozimo.in) — editorial layer: gifting tabs, /chocolate rows + carousel images, gifting page copy. Reads cached ~30s. - Fallbacks — if either backend is down the site serves the bundled
defaults from
src/data/catalog.ts; it never blanks.
Content editing (no deploys): PocketBase admin at https://cms.mozimo.in/_/ —
edit gifting_tabs (tiles, blurbs, product handles per tier, ordering),
collection_rows (row order, names, the 3 carousel images per collection),
gifting_page (hero copy). Changes go live within the cache TTL.
First-run seeding: scripts/pb-seed.mjs (runs automatically at container
start; also npm run seed) creates the collections and inserts the shipped
content into an empty database. Idempotent — it never overwrites edits.
Develop
npm run dev # vite dev server (port 3000), loads .env when present
npm run pb # one-time download + run PocketBase locally (:8090)
npm run seed # create PB schema + seed default content
npm run build # production build to dist/
npm start # serve the production build (node server.mjs)
npm run preview # serve the production build via vite preview
npm run lint # eslint (currently broken: leftover Next.js config)
Copy .env.example to .env and fill in the Shopify Storefront token and
PocketBase superuser credentials (.env* is gitignored).
Docker
docker build -t mozimo-web .
docker run -p 3000:3000 -p 8090:8090 -v mozimo_pb_data:/app/pb_data mozimo-web
Three-stage build (deps → builder → runner) on pinned node:26-trixie-slim:
dependencies install with npm ci and BuildKit cache mounts, the final image
runs as the unprivileged node user, ships production dependencies, the build
output, PocketBase v0.40.2 (multi-arch) and entrypoint.sh which starts both
processes, ensures the PocketBase superuser matches PB_SUPERUSER_EMAIL /
PB_SUPERUSER_PASSWORD on every boot, and seeds the CMS schema + defaults.
Volumes: /app/pb_data holds the CMS database — back it up. Ports: 3000
web, 8090 PocketBase (cms.mozimo.in → 8090 via Caddy, see ansible/).