Skip to main content
vibld

Template

Plexgrove

The overview page of a freshly created machine-learning model repository. It tells the owner the repo is empty and walks them through the two things that make it useful: filling in the model card metadata and pushing weight files from the command line or an SDK. It also shows download stats and hosted-inference status in a side rail.

Model repository overview with getting-started cards · App screen: details · Small tools and apps · full-stack app (auth + DB)

A mock-up of the screen, drawn from its layout, palette and typefaces. A build follows the full prompt below.

Start from this screenRead the build prompt

Typefaces

The catalog's own faces. A screen composed into a template is drawn in that template's typefaces.

  • Source Sans 3Headings: Source Sans 3 600, 20px section titles, 18px card titles
  • JetBrains MonoBody: Source Sans 3 400 16px/1.5; JetBrains Mono 400 14px for repo names, code and metadata keys

Patterns

  • global top bar with centred search and icon nav
  • owner/name repo header with copy button
  • tabbed repository sections
  • two-card getting-started empty state
  • code block with CLI/SDK tab switcher
  • ghosted metadata form preview
  • right rail stat and provider panels
  • NEW badges on nav items

States it is designed for

  • empty repo (getting-started cards shown)
  • populated repo (rendered model card replaces cards)
  • stats not tracked yet (dash plus explanatory line)
  • no inference providers (message plus request link)
  • like pending / failed with toast
  • copy failed (clipboard blocked) with manual-select fallback
  • loading skeleton for header and rail
  • private repo badge and permission-denied for non-members on Settings

Who it is for

  • ML engineers publishing models
  • research teams sharing checkpoints
  • open-source maintainers

Layout

  1. global top bar: logo left, search field (~240px) centre-left, icon+label nav right, avatar menu
  2. repo header band on a very pale grey: owner / repo name in monospace, copy icon, like button with count, licence chip
  3. tab row: Model card (active, dark underline), Files and versions, Community, Settings; overflow + 'Copy to…' action right
  4. main column (~60%): section title then two equal cards side by side (metadata card, push-files card), then a full-width tip strip
  5. right rail (~35%) separated by a hairline: downloads-last-month stat with help link, inference-providers panel with empty message and request link
  6. below 1024px the rail drops under the main column; below 640px the two cards stack and the nav collapses to a menu button

Palette

Neutral, technical, welcoming. It reads like documentation that happens to be interactive.

  • page background#ffffff
  • header band / card inset#f7f8fa
  • hairline border#e5e7eb
  • input border#8a8f98
  • primary text#111827
  • secondary text#5f6672
  • NEW badge / info accent#2d5bd7
  • like heart icon#dc3545
  • code text#1f2937
  • code comment#667085

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text17.74:14.5:1
Aamuted text on band5.44:14.5:1
Aacode comment on inset4.68:14.5:1
AaNEW badge / link accent5.85:14.5:1
input border3.25:13:1
focus ring (accent)5.51:13:1
like heart icon4.53: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
Source Sans 3 600, 20px section titles, 18px card titles
Body
Source Sans 3 400 16px/1.5; JetBrains Mono 400 14px for repo names, code and metadata keys

Repo name in JetBrains Mono 600 18px; badges 12px uppercase 600 with 0.06em tracking; no weights below 400.

Spacing and imagery

Comfortable density on a 4px grid; container max 1280px with 24px gutters; cards 24px padding, 12px radius, 1px border, no shadow; code insets 8px radius on the pale surface.

No photos. Small monochrome line icons beside nav and tabs; a faded, skewed mini-form preview inside the metadata card acts as the illustration; a tiny emoji-style avatar mark only for the brand slot.

Components

  • TopBar with search and icon nav
  • RepoHeader (owner, name, copy, like toggle, licence chip)
  • RepoTabs
  • GettingStartedCard
  • MetadataPreview (ghosted key/value rows)
  • CodeTabs (CLI / Python) with CopyButton
  • TipStrip
  • StatPanel (downloads)
  • ProviderPanel (empty + request link)
  • NewBadge

Interactions

  • copy buttons show a check icon and 'Copied' tooltip for 1.5s
  • like toggles optimistically and rolls back on error
  • CLI/Python tabs switch code without layout shift and remember the last choice
  • Git/HTTPS/SSH sub-tabs swap the clone command
  • 'Edit model card' opens the metadata editor route
  • tabs are keyboard navigable with arrow keys
  • search opens a results popover after 2 characters with 200ms debounce

