nusaiba
blockauth-4source: ok · hit
Auth 4
Two-column signup form in a centered layout — fast account creation above pricing.
npx shadcn add "https://nusaiba.dev/r/base-nova/auth-4.json"free
Where it goes
pricingsignup
Use cases
saas-landing
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Dependencies
Bundle weight · mediumanimationmotion
Registry dependencies
@nusaiba/foundationbuttoninputlabel
Files2 · source cached 10/11/2026, 12:39:20 PM
registry/blocks/auth/auth-data.ts
export const authSite = {
name: "Nusaiba",
domain: "nusaiba.dev",
namespace: "@nusaiba",
copyrightYear: 2026,
} as const;
export const authSignInCopy = {
eyebrow: "Welcome back",
title: "Sign in to Nusaiba",
description: "Access your registry token, Pro blocks, and account settings.",
submit: "Sign in",
forgot: "Forgot password?",
switchPrompt: "No account?",
switchAction: "Create one",
} as const;
export const authSignUpCopy = {
eyebrow: "Get started",
title: "Create your Nusaiba account",
description:
"Install motion blocks into your repo, unlock Pro registry access, and keep every file.",
submit: "Create account",
switchPrompt: "Already have an account?",
switchAction: "Sign in",
terms:
"By continuing, you agree to our Terms and acknowledge that blocks install into your own codebase.",
} as const;
export const authCenteredSignInCopy = {
eyebrow: "Account",
title: "Log in",
description: "Continue to your registry token, billing, and saved blocks.",
} as const;
export const authMagicLinkCopy = {
eyebrow: "Passwordless",
title: "Sign in with email",
description:
"We'll send a one-time link — no password to remember. Perfect for quick access before you install blocks.",
submit: "Send magic link",
hint: "Check your inbox at the address you used to purchase Pro.",
} as const;
export const authOAuthCopy = {
eyebrow: "Sign in",
title: "Choose how to continue",
description: "Use a provider or your work email — same account across CLI and site.",
divider: "or continue with email",
} as const;
export const authOtpCopy = {
eyebrow: "Verify",
title: "Enter the code",
description: "We sent a 6-digit code to your email. Paste it below to unlock Pro install.",
resend: "Resend code",
} as const;
export const authBenefitsCopy = {
eyebrow: "Why sign in",
title: "Ship landing pages faster",
description:
"One account for preview, purchase, and registry token — then install sections straight into your repo.",
} as const;
export const authBenefits = [
"Registry token for Pro block install",
"Copy Prompt history and CLI shortcuts",
"Commercial license for client projects",
"Lifetime updates on purchased blocks",
] as const;
export const authFramedCopy = {
eyebrow: "Registry access",
title: "Sign in to install",
description: "Preview blocks live, then add them to your landing page with one shadcn command.",
} as const;
export const authOAuthProviders = [
{ id: "github", label: "Continue with GitHub" },
{ id: "google", label: "Continue with Google" },
] as const;
export const authVisualCopy = {
eyebrow: "Install",
title: "Blocks that land in your repo",
description:
"Sign in to copy your registry token, unlock Pro sections, and keep full source ownership.",
} as const;
registry/blocks/auth/4/auth-section.tsx
"use client";
import Link from "next/link";
import { useRef } from "react";
import { motion, useInView, useReducedMotion } from "motion/react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { motionStagger, motionViewport } from "@/lib/motion-tokens";
import { cn } from "@/lib/utils";
import { authSignUpCopy } from "../auth-data";
import { SectionShell } from "@/components/layout-contract";
const spring = { type: "spring" as const, duration: 0.3, bounce: 0 };
export function AuthCenteredSignUpSection() {
const reduceMotion = useReducedMotion();
const ref = useRef<HTMLElement>(null);
const inView = useInView(ref, motionViewport);
const itemVariants = reduceMotion
? { hidden: { opacity: 1 }, visible: { opacity: 1 } }
: {
hidden: { opacity: 0, filter: "blur(4px)", y: 8 },
visible: { opacity: 1, filter: "blur(0px)", y: 0, transition: spring },
};
return (
<SectionShell spacingMode="section" ref={ref}>
<motion.div
animate={inView ? "visible" : "hidden"}
className="mx-auto w-full max-w-lg"
initial="hidden"
variants={{
hidden: {},
visible: { transition: { staggerChildren: motionStagger.item, delayChildren: 0.04 } },
}}
>
<motion.div className="text-center" variants={itemVariants}>
<p className="font-medium text-primary text-xs uppercase tracking-[0.22em]">
{authSignUpCopy.eyebrow}
</p>
<h1 className="mt-3 text-balance font-medium text-2xl tracking-tight md:text-3xl">
Start building your page
</h1>
<p className="mt-3 text-pretty text-muted-foreground text-sm">
Create an account to save your registry token and Pro license.
</p>
</motion.div>
<motion.form
className="mt-8 grid gap-4 sm:grid-cols-2"
variants={itemVariants}
>
<div className="space-y-2 sm:col-span-2">
<Label htmlFor="auth-4-name">Full name</Label>
<Input autoComplete="name" id="auth-4-name" placeholder="Alex Morgan" />
</div>
<div className="space-y-2">
<Label htmlFor="auth-4-email">Email</Label>
<Input
autoComplete="email"
id="auth-4-email"
placeholder="you@nusaiba.dev"
type="email"
/>
</div>
<div className="space-y-2">
<Label htmlFor="auth-4-password">Password</Label>
<Input
autoComplete="new-password"
id="auth-4-password"
placeholder="8+ characters"
type="password"
/>
</div>
<div className="sm:col-span-2">
<Button
className={cn("w-full active:scale-[0.96] transition-transform")}
type="button"
>
{authSignUpCopy.submit}
</Button>
</div>
</motion.form>
<motion.p
className="mt-4 text-pretty text-center text-muted-foreground text-xs"
variants={itemVariants}
>
{authSignUpCopy.terms}
</motion.p>
<motion.p className="mt-4 text-center text-muted-foreground text-sm" variants={itemVariants}>
{authSignUpCopy.switchPrompt}{" "}
<Link className="text-foreground underline-offset-4 hover:underline" href="#">
{authSignUpCopy.switchAction}
</Link>
</motion.p>
</motion.div>
</SectionShell>
);
}