Skip to main content
vibld

Template

Rekinto

A compact sign-in page for a developer API product that leads with three identity providers as icon buttons and offers email below. It suits technical users who mostly sign in with a work or code-host account.

Provider-first sign-in with icon button row · 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 400, 24px 'Sign in' heading; JetBrains Mono 500 for the wordmark lettering
  • InterBody: Inter 400, 16px, line-height 1.5

Patterns

  • top-centred wordmark
  • row of three icon-only provider buttons
  • divider between social and email
  • email-first form with arrow button
  • disabled-until-valid Continue
  • copyright footer

States it is designed for

  • default (Continue disabled)
  • valid email
  • submitting
  • code step
  • invalid code
  • OAuth cancelled
  • rate-limited
  • account uses SSO: redirect notice

Who it is for

  • developers integrating a verification or messaging API
  • technical founders

Layout

  1. wordmark centred at top (monospace lettering beside a square mark)
  2. vertically centred column ~190px (max 360px): heading, three equal icon buttons in a row, divider
  3. email label, input, Continue button with arrow
  4. 'No account yet? Sign up' line
  5. copyright footer centred at bottom
  6. on mobile the provider row keeps three equal columns with 48px min height

Palette

Precise, neutral, engineered; monospace details hint at a developer audience.

  • bg#ffffff
  • text#1b1c1f
  • muted#5f636b
  • button#f7f7f8
  • border#8b8f98
  • primary#1b1c1f
  • disabled#f2f2f3
  • link#3b63d6

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text17.04:14.5:1
Aamuted footer6.03:14.5:1
AaContinue label (enabled)17.04:14.5:1
Aalink text5.33:14.5:1
input border3.24:13:1
provider button border3.03:13:1
focus ring5.33: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 400, 24px 'Sign in' heading; JetBrains Mono 500 for the wordmark lettering
Body
Inter 400, 16px, line-height 1.5

Label 14px 500; Continue 15px 500 with trailing arrow icon.

Spacing and imagery

Density: Airy. Grid: 8px; 16px between groups; provider buttons 8px apart. Container: column 360px max. Radius: 6px buttons and inputs. Shadows: Provider buttons 0 1px 2px rgba(0,0,0,0.05).

Full-colour provider glyphs at 20px inside neutral buttons; no illustration.

Components

  • Wordmark
  • ProviderIconButton ×3 (with visually hidden label)
  • Divider
  • EmailField
  • ContinueButton
  • SignUpLink
  • CopyrightFooter
  • CodeStep

Interactions

  • Provider buttons launch OAuth
  • Continue enables once the email is valid; Enter submits
  • Email step leads to a one-time code step
  • Tooltips on provider icons show 'Continue with …'

Data

  • User{id, email, created_at}
  • Identity{user_id, provider (oauth-a|code-host|workplace|email)}
  • AuthAttempt{email_hash, ip_hash, at}

Guardrails

Experience

  • Icon-only providers need tooltips and accessible names
  • Keep Continue visibly disabled until valid, but explain why on submit attempt
  • Keep the sign-up link on the same screen
  • Remember the last provider and outline it
  • Keep the page free of marketing copy

Accessibility

  • Each icon button has aria-label 'Continue with …'
  • Disabled Continue uses aria-disabled so it stays focusable with an explanation
  • Divider is presentational
  • Visible label above the email input
  • Focus ring 2px blue offset 2px

Security

  • Rate-limit sign-in and code requests per email and IP
  • Validate OAuth redirect targets against an allowlist
  • Codes and magic links are single-use and expire in 10 minutes
  • Use CSRF-safe, PKCE OAuth flows and httpOnly session cookies

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 **Rekinto**, the sign-in page of a developer API product: three identity-provider icon buttons in a row, a divider, and an email field with Continue that leads to a one-time code. Build sign-in, the code step and sign-up with 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. Supabase Auth handles OAuth providers and email OTP.

### Pages & layout
1. **/sign-in**: wordmark top-centre; heading; three provider buttons; divider; 'Email address' label and input; Continue; sign-up prompt; copyright footer.
2. **/sign-in/code**: six-box code input, resend timer.
3. **/sign-up**: same layout with 'Create account' heading.

### Design system
- Colors: `--bg: #ffffff` (page), `--text: #1b1c1f` (headings and labels), `--muted: #5f636b` (footer and helper), `--button: #f7f7f8` (provider buttons), `--border: #8b8f98` (input and button borders), `--primary: #1b1c1f` (enabled Continue fill), `--disabled: #f2f2f3` (disabled Continue fill), `--link: #3b63d6` (Sign up link and focus ring).
- Fonts: Inter 400, 24px 'Sign in' heading; JetBrains Mono 500 for the wordmark lettering for headings; Inter 400, 16px, line-height 1.5 for body. Label 14px 500; Continue 15px 500 with trailing arrow icon.
- Spacing: Airy. 8px; 16px between groups; provider buttons 8px apart. Container: column 360px max.
- Radius: 6px buttons and inputs.
- Shadows: Provider buttons 0 1px 2px rgba(0,0,0,0.05).
- Motion: Continue fades from disabled to enabled over 120ms; arrow nudges 2px on hover.

### Components & interactions
ProviderIconButton is a 56×32px neutral button with a coloured provider glyph and hidden text. Continue is full width, pale when disabled and near-black when enabled.

- Provider buttons launch OAuth
- Continue enables once the email is valid; Enter submits
- Email step leads to a one-time code step
- Tooltips on provider icons show 'Continue with …'

### Data & state
Auth via Supabase; last provider stored in a cookie. react-hook-form + zod for email and code.

Entities: `User{id, email, created_at}`; `Identity{user_id, provider (oauth-a|code-host|workplace|email)}`; `AuthAttempt{email_hash, ip_hash, at}`.

States to build and show in a dev-only state switcher:
- default (Continue disabled)
- valid email
- submitting
- code step
- invalid code
- OAuth cancelled
- rate-limited
- account uses SSO: redirect notice

### Accessibility
- Each icon button has aria-label 'Continue with …'
- Disabled Continue uses aria-disabled so it stays focusable with an explanation
- Divider is presentational
- Visible label above the email input
- Focus ring 2px blue offset 2px
Verified contrast: body text: #1b1c1f on #ffffff = 17.04:1; muted footer: #5f636b on #ffffff = 6.03:1; Continue label (enabled): #ffffff on #1b1c1f = 17.04:1; link text: #3b63d6 on #ffffff = 5.33:1; input border: #8b8f98 on #ffffff = 3.24:1; provider button border: #8b8f98 on #f7f7f8 = 3.03:1; focus ring: #3b63d6 on #ffffff = 5.33:1.

### Security
- Rate-limit sign-in and code requests per email and IP
- Validate OAuth redirect targets against an allowlist
- Codes and magic links are single-use and expire in 10 minutes
- Use CSRF-safe, PKCE OAuth flows and httpOnly session cookies
RLS: `identities` select for the owning user only; `auth_attempts` no client access (service role only).

### Performance & SEO
Under 60KB JS; preload provider glyph sprite; title and meta description; noindex the code step.

### Guardrails
- Icon-only providers need tooltips and accessible names
- Keep Continue visibly disabled until valid, but explain why on submit attempt
- Keep the sign-up link on the same screen
- Remember the last provider and outline it
- Keep the page free of marketing copy
- 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:
- All three providers and email OTP work
- Disabled state explains itself
- Rate limits enforced
- Keyboard and screen reader friendly
- Sign-up link works

Open the builderAll templatesThis palette on its own