Template
Hardline Depot
A brutalist, editorial product catalog wired to a live Shopify store, with hosted checkout handled by Shopify. It suits small brands that want a bold, grid-heavy storefront for drops and collections without building commerce plumbing themselves; a demo mode lets it run with sample products.
Brutalist catalog storefront · Website · Small business site · full-stack app (auth + DB)
A mock-up of the homepage, drawn from this design’s layout, palette and typefaces. A build follows the full prompt below.
Start from this templateRead the build prompt
Typefaces
Anton keeps the raw condensed poster caps, Arimo has the Helvetica-like proportions of a Swiss catalog, and Source Serif 4 stays for the editorial product copy.
- AntonHeadings: hero 112px uppercase, section heads 48px
- ArimoBody: UI 16px, 12px uppercase captions
- Source Serif 4Accent: product descriptions only
Who it is for
- DTC brands launching a storefront
- Makers selling small-batch goods
- Curators of limited-edition drops
- Teams validating a product line before a full platform
Layout
- Split masthead: giant uppercase wordmark (three lines) left, tagline cell right
- Boxed nav bar: HOME / SHOP / COLLECTIONS / ABOUT / CONTACT cells, search and cart icon cells at right
- Black announcement bar (free shipping threshold) then a yellow scrolling marquee
- Collection filter chip row
- Dense masonry-like product grid with bordered cells, name + price captions, yellow hover outline
- Featured product spotlight: large grayscale lifestyle photo left, title, description, price and VIEW PRODUCT button right
- 'Shop by collections' band: yellow label cell + 8 numbered collection tiles with item counts and big ghost numerals
- Four value props with icons (handcrafted, sustainable, shipping, quality)
- Customer quotes, numbered FAQ accordion, newsletter 'Join the list' footer
Palette
Raw, bold, utilitarian, editorial, loud. It reads like a printed product catalog crossed with a Swiss poster.
- background (paper)
#f8f6f2 - text / borders
#0d0d0d - accent (signal yellow)
#ffdd00 - secondary surface
#ebe8e0 - muted
#e5e3dc - price/meta gray
#686868
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on paper background | 18.01:1 | 4.5:1 |
| Aa | text on yellow marquee and label cells | 14.43:1 | 4.5:1 |
| Aa | price/meta gray on paper | 5.16:1 | 4.5:1 |
| Aa | price/meta gray on secondary surface | 4.55:1 | 4.5:1 |
| Aa | body text on secondary surface | 15.87:1 | 4.5:1 |
| Aa | paper text on black announcement bar | 18.01:1 | 4.5:1 |
| 1px cell rules and input borders on paper | 18.01:1 | 3:1 | |
| black focus outline on paper | 18.01:1 | 3:1 |
As vibld’s tokens
The palette on the fifteen colour tokens vibld styles a project with, each text colour on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.
- background
- card
- muted
- primary *
- secondary
- accent
- destructive *
Type scale
- Display
- Heavy condensed grotesk (Anton) or wide grotesk, uppercase, 112px hero with -3% tracking; section heads 48px uppercase (Grotesk is not on Google Fonts; a vibld project loads Anton)
- Body
- Arimo 16px; captions 12px uppercase with 0.06em tracking
All-caps display with tiny uppercase labels; a serif is used only for product descriptions, giving an editorial catalog feel.
Spacing and imagery
Zero radius, 1px black rules everywhere, cells butt together in a strict grid; dense product grid with minimal gutters; full-width layout.
Product cut-outs on white and grayscale lifestyle photography; strong black-and-white treatment with yellow as the only color.
Components
- Oversized split masthead
- Cell-based nav bar
- Announcement bar
- Scrolling marquee
- Collection chips
- Bordered product card with price
- Featured product spotlight
- Numbered collection tiles with counts
- Value-prop icon row
- Testimonials block
- Numbered FAQ accordion
- Search modal
- Cart drawer
- Newsletter capture
Interactions
- Infinite marquee ticker
- Yellow offset outline on product hover
- Real-time search modal with instant results
- Collection filter and client-side sort
- Product image carousel on detail page
- Variant/stock selection disabling unavailable options
- Redirect to hosted checkout
- Demo-mode toggle for offline sample data
- Toast on add to cart / subscribe
Data
Product{handle, title, description, images[], priceRange, variants[], tags, collection}Variant{id, title, price, availableForSale, selectedOptions}Collection{handle, title, productCount}Cart{id, lines[{variantId, qty}], checkoutUrl}Subscriber{email, created_at} (Supabase)
Build prompt
The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.
The baseline
### How to use these prompts Paste a template's build prompt into your coding agent as the first message. Each prompt names its own stack, tokens and acceptance criteria; the rules below apply to all of them and can be prepended once per project. ### Engineering baseline - TypeScript strict mode, no `any`, small typed components, feature folders, and one source of truth for design tokens (CSS variables consumed by Tailwind). - Validate every input with a shared zod schema on the client and again on the server or edge function. Never trust client-side checks alone. - Show loading, empty and error states for every async view. Surface errors in plain language with a retry, and log details to the console in development only. - Keep secrets out of the bundle. Only publishable keys (for example a Supabase anon key) belong in client code; service-role keys, API keys and webhooks live in server or edge-function environment variables. ### Data and auth baseline (full-stack templates) - Enable Row Level Security on every table before inserting data. Default-deny, then add owner-scoped policies (`auth.uid() = user_id`) and explicit role checks for admin views. - Store roles in a separate table checked by a security-definer function, never in a user-editable profile field. - Upload files to private storage buckets with size and MIME limits, and serve them through signed URLs. - Rate-limit public endpoints (forms, auth, AI calls) and add a honeypot field or captcha to anonymous forms. - Take payments through a hosted checkout and verify webhooks by signature. Never handle raw card data. ### Accessibility and UX baseline - Target WCAG 2.2 AA: 4.5:1 contrast for normal text and 3:1 for large text, input borders, focus rings and meaningful icons or chart lines. Every palette in this catalog lists its verified pairs; re-check with a contrast tool after any colour change. - Keep body text at 16px or larger with 1.5 line height, nothing below 12px, no light weights under 24px, and uppercase only for short labels. - Give every interactive element a visible focus ring, full keyboard support, semantic landmarks, labelled form fields, and alt text on meaningful images. - Respect `prefers-reduced-motion` for every animation. Give drag-and-drop and carousels keyboard and button alternatives. - Build mobile-first and test at 375px, 768px and 1280px. ### Content guardrails - Use original copy, fictional sample data and placeholder or licensed imagery. Do not reuse another product's name, logo, screenshots or marketing text. - Label demo testimonials and metrics as samples. Collect the minimum personal data the feature needs.
### Goal
Build **Hardline Depot**, a brutalist catalog storefront for a small outdoor-and-home goods brand. It pulls products from a headless commerce API (Shopify Storefront API or a mock) and sends buyers to hosted checkout. Audience: design-forward shoppers who browse by collection and limited drops. The job: make a catalog feel like a bold printed zine while staying fast and shoppable.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Dialog, Sheet, Accordion, Select), lucide-react. TanStack Query for catalog fetching and caching, Embla Carousel for product images, Sonner for toasts, react-hook-form + zod for the newsletter. Supabase: one `subscribers` table plus an Edge Function that proxies Storefront API calls so the token and rate limiting stay server-side. Include a demo-mode flag that serves local JSON fixtures.
### Pages & layout
1. **Home** – split masthead (giant 3-line uppercase wordmark left, tagline cell right); cell nav (Home/Shop/Collections/About/Contact + search and cart cells); black shipping-threshold bar; yellow marquee; collection chip row; dense bordered product grid; featured-product spotlight (big grayscale photo, title, copy, price, View product); "Shop by collections" band with 8 numbered tiles and item counts; four value props; quotes; numbered FAQ; "Join the list" newsletter; footer.
2. **Shop** – grid with collection filter, sort (price, newest, A–Z) and result count.
3. **Collection** – header with count, same grid.
4. **Product** – carousel left, title/price/variant selector/quantity/add to cart right, description and specs below.
5. **About**, **Contact** – simple text pages on the grid.
### Design system
- Tokens: `--background: #f8f6f2`, `--foreground: #0d0d0d`, `--accent: #ffdd00`, `--secondary: #ebe8e0`, `--muted: #e5e3dc`, `--border: #0d0d0d`, `--radius: 0`.
- Fonts: Anton (display, uppercase, -0.03em), Arimo (UI), Source Serif 4 for product descriptions. Scale: 12 / 14 / 16 / 24 / 48 / clamp(64px, 9vw, 120px).
- Spacing: 4px base, grid cells separated by 1px rules rather than gaps. No shadows; hover uses a 4px yellow offset outline.
- Motion: marquee 30s linear loop; hover transitions 150ms; drawer 250ms ease-out.
### Components & interactions
Product card (default/hover/sold-out/loading skeleton), chip (default/active/focus), search dialog (empty prompt, loading, no results, results with keyboard navigation), variant selector (unavailable options disabled), add-to-cart (idle/loading/success toast/error), cart sheet (empty state, line qty stepper, subtotal, checkout button that redirects to the hosted checkout URL), FAQ accordion, newsletter form (validation errors inline, success), demo-mode badge.
### Data & state
`Product{handle,title,description,images[],variants[],collection,tags}`, `Variant{id,title,price,available}`, `Collection{handle,title,count}`, `Cart{id,lines[],checkoutUrl}`. Server data through TanStack Query; cart ID in localStorage; filter/sort in URL search params. Seed 12 fictional products across 8 collections with realistic prices.
### Accessibility
Black on paper (18:1) and black on yellow (14.4:1) pass AA; price/meta gray `#686868` passes on paper (5.2:1) and on the secondary surface (4.55:1). Yellow is used only as a fill or decorative hover outline, never as text on paper. Uppercase is limited to short labels and headings; product descriptions stay in sentence case. Pause control for the marquee and stop it under `prefers-reduced-motion`; mark it `aria-hidden` and repeat its text once in visible static copy. Focus rings: 2px black outline plus yellow offset. Search dialog traps focus and restores it on close. Variant buttons use `aria-pressed`; sold-out state is announced in text, not only by color. Alt text on every product image.
Verified contrast: body text on paper background #0d0d0d on #f8f6f2 = 18.01:1; text on yellow marquee and label cells #0d0d0d on #ffdd00 = 14.43:1; price/meta gray on paper #686868 on #f8f6f2 = 5.16:1; price/meta gray on secondary surface #686868 on #ebe8e0 = 4.55:1; body text on secondary surface #0d0d0d on #ebe8e0 = 15.87:1; paper text on black announcement bar #f8f6f2 on #0d0d0d = 18.01:1; 1px cell rules and input borders on paper #0d0d0d on #f8f6f2 = 18.01:1.
### Security
Storefront token only in the Edge Function environment; the client calls the function. Validate handles and query params with zod on both sides. Supabase RLS on `subscribers`: insert-only for anon, no select; unique email constraint; rate-limit by IP in the function; honeypot field. Never collect card data – always redirect to the hosted checkout URL, and verify it is on the expected commerce domain before redirecting.
### Performance & SEO
Responsive `srcset` from the image CDN, lazy-load below-fold cards, skeletons instead of layout shift. Prefetch product queries on hover. Per-product meta, OG image and Product JSON-LD; semantic `h1` per page. Lighthouse 90+.
### Guardrails
- Original copy, fictional products and placeholder imagery; no third-party logos or trademarked names.
- No fabricated customer quotes presented as real; label sample reviews as examples.
- Store only emails, nothing else, for subscribers.
- Small typed components, no `any`, visible error states for failed fetches.
- Done when: demo mode and live mode both render the grid; filters and sort sync to the URL; add to cart and redirect to checkout work; search is fully keyboard operable; the marquee respects reduced motion.