Template
Brightwire
A modern subscription news site with a condensed display nameplate, section navigation, a live-updates ticker, a three-column editorial front page and a paywall/subscribe block. It targets independent journalists and small outlets moving from social platforms to an owned publication with email sign-in and Stripe subscriptions.
Members-only newsroom · Website · Small business site · full-stack app (auth + DB)
Who it is for
- Independent journalists and newsletters
- Small digital newsrooms
- Creators moving to owned media
- Organizations running content hubs
Layout
- Header row: search icon + date left, condensed uppercase nameplate center, SIGN IN text link and pink SUBSCRIBE button right
- Section nav: U.S., World, Business, Arts, Lifestyle, Opinion, Video, Audio, Science, Sports
- LIVE ticker row with topic names and relative timestamps in accent color
- Three-column front: stacked story list left (kicker, headline, dek, read time), lead story center, secondary story right, separated by vertical rules
- Three-up story row below a rule
- Gray rounded subscribe panel: condensed headline, subcopy, pink CTA with weekly price
- Centered footer with nameplate and copyright
Palette
Crisp, urgent, contemporary, trustworthy, clean. It feels like a digital-first daily with a sharp red pulse.
- background
#ffffff - text
#171717 - primary (rose)
#e00029 - surface/secondary
#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 text on white | 5.74:1 | 4.5:1 |
| Aa | muted text on subscribe panel | 5.27:1 | 4.5:1 |
| Aa | white label on rose primary button | 5.00:1 | 4.5:1 |
| Aa | rose text on white | 5.00:1 | 4.5:1 |
| Aa | rose text on subscribe panel | 4.58:1 | 4.5:1 |
| Aa | kicker text on white | 5.88:1 | 4.5:1 |
| Aa | dark mode body text | 17.11:1 | 4.5:1 |
| Aa | dark mode primary text | 6.44:1 | 4.5:1 |
| Aa | dark mode label on primary button | 6.44:1 | 4.5:1 |
| Aa | dark mode muted text | 7.48:1 | 4.5:1 |
| input border on white | 4.54: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
- Display
- Bebas Neue condensed caps for nameplate (48px, +1.2px tracking) and promo headings
- Body
- Switzer 16px; headlines Switzer 700 with -0.75px tracking; 12px condensed kickers in deep rose (Switzer is not on Google Fonts; a vibld project loads Inter)
Condensed caps give a tabloid punch while a neo-grotesk keeps headlines crisp and contemporary.
Spacing and imagery
Dense front page, 1250px container, rules instead of cards, 0-radius buttons in nav, 10px radius on subscribe panel and CTA.
Mostly text-led front page; article cards support images with skeleton loading; no decorative illustration.
Components
- Nameplate header with date and search
- Sign in link and subscribe button
- Section nav bar
- Live updates ticker
- Kicker labels
- Story card variants (lead, list, compact)
- Read-time meta
- Vertical column rules
- Subscribe/paywall panel
- Auth dialogs (email)
- Skeleton loaders
- Footer
Interactions
- Live ticker updates with relative times
- Email sign in / sign up flow
- Stripe checkout for subscription
- Paywall gating premium articles
- Skeleton loading states
- Mobile nav drawer
- Dark mode toggle
- Hover underline on headlines
Data
Article{id, slug, section, kicker, headline, dek, body, readMinutes, image, isPremium, publishedAt}Section{slug, name, order}LiveUpdate{id, topic, publishedAt}Profile{id, email, subscription_status, stripe_customer_id}Subscription{user_id, plan, status, current_period_end}
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 **Brightwire**, a subscription news publication for a fictional independent newsroom. Readers skim a dense front page, open articles, and hit a metered paywall that asks them to subscribe at a low weekly price. The job: publish across ten sections, surface live developments, and convert readers into paying subscribers. ### Stack React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Dialog, Sheet, Skeleton, Tabs, DropdownMenu), lucide-react, TanStack Query for data, react-hook-form + zod for auth forms, date-fns for relative times, Framer Motion for the ticker. **Supabase**: Postgres for articles, sections, live updates and profiles; Auth (email magic link + password); Edge Functions for Stripe Checkout session creation and the Stripe webhook. Stripe hosted Checkout and Customer Portal. ### Pages & layout 1. **Front page** – header: search + long date left, condensed nameplate center, Sign in link and rose Subscribe button right. Section nav. "LIVE" ticker with topics and "4m ago" timestamps. Three-column grid split by vertical rules: story stack (kicker, headline, dek, read time) | lead story with big headline and long dek | secondary column. Rule, then a three-up row. Subscribe panel (gray rounded box, condensed caps heading, one-line pitch, rose button with price). Footer. 2. **Section page** – section title, lead + list, pagination. 3. **Article** – kicker, headline, dek, byline, read time, image, body; premium articles show the first paragraphs then a paywall card. 4. **Auth** – sign in / create account dialogs. **Account** – plan, status, manage billing link. 5. **Subscribe** – plan cards (weekly, annual) leading to checkout. ### Design system - Tokens: `--background: #ffffff`, `--foreground: #171717`, `--primary: #e00029`, `--primary-foreground: #ffffff`, `--secondary: #f5f5f5`, `--border: #e6e6e6` (decorative rules), `--input-border: #767676`, `--muted-foreground: #666666`, `--radius: 0.625rem`. Dark: background `#0f0f10`, foreground `#f2f2f2`, primary `#ff5c79`, primary-foreground `#0f0f10`, muted-foreground `#a1a1aa`. - Fonts: Bebas Neue for nameplate and promo headings; Switzer or Inter for everything else (700 headlines, -0.02em). Scale: 12 (kicker caps, +0.06em) / 14 / 16 / 20 / 24 / 36 / 48. - Spacing: 4px base, 24px column gutters, 1px rules; container 1248px. - Motion: ticker items fade in 300ms; hover underline 150ms; skeleton shimmer 1.2s. ### Components & interactions Header (default, signed-in avatar menu), subscribe button (hover darken, focus ring, loading while creating checkout), ticker (new item animation, pause on hover/focus), story cards (lead/list/compact, with and without image, skeleton), paywall card (signed out / signed in without plan / subscribed hides it), auth forms (errors inline, loading, email sent), account billing (portal redirect, error toast), empty section state, 404. ### Data & state Tables: `sections(slug,name,position)`, `articles(id,slug,section_slug,kicker,headline,dek,body_md,read_minutes,image_url,is_premium,published_at)`, `live_updates(id,topic,published_at)`, `profiles(id→auth.users,display_name)`, `subscriptions(user_id,plan,status,current_period_end,stripe_customer_id)`. Server state via TanStack Query; auth session via Supabase client. Seed 30 fictional articles with invented places and people, ten sections, and five live updates; include curated fallback content if a query fails. ### Accessibility The rose primary is set to `#e00029` so white button labels reach 5.0:1 and rose text passes on white (5.0:1) and on the `#f5f5f5` panel (4.58:1); small kickers use `#c8102e` (5.9:1). In dark mode, labels on the `#ff5c79` primary are `#0f0f10` (6.4:1). Inputs use `--input-border: #767676` (4.5:1); the `#e6e6e6` rule is decorative. Ticker must be pausable and announced politely (`aria-live="polite"`, not assertive). Headline links have visible focus rings. Paywall content isn't hidden with CSS only. Forms have labels and error text tied via `aria-describedby`. Respect reduced motion for ticker and skeletons. Verified contrast: body text on white #171717 on #ffffff = 17.93:1; muted text on white #666666 on #ffffff = 5.74:1; muted text on subscribe panel #666666 on #f5f5f5 = 5.27:1; white label on rose primary button #ffffff on #e00029 = 5.0:1; rose text on white #e00029 on #ffffff = 5.0:1; rose text on subscribe panel #e00029 on #f5f5f5 = 4.58:1. ### Security RLS: `articles` public select where `published_at <= now()`; full `body_md` of premium articles served only through a view or RPC that checks an active subscription. `subscriptions` writable only by the webhook (service role in Edge Function env), readable by owner. Verify Stripe webhook signatures. zod validation on forms and in functions. Sanitize markdown with DOMPurify. Only the anon key in the client. Rate-limit auth and checkout endpoints. ### Performance & SEO SSR or prerender article pages for crawlers, NewsArticle JSON-LD with `isAccessibleForFree` for premium, OG tags, sitemap and RSS. Lazy images, route splitting, cache sections with stale-while-revalidate. Lighthouse 90+. ### Guardrails - Original, fictional stories only; no real politicians, outlets or logos. - No fabricated quotes from real people. - Store the minimum PII (email, Stripe customer ID). - Small typed components, no `any`, visible error handling. - Done when: a reader can sign up, subscribe in test mode and immediately read a premium article; the webhook updates status; the ticker pauses; RLS blocks premium bodies for non-subscribers; Lighthouse accessibility 95+.