Data

  • Repo{id, owner_id, name, kind (model|dataset|app), visibility (public|private), licence, likes, created_at}
  • RepoFile{id, repo_id, path, size_bytes, sha, uploaded_at}
  • ModelCard{repo_id, metadata jsonb, readme_md, updated_at}
  • DownloadStat{repo_id, month, count}
  • Like{repo_id, user_id}

Guardrails

Experience

  • Show the two getting-started cards only while the repo has zero files; swap to the rendered card as soon as the first file lands.
  • Keep the command snippets runnable as written, with the real repo slug interpolated.
  • Put the one primary action per card (edit card, upload) in the card body, never in the rail.
  • Explain dashes: a missing stat always carries a one-line reason and a help link.
  • Keep the tab row sticky under the top bar on scroll so owners can jump to Files or Settings.

Accessibility

  • Tabs use role=tablist with aria-selected and arrow-key roving focus.
  • Copy buttons have aria-label 'Copy command' and announce 'Copied' through a polite live region.
  • Code blocks are real <pre><code> with horizontal scroll and a visible focus ring when scrolled by keyboard.
  • The like toggle uses aria-pressed and includes the count in its accessible name.
  • The ghosted metadata preview is aria-hidden; the real editor is a separate accessible form.

Security

  • RLS: repos readable when public or when the user is a member; only owners and maintainers may write files or edit the card.
  • Never print access tokens in snippets; show a placeholder and link to token settings.
  • Validate file paths server-side (no '..', max length, allowed characters) and cap upload size.
  • Rate-limit like toggles and search per user and IP.

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 an entry'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 entries)
- 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.

### SaaS screen baseline
- Design every screen for its full set of states: first-run empty, loading skeleton, partial data, error with retry, permission-denied, and success feedback. Each entry lists the states its screen needs.
- Keep destructive actions (delete, revoke, downgrade, remove member) behind a confirmation that names the object, and prefer undo over a second dialog where the action is reversible.
- Enforce authorisation on the server for every action a screen exposes. Hiding a button is not access control; check the role again in the API or RLS policy.
- Never show secrets (API keys, tokens) in full after creation. Show them once, then mask them, and offer rotate and revoke.
- Keep the app shell (navigation, workspace switcher, account menu) consistent across screens, and preserve filters, sort and scroll position when the user navigates back.
### Goal
Build **Plexgrove**, the overview screen for a newly created model repository on a model-sharing hub. The owner lands here right after creating the repo; the page must make the empty state useful by guiding them to complete metadata and push files, while showing the repo's identity, tabs and side stats exactly as they will look once populated.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Tabs, Tooltip, DropdownMenu), lucide-react, TanStack Query, react-hook-form + zod. Supabase Auth, Postgres and Storage.

### Pages & layout
1. **App shell**: global top bar (logo, search, Models / Datasets / Apps / Docs / Pricing links, avatar menu).
2. **Repo overview** (`/:owner/:repo`): header band, tab row, main column with the getting-started pair and tip strip, right rail with stats and provider panels.
3. **Files** tab: simple file table (path, size, updated) with an empty state that links back to the push instructions.
4. **Metadata editor** (`/:owner/:repo/edit`): form for licence, language, base model, pipeline tag and tags.
5. Responsive: rail moves below main at <1024px; cards stack at <640px.

### Design system
- Colors: `--bg: #ffffff` (page background), `--surface: #f7f8fa` (header band / card inset), `--border: #e5e7eb` (hairline border), `--input-border: #8a8f98` (input border), `--fg: #111827` (primary text), `--muted: #5f6672` (secondary text), `--accent: #2d5bd7` (NEW badge / info accent), `--heart: #dc3545` (like heart icon), `--code: #1f2937` (code text), `--comment: #667085` (code comment).
- Fonts: Source Sans 3 600, 20px section titles, 18px card titles for headings; Source Sans 3 400 16px/1.5; JetBrains Mono 400 14px for repo names, code and metadata keys for body. Repo name in JetBrains Mono 600 18px; badges 12px uppercase 600 with 0.06em tracking; no weights below 400.
- Spacing: Comfortable density on a 4px grid; container max 1280px with 24px gutters; cards 24px padding, 12px radius, 1px border, no shadow; code insets 8px radius on the pale surface.
- Radius: 12px cards, 8px buttons and code insets, full pills for badges and the licence chip.
- Shadows: none; separate regions with the pale band and 1px hairlines.
- Motion: 150ms colour/opacity transitions; tab indicator slides 200ms ease-out.

