Template
Noxley
In a model-hosting hub's account settings, a user reviews every repository they own - models, datasets, spaces and buckets - with type, last update, visibility and storage used, to manage quota and visibility at a glance.
Account repositories overview table in settings · App screen: dashboard · 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 700 22px section title
- Source Sans 3Body: Source Sans 3 400 16px / 1.5; table 15px
Patterns
- settings left nav with profile header card
- tabs above table (overview/storage)
- type filter pills with All selected
- filter-by-name search input
- sortable column headers
- visibility badge
- monospace size column
States it is designed for
- loading table skeleton
- no repositories (empty with Create links per type)
- filter yields nothing ('No repositories match' + clear)
- very long names truncate with tooltip
- storage over quota banner
- error with retry
Who it is for
- ML practitioners with many repos
- org admins auditing storage
Layout
- Top nav: logo, global search, section links, avatar
- Left settings panel (~180px): avatar + name + handle chip, then nav (profile, account, authentication, organizations, billing, downloads, repositories active, access tokens, SSH keys, inference providers, webhooks, papers, notifications, jobs, hardware, local apps, gated repositories)
- Main: h2 Repositories, tabs Overview / Storage, Documentation link right
- Toolbar: type pills (All, Models, Datasets, Spaces, Buckets) + filter input right
- Table: Repository (mono link), Type (icon + label), Updated (relative), Visibility (badge), Storage (mono), % of total; sortable headers with arrows
- Mobile: settings nav becomes a select; table becomes stacked rows with type and visibility as badges
Palette
Plain, technical and orderly - a developer settings page with no decoration.
- page
#ffffff - panel
#fafbfc - text
#111827 - muted text
#6b7280 - pill selected
#111827 - on pill selected
#ffffff - badge border
#8c95a2 - model icon
#6d5dfc - link
#111827 - row border
#eef0f3 - focus ring
#3b82f6
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on white | 17.74:1 | 4.5:1 |
| Aa | muted text on panel | 4.67:1 | 4.5:1 |
| Aa | selected pill label | 17.74:1 | 4.5:1 |
| visibility badge border | 3.03:1 | 3:1 | |
| model type icon on white | 4.54:1 | 3:1 | |
| focus ring on white | 3.68:1 | 3:1 | |
| Aa | unselected pill text on white | 4.83: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 scale
- Display
- Source Sans 3 700 22px section title
- Body
- Source Sans 3 400 16px / 1.5; table 15px
JetBrains Mono 15px for repo paths and sizes (dense table); badges 12px 600.
Spacing and imagery
Dense table; 44px rows, 12px cell padding, 24px section gap; radius 6px pills and inputs, 4px badges; no shadows.
Small type icons per repo kind; avatar in the panel header.
Components
- TopNav
- SettingsPanel with ProfileHeader
- Tabs
- TypeFilterPills
- FilterInput
- RepoTable (TanStack Table)
- VisibilityBadge
- TypeCell
- StorageTab with stacked bar per type
Interactions
- Pills filter the table; counts update in the pill labels
- Filter input filters by name as you type (client-side for <500 rows, server-side above)
- Header click sorts; second click reverses; aria-sort updates
- Row hover highlights; repo name link opens the repo
- Storage tab shows a horizontal bar breakdown and the largest repos
Data
Repo{id, owner_id, name, type (model|dataset|space|bucket), visibility (public|private|gated), updated_at, storage_bytes}StorageQuota{owner_id, limit_bytes, used_bytes}
Guardrails
Experience
- Default to All with the most recently updated first
- Keep type visible as icon plus text
- Show storage as bytes with sensible units
- Make filtering instant
- Offer a clear reset when filters hide everything
Accessibility
- Table uses th with aria-sort; sort buttons inside headers
- Pills are a toggle-button group with aria-pressed
- Repo names in mono still have sufficient size (15px) and link underline on hover/focus
- Relative dates have a title/tooltip with the absolute date
- Settings nav marks current page with aria-current
Security
- RLS: users only list repos they own or orgs they belong to
- Private repo names are never exposed in public endpoints
- Visibility changes require confirmation and are audited
- Sanitize filter input used in server queries (parameterised)
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 **Noxley**, the Repositories page of a model-hosting hub's account settings with filter pills, search, a sortable table and a Storage tab. Seed about 30 fictional repos across types.
### Stack
Use React 18, TypeScript, Vite, Tailwind CSS, shadcn/ui, Radix, lucide-react, TanStack Query, react-hook-form, zod, Supabase, TanStack Table, date-fns. Use Supabase for Auth, Postgres (row-level security on every table) and Storage where noted; keep only the anon key in the browser and run privileged work in Edge Functions.
### Pages & layout
1. **/settings/repositories** (Overview and Storage tabs).
2. Other settings nav items as placeholders.
Regions, in order:
- Top nav: logo, global search, section links, avatar
- Left settings panel (~180px): avatar + name + handle chip, then nav (profile, account, authentication, organizations, billing, downloads, repositories active, access tokens, SSH keys, inference providers, webhooks, papers, notifications, jobs, hardware, local apps, gated repositories)
- Main: h2 Repositories, tabs Overview / Storage, Documentation link right
- Toolbar: type pills (All, Models, Datasets, Spaces, Buckets) + filter input right
- Table: Repository (mono link), Type (icon + label), Updated (relative), Visibility (badge), Storage (mono), % of total; sortable headers with arrows
- Mobile: settings nav becomes a select; table becomes stacked rows with type and visibility as badges
### Design system
- Colors: `--page: #ffffff` (page), `--panel: #fafbfc` (panel), `--text: #111827` (text), `--muted-text: #6b7280` (muted text), `--pill-selected: #111827` (pill selected), `--on-pill-selected: #ffffff` (on pill selected), `--badge-border: #8c95a2` (badge border), `--model-icon: #6d5dfc` (model icon), `--link: #111827` (link), `--row-border: #eef0f3` (row border), `--focus-ring: #3b82f6` (focus ring).
- Fonts: Source Sans 3 700 22px section title for headings; Source Sans 3 400 16px / 1.5; table 15px for body. JetBrains Mono 15px for repo paths and sizes (dense table); badges 12px 600.
- Spacing, radius and shadows: Dense table; 44px rows, 12px cell padding, 24px section gap; radius 6px pills and inputs, 4px badges; no shadows.
- Motion: 150-200 ms ease-out for hover, focus and overlay transitions; overlays fade and scale from 98% to 100%; everything collapses to an instant change under prefers-reduced-motion.
- Mood: Plain, technical and orderly - a developer settings page with no decoration. Imagery: Small type icons per repo kind; avatar in the panel header.
### Components & interactions
Build these components: TopNav; SettingsPanel with ProfileHeader; Tabs; TypeFilterPills; FilterInput; RepoTable (TanStack Table); VisibilityBadge; TypeCell; StorageTab with stacked bar per type.
- Pills filter the table; counts update in the pill labels
- Filter input filters by name as you type (client-side for <500 rows, server-side above)
- Header click sorts; second click reverses; aria-sort updates
- Row hover highlights; repo name link opens the repo
- Storage tab shows a horizontal bar breakdown and the largest repos
### Data & state
Model: `Repo{id, owner_id, name, type (model|dataset|space|bucket), visibility (public|private|gated), updated_at, storage_bytes}`; `StorageQuota{owner_id, limit_bytes, used_bytes}`.
Filter and sort state live in URL search params. Percent of total is computed from the quota row.
States to implement and demo:
- loading table skeleton
- no repositories (empty with Create links per type)
- filter yields nothing ('No repositories match' + clear)
- very long names truncate with tooltip
- storage over quota banner
- error with retry
### Accessibility
- Table uses th with aria-sort; sort buttons inside headers
- Pills are a toggle-button group with aria-pressed
- Repo names in mono still have sufficient size (15px) and link underline on hover/focus
- Relative dates have a title/tooltip with the absolute date
- Settings nav marks current page with aria-current
- Body text is 16px with line-height 1.5 (15px only inside dense tables), nothing renders below 12px, weights of 300 or lighter appear only at 24px and above, and uppercase is limited to short labels with at least 0.05em tracking.
Verified contrast: body text on white: #111827 on #ffffff = 17.74:1; muted text on panel: #6b7280 on #fafbfc = 4.67:1; selected pill label: #ffffff on #111827 = 17.74:1; visibility badge border: #8c95a2 on #ffffff = 3.03:1; model type icon on white: #6d5dfc on #ffffff = 4.54:1; focus ring on white: #3b82f6 on #ffffff = 3.68:1; unselected pill text on white: #6b7280 on #ffffff = 4.83:1.
### Security
- RLS: users only list repos they own or orgs they belong to
- Private repo names are never exposed in public endpoints
- Visibility changes require confirmation and are audited
- Sanitize filter input used in server queries (parameterised)
RLS: `repos` - select where owner is the user or an org they belong to; update visibility only by owner/org admin; `storage_quotas` - select own.
### Performance & SEO
Paginate server-side above 500 rows; virtualise rows. Noindex settings.
### Guardrails
- Default to All with the most recently updated first
- Keep type visible as icon plus text
- Show storage as bytes with sensible units
- Make filtering instant
- Offer a clear reset when filters hide everything
- Use the product name Noxley and fresh, generic copy throughout; all people, companies, amounts and IDs are invented, and no third-party brand, logo or wordmark appears.
- Keep components small and typed (no `any`), and surface every failure visibly instead of swallowing it.
Acceptance criteria:
- [ ] Filtering, search and sort combine correctly
- [ ] Storage tab sums match table
- [ ] Empty and no-match states render
- [ ] Stacked rows at 390px
- [ ] Contrast pairs pass