Skip to main content
vibld

Template

Glyphshelf

A typeface discovery directory with a CMS behind it. Visitors browse a filterable grid of live-rendered font specimens, open detail pages with a type tester and glyph grid, and explore collections and foundries, while admins import fonts from Google Fonts and watch view/download analytics.

Font discovery directory with CMS · App · Small tools and apps · 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

The font-specimen browser needs the most characterless UI face so the specimens carry all the personality, which is exactly Inter's job; it is one of few templates that keep it.

  • InterHeadings: page titles 48px 700 at -0.02em
  • InterBody: body 16px, meta 12px grey

Who it is for

  • Independent type foundries
  • Designers curating font collections
  • Typography bloggers and educators
  • Agencies building internal font libraries

Layout

  1. Sticky header: wordmark left, centered search field with '/' shortcut, Collections/About/Sign in right
  2. Intro hero: large title, one-line subtitle, dark 'Try demo' pill
  3. Horizontal quick-collection chip strip (New Releases, Trending, Variable, Sans, Serif, Mono)
  4. Two-column browse: left filter sidebar (grid/list toggle, sort, category chips, classification select, property checkboxes, weight range, license); right 3-column specimen card grid with count
  5. 'Load more' outlined button
  6. Footer with wordmark, tagline, links, copyright
  7. Font detail page: type tester with weight/size sliders, character set grid
  8. Collections, Foundry profiles, About, Admin (importer, CRUD table, analytics)

Palette

Neutral, exhibition-like, utilitarian, calm, precise. The UI recedes like a white-walled museum so the letterforms are the exhibits.

  • background#ffffff
  • text / primary#1a1a1a
  • card surface#e7e7e4
  • muted surface#f8f8f7
  • border#dfdfdd
  • secondary text#5c5c59
  • input border#909089

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text on background17.40:14.5:1
Aaspecimen text on card surface14.05:14.5:1
Aameta/secondary text on background6.71:14.5:1
Aameta/secondary text on card surface5.41:14.5:1
Aameta/secondary text on muted surface6.31:14.5:1
Aawhite on dark pill CTA / active chip17.40:14.5:1
Aachip text on muted surface16.38:14.5:1
input/checkbox border on background3.21:13:1
input/checkbox border on muted surface3.02:13:1
focus ring on background17.40: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
Inter 700, 48px, -0.02em tracking for page titles; specimen 'Aa' rendered at ~160px in each actual font
Body
Inter 400 16px; meta text 12px grey

Neutral UI sans stays quiet so the specimen fonts carry all personality

Spacing and imagery

Full-width layout with 24px gutters, 300px sidebar, 3-col card grid with 16px gaps; tall cards (~380px); 8px radius, pill chips; hairline dividers between bands

No photography; imagery is the typography itself -- big 'Aa' glyph pairs and pangram samples on warm-grey cards.

Components

  • Search input with keyboard shortcut hint
  • Collection chip strip
  • Filter sidebar with collapsible sections
  • Grid/list segmented toggle
  • Sort select
  • Category pill toggles
  • Property checkboxes
  • Specimen card (name, style count, Aa, pangram, designer)
  • Load more button
  • Type tester with sliders and editable text
  • Glyph grid with copy
  • Admin importer form
  • Admin CRUD table
  • Analytics charts

Interactions

  • '/' focuses search; debounced filtering
  • Filters update the grid and count instantly; collapsible sections
  • Grid/list view toggle
  • Hover on specimen card raises tone slightly
  • Weight and size sliders re-render sample live
  • Glyph hover enlarge and click-to-copy with toast
  • Load more pagination
  • Admin import auto-detects weights and previews

Data

  • Font{id, family, slug, category, classification, weights[], has_italic, is_variable, license, designer, foundry_id, google_url, created_at}
  • Foundry{id, name, slug, bio, url}
  • Collection{id, name, slug, font_ids[]}
  • FontEvent{id, font_id, type(view|download|preview), device, referrer, created_at}
  • Profile{id, role(admin|user)}

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 **Glyphshelf**, an open font discovery directory. Visitors browse live-rendered specimens, filter by category and properties, and test any typeface with their own text. Admins curate the catalog through a small CMS that imports families from the Google Fonts API and shows which fonts get attention. The job: make comparing typefaces fast and let the letterforms speak.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix), lucide-react. TanStack Query for catalog data and infinite "load more"; react-hook-form + zod for admin forms; Recharts for analytics; Sonner for toasts; Vaul drawer for mobile filters. Supabase: Postgres (fonts, foundries, collections, events), Auth (admin login), Edge Function to fetch Google Fonts metadata server-side.