### Components & interactions
TopBar, RepoHeader, RepoTabs, GettingStartedCard (title, description, action, slot), MetadataPreview (skewed, 60% opacity, aria-hidden), CodeTabs (CLI / Python and Git / HTTPS / SSH), CopyButton, TipStrip, StatPanel, ProviderPanel, NewBadge, LikeToggle.

Interactions: copy buttons show a check icon and 'Copied' tooltip for 1.5s; like toggles optimistically and rolls back on error; CLI/Python tabs switch code without layout shift and remember the last choice; Git/HTTPS/SSH sub-tabs swap the clone command; 'Edit model card' opens the metadata editor route; tabs are keyboard navigable with arrow keys; search opens a results popover after 2 characters with 200ms debounce.

States to build: empty repo (getting-started cards shown); populated repo (rendered model card replaces cards); stats not tracked yet (dash plus explanatory line); no inference providers (message plus request link); like pending / failed with toast; copy failed (clipboard blocked) with manual-select fallback; loading skeleton for header and rail; private repo badge and permission-denied for non-members on Settings.

### Data & state
Seed one fictional owner with an empty model repo and a second, populated repo for comparison. Derive `isEmpty` from file count. Store the last chosen snippet tab in localStorage (wrapped in try/catch). Keep route params in the URL; server state lives in TanStack Query with optimistic like updates.

Model: `Repo{id, owner_id, name, kind (model|dataset|app), visibility (public|private), licence, likes, created_at}`; `RepoFile{id, repo_id, path, size_bytes, sha, uploaded_at}`; `ModelCard{repo_id, metadata jsonb, readme_md, updated_at}`; `DownloadStat{repo_id, month, count}`; `Like{repo_id, user_id}`.

### Accessibility
Tabs use role=tablist with aria-selected and arrow-key roving focus. Copy buttons have aria-label 'Copy command' and announce 'Copied' through a polite live region. Code blocks are real <pre><code> with horizontal scroll and a visible focus ring when scrolled by keyboard. The like toggle uses aria-pressed and includes the count in its accessible name. The ghosted metadata preview is aria-hidden; the real editor is a separate accessible form. Body text is 16px; code is 14px only inside code blocks. Visible 2px accent focus rings on every control.
Verified contrast: body text: #111827 on #ffffff = 17.74:1; muted text on band: #5f6672 on #f7f8fa = 5.44:1; code comment on inset: #667085 on #f7f8fa = 4.68:1; NEW badge / link accent: #2d5bd7 on #ffffff = 5.85:1; input border: #8a8f98 on #ffffff = 3.25:1; focus ring (accent): #2d5bd7 on #f7f8fa = 5.51:1; like heart icon: #dc3545 on #ffffff = 4.53:1.

### Security
RLS: repos readable when public or when the user is a member; only owners and maintainers may write files or edit the card. Never print access tokens in snippets; show a placeholder and link to token settings. Validate file paths server-side (no '..', max length, allowed characters) and cap upload size. Rate-limit like toggles and search per user and IP. Tables: `repos` (select public or member; insert own; update/delete owner or maintainer), `repo_files` (select follows repo; insert/delete maintainers), `model_cards` (select follows repo; update maintainers), `likes` (insert/delete own row only), `download_stats` (select follows repo; writes only from a service role job).

### Performance & SEO
Code-split the metadata editor and file table. Syntax-highlight snippets with a tiny tokenizer or none. Server-render or prerender public repo pages with title, description and OG tags; noindex private repos and settings routes.

### Guardrails
- Show the two getting-started cards only while the repo has zero files; swap to the rendered card as soon as the first file lands.
- Keep the command snippets runnable as written, with the real repo slug interpolated.
- Put the one primary action per card (edit card, upload) in the card body, never in the rail.
- Explain dashes: a missing stat always carries a one-line reason and a help link.
- Keep the tab row sticky under the top bar on scroll so owners can jump to Files or Settings.
- Write all copy fresh; use invented people, companies and numbers only. No real brands, logos, wordmarks or third-party product names anywhere in the UI or seed data.
- Do not trace or copy any existing product's layout assets, icons or illustrations; draw generic ones.
- Acceptance criteria:
  - [ ] An empty repo shows both getting-started cards and snippets with the real slug
  - [ ] Uploading one file swaps the cards for the rendered model card
  - [ ] Like toggles optimistically and survives reload
  - [ ] Non-members cannot open Settings (permission-denied view)
  - [ ] All tabs, copy buttons and the like toggle work by keyboard

Open the builderAll templatesThis palette on its own