Skip to main content
vibld

Template

Doorfee

A starter that shows how to sell access to an existing web app: users sign in with a marketplace account, and pages are gated by login or by owning a product, with a purchase prompt that sends them to a hosted checkout. It is a teaching hub with working examples rather than a full product.

Paid-access gate starter for a web app · 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.

Add app screens

Pick up to 6 screens, such as a dashboard, settings or an empty state. Each is built in this design’s own palette and typefaces, with its states and guardrails.

Account setup
Add edit
Analytics
Appearance
Calendar
Chat
Checklist
Checkout
Confirmation
Dashboard
Delete account
Details
Discovery questions
Empty state
Flowchart
Import export
Inbox
Integrations
Invite team
Loading
Login
Onboarding
Plans
Playground
Product tour
Referral
Search
Settings
Share
Sign up
Success
Table
Team members
Text editor
Upgrade
Usage
Verification
Welcome

Start from this templateRead the build prompt

Typefaces

Reddit Sans and Reddit Mono are a matched pair, friendly and legible for a light developer starter, with a heavy weight for the uppercase banner.

  • Reddit SansHeadings: card titles 24px 600, banner headline 64px 800 uppercase +0.02em
  • Reddit SansBody: body 16px/1.5 400
  • Reddit MonoFigures and code: hint chip 14px with the file path in 700

Patterns

  • hub page with monospace hint chip
  • centered logo tile with coral glow
  • four-column link cards with arrow nudge
  • gated route examples (public, signed-in, must-own)
  • purchase prompt card
  • bright marketplace-style banner

States it is designed for

  • signed out on gated page (sign-in prompt)
  • signed in without the product (purchase prompt)
  • signed in with access (content)
  • checkout returned, access still syncing (pending with refresh)
  • OAuth error
  • membership expired (renew prompt)

Who it is for

  • developers monetising a small app
  • creators selling software access
  • teams prototyping paywalls

Layout

  1. Top row: monospace hint chip left ('edit this file to begin' style), small 'by' + logo mark right; on mobile the chip spans full width at top and the mark moves to the bottom
  2. Center: 112px rounded logo tile with a large blurred coral glow behind
  3. Link cards: four columns (Server-rendered examples, App-router examples, Documentation, Community), each title + arrow and two-line description; 2x2 under 1024px, one column under 640px
  4. Example pages: header with sign-in state, gated content card or purchase prompt card
  5. Soft vertical grey-to-white gradient background

Palette

Light, friendly, developer-starter. Grey mist with a single warm coral glow; marketing banner uses a bright blue grid.

  • background gradient top#d6dbdc
  • background gradient bottom / card#ffffff
  • primary text#000000
  • secondary text#51575c
  • hint chip fill#eef0f1
  • coral glow#ff6a4d
  • coral link / accent text#c2410c
  • card hover border / input border#80868a
  • primary button fill#111111
  • marketing banner blue#1a7fd6

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text21.00:14.5:1
Aabody on gradient top15.03:14.5:1
Aamuted text5.24:14.5:1
Aahint chip text18.37:14.5:1
Aacoral link text5.18:14.5:1
Aabutton label18.88:14.5:1
card / input border3.69:13:1
banner headline (large)4.16: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
Reddit Sans 600, 24px/1.3 card titles
Body
Reddit Sans 400, 16px/1.5

Hint chip in Reddit Mono 14px with the file path in 700; banner headline uses Reddit Sans 800 uppercase at 64px with 0.02em tracking.

Spacing and imagery

Airy; 1100px container; cards 16px padding, radius 12px, transparent border that appears on hover; logo tile 24px radius; chip 12px radius.

Big blurred coral radial glow behind the logo tile; optional bright blue banner with a faint grid for the marketing variant; product cards with cover images in a store preview.

Components

  • HintChip
  • LogoTile with glow
  • LinkCard
  • SignInButton (marketplace OAuth)
  • AccessGate (login|product)
  • PurchasePromptCard
  • UserBadge
  • StoreBanner
  • ErrorCard

Interactions

  • Link card hover shows border and nudges the arrow 4px right
  • Sign-in returns to the page the user started on
  • Purchase prompt opens hosted checkout for the recommended plan; returns to the gated page
  • Glow is static under reduced motion (no drift)

Data

  • User{id, provider_user_id, username, email}
  • Product{id, name, recommended_plan_id}
  • Membership{id, user_id, product_id, status (active|expired|canceled), valid_until}
  • Session{id, user_id, expires_at}

Guardrails

Experience

  • Each example page states its rule in one sentence at the top ('Only members can see this')
  • Purchase prompt shows the plan price and what unlocks
  • Return users to where they started after sign-in or checkout
  • Keep the hub to four cards
  • Show an expiry date when access is time-limited

Accessibility

  • Link cards are single links with the arrow aria-hidden
  • Chip text keeps 4.5:1 on the grey fill
  • Gate states are announced as page headings, not only visuals
  • Glow is decorative
  • Mobile keeps readable 16px text without the cramped four-column wrap
  • Focus ring 2px black with offset

