Skip to main content
vibld

Template

Wickerfund

A billing page for a pay-as-you-go developer API where customers prepay a balance and spend it across several metered services. It shows the remaining balance at all times, lists past top-ups and invoices, and breaks down cumulative monthly spend per service so a team can decide when to top up.

Prepaid balance billing screen with top-up history · App screen: upgrade · 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.

  • InterHeadings: Inter 500, 24px page title, 20px card titles, -0.01em tracking
  • InterBody: Inter 400 16px / 1.5; table cells 15px; helper text 14px

Patterns

  • top bar with workspace and product switchers
  • balance readout beside primary top-up button
  • underlined tab row under the top bar
  • stacked section cards on a tinted canvas
  • dashed-border empty state inside a card
  • monthly usage ledger table with monospace figures
  • command-palette search trigger with keyboard hint

States it is designed for

  • Loading: skeleton rows in both tables and a shimmer bar where the balance sits
  • Empty top-up history: dashed box with inbox icon and 'contact support' link
  • Zero usage month: row still shows with 0 values, never hidden
  • Balance zero or negative: balance turns to a warning style with text 'Top up to keep requests flowing'
  • Checkout cancelled: neutral toast, balance unchanged
  • Checkout success: success toast and new history row
  • Error loading usage: inline error in the card with Retry
  • Long service lists: table scrolls horizontally with sticky Date column

Who it is for

  • developers on prepaid API plans
  • finance or ops leads reconciling invoices
  • startup founders watching burn

Layout

  1. Top bar (56px): square logo mark, workspace switcher, product/service switcher; right side: two-line balance readout (label over monospace amount), dark 'Top up' button, round avatar
  2. Tab row: Overview / Billing / Configure with a 2px underline on the active tab; search trigger with a keyboard-shortcut chip at far right
  3. Main canvas: pale grey, centred column max 600px wide on desktop with page title
  4. Card 1: top-up history (title, helper line, table or dashed empty state with support link)
  5. Card 2: usage history table (Date, Total cost, one column per metered service) with pagination footer
  6. Below 768px: switchers collapse into one menu, balance moves under the page title, tables scroll horizontally inside the card with a sticky first column

Palette

Quiet, precise, ledger-like. The page should feel like a bank statement rendered by a developer tool: calm neutrals, one dark action, money always visible.

  • canvas#f9f9fb
  • surface#ffffff
  • text#18181b
  • muted#63636b
  • border#e4e4e9
  • input-border#8a8a93
  • primary#18181b
  • on-primary#ffffff
  • link#2f5bd3
  • focus#3b63d9
  • success#1f7a4d

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text17.72:14.5:1
Aamuted helper on canvas5.66:14.5:1
Aaprimary button label17.72:14.5:1
Aasupport link5.90:14.5:1
input border3.42:13:1
focus ring on canvas5.03:13:1
Aasuccess badge text5.32:14.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
Inter 500, 24px page title, 20px card titles, -0.01em tracking
Body
Inter 400 16px / 1.5; table cells 15px; helper text 14px

Currency and counts in JetBrains Mono 400 14-15px with tabular numerals; similar to the observed neo-grotesk UI face. No uppercase labels except the shortcut chip (12px, 0.05em tracking).

Spacing and imagery

Comfortable density; 4px base, card padding 24px, 16px gap between cards; main column 600px desktop; radius 12px cards, 8px buttons, 10px inner empty-state box; shadows none, cards use a 1px #e4e4e9 border.

No photography. Line icons (inbox tray for empty state, plus for top-up, magnifier for search) at 1.5px stroke; no charts on this page.

Components

  • WorkspaceSwitcher and ServiceSwitcher dropdowns
  • BalanceReadout (label + monospace amount)
  • TopUpButton opening a top-up dialog with preset amounts
  • Underlined Tabs
  • SearchTrigger with shortcut chip opening a command palette
  • SectionCard
  • TopUpHistoryTable with invoice download links
  • EmptyState with icon, heading, body and support link
  • UsageHistoryTable with per-service columns and cost tooltips
  • Pagination (Previous / Next)
  • Avatar menu

Interactions

  • Top-up dialog: preset amount chips (e.g. 20 / 50 / 100 / custom), then hands off to a hosted checkout provider; balance animates to new value on return
  • Cost cells have a dotted underline; hover or focus shows a tooltip with the per-unit breakdown
  • Command palette opens with Cmd/Ctrl+K, arrow keys move, Enter navigates
  • Tabs are links with aria-current; underline slides 150ms between tabs
  • Invoice rows expose a download icon button; row hover tints #f9f9fb

Data

  • Workspace{id, name, currency (EUR|USD|GBP)}
  • Balance{workspace_id, amount_cents, updated_at}
  • TopUp{id, workspace_id, amount_cents, status (pending|paid|failed|refunded), invoice_url, created_at}
  • UsageMonth{workspace_id, month, service (verify|messages|lookup), units, cost_cents}
  • Member{workspace_id, user_id, role (owner|billing|developer)}

Guardrails

Experience

  • Keep the balance visible in the top bar on every tab, not only on Billing
  • Show zero-usage months as rows with 0 so the ledger has no gaps
  • Let the empty state point to support, since older invoices may not be listed
  • Put per-unit pricing in cost tooltips instead of adding columns
  • Top-up opens preset amounts first; a custom amount is one extra field, not a separate page
  • Never auto-charge from this page; every top-up is an explicit action

Accessibility

  • Balance readout is a labelled group so screen readers announce 'Balance, 0.00 euros'
  • Tables use th scope='col', a caption, and right-aligned numeric cells
  • Tooltips on cost cells open on focus as well as hover and are dismissible with Escape
  • Shortcut chip is aria-hidden; the search trigger has an accessible name
  • Focus ring 2px #3b63d9 with 2px offset on all interactive elements
  • Tab row uses nav with aria-current='page' rather than ARIA tabs, because each tab is a route

