{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "clerk-sign-up",
  "title": "Clerk Sign Up",
  "description": "Multi-step sign-up form with name, email, password and email verification via OTP input. Includes password strength indicator.",
  "dependencies": [
    "@clerk/nextjs"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/blocks/clerk/clerk-sign-up/components/elements/clerk-sign-up.tsx",
      "content": "\"use client\";\n\nimport { useRouter } from \"next/navigation\";\nimport type * as React from \"react\";\nimport { useCallback, useRef, useState } from \"react\";\n\nimport { useClerk, useSignUp } from \"@clerk/nextjs\";\n\nfunction cn(...classes: (string | boolean | undefined)[]) {\n  return classes.filter(Boolean).join(\" \");\n}\n\nfunction EyeIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={className}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"16\"\n      height=\"16\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n    >\n      <path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" />\n      <circle cx=\"12\" cy=\"12\" r=\"3\" />\n    </svg>\n  );\n}\n\nfunction EyeOffIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={className}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"16\"\n      height=\"16\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n    >\n      <path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\" />\n      <path d=\"M14.084 14.158a3 3 0 0 1-4.242-4.242\" />\n      <path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\" />\n      <path d=\"m2 2 20 20\" />\n    </svg>\n  );\n}\n\nfunction CheckIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={className}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"14\"\n      height=\"14\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2.5\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n    >\n      <polyline points=\"20 6 9 17 4 12\" />\n    </svg>\n  );\n}\n\nfunction GoogleIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={className}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"18\"\n      height=\"18\"\n      viewBox=\"0 0 24 24\"\n    >\n      <path\n        d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z\"\n        fill=\"#4285F4\"\n      />\n      <path\n        d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n        fill=\"#34A853\"\n      />\n      <path\n        d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18A11.96 11.96 0 0 0 0 12c0 1.94.46 3.77 1.28 5.4l3.56-2.77.01-.54z\"\n        fill=\"#FBBC05\"\n      />\n      <path\n        d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n        fill=\"#EA4335\"\n      />\n    </svg>\n  );\n}\n\nfunction GitHubIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={className}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"18\"\n      height=\"18\"\n      viewBox=\"0 0 24 24\"\n      fill=\"currentColor\"\n    >\n      <path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z\" />\n    </svg>\n  );\n}\n\nfunction MicrosoftIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={className}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"18\"\n      height=\"18\"\n      viewBox=\"0 0 24 24\"\n    >\n      <rect x=\"2\" y=\"2\" width=\"9.5\" height=\"9.5\" fill=\"#F25022\" />\n      <rect x=\"12.5\" y=\"2\" width=\"9.5\" height=\"9.5\" fill=\"#7FBA00\" />\n      <rect x=\"2\" y=\"12.5\" width=\"9.5\" height=\"9.5\" fill=\"#00A4EF\" />\n      <rect x=\"12.5\" y=\"12.5\" width=\"9.5\" height=\"9.5\" fill=\"#FFB900\" />\n    </svg>\n  );\n}\n\nfunction AppleIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={className}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"18\"\n      height=\"18\"\n      viewBox=\"0 0 24 24\"\n      fill=\"currentColor\"\n    >\n      <path d=\"M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\n    </svg>\n  );\n}\n\nconst oauthIcons: Record<\n  string,\n  (props: { className?: string }) => React.ReactNode\n> = {\n  oauth_google: GoogleIcon,\n  oauth_github: GitHubIcon,\n  oauth_apple: AppleIcon,\n  oauth_microsoft: MicrosoftIcon,\n};\n\nconst oauthLabels: Record<string, string> = {\n  oauth_google: \"Google\",\n  oauth_github: \"GitHub\",\n  oauth_apple: \"Apple\",\n  oauth_microsoft: \"Microsoft\",\n};\n\nfunction ArrowLeftIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={className}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"16\"\n      height=\"16\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n    >\n      <path d=\"m12 19-7-7 7-7\" />\n      <path d=\"M19 12H5\" />\n    </svg>\n  );\n}\n\nexport interface ClerkSignUpProps {\n  className?: string;\n  showOAuth?: boolean;\n  heading?: string;\n  subheading?: string;\n  redirectUrl?: string;\n  signInUrl?: string;\n  afterSSOUrl?: string;\n}\n\ntype PasswordRequirement = {\n  label: string;\n  met: boolean;\n};\n\nfunction getPasswordRequirements(password: string): PasswordRequirement[] {\n  return [\n    { label: \"8+ characters\", met: password.length >= 8 },\n    { label: \"Uppercase letter\", met: /[A-Z]/.test(password) },\n    { label: \"Number\", met: /\\d/.test(password) },\n  ];\n}\n\nexport function ClerkSignUp({\n  className,\n  showOAuth = true,\n  heading = \"Create your account\",\n  subheading = \"Welcome! Please fill in the details to get started.\",\n  redirectUrl = \"/\",\n  signInUrl = \"/sign-in\",\n  afterSSOUrl = \"/sso-callback\",\n}: ClerkSignUpProps) {\n  const { signUp, fetchStatus } = useSignUp();\n  const clerk = useClerk();\n  const router = useRouter();\n\n  // biome-ignore lint/suspicious/noExplicitAny: accessing clerk environment internals for social provider detection\n  const socialStrategies: string[] | undefined = (clerk as any).clerkjs\n    ?.environment?.userSettings?.socialProviderStrategies;\n  const oauthProviders = socialStrategies\n    ? socialStrategies.map((s: string) => ({ strategy: s }))\n    : undefined;\n\n  const [step, setStep] = useState<\"form\" | \"verify\">(\"form\");\n  const [firstName, setFirstName] = useState(\"\");\n  const [lastName, setLastName] = useState(\"\");\n  const [email, setEmail] = useState(\"\");\n  const [password, setPassword] = useState(\"\");\n  const [showPassword, setShowPassword] = useState(false);\n  const [error, setError] = useState<string | null>(null);\n\n  const [otp, setOtp] = useState<string[]>(Array(6).fill(\"\"));\n  const otpRefs = useRef<(HTMLInputElement | null)[]>([]);\n\n  const requirements = getPasswordRequirements(password);\n  const allRequirementsMet = requirements.every((r) => r.met);\n  const canContinue =\n    firstName.trim() !== \"\" &&\n    lastName.trim() !== \"\" &&\n    email.trim() !== \"\" &&\n    allRequirementsMet;\n\n  const isFetching = fetchStatus === \"fetching\";\n\n  const handleOAuth = useCallback(\n    async (strategy: string) => {\n      setError(null);\n      const { error: ssoError } = await signUp.sso({\n        strategy: strategy as \"oauth_google\",\n        redirectUrl,\n        redirectCallbackUrl: afterSSOUrl,\n      });\n      if (ssoError) {\n        setError(ssoError.message ?? \"OAuth failed. Please try again.\");\n      }\n    },\n    [signUp, afterSSOUrl, redirectUrl],\n  );\n\n  const handleContinue = useCallback(async () => {\n    if (!canContinue) return;\n    setError(null);\n    const { error: pwError } = await signUp.password({\n      emailAddress: email,\n      password,\n      firstName,\n      lastName,\n    });\n    if (pwError) {\n      setError(pwError.message ?? \"Sign up failed.\");\n      return;\n    }\n    const { error: sendError } = await signUp.verifications.sendEmailCode();\n    if (sendError) {\n      setError(sendError.message ?? \"Failed to send verification code.\");\n      return;\n    }\n    setStep(\"verify\");\n  }, [canContinue, signUp, email, password, firstName, lastName]);\n\n  const handleOtpChange = useCallback(\n    (index: number, value: string) => {\n      if (value.length > 1) {\n        const chars = value.slice(0, 6).split(\"\");\n        const next = [...otp];\n        chars.forEach((char, i) => {\n          if (index + i < 6) next[index + i] = char;\n        });\n        setOtp(next);\n        const focusIndex = Math.min(index + chars.length, 5);\n        otpRefs.current[focusIndex]?.focus();\n        return;\n      }\n\n      if (!/^\\d*$/.test(value)) return;\n\n      const next = [...otp];\n      next[index] = value;\n      setOtp(next);\n\n      if (value && index < 5) {\n        otpRefs.current[index + 1]?.focus();\n      }\n    },\n    [otp],\n  );\n\n  const handleOtpKeyDown = useCallback(\n    (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {\n      if (e.key === \"Backspace\" && !otp[index] && index > 0) {\n        otpRefs.current[index - 1]?.focus();\n      }\n    },\n    [otp],\n  );\n\n  const otpCode = otp.join(\"\");\n  const canVerify = otpCode.length === 6;\n\n  const handleVerify = useCallback(async () => {\n    if (!canVerify) return;\n    setError(null);\n    const { error: verifyError } = await signUp.verifications.verifyEmailCode({\n      code: otpCode,\n    });\n    if (verifyError) {\n      setError(verifyError.message ?? \"Verification failed.\");\n      return;\n    }\n    const { error: finalizeError } = await signUp.finalize();\n    if (finalizeError) {\n      setError(finalizeError.message ?? \"Failed to complete sign up.\");\n      return;\n    }\n    router.push(redirectUrl);\n  }, [canVerify, signUp, otpCode, router, redirectUrl]);\n\n  const handleResend = useCallback(async () => {\n    setOtp(Array(6).fill(\"\"));\n    otpRefs.current[0]?.focus();\n    await signUp.verifications.sendEmailCode();\n  }, [signUp]);\n\n  return (\n    <div\n      data-slot=\"clerk-sign-up\"\n      className={cn(\n        \"w-full max-w-[400px] rounded-xl border border-border bg-card shadow-sm\",\n        className,\n      )}\n    >\n      <div data-slot=\"header\" className=\"px-8 pt-8 pb-6 text-center\">\n        {step === \"verify\" && (\n          <button\n            type=\"button\"\n            data-slot=\"back-button\"\n            onClick={() => {\n              setStep(\"form\");\n              setError(null);\n            }}\n            className=\"mb-4 inline-flex items-center gap-1 text-sm text-muted-foreground transition-colors hover:text-foreground\"\n          >\n            <ArrowLeftIcon className=\"h-4 w-4\" />\n            Back\n          </button>\n        )}\n        <h1\n          data-slot=\"heading\"\n          className=\"text-xl font-semibold tracking-tight text-foreground\"\n        >\n          {step === \"form\" ? heading : \"Verify your email\"}\n        </h1>\n        <p\n          data-slot=\"subheading\"\n          className=\"mt-1.5 text-sm text-muted-foreground\"\n        >\n          {step === \"form\"\n            ? subheading\n            : `Enter the verification code sent to ${email}`}\n        </p>\n      </div>\n\n      {step === \"form\" && (\n        <div data-slot=\"form-body\" className=\"px-8 pb-8\">\n          {showOAuth && (\n            <>\n              <div data-slot=\"oauth-buttons\" className=\"flex gap-2\">\n                {!oauthProviders ? (\n                  <>\n                    <div className=\"h-10 flex-1 animate-pulse rounded-lg bg-muted\" />\n                    <div className=\"h-10 flex-1 animate-pulse rounded-lg bg-muted\" />\n                  </>\n                ) : (\n                  oauthProviders.map(({ strategy }) => {\n                    const Icon = oauthIcons[strategy];\n                    const label =\n                      oauthLabels[strategy] ?? strategy.replace(\"oauth_\", \"\");\n                    if (!Icon) return null;\n                    return (\n                      <button\n                        key={strategy}\n                        type=\"button\"\n                        data-slot={`oauth-${strategy.replace(\"oauth_\", \"\")}`}\n                        onClick={() => handleOAuth(strategy)}\n                        className=\"flex flex-1 items-center justify-center gap-2 rounded-lg border border-border bg-card px-3 py-2.5 text-sm font-medium text-foreground transition-colors hover:bg-accent\"\n                      >\n                        <Icon />\n                        {label}\n                      </button>\n                    );\n                  })\n                )}\n              </div>\n\n              <div data-slot=\"divider\" className=\"my-6 flex items-center gap-3\">\n                <div className=\"h-px flex-1 bg-border\" />\n                <span className=\"text-xs uppercase text-muted-foreground\">\n                  or\n                </span>\n                <div className=\"h-px flex-1 bg-border\" />\n              </div>\n            </>\n          )}\n\n          <div data-slot=\"fields\" className=\"space-y-4\">\n            <div className=\"flex gap-3\">\n              <div className=\"flex-1 space-y-1.5\">\n                <label\n                  data-slot=\"label\"\n                  htmlFor=\"clerk-signup-first-name\"\n                  className=\"block text-sm font-medium text-foreground\"\n                >\n                  First name\n                </label>\n                <input\n                  id=\"clerk-signup-first-name\"\n                  data-slot=\"input\"\n                  type=\"text\"\n                  value={firstName}\n                  onChange={(e) => setFirstName(e.target.value)}\n                  className=\"h-9 w-full rounded-lg border border-border bg-background px-3 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary focus:ring-1 focus:ring-primary\"\n                />\n              </div>\n              <div className=\"flex-1 space-y-1.5\">\n                <label\n                  data-slot=\"label\"\n                  htmlFor=\"clerk-signup-last-name\"\n                  className=\"block text-sm font-medium text-foreground\"\n                >\n                  Last name\n                </label>\n                <input\n                  id=\"clerk-signup-last-name\"\n                  data-slot=\"input\"\n                  type=\"text\"\n                  value={lastName}\n                  onChange={(e) => setLastName(e.target.value)}\n                  className=\"h-9 w-full rounded-lg border border-border bg-background px-3 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary focus:ring-1 focus:ring-primary\"\n                />\n              </div>\n            </div>\n\n            <div className=\"space-y-1.5\">\n              <label\n                data-slot=\"label\"\n                htmlFor=\"clerk-signup-email\"\n                className=\"block text-sm font-medium text-foreground\"\n              >\n                Email address\n              </label>\n              <input\n                id=\"clerk-signup-email\"\n                data-slot=\"input\"\n                type=\"email\"\n                value={email}\n                onChange={(e) => setEmail(e.target.value)}\n                className=\"h-9 w-full rounded-lg border border-border bg-background px-3 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary focus:ring-1 focus:ring-primary\"\n              />\n            </div>\n\n            <div className=\"space-y-1.5\">\n              <label\n                data-slot=\"label\"\n                htmlFor=\"clerk-signup-password\"\n                className=\"block text-sm font-medium text-foreground\"\n              >\n                Password\n              </label>\n              <div className=\"relative\">\n                <input\n                  id=\"clerk-signup-password\"\n                  data-slot=\"input\"\n                  type={showPassword ? \"text\" : \"password\"}\n                  value={password}\n                  onChange={(e) => setPassword(e.target.value)}\n                  className=\"h-9 w-full rounded-lg border border-border bg-background px-3 pr-9 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary focus:ring-1 focus:ring-primary\"\n                />\n                <button\n                  type=\"button\"\n                  data-slot=\"toggle-password\"\n                  onClick={() => setShowPassword((prev) => !prev)}\n                  className=\"absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground transition-colors hover:text-foreground\"\n                >\n                  {showPassword ? (\n                    <EyeOffIcon className=\"h-4 w-4\" />\n                  ) : (\n                    <EyeIcon className=\"h-4 w-4\" />\n                  )}\n                </button>\n              </div>\n\n              {password.length > 0 && (\n                <ul\n                  data-slot=\"password-requirements\"\n                  className=\"mt-2 space-y-1\"\n                >\n                  {requirements.map((req) => (\n                    <li\n                      key={req.label}\n                      className={cn(\n                        \"flex items-center gap-1.5 text-xs transition-colors\",\n                        req.met ? \"text-emerald-500\" : \"text-muted-foreground\",\n                      )}\n                    >\n                      <CheckIcon\n                        className={cn(\n                          \"h-3.5 w-3.5 shrink-0\",\n                          req.met\n                            ? \"text-emerald-500\"\n                            : \"text-muted-foreground/40\",\n                        )}\n                      />\n                      {req.label}\n                    </li>\n                  ))}\n                </ul>\n              )}\n            </div>\n          </div>\n\n          <div id=\"clerk-captcha\" />\n\n          {error && (\n            <p\n              data-slot=\"error\"\n              className=\"mt-3 text-center text-sm text-destructive\"\n            >\n              {error}\n            </p>\n          )}\n\n          <button\n            type=\"button\"\n            data-slot=\"continue-button\"\n            disabled={!canContinue || isFetching}\n            onClick={handleContinue}\n            className={cn(\n              \"mt-6 h-9 w-full rounded-lg text-sm font-medium transition-colors\",\n              canContinue && !isFetching\n                ? \"bg-primary text-primary-foreground hover:bg-primary/90\"\n                : \"cursor-not-allowed bg-primary/50 text-primary-foreground/70\",\n            )}\n          >\n            {isFetching ? \"Creating account...\" : \"Continue\"}\n          </button>\n\n          <p\n            data-slot=\"footer\"\n            className=\"mt-4 text-center text-sm text-muted-foreground\"\n          >\n            Already have an account?{\" \"}\n            <button\n              type=\"button\"\n              onClick={() => router.push(signInUrl)}\n              className=\"font-medium text-primary underline-offset-4 hover:underline\"\n            >\n              Sign in\n            </button>\n          </p>\n        </div>\n      )}\n\n      {step === \"verify\" && (\n        <div data-slot=\"verify-body\" className=\"px-8 pb-8\">\n          <div data-slot=\"otp-group\" className=\"flex justify-center gap-2\">\n            {otp.map((digit, index) => (\n              <input\n                // biome-ignore lint/suspicious/noArrayIndexKey: OTP digit positions are stable\n                key={index}\n                ref={(el) => {\n                  otpRefs.current[index] = el;\n                }}\n                data-slot=\"otp-input\"\n                type=\"text\"\n                inputMode=\"numeric\"\n                maxLength={1}\n                value={digit}\n                onChange={(e) => handleOtpChange(index, e.target.value)}\n                onKeyDown={(e) => handleOtpKeyDown(index, e)}\n                onFocus={(e) => e.target.select()}\n                className={cn(\n                  \"h-11 w-10 rounded-lg border bg-background text-center text-lg font-medium text-foreground outline-none transition-colors\",\n                  digit\n                    ? \"border-primary\"\n                    : \"border-border focus:border-primary focus:ring-1 focus:ring-primary\",\n                )}\n              />\n            ))}\n          </div>\n\n          {error && (\n            <p\n              data-slot=\"error\"\n              className=\"mt-3 text-center text-sm text-destructive\"\n            >\n              {error}\n            </p>\n          )}\n\n          <button\n            type=\"button\"\n            data-slot=\"verify-button\"\n            disabled={!canVerify || isFetching}\n            onClick={handleVerify}\n            className={cn(\n              \"mt-6 h-9 w-full rounded-lg text-sm font-medium transition-colors\",\n              canVerify && !isFetching\n                ? \"bg-primary text-primary-foreground hover:bg-primary/90\"\n                : \"cursor-not-allowed bg-primary/50 text-primary-foreground/70\",\n            )}\n          >\n            {isFetching ? \"Verifying...\" : \"Verify\"}\n          </button>\n\n          <p\n            data-slot=\"resend\"\n            className=\"mt-4 text-center text-sm text-muted-foreground\"\n          >\n            Didn&apos;t receive a code?{\" \"}\n            <button\n              type=\"button\"\n              onClick={handleResend}\n              className=\"font-medium text-primary underline-offset-4 hover:underline\"\n            >\n              Resend\n            </button>\n          </p>\n        </div>\n      )}\n\n      <div\n        data-slot=\"branding\"\n        className=\"flex items-center justify-center border-t border-border px-8 py-4\"\n      >\n        <span className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n          Secured by\n          <span className=\"font-semibold text-foreground\">clerk</span>\n        </span>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "docs": "A complete sign-up form with registration and email verification steps. Features 6-digit OTP input with auto-focus and password requirements indicator. Wire up with Clerk's useSignUp() hook.",
  "categories": [
    "clerk"
  ],
  "type": "registry:block"
}