{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "auth-signup-card",
  "title": "Sign-up card",
  "description": "Centered sign-up card over a grid and light beams, with live password rules, terms and social sign-up.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "button",
    "input",
    "label",
    "https://velora.colorlib.com/r/background-beams.json",
    "https://velora.colorlib.com/r/grid-pattern.json"
  ],
  "files": [
    {
      "path": "src/components/blocks/auth-signup-card.tsx",
      "content": "\"use client\";\n\nimport { useId, useState } from \"react\";\nimport { CheckIcon, CircleIcon, EyeIcon, EyeOffIcon } from \"lucide-react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { BackgroundBeams } from \"@/components/velora/background-beams\";\nimport { GridPattern } from \"@/components/velora/grid-pattern\";\nimport { cn } from \"@/lib/utils\";\n\nconst BRAND = \"Acme\";\nconst TITLE = \"Create your account\";\nconst SUBTITLE = \"Start a 14-day free trial. No credit card required.\";\nconst LINKS = { login: \"#\", terms: \"#\", privacy: \"#\", home: \"#\" };\n\nconst RULES = [\n  { label: \"At least 8 characters\", test: (value: string) => value.length >= 8 },\n  { label: \"One uppercase letter\", test: (value: string) => /[A-Z]/.test(value) },\n  { label: \"One number\", test: (value: string) => /\\d/.test(value) },\n  { label: \"One symbol\", test: (value: string) => /[^A-Za-z0-9]/.test(value) },\n];\n\n/**\n * Centered sign-up card over a grid and slow light beams. Password rules\n * tick off as you type. Submitting does nothing — wire `handleSubmit` to\n * your auth provider.\n */\nexport function AuthSignupCard() {\n  const id = useId();\n  const [password, setPassword] = useState(\"\");\n  const [showPassword, setShowPassword] = useState(false);\n  const passed = RULES.filter((rule) => rule.test(password)).length;\n\n  function handleSubmit(event: React.FormEvent<HTMLFormElement>) {\n    event.preventDefault();\n  }\n\n  return (\n    <section className=\"relative isolate overflow-hidden bg-background px-6 py-20 sm:py-24 lg:px-8\">\n      <GridPattern\n        width={44}\n        height={44}\n        squares={[\n          [3, 2],\n          [5, 4],\n          [9, 1],\n          [11, 6],\n          [15, 3],\n          [18, 8],\n        ]}\n        className=\"-z-10 fill-primary/5 [mask-image:radial-gradient(ellipse_70%_60%_at_top,black,transparent)]\"\n      />\n      <BackgroundBeams className=\"-z-10 opacity-70\" />\n      <div\n        aria-hidden\n        className=\"absolute top-0 left-1/2 -z-10 h-80 w-2xl -translate-x-1/2 rounded-full bg-brand/10 blur-3xl\"\n      />\n\n      <div className=\"mx-auto flex min-h-[44rem] max-w-md flex-col justify-center\">\n        <div className=\"text-center\">\n          <a\n            href={LINKS.home}\n            aria-label={`${BRAND} home`}\n            className=\"inline-flex rounded-lg focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-ring\"\n          >\n            <LogoMark />\n          </a>\n          <h2 className=\"mt-6 text-3xl font-semibold tracking-tight\">{TITLE}</h2>\n          <p className=\"mt-2 text-pretty text-muted-foreground\">{SUBTITLE}</p>\n        </div>\n\n        <div className=\"mt-10 rounded-2xl border bg-card/80 p-6 shadow-xl shadow-brand/5 backdrop-blur sm:p-8\">\n          <div className=\"grid grid-cols-2 gap-3\">\n            <Button type=\"button\" variant=\"outline\" size=\"lg\" className=\"h-10\">\n              <GitHubMark />\n              GitHub\n            </Button>\n            <Button type=\"button\" variant=\"outline\" size=\"lg\" className=\"h-10\">\n              <GoogleMark />\n              Google\n            </Button>\n          </div>\n\n          <div className=\"my-7 flex items-center gap-4 text-xs text-muted-foreground uppercase\">\n            <span aria-hidden className=\"h-px flex-1 bg-border\" />\n            or with email\n            <span aria-hidden className=\"h-px flex-1 bg-border\" />\n          </div>\n\n          <form onSubmit={handleSubmit} className=\"space-y-5\">\n            <div className=\"space-y-2\">\n              <Label htmlFor={`${id}-name`}>Full name</Label>\n              <Input\n                id={`${id}-name`}\n                name=\"name\"\n                required\n                autoComplete=\"name\"\n                placeholder=\"Ada Lovelace\"\n                className=\"h-10 px-3\"\n              />\n            </div>\n\n            <div className=\"space-y-2\">\n              <Label htmlFor={`${id}-email`}>Work email</Label>\n              <Input\n                id={`${id}-email`}\n                name=\"email\"\n                type=\"email\"\n                required\n                autoComplete=\"email\"\n                placeholder=\"you@company.com\"\n                className=\"h-10 px-3\"\n              />\n            </div>\n\n            <div className=\"space-y-2\">\n              <Label htmlFor={`${id}-password`}>Password</Label>\n              <div className=\"relative\">\n                <Input\n                  id={`${id}-password`}\n                  name=\"password\"\n                  type={showPassword ? \"text\" : \"password\"}\n                  required\n                  minLength={8}\n                  autoComplete=\"new-password\"\n                  value={password}\n                  onChange={(event) => setPassword(event.target.value)}\n                  aria-describedby={`${id}-rules`}\n                  className=\"h-10 pr-11 pl-3\"\n                />\n                <Button\n                  type=\"button\"\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  aria-label=\"Show password\"\n                  aria-pressed={showPassword}\n                  aria-controls={`${id}-password`}\n                  onClick={() => setShowPassword((shown) => !shown)}\n                  className=\"absolute top-1 right-1 text-muted-foreground hover:text-foreground\"\n                >\n                  {showPassword ? <EyeOffIcon aria-hidden /> : <EyeIcon aria-hidden />}\n                </Button>\n              </div>\n\n              <div aria-hidden className=\"grid grid-cols-4 gap-1.5 pt-1\">\n                {RULES.map((rule, i) => (\n                  <span\n                    key={rule.label}\n                    className={cn(\n                      \"h-1 rounded-full bg-muted transition-colors\",\n                      i < passed && \"bg-gradient-to-r from-brand-from to-brand-to\"\n                    )}\n                  />\n                ))}\n              </div>\n\n              <ul id={`${id}-rules`} className=\"grid grid-cols-1 gap-x-4 gap-y-1.5 pt-1 text-xs sm:grid-cols-2\">\n                {RULES.map((rule) => {\n                  const met = rule.test(password);\n                  return (\n                    <li\n                      key={rule.label}\n                      className={cn(\n                        \"flex items-center gap-1.5 transition-colors\",\n                        met ? \"text-foreground\" : \"text-muted-foreground\"\n                      )}\n                    >\n                      {met ? (\n                        <CheckIcon aria-hidden className=\"size-3.5 text-primary\" />\n                      ) : (\n                        <CircleIcon aria-hidden className=\"size-3.5\" />\n                      )}\n                      {rule.label}\n                      <span className=\"sr-only\">{met ? \" (done)\" : \" (required)\"}</span>\n                    </li>\n                  );\n                })}\n              </ul>\n            </div>\n\n            <div className=\"flex items-start gap-2.5\">\n              <input\n                id={`${id}-terms`}\n                name=\"terms\"\n                type=\"checkbox\"\n                required\n                className=\"mt-0.5 size-4 shrink-0 cursor-pointer accent-primary dark:scheme-dark focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n              />\n              <Label htmlFor={`${id}-terms`} className=\"block leading-snug font-normal text-muted-foreground\">\n                I agree to the{\" \"}\n                <a\n                  href={LINKS.terms}\n                  className=\"rounded-sm font-medium text-foreground underline underline-offset-4 hover:text-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n                >\n                  Terms of Service\n                </a>{\" \"}\n                and{\" \"}\n                <a\n                  href={LINKS.privacy}\n                  className=\"rounded-sm font-medium text-foreground underline underline-offset-4 hover:text-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n                >\n                  Privacy Policy\n                </a>\n                .\n              </Label>\n            </div>\n\n            <Button type=\"submit\" size=\"lg\" className=\"h-10 w-full\">\n              Create account\n            </Button>\n          </form>\n        </div>\n\n        <p className=\"mt-8 text-center text-sm text-muted-foreground\">\n          Already have an account?{\" \"}\n          <a\n            href={LINKS.login}\n            className=\"rounded-sm font-medium text-foreground underline-offset-4 hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n          >\n            Log in\n          </a>\n        </p>\n      </div>\n    </section>\n  );\n}\n\nfunction LogoMark() {\n  return (\n    <svg aria-hidden viewBox=\"0 0 24 24\" className=\"size-11\">\n      <rect width=\"24\" height=\"24\" rx=\"7\" className=\"fill-primary\" />\n      <path\n        d=\"M7 16.5 12 7l5 9.5\"\n        fill=\"none\"\n        strokeWidth=\"2.2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        className=\"stroke-primary-foreground\"\n      />\n    </svg>\n  );\n}\n\nfunction GitHubMark() {\n  return (\n    <svg aria-hidden viewBox=\"0 0 24 24\" fill=\"currentColor\">\n      <path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\" />\n    </svg>\n  );\n}\n\nfunction GoogleMark() {\n  return (\n    <svg aria-hidden viewBox=\"0 0 24 24\" fill=\"currentColor\">\n      <path d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09Z\" />\n      <path 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.84A11 11 0 0 0 12 23Z\" />\n      <path d=\"M5.84 14.1A6.6 6.6 0 0 1 5.5 12c0-.73.13-1.43.34-2.1V7.07H2.18A11 11 0 0 0 1 12c0 1.78.43 3.45 1.18 4.93l3.66-2.84Z\" />\n      <path d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1A11 11 0 0 0 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53Z\" />\n    </svg>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/blocks/auth-signup-card.tsx"
    }
  ],
  "categories": [
    "auth-sections"
  ],
  "type": "registry:block"
}