Security

  • Check access on the server for every gated route and API; never ship gated content to unauthorized clients
  • RLS: memberships readable only by owner; writes only from the webhook function
  • OAuth state and PKCE; session cookies httpOnly, secure, sameSite=lax
  • Verify checkout webhook signatures; idempotent membership upserts
  • Client id is public; client secret and API key server-only

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 **Doorfee**, a starter that demonstrates selling access to a web app. Users sign in with a marketplace-style OAuth account; pages are gated by login or by owning a product; users without access see a purchase prompt that opens a hosted checkout for the recommended plan. The home page is a hub linking to working examples.

### Stack
Next.js (App Router plus a legacy pages example if desired), React, TypeScript, Tailwind CSS, lucide-react, zod. Supabase Auth with a custom OAuth provider (or email) and Postgres for memberships; an Edge Function handles checkout webhooks. Use a hosted checkout provider.

### Pages & layout
1. **/**: soft grey-to-white gradient. Top row: monospace hint chip left, small "by" + mark right. Center: large rounded logo tile with a blurred coral glow. Four link cards (Server-rendered examples, App-router examples, Documentation, Community) with title, arrow and two-line description.
2. **/examples/public**: shows sign-in state and a sign-in / sign-out button.
3. **/examples/members**: signed-in only; redirects to sign-in with a return path.
4. **/examples/owners**: must own the product; otherwise shows the PurchasePromptCard (plan name, price, benefits, "Get access").
5. **/checkout/return**: polls until the membership is active, then forwards.
6. Optional **/store** marketing banner: bright blue with faint grid, uppercase headline, row of product cards.
Cards go 2x2 under 1024px and one column under 640px; the hint chip spans full width on mobile.

### Design system
- Colors: `--bg-top: #d6dbdc` (background gradient top), `--bg: #ffffff` (background gradient bottom / card), `--fg: #000000` (primary text), `--muted: #51575c` (secondary text), `--chip: #eef0f1` (hint chip fill), `--glow: #ff6a4d` (coral glow), `--coral-text: #c2410c` (coral link / accent text), `--border: #80868a` (card hover border / input border), `--btn: #111111` (primary button fill), `--banner: #1a7fd6` (marketing banner blue).
- Fonts: Reddit Sans 600 card titles 24px, 400 body 16px/1.5; Reddit Mono 14px for the chip; banner headline Reddit Sans 800 uppercase 64px with 0.02em tracking.
- Spacing: 8px base; 16px card padding; 32px gap; 96px between top row and logo.
- Radius: 12px cards and chip, 24px logo tile, 8px buttons.
- Shadows: logo tile `0 8px 24px rgb(0 0 0 / 0.08)`; glow is a 320px blurred radial of `#ff6a4d`.
- Motion: arrow nudge 150ms; none under reduced motion.

### Components & interactions
HintChip, LogoTile, LinkCard (border appears on hover, arrow nudges), SignInButton, AccessGate (server component with `rule: 'login' | 'product'`), PurchasePromptCard, UserBadge, StoreBanner, ErrorCard.

### Data & state
`users(id, provider_user_id, username)`, `products(id, name, recommended_plan_id)`, `memberships(user_id, product_id, status, valid_until)`. A server helper `hasAccess(userId, productId)` checks status and expiry. Webhooks create or update memberships. Seed one product and two invented users (one with access).

### Accessibility
Cards are single links; arrows are decorative. Each example page opens with an h1 that states the rule and the user's current access. Chip text passes on its fill. Focus ring 2px `#000000`.
Verified contrast: body text: #000000 on #ffffff = 21.0:1; body on gradient top: #000000 on #d6dbdc = 15.03:1; muted text: #51575c on #d6dbdc = 5.24:1; hint chip text: #000000 on #eef0f1 = 18.37:1; coral link text: #c2410c on #ffffff = 5.18:1; button label: #ffffff on #111111 = 18.88:1; card / input border: #80868a on #ffffff = 3.69:1; banner headline (large): #ffffff on #1a7fd6 = 4.16:1.

### Security
- Gate on the server for pages and API routes; never render gated content then hide it.
- RLS: `memberships` select where `user_id = auth.uid()`; insert/update only via the service role in the webhook function.
- OAuth with state + PKCE; httpOnly secure cookies.
- Verify webhook signatures; upsert idempotently. Client id public, secrets server-only.

### Performance & SEO
Hub is static; example pages dynamic. Glow is CSS. Noindex example and checkout routes.

### Guardrails
- Invent product and store names, covers and prices.
- Never rely on client checks for access.
- Acceptance criteria: (1) signed-out users are redirected from members-only pages and returned after sign-in; (2) non-owners see the purchase prompt; (3) completing checkout grants access without manual refresh; (4) expired memberships lose access; (5) mobile layout has no overlapping card text.

Open the builderAll templatesThis palette on its own