{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "auth-2",
  "title": "Split Sign-In With Brand Panel",
  "description": "Two-column sign-in pairing a dark brand panel that lists product features with a plain email and password form, no social login buttons.",
  "dependencies": [
    "zod",
    "@base-ui/react"
  ],
  "registryDependencies": [
    "button",
    "checkbox",
    "field",
    "input",
    "sonner"
  ],
  "files": [
    {
      "path": "registry/blocks/auth/2/auth-block.tsx",
      "content": "\"use client\"\n\nimport { useState } from \"react\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n  Field,\n  FieldDescription,\n  FieldError,\n  FieldGroup,\n  FieldLabel,\n} from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport { Toaster } from \"@/components/ui/sonner\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\n\nconst BRAND = \"Acme\"\nconst TAGLINE = \"Collaborative work, simplified.\"\nconst FEATURES = [\n  \"Real-time project dashboards\",\n  \"Role-based access control\",\n  \"Audit logs & compliance reports\",\n]\n\nconst signInSchema = z.object({\n  email: z\n    .string()\n    .min(1, \"Email is required\")\n    .email(\"Enter a valid email address\"),\n  password: z.string().min(8, \"Password must be at least 8 characters\"),\n})\n\nexport default function AuthBlock() {\n  const [errors, setErrors] = useState<Record<string, string>>({})\n\n  function handleSubmit(event: React.FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n    const data = Object.fromEntries(new FormData(event.currentTarget))\n    const result = signInSchema.safeParse(data)\n    if (!result.success) {\n      const next: Record<string, string> = {}\n      for (const issue of result.error.issues) {\n        const key = issue.path[0]\n        if (typeof key === \"string\" && !next[key]) {\n          next[key] = issue.message\n        }\n      }\n      setErrors(next)\n      return\n    }\n    setErrors({})\n    toast.promise(new Promise((resolve) => setTimeout(resolve, 1400)), {\n      loading: \"Signing you in…\",\n      success: \"Welcome back to Acme!\",\n      error: \"Sign-in failed. Please try again.\",\n    })\n  }\n\n  function clearError(name: string) {\n    setErrors((prev) => {\n      if (!prev[name]) return prev\n      const next = { ...prev }\n      delete next[name]\n      return next\n    })\n  }\n\n  return (\n    <section className=\"flex w-full items-center justify-center bg-background text-foreground\">\n      <Toaster />\n      <div className=\"flex w-full max-w-4xl flex-col overflow-hidden rounded-xl md:flex-row\">\n        <div className=\"dark flex flex-col justify-between gap-10 bg-background px-10 py-12 text-foreground md:w-1/2\">\n          <div>\n            <span className=\"text-xl font-bold tracking-tight\">{BRAND}</span>\n          </div>\n          <div className=\"flex flex-col gap-6\">\n            <p className=\"font-heading text-3xl leading-tight font-bold tracking-tight\">\n              {TAGLINE}\n            </p>\n            <ul className=\"flex flex-col gap-3\">\n              {FEATURES.map((f) => (\n                <li\n                  key={f}\n                  className=\"flex items-center gap-3 text-sm text-foreground/80\"\n                >\n                  <span className=\"flex size-5 shrink-0 items-center justify-center rounded-md border border-foreground/30 bg-foreground/10 text-foreground\">\n                    <IconPlaceholder\n                      lucide=\"Check\"\n                      tabler=\"IconCheck\"\n                      hugeicons=\"Tick02Icon\"\n                      phosphor=\"Check\"\n                      remixicon=\"RiCheckLine\"\n                      className=\"size-3.5\"\n                      aria-hidden=\"true\"\n                    />\n                  </span>\n                  {f}\n                </li>\n              ))}\n            </ul>\n          </div>\n          <p className=\"text-xs text-foreground/50\">\n            © <span suppressHydrationWarning>{new Date().getFullYear()}</span>{\" \"}\n            {BRAND} Inc. All rights reserved.\n          </p>\n        </div>\n\n        <div className=\"flex flex-col justify-center gap-8 border border-border bg-card px-10 py-12 md:w-1/2\">\n          <div className=\"flex flex-col gap-1\">\n            <h1 className=\"font-heading text-xl font-bold tracking-tight\">\n              Sign in\n            </h1>\n            <p className=\"text-sm text-muted-foreground\">\n              Enter your credentials to access your workspace.\n            </p>\n          </div>\n\n          <form\n            className=\"flex flex-col gap-6\"\n            onSubmit={handleSubmit}\n            noValidate\n          >\n            <FieldGroup>\n              <Field>\n                <FieldLabel htmlFor=\"email\">Email address</FieldLabel>\n                <div className=\"relative\">\n                  <IconPlaceholder\n                    lucide=\"Mail\"\n                    tabler=\"IconMail\"\n                    hugeicons=\"MailIcon\"\n                    phosphor=\"Envelope\"\n                    remixicon=\"RiMailLine\"\n                    className=\"pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-muted-foreground\"\n                    aria-hidden=\"true\"\n                  />\n                  <Input\n                    id=\"email\"\n                    name=\"email\"\n                    type=\"email\"\n                    placeholder=\"name@company.com\"\n                    className=\"pl-8\"\n                    autoComplete=\"email\"\n                    aria-invalid={!!errors.email}\n                    onChange={() => clearError(\"email\")}\n                  />\n                </div>\n                <FieldError>{errors.email}</FieldError>\n              </Field>\n\n              <Field>\n                <div className=\"flex items-center justify-between\">\n                  <FieldLabel htmlFor=\"password\">Password</FieldLabel>\n                  <Button\n                    variant=\"link\"\n                    size=\"xs\"\n                    className=\"h-auto p-0 text-xs\"\n                    render={<a href=\"#\" />}\n                    nativeButton={false}\n                  >\n                    Forgot Password?\n                  </Button>\n                </div>\n                <div className=\"relative\">\n                  <IconPlaceholder\n                    lucide=\"Lock\"\n                    tabler=\"IconLockPassword\"\n                    hugeicons=\"LockPasswordIcon\"\n                    phosphor=\"Lock\"\n                    remixicon=\"RiLockPasswordLine\"\n                    className=\"pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-muted-foreground\"\n                    aria-hidden=\"true\"\n                  />\n                  <Input\n                    id=\"password\"\n                    name=\"password\"\n                    type=\"password\"\n                    placeholder=\"••••••••\"\n                    className=\"pl-8\"\n                    autoComplete=\"current-password\"\n                    aria-invalid={!!errors.password}\n                    onChange={() => clearError(\"password\")}\n                  />\n                </div>\n                {errors.password ? (\n                  <FieldError>{errors.password}</FieldError>\n                ) : (\n                  <FieldDescription>\n                    Must be at least 8 characters.\n                  </FieldDescription>\n                )}\n              </Field>\n\n              <Field orientation=\"horizontal\">\n                <FieldLabel\n                  htmlFor=\"remember\"\n                  className=\"font-normal text-muted-foreground\"\n                >\n                  <Checkbox id=\"remember\" name=\"remember\" />\n                  Keep me signed in\n                </FieldLabel>\n              </Field>\n            </FieldGroup>\n\n            <Button type=\"submit\" className=\"w-full\" size=\"lg\">\n              Sign In\n            </Button>\n          </form>\n\n          <p className=\"text-center text-xs text-muted-foreground\">\n            By signing in you agree to our{\" \"}\n            <Button\n              variant=\"link\"\n              className=\"h-auto p-0 text-xs\"\n              render={<a href=\"#\" />}\n              nativeButton={false}\n            >\n              Terms of Service\n            </Button>{\" \"}\n            and{\" \"}\n            <Button\n              variant=\"link\"\n              className=\"h-auto p-0 text-xs\"\n              render={<a href=\"#\" />}\n              nativeButton={false}\n            >\n              Privacy Policy\n            </Button>\n            .\n          </p>\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "meta": {
    "height": "510px",
    "tier": "free"
  },
  "docs": "Requires a `base-*` style in components.json (the `shadcn init` default). Legacy `new-york`/`radix-*` styles install Radix primitives, which reject the `render` prop this block uses.",
  "categories": [
    "auth"
  ],
  "type": "registry:block"
}