Template
Northpoint Dispatch
A B2B content marketing hub that brings a blog, newsletters, gated resources and podcast episodes under one brand. It is built for marketing teams, consultants and solopreneurs who publish thought leadership and want to grow an email list and capture leads through downloadable resources.
B2B content marketing hub · Website · Small business site · full-stack app (auth + DB)
Who it is for
- B2B marketing teams
- Consultants publishing thought leadership
- Solopreneurs building a content brand
- Agencies running client content sites
Layout
- Sticky header: two-tone wordmark, Blog / Newsletters / Resources / Podcasts links, search icon and blue Subscribe button
- Featured hero: large rounded photo with headline, dek, author and date left; 'Featured Posts' ruled list with titles, authors and dates right
- Four-column post card grid (image, title, excerpt, author, date)
- Full-width blue newsletter band: mail icon, headline, subscriber count line, email field and white Subscribe button
- Footer: wordmark, About / Privacy / Terms / Contact, copyright
- Other pages: newsletter product pages, gated resource library with form, podcast episode list/player, topic cluster pages, article with reading progress
Palette
Clean, professional, confident, modern, trustworthy. It feels like a well-run SaaS company's resource center.
- background
#ffffff - text
#171717 - primary (blue)
#006fe6 - surface
#f5f5f5 - border
#e6e6e6 - muted text
#666666
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on white | 17.93:1 | 4.5:1 |
| Aa | muted excerpt text on white | 5.74:1 | 4.5:1 |
| Aa | muted text on surface | 5.27:1 | 4.5:1 |
| Aa | blue link text on white | 4.75:1 | 4.5:1 |
| Aa | white label on blue primary button and band text | 4.75:1 | 4.5:1 |
| Aa | placeholder text in white email field | 5.74:1 | 4.5:1 |
| white field outline against blue band | 4.75:1 | 3:1 | |
| input border on white | 4.54:1 | 3:1 | |
| Aa | dark mode body text | 16.15:1 | 4.5:1 |
| Aa | dark mode primary link text | 5.91:1 | 4.5:1 |
| Aa | dark mode label on primary button | 5.91:1 | 4.5: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
- Display
- Satoshi 700, 36px hero headline, 18px card titles (Satoshi is not on Google Fonts; a vibld project loads Plus Jakarta Sans)
- Body
- Satoshi 16px, gray excerpts, 13px author/date meta (Satoshi is not on Google Fonts; a vibld project loads Plus Jakarta Sans)
One geometric grotesk throughout keeps it modern and SaaS-like; weight and gray value do the hierarchy.
Spacing and imagery
Balanced; 1216px container, 2/3 + 1/3 hero split, 4-up grid with 24px gaps, 12px image radius, 10px button radius.
Workplace and tech photography in rounded frames; social/app-inspired thumbnails; no illustrations.
Components
- Sticky header with Subscribe CTA
- Featured article hero
- Featured posts ruled list
- Post card
- Topic cluster chips
- Newsletter band form
- Newsletter product page
- Gated resource card + lead form
- Podcast episode card with player
- Reading progress bar
- Curated sidebar posts
- Search dialog
Interactions
- Two-state newsletter form (input to success)
- Gated download unlock after form submit
- Card hover lift and image zoom
- Reading progress bar
- Topic filtering
- Sticky header shadow on scroll
- Audio play/pause on episodes
- Dark mode toggle
Data
Post{slug, title, excerpt, body, author, date, cover, topics[], featured}Newsletter{slug, name, cadence, description, sampleIssues[]}Resource{slug, title, type, cover, fileUrl, gated}Episode{number, title, guest, duration, audioUrl, publishedAt}Lead{email, name, company, resourceSlug}Topic{slug, name}
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 **Northpoint Dispatch**, a content hub for a fictional B2B software company's marketing team. It publishes articles, several email newsletters, downloadable resources behind a short form, and a podcast. Audience: marketers and operators looking for practical playbooks. The job: build authority, grow subscribers and capture qualified leads.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Dialog, Input, Tabs, Badge, Card, Toast), lucide-react, Framer Motion for card and form transitions, react-hook-form + zod for all forms, TanStack Query for data. **Supabase**: Postgres tables for `subscribers` and `leads`, Storage for gated PDFs served via signed URLs, and an Edge Function that validates lead submissions and returns a short-lived download link. Content (posts, episodes) can be Markdown files or a `posts` table.
### Pages & layout
1. **Home** – sticky header (two-tone wordmark, Blog/Newsletters/Resources/Podcasts, search, blue Subscribe). Hero: large rounded image, headline, dek, author + date on the left (8 cols); "Featured posts" ruled list on the right (4 cols). Four-up latest posts grid. Full-width blue newsletter band with icon, heading, social-proof line, inline form. Footer.
2. **Blog** – topic cluster chips, grid, pagination. **Article** – progress bar, title, author, date, body, curated sidebar posts, inline newsletter.
3. **Newsletters** – cards per newsletter (cadence, description, subscribe), each with its own page and sample issues.
4. **Resources** – library of templates/guides with type badges; gated items open a short form, then reveal the download.
5. **Podcasts** – episode list with play buttons and show notes.
### Design system
- Tokens: `--background: #ffffff`, `--foreground: #171717`, `--primary: #006fe6`, `--primary-foreground: #ffffff`, `--secondary: #f5f5f5`, `--border: #e6e6e6` (decorative), `--input-border: #767676`, `--muted-foreground: #666666`, `--radius: 0.625rem`. Dark: `#0b0d12` background, `#e8eaef` text, primary `#3b8cff`, primary-foreground `#0b0d12`.
- Font: Satoshi (or General Sans) 400/500/700. Scale: 13 / 14 / 16 / 18 / 24 / 36 / 48.
- Spacing: 8px base; 24px grid gaps; sections 80px. Images 12px radius; buttons 10px.
- Motion: hover lift 200ms, form state swap 250ms cross-fade, header shadow appears after 8px scroll.
### Components & interactions
Header (default/scrolled), Subscribe button, post card (default/hover/focus/skeleton), featured list item, topic chip (active), newsletter form (idle → submitting → success message replaces form; inline errors; duplicate email handled gracefully), resource card (locked/unlocked), lead dialog (name, work email, company, consent checkbox), episode row (play/pause/loading, duration), search dialog (recent, results, empty), progress bar, dark mode toggle.
### Data & state
Tables: `subscribers(id,email,newsletter_slug,created_at)`, `leads(id,email,name,company,resource_slug,consent,created_at)`, optional `posts`. Content types: `Post{slug,title,excerpt,body,author,date,cover,topics[],featured}`, `Newsletter{slug,name,cadence,description}`, `Resource{slug,title,type,cover,storagePath,gated}`, `Episode{number,title,guest,duration,audioUrl}`. Seed 12 posts with invented authors, 3 newsletters, 6 resources and 5 episodes.
### Accessibility
Blue `#006fe6` on white is 4.75:1, so it passes for link text and for white button labels. In the blue band, body text is white (4.75:1), the email field is white with a `#666666` placeholder (5.7:1) and a 1px white outline that separates it from the band (4.75:1). On white, inputs use `--input-border: #767676`; the `#e6e6e6` border is decorative. In dark mode, labels on the `#3b8cff` primary are `#0b0d12` (5.9:1). Forms: visible labels, error messages linked with `aria-describedby`, success announced via `aria-live`. The audio player has labeled controls and keyboard support. Progress bar hidden from AT. Reduced motion disables lifts.
Verified contrast: body text on white #171717 on #ffffff = 17.93:1; muted excerpt text on white #666666 on #ffffff = 5.74:1; muted text on surface #666666 on #f5f5f5 = 5.27:1; blue link text on white #006fe6 on #ffffff = 4.75:1; white label on blue primary button and band text #ffffff on #006fe6 = 4.75:1; placeholder text in white email field #666666 on #ffffff = 5.74:1.
### Security
RLS: `subscribers` and `leads` accept inserts only through the Edge Function (service role key in function env), no public select. Validate with zod on client and in the function; enforce work-email format, honeypot and per-IP rate limiting. Gated files live in a private bucket; the function returns a signed URL valid for a few minutes. Consent checkbox recorded with timestamp; collect only the fields you use. Sanitize Markdown with DOMPurify. Only the anon key in the browser.
### Performance & SEO
Lazy-load card images, responsive sizes, route-level splitting. Article and PodcastEpisode JSON-LD, OG images, RSS for blog and podcast, sitemap. Lighthouse 90+.
### Guardrails
- Original articles, fictional authors and placeholder imagery; no real companies' logos or brand names.
- No fabricated subscriber counts or testimonials presented as fact; mark sample numbers as placeholders.
- Minimal PII; no storing data you don't use.
- Small typed components, no `any`, visible error states.
- Done when: newsletter form swaps to success and stores one row; gated download only works after a valid submission; episodes play; topic filters work; Lighthouse accessibility 95+.