Template
Wharfline
An account settings page on a model-and-dataset hosting hub that shows how much download egress the account used in a period against a monthly allowance. It helps heavy users and orgs see whether they are close to their bandwidth limit before it affects downloads.
Download bandwidth usage chart in account settings · App screen: usage · 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, 18px page title; wordmark area 18px
- Source Sans 3Body: Source Sans 3 400 16px / 1.5; nav links 15px
Patterns
- top navigation with global search
- account settings left nav with profile header
- quota pill above chart
- daily bar chart with rotated date labels
- period dropdown
- 'new' badge on nav item
States it is designed for
- Loading: grey placeholder bars
- Zero usage: flat baseline with '0 Bytes' axis and a caption 'No downloads in this period'
- Near quota (>80%): pill shows a warning label and text 'Approaching limit'
- Over quota: banner explaining throttling and link to upgrade
- Error: inline message with Retry in place of chart
- Very large values: units scale (MB, GB, TB) with one decimal
Who it is for
- ML practitioners pulling large files
- org admins tracking egress quotas
- researchers on free accounts
Layout
- Global top nav: logo mark + wordmark, wide search input, section links with small icons, 'new' badge, avatar
- Settings sidebar (220px, faint tinted panel): avatar + account name + handle chip; list of settings links with the active one bold and tinted, a small 'new' badge on Downloads
- Main: H2 title, muted subtitle; row with quota pill (label, info icon, used / allowance) on the left and period dropdown on the right
- Chart area: vertical axis label, one bar per day with rotated date ticks, zero baseline
- Below 900px the settings nav becomes a select menu above the content; chart becomes horizontally scrollable with fixed y-axis
Palette
Utilitarian, open-source friendly, neutral greys with small pops of blue for 'new' and links.
- canvas
#ffffff - panel
#f9fafb - text
#111827 - muted
#6b7280 - border
#e5e7eb - input-border
#8b93a1 - bar
#4f5b6b - accent
#2563eb - new-badge-text
#1d4ed8 - new-badge-bg
#eff4ff - focus
#2563eb
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 17.74:1 | 4.5:1 |
| Aa | muted subtitle | 4.83:1 | 4.5:1 |
| Aa | nav text on panel | 16.98:1 | 4.5:1 |
| Aa | new badge text | 6.08:1 | 4.5:1 |
| chart bar | 6.91:1 | 3:1 | |
| input border | 3.09:1 | 3:1 | |
| focus ring | 5.17: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 scale
- Display
- Source Sans 3 700, 18px page title; wordmark area 18px
- Body
- Source Sans 3 400 16px / 1.5; nav links 15px
Handle chip and quota numbers in JetBrains Mono 13-14px; similar to the observed humanist sans. Axis ticks 12px rotated -45deg.
Spacing and imagery
Airy; 4px base; content max 1100px; settings nav 220px; chart height 220px; radius 8px pills and buttons; soft 0 1px 2px shadows on the quota pill and period button; nav hover tints.
No imagery beyond a round avatar and tiny nav icons; chart is plain slate bars on white with light gridlines.
Components
- TopNav with search
- SettingsNav with profile header and NewBadge
- QuotaPill with info tooltip
- PeriodSelect
- EgressBarChart
- Axis labels
- EmptyChart baseline
- UsageTable fallback
Interactions
- Period dropdown (7 days, 30 days, current month, previous month) refetches and animates bars from baseline
- Hovering or focusing a bar shows date and bytes in a tooltip with human-readable units
- Info icon tooltip explains what counts as egress
- Settings nav links show hover tint and keyboard focus ring
Data
Account{id, handle, display_name, plan (free|pro|org)}EgressDaily{account_id, day, bytes}Quota{plan, monthly_bytes}
Guardrails
Experience
- Always show used vs allowance next to the chart, not only inside it
- Use binary-aware, human units consistently (e.g. GB with one decimal)
- Keep the period selector near the chart, right-aligned
- Mark new settings items with a small text badge, never an unexplained dot
- Offer a table view for exact numbers
Accessibility
- Chart has an accessible data table alternative and a text summary ('12.4 GB of 20 TB used this month')
- Rotated tick labels are also available in the table; do not rely on them alone
- Info tooltip opens on focus and is described by aria-describedby
- Active settings link uses aria-current='page'
- Focus ring 2px #2563eb on nav links, dropdown and bars
Security
- RLS: egress_daily readable only by the owning account or org admins
- Egress rows written by a server job with service role; no client writes
- Validate period param server-side
- Do not expose other members' usage in personal settings
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 **Wharfline**, the Settings > Downloads page of a hub where people host and download models and datasets. It shows daily download egress for a period against a monthly allowance so users can see how close they are to throttling.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix), lucide-react, Recharts for the bar chart, TanStack Query, date-fns, zod. Supabase Auth + Postgres for accounts, plans and daily egress.
### Pages & layout
1. **Top nav**: logo mark and wordmark, wide search input, section links (Models, Datasets, Apps, Storage with a 'new' badge, Docs, Pricing), avatar.
2. **Settings layout**: faint tinted left panel with avatar, name and handle chip, then a long list of settings links (Profile, Account, Authentication, Organizations, Billing, Downloads [active, 'new'], Repositories, Access tokens, SSH keys, Webhooks, Notifications ...).
3. **Downloads content**: title and muted subtitle; row with quota pill ('Downloads this month', info icon, used / allowance) and period dropdown; 220px daily bar chart with y-axis label and rotated date ticks; 'View as table' toggle below.
4. Responsive: settings list becomes a select above content below 900px; chart scrolls horizontally with a pinned y-axis.
### Design system
- Colors: `--canvas: #ffffff`, `--panel: #f9fafb`, `--text: #111827`, `--muted: #6b7280`, `--border: #e5e7eb`, `--input-border: #8b93a1`, `--bar: #4f5b6b`, `--accent: #2563eb`, `--new-badge-text: #1d4ed8`, `--new-badge-bg: #eff4ff`, `--focus: #2563eb`.
- Fonts: Source Sans 3 400/600/700 (16px/1.5 body, 18px title); JetBrains Mono 13-14px for handle and figures.
- Spacing: 4px scale; 32px between title block and chart; nav items 36px tall.
- Radius: 8px pills, buttons and nav highlights; 999px badges.
- Shadows: 0 1px 2px rgba(17,24,39,.06) on pill and dropdown.
- Motion: bars grow from baseline 250ms on period change; none with reduced motion.
### Components & interactions
TopNav, GlobalSearch, SettingsNav (profile header, NewBadge, active state), QuotaPill (info tooltip, warning label when above 80%), PeriodSelect, EgressBarChart (tooltips, keyboard-focusable bars), ChartTableToggle, UsageTable, OverQuotaBanner, ErrorState.
### Data & state
Tables `accounts(id, handle, display_name, plan)`, `plan_quotas(plan, monthly_bytes)`, `egress_daily(account_id, day, bytes)`. One query returns days in range plus month-to-date total. Period in URL. Format bytes with a single helper. Seed: a free account with zero egress (flat chart) and a pro account with 30 days of varied usage near 80% of allowance.
### Accessibility
Provide a one-sentence text summary above the chart, a data table toggle, focusable bars with tooltips, aria-current on the active nav link and tooltips reachable by keyboard.
Verified contrast: body text: #111827 on #ffffff = 17.74:1; muted subtitle: #6b7280 on #ffffff = 4.83:1; nav text on panel: #111827 on #f9fafb = 16.98:1; new badge text: #1d4ed8 on #eff4ff = 6.08:1; chart bar: #4f5b6b on #ffffff = 6.91:1; input border: #8b93a1 on #ffffff = 3.09:1; focus ring: #2563eb on #ffffff = 5.17:1.
### Security
RLS on `egress_daily`: select where account_id = auth.uid() (or org admin via membership). No client inserts. Validate period input. Keep quota enforcement server-side.
### Performance & SEO
Lazy-load the chart library; render the summary text first. Aggregate server-side. Settings routes noindex.
### Guardrails
- Invented handles and figures only.
- Do not colour-code usage without a text label.
- Acceptance criteria: (1) zero-usage shows flat baseline and caption; (2) period change updates pill and chart; (3) >80% shows warning label; (4) table view matches chart; (5) nav fully keyboard operable.