Skip to main content
vibld

Template

Marginalia

A personal essay newsletter site for a single writer, built around a centered masthead with portrait, a tiered grid of essays and simple subscribe forms. It gives independent writers an elegant home for long-form posts without platform fees.

Single-author essay newsletter site · Website · Small business site · static site

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

Spectral is a delicate, light literary serif for the masthead, and Ysabeau Office is a Garamond-derived sans that keeps the metadata soft, like a printed zine.

  • SpectralHeadings: masthead 96px 300, essay titles 36px, quarter-card titles 24px at 500
  • Ysabeau OfficeBody: body 16-18px, 12px uppercase labels

Who it is for

  • Independent essayists and newsletter writers
  • Founders publishing opinion pieces
  • Curators of weekly digests
  • Cultural critics building a readership

Layout

  1. Centered masthead: framed square portrait, very large light serif name, grey Inter tagline
  2. Thin rule and uppercase tracked nav (Home, Subscribe, Social, Email)
  3. Featured essay: full-width framed image with date and serif title
  4. Row of two framed essays
  5. Divider then four-column row of smaller framed essays
  6. Newsletter signup block
  7. Footer with social links
  8. Essay page with narrow reading column

Palette

Soft, literary, calm, warm, refined. Like a quiet printed zine in blush and cocoa tones.

  • background dusty rose#e5dcdd
  • text#433234
  • primary cocoa#494036
  • frame / card#ffffff
  • accent coral#f37b68
  • secondary text#6b5b5c
  • rule#8c7f80
  • input border#7d6f70

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text on dusty rose8.95:14.5:1
Aabody text on white mat/card12.04:14.5:1
Aasecondary text (tagline, dates) on dusty rose4.77:14.5:1
Aasecondary text on white card6.41:14.5:1
Aawhite on cocoa primary button10.15:14.5:1
Aacocoa link text on dusty rose7.54:14.5:1
cocoa focus ring on dusty rose7.54:13:1
input border on dusty rose3.56:13:1
input border on white4.79:13: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
Spectral 300, 96px masthead, -0.025em; 36px essay titles (quarter-card titles 24px at weight 500)
Body
Ysabeau Office 400 16–18px, uppercase 12px labels (1-3 words) with 0.1em tracking

Delicate light serif for titles against clean Ysabeau Office for metadata -- literary and airy

Spacing and imagery

Centered 980px container, 3-tier grid (1 / 2 / 4 columns), 40px gutters; images inside thick 12px white mats with no radius; generous vertical breathing room

Pastel abstract still-life photography (paper shapes, circles, stripes) in peach and blush, each matted in white like prints; a single portrait photo.

Components

  • Framed portrait
  • Serif masthead
  • Uppercase text nav
  • Hairline divider
  • Featured essay card
  • Two-up essay cards
  • Four-up essay cards
  • Date eyebrow
  • Subscribe form
  • Reading-width article layout
  • Mobile drawer nav
  • Toast confirmation

Interactions

  • Image hover subtle zoom within mat
  • Title underline on hover
  • Subscribe submit with toast
  • Mobile drawer menu
  • Visible keyboard focus rings
  • Lazy-loaded images fade in

Data

  • Essay{slug, title, date, cover, excerpt, body_md, reading_time}
  • Author{name, portrait, tagline, socials[]}
  • Subscriber{email, created_at} (if backend)

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 **Marginalia**, a single-author essay site and newsletter home. A writer publishes long-form pieces; readers browse a calm, tiered grid of essays and subscribe by email. The job: make essays feel like printed pieces and turn casual readers into subscribers. Invent the writer's name (e.g. "Juno Hale") -- do not use any real person.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix), lucide-react. Content from local MDX/markdown files (with frontmatter) loaded at build time; Vaul for the mobile drawer; Sonner for toasts; react-hook-form + zod for the signup form. Backend only for subscriptions: a Supabase table + Edge Function, or a hosted newsletter provider's form endpoint.