### Pages & layout
1. **Home/browse** – sticky header (wordmark, centered search with "/" hint, nav). Short intro title + subtitle + dark pill CTA. Horizontal chip strip for quick collections. Then a 300px filter sidebar (grid/list toggle, sort, category pills, classification select, variable/italic/multi-weight checkboxes, weight range, license) beside a 3-column specimen grid with "Showing X of Y" and a Load more button.
2. **Font detail** – header with family, designer, style count; type tester (editable text, weight slider limited to available weights, size slider 12–200px, italic toggle); character set grid; related fonts.
3. **Collections** and **Foundry** pages – filtered grids with a short header.
4. **About**.
5. **Admin** – importer (paste URL or family name → preview → publish), fonts table with edit/delete, analytics dashboard.

### Design system
Monochrome light, museum-like UI. `--background: #ffffff`, `--foreground: #1a1a1a`, `--card: #e7e7e4`, `--muted: #f8f8f7`, `--border: #dfdfdd`, `--muted-foreground: #5c5c59`, `--input-border: #909089` (inputs, checkboxes, range track); `--border` is for decorative hairlines only. UI font: Inter; specimens load their own family via the Google Fonts CSS API with `display=swap`. Scale 12/14/16/20/32/48 (UI body 16px/1.5; meta text 12px minimum at weight 400+), specimen "Aa" ~160px. Spacing 4-pt; 24px page gutters, 16px grid gap. Radius 8px cards, full pills for chips. No shadows; tone shifts on hover. Motion 150ms ease-out.

### Components & interactions
SearchBar (focus via "/", clear button, no-results state), ChipStrip (scrollable, active chip filled), FilterSidebar (collapsible sections, reset all), ViewToggle, SpecimenCard (loading skeleton until font loads, hover tint), TypeTester, GlyphGrid (hover enlarge, click copies + toast), LoadMore (loading/disabled at end), EmptyState ("No fonts match these filters"), Admin ImportForm (validating/preview/error), DataTable, AnalyticsCharts.

### Data & state
`fonts`, `foundries`, `collections` (+ join table), `font_events`, `profiles(role)`. Filters live in URL search params so views are shareable. Seed ~30 open-source families with plausible metadata and fictional foundry bios.

### Accessibility
Search and all filters are labeled controls; chips are toggle buttons with `aria-pressed`. Sliders expose value text ("Weight 600"). Glyph grid cells are buttons with the character name as label and announce "copied" via live region. Grey meta text on #e7e7e4 must reach 4.5:1 (#5c5c59 = 5.4:1 on #e7e7e4). Visible focus ring; mobile filter drawer traps focus and returns it. Verified contrast: body text #1a1a1a on #ffffff = 17.4:1; specimen text #1a1a1a on #e7e7e4 = 14.0:1; meta/secondary text #5c5c59 on #e7e7e4 = 5.4:1; white #ffffff on #1a1a1a = 17.4:1; input/checkbox border #909089 on #ffffff = 3.2:1.

### Security
RLS: public `select` on published fonts/foundries/collections; insert/update/delete only where `profiles.role = 'admin'`. `font_events` insert-only for anon with rate limiting in an Edge Function; no select for anon. Validate importer input with zod on client and in the Edge Function (allow only fonts.googleapis.com URLs). Never expose service keys; sanitize any foundry bio markdown with DOMPurify.

### Performance & SEO
Load specimen fonts only for visible cards (IntersectionObserver) and subset with `text=` where possible. Code-split admin. Per-font meta titles and OG images; semantic headings; Lighthouse 90+.

### Guardrails
- Original copy; only list openly licensed fonts, credit designers accurately.
- No trademarked logos; placeholder foundry names.
- Analytics store no IP addresses or personal identifiers.
- Small typed components, no `any`, visible error states.
- Done when: filters and search combine correctly and persist in URL, a detail page tests weights live, glyph copy works by keyboard, an admin can import and publish a family, and non-admins cannot write.

Open the builderAll templatesThis palette on its own