Build guide
How this storefront was made
A design mockup by Vistaline Digital for Carlos' House of Spice, built as the starting point for a future Shopify store. Everything on this page documents the concept, the research grounding, and the pipeline.
Concept
One rule drove every decision: conventional store, characterful skin. The structure deliberately mirrors two proven Canadian spice retailers (silkroadspices.ca and omfoods.com) because the shop's owner needs a store customers instantly know how to use, not an art piece. The creative freedom lives entirely in the identity layer: the wordmark, palette, type and photography are drawn from the real shop's printed navy banner, spray-painted shutters and packed sky-blue aisle.
Research grounding
- Structure: announcement bar, mega-menu Shop nav with Shop-by-Cuisine, cart drawer with free-shipping progress, homepage order (hero → trust badges → feature rows → collections grid → visit band → newsletter), sidebar collection pages, and the Silk Road product-page anatomy (gallery left; format pills, size selector, qty, pickup note right).
- Business facts (verified press + the shop's own materials): in Kensington Market since 1975 (founding year per the owner, 2026-07; press had said "early 1970s"); Carlos Pereira walked in as a 15-year-old in 1977, worked 35 years for the original owners, bought the shop in 2012 ("I just added my name to the sign"); famous for custom blends of up to 18 spices mixed downstairs; 4.8★ across 420+ Google reviews.
- Placeholders: every product name, description, weight and origin is a marked slot ([SPICE NAME NN], [ORIGIN], …). Prices are numeric so the cart works, but flagged everywhere as demo pricing. No invented testimonials, products or quotes.
Palette
Lifted from the storefront: chili red from the spray-painted shutters, warm black from the printed banner, cream lettering, turmeric as an accent — plus, from the banner itself, the magenta of the "Carlos'" cloud and the navy of its field (normalized picks from the photographed gamut). Roles are strict: chili owns CTAs, magenta owns brand/badges/stock accents (the two never sit adjacent in one component), navy is a dark-band field color, and no magenta text ever sits on navy (2.38:1). The earlier brush-red and market-green accents were retired.
Type
- Archivo (700/800): display grotesk for headings, page heads and product names — hero/display at 800, section heads at 700; the "Carlos'" wordmark patch is Archivo 800 italic on magenta.
- Karla: warm grotesk for UI and body text.
- DM Mono (500): numerals only — prices, weight/size meta, cart and checkout totals, the free-shipping threshold, fact figures.
Build pipeline
- Static multi-page site:
Vite+ vanilla JS, no framework. Seven pages share one injected chrome module (header, mega-menu, cart drawer, footer). - Cart is real: localStorage-persisted line items with format/size variants, quantity, subtotal and a free-shipping progress bar; checkout is an explicit demo stub.
- Both browse paths work as URLs:
/shop?type=…and/shop?region=…, plus search?q=…and client-side sorting. - Photography: the storefront hero, aisle, sign close-up and street-corner press photo are real photos of the shop, and every homepage section (feature rows, collection mosaic, trust-bar texture, visit band) is cropped from those four; AI-generated product stills (top-down bowl-on-linen, one documentary template) appear only as product-card thumbnails.
- QA: Playwright screenshot + functional passes at desktop and mobile widths; deployed on Netlify.
Handoff intent: this mockup maps 1:1 onto Shopify (collections = the type taxonomy, tags = the cuisine regions, variants = format × size), so the real store can be assembled without redesign.
Upgrade pass (July 2026)
- Real-store parity: predictive search dropdown, sticky mobile add-to-cart, sold-out states with real disabled logic, a bundle-tier sampler card, recently-viewed rail, payment-brand icons, branded 404, and a policies hub replacing the misrouted footer links.
- Wholesale flow: dedicated
/wholesalepage with a live Netlify Forms inquiry (honeypot spam trap, custom thanks page), linked from the nav, footer, homepage and contact page. - De-slop pass: square CTAs, hairline borders instead of card shadows, one-badge-max merchandising, script type confined to the wordmark + hero, demo disclosures cut to two (quiet footer footnote + checkout banner), copy de-templated per an external audit.
- Imagery: every SKU got a dedicated grid photo (five had been borrowing feature/hero shots); features and interiors regenerated documentary-style; all media recompressed to web weight with a unified grade.
- Mobile: 44px tap targets, 16px inputs (no iOS zoom), cuisine nav + wholesale in the hamburger menu, footer overflow fixed at 390px.
Hygiene pass (July 2026)
- Geometry system: border-radius collapsed to two values (0 for every interactive control and flush image tile, 8px for card/panel containers), letter-spacing collapsed to three, remaining box-shadows replaced with hairline borders, decorative list bullets removed.
- Type: headings bumped to weight 700 (hero 800), the two digital tilts on the script face removed, all page-title and section-heading sizes unified onto two shared clamp() tokens.
- Photography: a stock street photo with an inaccurate caption was replaced by a real crop of the shop's own corner; the hero scrim was lightened so the storefront reads.
- Placeholder state: the bracketed catalogue slots now render muted with a "Naming with the shop" chip and screen-reader-clean names, so the unfilled catalogue reads as intentional.
- Font comps: a
?font=switcher previewed candidate display families for the client ahead of the direction decision.
Direction pass (July 2026)
- Type system: display family moved from Fraunces to Archivo (client-approved); the Yellowtail script was retired and the "Carlos'" wordmark patch redesigned as Archivo 800 italic on the banner's magenta. DM Mono became permanent, scoped to numerals.
?font=frauncespreviews the old stack;?font=defaultclears it. - Palette: magenta
#b42d58and navy#14294dadded from the banner; brush red and market green retired. Featured Collections and the newsletter band moved from warm ink/chili to navy; badges and stock accents consolidated onto one magenta treatment; prices unified to ink so chili stays CTA-only. Every new text/background pair verified ≥4.5:1. - Copy: founding claim standardized to "Since 1975" sitewide (owner-supplied year, flagged for final confirmation).
Revision round, July 2026
- Font revert: client feedback after seeing the direction pass live ("I liked how it was before... a little too mechanical... revert back to that"): the display stack reverted from Archivo back to Fraunces + the Yellowtail script wordmark/kicker as the production default. The
?font=switcher inverted with it:?font=archivonow previews the retired direction (Archivo headings, italic magenta wordmark patch) as the comparison mode;?font=defaultclears it. Archivo stays in every page's static Google Fonts request since the comparison mode needs it. - Free shipping threshold: raised from the $75 placeholder to $150, the client-agreed real margin, in the announcement bar and the cart's free-shipping progress bar.
- Header rebuild: modeled on Silk Road Spice Merchant and OM Foods: the header dropped its centered ~1240px cap so the wordmark sits flush left and the tools sit flush right with no dead cream space; nav links grew (uppercase, larger, tracked) so Shop and Wholesale read as first-class destinations. The desktop search stayed an icon + expanding field (inverting it into an always-visible inline field was judged to exceed this round's scope; noted for a future pass).
- Shop page rebuild: the category/cuisine sidebar is gone. In its place: a compact page head ("Shop All · 17 products", OM pattern) and a toolbar of two native filter selects (Category, Cuisine) plus the existing sort, all URL-driven. The grid now runs 2/3/4/5-across as the viewport widens (700/1060/1500px), with cards tightened to suit the density.
- Trust band: now uses the same storefront photo as the hero (a lower crop, same dark overlay) instead of a different aisle photo, so it reads as a continuation of the hero rather than an unrelated scene.
- Imagery + copy: the three homepage feature rows use the AI-generated ingredient/product stills again (real shop photos stay on the collections tiles and visit band); "squeeze down the aisle" phrasing was cut from the homepage and About page; the homepage's House Blends bullet swapped a wholesale order-size stat for a direct-to-consumer line, with the Montreal wholesale fact kept on the About and Wholesale pages where it's relevant context.
The Spice Atlas (July 2026)
A single showpiece route at /atlas: an interactive globe of where spice actually comes from, deliberately allowed to leave the shop's daytime design system (the one page that runs dark). Built as a technical and editorial demonstration piece.
- Content: 8 regions, 45 countries, 182 spices with real botany, trade history and named growing origins (Kerala's Malabar coast, the Banda Islands, Urfa and Maras, La Vera, Guntur, Zanzibar, Papantla and so on), authored against a strict schema with an accuracy-first rule set and validated at merge time (unique ids, no dangling origin references, chilies must carry Scoville ranges, no em dashes). Store commerce stays a marked placeholder on every spice card ([IN STOCK], [PRICE], [SHOP THIS SPICE]) until the real catalogue exists.
- The globe: three.js. The land is ~15,000 spice-dust particles (turmeric, paprika, chili, cinnamon, cardamom, saffron hues) sampled on a fibonacci sphere against a Natural Earth land mask precomputed at build time into an 8.5KB bitfield, so the client ships no GIS code. Custom GLSL for the dust (twinkle, region-constellation glow on hover, view-angle energy balance), the atmosphere fresnel rim, and the eight real trade routes drawn as animated caravan-light arcs (maritime spice route, Cape passage, Manila galleon, Zanzibar clove run, overland silk road, vanilla crossing among them). Camera flights are slerp-eased; regions and countries get their own framing, with per-region overrides where the honest centroid is open ocean (Southeast Asia).
- Drill-down: world index → region dossier → country dossier with an inline SVG chart of the real country outline (Natural Earth 50m, pre-projected at build time, whole-pixel rounded) and its named origins pinned by lat/lon. Hash-routed (#/r/region/c/country), so every view deep-links, back/forward work, and Escape climbs a level. Search ("/" anywhere) indexes regions, countries, origins, spices and their trade synonyms, and flies the camera to whatever it lands on.
- Generated assets: the intro veil's spice-nebula artwork was generated with FLUX.2 and animated into a 5-second ambient loop with Kling 3.0 Turbo (both via Higgsfield), then graded and compressed to a 148KB still + 613KB video that fades in over it. The still doubles as the route's social-share image. 8.5 Higgsfield credits total.
- Performance and fallbacks: the page's JS is code-split from the shop (~330KB gzipped incl. three.js and the full dataset), renders at device pixel ratio ≤2, pauses when the tab hides, halves the particle count on mobile, honors prefers-reduced-motion (no autorotate, no twinkle, instant flights, no veil video), and degrades without WebGL to a centered fully-navigable atlas over a static night gradient. Mobile gets its own camera distances and a draggable bottom-sheet panel.
- QA: 16 atlas assertions joined the functional suite (96 total) and both atlas views joined the 15-route mobile overflow sweep.
- Texture + brand pass (same week): the globe gained a real surface: a vector land/ocean duotone rendered from Natural Earth at build time, graded to the shop's warm ink and umber, with NASA Black Marble city lights screened on top in turmeric, so ports and cities glow like embers under the dust. The page's chrome was pulled fully into the shop's brand family: the real chili-patch Yellowtail wordmark in the top bar, Karla as the UI face (replacing Space Grotesk), a Yellowtail "Spice of your life" kicker on the veil, and the whole indigo palette warmed to the shop's ink/cream/taupe. Verified by projecting known coordinates to screen pixels so the texture, particles, beacons and SVG charts provably share one geography.
- Integration pass (client direction): the atlas stopped being a separate full-screen experience and became a page of the shop. The intro veil, starfield, coordinate HUD and private header were removed; the page now opens with the standard site chrome and an editorial intro, frames the globe in a full-bleed ink band (the About page's fact-strip pattern at room scale) with the index panel in normal flow beside it, and closes with a shop-by-origin tile strip that links each mapped region to its shelf. Every region accent was remapped into the sign's own family (turmeric / chili / magenta / saffron, no two neighbours alike), beacon sprites went from lens-flare blooms to ringed chart markers, and the renderer pauses whenever the band scrolls offscreen. The QA contract now asserts the integration itself: site header and footer present, no veil, and a computed check that every region accent stays warm.