Skip to main content
vibld

Template

Ripplo

A clean sign-in page for an AI assistant workspace. Users enter an email and continue to a magic link or password step, or use one of two social providers; new users follow a sign-up link.

Email-first sign-in with social options · App screen: login · 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 600, 22px heading
  • InterBody: Inter 400, 16px, line-height 1.5

Patterns

  • centred narrow auth column
  • email-first continue
  • OR divider
  • full-width outlined social buttons
  • colourful block wordmark
  • footer legal links

States it is designed for

  • default
  • invalid email
  • submitting
  • code sent with resend timer
  • wrong code
  • SSO required for domain: redirect notice
  • account not found: offer sign-up
  • rate-limited
  • OAuth error returned in URL

Who it is for

  • knowledge workers joining a company AI workspace
  • new trial users

Layout

  1. centred column ~240px wide at desktop (max 360px): wordmark, 'Welcome' heading, email label and field, primary Continue
  2. OR divider
  3. two outlined social buttons
  4. sign-up prompt with link
  5. footer: terms and privacy links
  6. on mobile the column takes full width with 16px gutters

Palette

Friendly, clean and fast; nothing between the user and their workspace.

  • bg#ffffff
  • field#f4f5f6
  • text#16181d
  • muted#5f646d
  • primary#1e76d9
  • link#1a6fd0
  • border#8b919b
  • logo-a#3f9a4c
  • logo-b#e8553d

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text17.76:14.5:1
Aaplaceholder5.45:14.5:1
AaContinue label4.52:14.5:1
Aalink text4.97:14.5:1
input and button border3.17:13:1
focus ring4.52: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
Inter 600, 22px heading
Body
Inter 400, 16px, line-height 1.5

Field label 14px 600; divider 'OR' 12px uppercase 0.08em tracking.

Spacing and imagery

Density: Airy. Grid: 8px; 16px between groups. Container: column max 360px. Radius: 8px inputs and buttons. Shadows: none.

A playful geometric block wordmark only.

Components

  • Wordmark
  • EmailForm
  • PrimaryButton
  • OrDivider
  • SocialButton (provider icon + label)
  • OtpStep
  • LegalFooter

Interactions

  • Continue validates email and moves to a one-time code or password step based on account type
  • Social buttons open provider OAuth
  • Enter submits; email autofocus
  • Remember last-used method and highlight it

Data

  • User{id, email, created_at, last_sign_in_method (email|oauth-a|code-host)}
  • Workspace{id, domain, sso_required}
  • AuthAttempt{email_hash, ip_hash, at}

Guardrails

Experience

  • Email is the default path; social is secondary
  • Never reveal whether an account exists on the first step beyond 'check your email'
  • Keep terms and privacy visible
  • Autofocus email; support paste of full codes
  • Show which method was used last

Accessibility

  • Visible labels (not placeholder-only)
  • Divider text is decorative and hidden from AT
  • Errors announced and linked to fields
  • Social buttons have text labels, not just logos
  • Focus order follows visual order

Security

  • Rate-limit OTP sends and verifications per email and IP
  • OTP codes expire in 10 minutes and are single-use
  • Enforce SSO for domains that require it server-side
  • Validate redirect URLs against an allowlist
  • CSRF-protected auth callbacks

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 **Ripplo**, the sign-in page of an AI workspace: a centred email-first form with Continue, an OR divider and two social provider buttons, plus a sign-up link and legal footer. Build the email and code steps and all error states.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui on Radix primitives and lucide-react icons. TanStack Query for server state, react-hook-form + zod for every form, date-fns for relative times. Supabase for Auth, Postgres with row-level security and Edge Functions for anything that needs a secret. Use Supabase Auth for email OTP and OAuth providers.

### Pages & layout
1. **/login**: wordmark, heading, email field, Continue, divider, two social buttons, sign-up prompt, footer.
2. **/login/code**: 6-digit code input with resend timer and 'use a different email'.
3. **/signup**: same layout with name field.
4. **/auth/callback** handler with error display.

### Design system
- Colors: `--bg: #ffffff` (page), `--field: #f4f5f6` (input fill), `--text: #16181d` (primary text), `--muted: #5f646d` (placeholder and footer), `--primary: #1e76d9` (Continue button), `--link: #1a6fd0` (sign-up link), `--border: #8b919b` (outlined buttons and input), `--logo-a: #3f9a4c` (decorative wordmark block), `--logo-b: #e8553d` (decorative wordmark block).
- Fonts: Inter 600, 22px heading for headings; Inter 400, 16px, line-height 1.5 for body. Field label 14px 600; divider 'OR' 12px uppercase 0.08em tracking.
- Spacing: Airy. 8px; 16px between groups. Container: column max 360px.
- Radius: 8px inputs and buttons.
- Shadows: none.
- Motion: Button press scale 0.98; step change (email → code) slides 12px and fades.

### Components & interactions
SocialButton: full-width outlined button with a 16px monochrome provider glyph and 'Continue with …' label. OrDivider: hairline rules either side of a small uppercase label.

- Continue validates email and moves to a one-time code or password step based on account type
- Social buttons open provider OAuth
- Enter submits; email autofocus
- Remember last-used method and highlight it

### Data & state
Use Supabase Auth; store last method in a cookie. Form state via react-hook-form + zod.

Entities: `User{id, email, created_at, last_sign_in_method (email|oauth-a|code-host)}`; `Workspace{id, domain, sso_required}`; `AuthAttempt{email_hash, ip_hash, at}`.

States to build and show in a dev-only state switcher:
- default
- invalid email
- submitting
- code sent with resend timer
- wrong code
- SSO required for domain: redirect notice
- account not found: offer sign-up
- rate-limited
- OAuth error returned in URL

### Accessibility
- Visible labels (not placeholder-only)
- Divider text is decorative and hidden from AT
- Errors announced and linked to fields
- Social buttons have text labels, not just logos
- Focus order follows visual order
Verified contrast: body text: #16181d on #ffffff = 17.76:1; placeholder: #5f646d on #f4f5f6 = 5.45:1; Continue label: #ffffff on #1e76d9 = 4.52:1; link text: #1a6fd0 on #ffffff = 4.97:1; input and button border: #8b919b on #ffffff = 3.17:1; focus ring: #1e76d9 on #ffffff = 4.52:1.

### Security
- Rate-limit OTP sends and verifications per email and IP
- OTP codes expire in 10 minutes and are single-use
- Enforce SSO for domains that require it server-side
- Validate redirect URLs against an allowlist
- CSRF-protected auth callbacks
RLS: `workspaces` domain lookup is exposed only through an Edge Function returning `sso_required`; `auth_attempts` has no client access.

### Performance & SEO
Static shell under 60KB JS; preconnect to the auth endpoint; add title and meta description; allow indexing of /login only.

### Guardrails
- Email is the default path; social is secondary
- Never reveal whether an account exists on the first step beyond 'check your email'
- Keep terms and privacy visible
- Autofocus email; support paste of full codes
- Show which method was used last
- Write fresh, generic copy and invented sample data; no real brands, logos, product names or people.
- Keep components small and typed (no `any`); surface every error visibly with a way to recover.

Acceptance criteria:
- Email OTP flow works end to end
- Social OAuth returns to the app
- Errors are specific and announced
- Rate limiting enforced
- SSO-required domains are redirected

Open the builderAll templatesThis palette on its own