Skip to content

Auth Flow

Every screen between a stranger and a working account: sign in, sign up, reset, the second factor, SSO by email domain, and the first-run setup on the other side.

7 routes7 pages · 14 blocks32 files · 3,431 lineslucide-reactAdded 10 Sept 2026

What's included

  • app/forgot/page.tsx
  • app/globals.css
  • app/layout.tsx
  • app/not-found.tsx
  • app/page.tsx
  • app/signup/page.tsx
  • and 11 more files
  • 7 pages it is built from, installed with it
  • Needs lucide-react

Works with

  • React
  • Next.js
  • Tailwind CSS
  • TypeScript

npx hoverlab init auth-flow ./my-app

Or over MCP, from your editor's agent — no account needed.

License

Free to read, copy and install, for personal and non-commercial projects. Shipping it in client work or a paid product needs Pro ($79 once). The source lands in your repo and stops being ours — no attribution, nothing to upgrade.

Was this useful?

Every screen

Acme Inc

Welcome back

Sign in to pick up where you left off.

or continue with email
Forgot?

New here? Create an account

TermsPrivacySupport

Live components in your current theme — switch routes, or the phone icon to check the mobile layout. Colours are this template’s Midnight palette, which ships in app/globals.css. Navy, mid corners, nothing else. Six screens where the only thing that matters is the form — so the palette has one colour and spends all of it on the button.

Get it

32 files · .zip · nothing to configure

then

cd auth-flow
npm install
npm run dev

The archive contains the whole project — routes, blocks, theme tokens, Tailwind and PostCSS config, tsconfig and a .gitignore. One runtime dependency, and no Hoverlab dependency at all: it is your code from the moment it unzips.

For AI

The component, its props, the design tokens it expects and the command that installs it — as one prompt. Paste it into Claude, Cursor, v0 or ChatGPT and what they build around it will match the rest of the catalog instead of inventing its own system.

See the prompt

Routes

PathPageFile
/Sign-In Screenapp/page.tsx
/signupSignup Pageapp/signup/page.tsx
/forgotForgot Passwordapp/forgot/page.tsx
/two-factorTwo-Factor Challengeapp/two-factor/page.tsx
/ssoSSO Sign Inapp/sso/page.tsx
/welcomeOnboardingapp/welcome/page.tsx
404404 Pageapp/not-found.tsx

What you get

project root(8 files)

  • GETTING-STARTED.md
  • gitignore
  • next.config.ts
  • package.json
  • postcss.config.mjs
  • README.md
  • tailwind.config.ts
  • tsconfig.json

app/(9 files)

  • forgot/page.tsx
  • globals.css
  • layout.tsx
  • not-found.tsx
  • page.tsx
  • signup/page.tsx
  • sso/page.tsx
  • two-factor/page.tsx
  • welcome/page.tsx

components/(15 files)

  • auth-forgot-password.tsx
  • auth-login-card.tsx
  • auth-magic-link-form.tsx
  • auth-otp-verify.tsx
  • auth-signup-split.tsx
  • auth-sso-domain.tsx
  • auth-two-factor.tsx
  • logo-cloud.tsx
  • not-found-404.tsx
  • onboarding-checklist.tsx
  • setup-wizard.tsx
  • sso-enterprise-split.tsx
  • testimonial-ratings.tsx
  • theme-provider.tsx
  • workspace-setup-form.tsx

Every file is listed. The 14 files in components/ are the blocks the pages import — each one has its own page if you want to read it on its own.

Project files

Everything except the blocks. Opens on app/globals.css — the file that makes the rest look right, since every block styles itself with bg-card and text-muted-foreground rather than literal colours.

app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;

/**
 * Design tokens — the Midnight palette.
 *
 * Navy, mid corners, nothing else. Six screens where the only thing that matters is the form — so the palette has one colour and spends all of it on the button.
 *
 * This file is the reason a pasted block looks right. Every block and page
 * styles itself with semantic classes — `bg-card`, `text-muted-foreground`,
 * `border-border` — rather than literal colours, so they inherit whatever
 * you define here instead of fighting it. Change a value below and every
 * section in the project moves with it. Change the hue on `--primary` and
 * `--ring` together and you have rebranded the site.
 *
 * Values are bare HSL channels, not `hsl(...)` calls. That is what lets
 * Tailwind compose them with an alpha suffix: `bg-primary/10` expands to
 * `hsl(var(--primary) / 0.1)`, which is impossible if the variable already
 * carries its own function wrapper.
 *
 * Every foreground/background pair below clears WCAG AA (4.5:1) in both
 * themes. If you retune one, check the pair rather than trusting the eye —
 * mid-lightness accents are the ones that fail.
 */

@layer base {
  :root {
    --background: 234 35% 99%;
    --foreground: 234 38% 10%;
    --card: 0 0% 100%;
    --card-foreground: 234 38% 10%;
    --popover: 0 0% 100%;
    --popover-foreground: 234 38% 10%;
    --primary: 234 55% 34%;
    --primary-foreground: 0 0% 100%;
    --secondary: 234 30% 95%;
    --secondary-foreground: 234 38% 18%;
    --muted: 234 22% 95%;
    --muted-foreground: 234 12% 40%;
    --accent: 256 40% 93%;
    --accent-foreground: 256 45% 20%;
    --destructive: 0 72% 47%;
    --destructive-foreground: 0 0% 100%;
    --border: 234 20% 90%;
    --input: 234 20% 90%;
    --ring: 234 55% 34%;

    --radius: 0.5rem;
  }

  .dark {
    --background: 234 36% 5%;
    --foreground: 234 15% 97%;
    --card: 234 28% 8%;
    --card-foreground: 234 15% 97%;
    --popover: 234 28% 8%;
    --popover-foreground: 234 15% 97%;
    --primary: 234 80% 74%;
    --primary-foreground: 234 42% 7%;
    --secondary: 234 22% 15%;
    --secondary-foreground: 234 15% 97%;
    --muted: 234 22% 15%;
    --muted-foreground: 234 10% 68%;
    --accent: 256 26% 18%;
    --accent-foreground: 256 45% 88%;
    --destructive: 0 62% 52%;
    --destructive-foreground: 0 0% 100%;
    --border: 234 18% 19%;
    --input: 234 18% 19%;
    --ring: 234 80% 74%;
  }
}

@layer base {
  * {
    @apply border-border;
  }

  body {
    @apply bg-background text-foreground antialiased;
  }

  /**
   * Global motion opt-out.
   *
   * Blocks guard their own animations with Tailwind's `motion-safe:`, but
   * third-party CSS and anything you add later will not. This is the
   * backstop: it neutralises every animation and transition on the page
   * for users who have asked the OS for reduced motion, rather than
   * relying on each author to remember.
   */
  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
}

More Account & Access

Pro
Open the full page for this template

Customer Portal

The usage meter before the invoice

What a paying customer needs and never gets: this period’s usage with the overage rate on it, every invoice as a PDF, the plan, the card — and a 403 that names who can grant what was refused.

7 routes7 pages18 blocksAmethyst