### Pages & layout
1. **Home** – centered masthead: square portrait in a thick white mat with soft shadow, 96px light serif name, 24px grey tagline; hairline rule; uppercase tracked nav (Home, Subscribe, social, Email). Then a featured essay (full-width matted image, date eyebrow, serif title), a row of two, a divider, a row of four smaller cards, then "load more" or pagination. Subscribe band and footer.
2. **Essay** – date, 56px serif title, subtitle, matted hero image, 680px reading column, pull quotes, end-of-post subscribe box, previous/next.
3. **Subscribe** – short pitch, email field, frequency note.
4. **About** – portrait and bio.

### Design system
`--background: #e5dcdd` (dusty rose), `--foreground: #433234`, `--primary: #494036`, `--card: #ffffff` (mats), `--accent: #f37b68`, `--muted-foreground: #6b5b5c`, `--rule: #8c7f80` (decorative hairlines), `--input-border: #7d6f70`; coral is decorative only, links and buttons use cocoa. Fonts: Spectral 300/400 (display/titles) + Ysabeau Office 400/500 (body/meta). Scale 12 (tracked caps) / 16 / 18 / 24 / 36 / 56 / 96; body line-height 1.7. Radius 0 everywhere. Mats: 12px white padding plus `0 10px 30px rgb(67 50 52 / .08)` on the portrait. Motion: 300ms ease image scale 1.03 on hover.

### Components & interactions
Masthead, TextNav (active underline), EssayCard in three sizes (featured/half/quarter), MattedImage, DateEyebrow, Divider, SubscribeForm (idle/submitting/success/already-subscribed/error), ArticleBody (prose styles), PullQuote, PrevNext, MobileDrawer, Footer.

### Data & state
Essays as markdown files with `title, date, cover, excerpt, slug`; build a typed index sorted by date. Subscribers table (email unique, created_at, confirmed boolean) if self-hosting. Seed 12 fictional essays with original titles about craft and building, with abstract pastel placeholder images.

### Accessibility
Check contrast: #433234 on #e5dcdd is ~8:1; grey tagline and date text must stay ≥ 4.5:1 (#6b5b5c = 4.7:1 on rose, not lighter). Light 300-weight serif only at ≥ 36px (smaller serif titles use 500); body stays Ysabeau Office 400 at 16-18px, reading column ~65ch; Georgia/serif and system-ui fallbacks. One `h1` per page, essay titles as `h2` on index. Images: meaningful alt for covers or empty alt if decorative. Focus rings visible against rose (use cocoa 2px outline). Drawer traps focus; respect reduced motion. Verified contrast: body text #433234 on #e5dcdd = 8.9:1; secondary text #6b5b5c on #e5dcdd = 4.7:1; secondary text #6b5b5c on #ffffff = 6.4:1; white #ffffff on #494036 = 10.1:1; input border #7d6f70 on #e5dcdd = 3.5:1.

### Security
Proportionate: validate email with zod client-side and server-side; honeypot field and rate limiting on the subscribe endpoint; double opt-in confirmation email. No secrets in the client. Render markdown through a sanitizer (DOMPurify / rehype-sanitize). External social links use `rel="noopener noreferrer"`.

### Performance & SEO
Pre-render routes; responsive images with `srcset` and lazy loading below the fold; preload the two fonts with `display=swap`. Per-essay meta description, OG image, canonical URL, RSS feed, sitemap. Lighthouse 95+.

### Guardrails
- Original essay titles and copy; placeholder imagery only; no real person as the author.
- No fabricated subscriber counts or testimonials.
- Store only email addresses; provide unsubscribe.
- Typed small components, no `any`, visible form errors.
- Done when: the 1/2/4 grid collapses cleanly to one column on mobile, essays render from markdown with sanitized output, subscribe handles success/duplicate/error, RSS validates, and Lighthouse accessibility is 100.

Open the builderAll templatesThis palette on its own