Security

  • RLS: balances, top_ups and usage_months readable only by members of the workspace; only owner or billing roles can create top-ups
  • Balance is credited only by a server-side webhook from the checkout provider after signature verification, never by the client
  • Invoice URLs are short-lived signed links generated on demand
  • Validate top-up amounts server-side (min, max, integer cents) with zod
  • Write an audit log row for every top-up, refund and role change

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 **Wickerfund**, the Billing tab of a prepaid, pay-as-you-go API console. Customers load a balance, spend it across three metered services (verifications, transactional messages, lookups) and use this page to see their balance, their past top-ups and invoices, and a month-by-month ledger of what each service cost.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix) with lucide-react icons. TanStack Query for server state, react-hook-form + zod for the top-up form, date-fns for month labels. Supabase Auth and Postgres for workspaces, balances, top-ups and usage; a Supabase Edge Function receives webhooks from a hosted checkout provider.

### Pages & layout
1. **App shell**: 56px top bar with logo mark, workspace switcher, service switcher, balance readout (label 'Balance' above a monospace amount), dark 'Top up' button and avatar menu. Under it a tab row (Overview, Billing, Configure) with a search trigger showing a Cmd K chip on the right.
2. **Billing page**: page title, then two stacked cards in a 600px column on a #f9f9fb canvas.
   - *Top-up history*: title, one-line description, table (Date, Amount, Status, Invoice) or a dashed-border empty state with an inbox icon, 'No top-ups yet', and a short note with a support link.
   - *Usage history*: title, 'Cumulative usage per month', table with Date, Total cost and one column per service; Previous / Next pagination.
3. **Top-up dialog**: preset amount chips, optional custom amount, summary line, 'Continue to checkout'.
4. Mobile: switchers collapse into one sheet, tables scroll sideways with sticky first column.

### Design system
- Colors: `--canvas: #f9f9fb`, `--surface: #ffffff`, `--text: #18181b`, `--muted: #63636b`, `--border: #e4e4e9`, `--input-border: #8a8a93`, `--primary: #18181b`, `--on-primary: #ffffff`, `--link: #2f5bd3`, `--focus: #3b63d9`, `--success: #1f7a4d`.
- Fonts: Inter (400/500) for UI at 16px/1.5, card titles 20px, page title 24px; JetBrains Mono 14-15px with tabular numerals for money and counts.
- Spacing: 4px scale (4, 8, 12, 16, 24, 32); card padding 24px; 16px between cards.
- Radius: 12px cards, 8px buttons and inputs, 999px amount chips.
- Shadows: none; 1px `--border` outlines. Empty-state box uses a 1px dashed border.
- Motion: 150ms ease-out on tab underline and hover; balance number counts up over 400ms after a successful top-up (disabled with reduced motion).

### Components & interactions
WorkspaceSwitcher, ServiceSwitcher, BalanceReadout, TopUpButton + TopUpDialog (preset chips as a radio group, custom amount field with inline zod errors, disabled submit while creating the checkout session), Tabs-as-links, CommandPalette (Cmd/Ctrl+K), SectionCard, TopUpHistoryTable (status badge, invoice download icon button), EmptyState, UsageHistoryTable (cost cells with dotted underline and a tooltip showing units x unit price), Pagination, Toasts for success, cancel and error.

### Data & state
Tables: `workspaces`, `members(workspace_id, user_id, role)`, `balances(workspace_id, amount_cents)`, `top_ups(id, workspace_id, amount_cents, status, invoice_path, created_at)`, `usage_months(workspace_id, month, service, units, cost_cents)`. Balance and lists come from TanStack Query with 30s stale time; after returning from checkout, poll the balance until the webhook lands (max 20s) then show the toast. Seed mock data: one workspace in EUR, two paid top-ups, four months of usage including an all-zero month. Selected page of the usage table lives in the URL.

### Accessibility
Label the balance region, give each table a caption, right-align numbers, and make cost tooltips reachable by keyboard. Amount chips are a radiogroup with arrow-key navigation. Status badges carry text, not colour alone. Respect prefers-reduced-motion for the count-up.
Verified contrast: body text: #18181b on #ffffff = 17.72:1; muted helper on canvas: #63636b on #f9f9fb = 5.66:1; primary button label: #ffffff on #18181b = 17.72:1; support link: #2f5bd3 on #ffffff = 5.9:1; input border: #8a8a93 on #ffffff = 3.42:1; focus ring on canvas: #3b63d9 on #f9f9fb = 5.03:1; success badge text: #1f7a4d on #ffffff = 5.32:1.

### Security
Enable RLS on every table: members can select rows where `workspace_id` is in their memberships; only `owner` or `billing` roles may insert into `top_ups` (as `pending`); no client role may update `balances` - only the webhook Edge Function (service role) credits it after verifying the provider signature and idempotency key. Invoice downloads use signed URLs valid for 60s. Rate-limit checkout-session creation per user. Keep the service key server-side only.

### Performance & SEO
Code-split the top-up dialog and command palette. Paginate usage server-side (12 months per page). Mark all console routes noindex. Keep the shell under 150KB gzipped JS.

### Guardrails
- All copy, service names and figures are invented; no real brands.
- Never show a balance the server has not confirmed.
- Keep money in integer cents end to end; format only at render time.
- Acceptance criteria: (1) balance shows on every tab; (2) empty, loading, error and populated states render for both cards; (3) a test webhook credits the balance and adds a history row; (4) a developer-role member cannot start a top-up; (5) tables and tooltips work by keyboard alone.

Open the builderAll templatesThis palette on its own