Brand gradient panel with a customer testimonial beside the create-account form.
Create your Cronus workspace.
Already have an account? Sign in
“Cronus replaced four tools on day one — and our checkout conversion is up 23%.”
Install with the CLI, or add the packages and paste the source below.
Add Sign Up to your app with its source-owned dependencies.
npx cronus-ui add signup
Install the Cronus UI packages, then paste the block below.
Copy the source for Split panel. Every class is a semantic token, so it re-themes with your app.
"use client";import { Avatar, AvatarFallback, Button, Checkbox, Input, Label } from "@cronus-ui/ui";import { signUpEmail } from "../lib/auth-adapter.js";import { ChartColumnIncreasing, Quote } from "lucide-react";import { type FormEvent, useEffect, useState } from "react";const INVITE_STORAGE_KEY = "cronus-invitation";function readSignupInvitation(): boolean {if (typeof window === "undefined") return false;try {const fromUrl = new URLSearchParams(window.location.search).get("invitation");if (fromUrl) {sessionStorage.setItem(INVITE_STORAGE_KEY, fromUrl);return true;}return Boolean(sessionStorage.getItem(INVITE_STORAGE_KEY));} catch {return false;}}export function SignupSplitBlock() {const [pending, setPending] = useState(false);const [error, setError] = useState<string | null>(null);const [joining, setJoining] = useState(false);useEffect(() => {setJoining(readSignupInvitation());}, []);async function onSubmit(event: FormEvent<HTMLFormElement>) {event.preventDefault();const form = new FormData(event.currentTarget);const name = String(form.get("name") ?? "");const email = String(form.get("email") ?? "");const password = String(form.get("password") ?? "");setError(null);setPending(true);try {await signUpEmail({ email, password, name });} catch (err) {setError(err instanceof Error ? err.message : "Something went wrong.");} finally {setPending(false);}}return (<div className="flex w-full items-center justify-center py-4"><div className="grid w-full max-w-4xl overflow-hidden rounded-2xl border border-border bg-surface-raised shadow-lg lg:grid-cols-2">{/* Create-account form */}<div className="flex flex-col justify-center gap-6 p-8 sm:p-10 lg:order-2"><div className="flex flex-col gap-1"><h2 className="font-display text-xl font-semibold text-fg">{joining ? "Join the workspace" : "Create your account"}</h2><p className="text-sm text-fg-secondary">{joining? "Create your account to accept the invitation.": "Create your Cronus workspace."}</p></div><form onSubmit={onSubmit} className="flex flex-col gap-4" aria-busy={pending}><div className="flex flex-col gap-2"><Label htmlFor="signup-split-name">Full name</Label><Inputid="signup-split-name"name="name"placeholder="Ada Lovelace"autoComplete="name"/></div><div className="flex flex-col gap-2"><Label htmlFor="signup-split-email">Email</Label><Inputid="signup-split-email"name="email"type="email"placeholder="you@company.com"autoComplete="email"/></div><div className="flex flex-col gap-2"><Label htmlFor="signup-split-password">Password</Label><Inputid="signup-split-password"name="password"type="password"placeholder="••••••••"autoComplete="new-password"/><p className="text-xs text-fg-tertiary">Must be at least 8 characters.</p></div><LabelhtmlFor="signup-split-terms"className="flex items-start gap-2 font-normal text-fg-secondary"><Checkbox id="signup-split-terms" defaultChecked />I agree to the Terms and PrivacyPolicy.</Label>{error ? (<p role="alert" className="text-sm text-error-strong">{error}</p>) : null}<Buttontype="submit"variant="primary"size="lg"className="w-full"disabled={pending}aria-busy={pending}>{pending? joining? "Joining…": "Creating account…": joining? "Join workspace": "Create account"}</Button></form><p className="text-sm text-fg-secondary">Already have an account?{" "}<ahref="/login"className="font-medium text-primary-strong underline-offset-4 hover:underline">Sign in</a></p></div>{/* Brand panel */}<div className="relative overflow-hidden bg-gradient-primary-strong p-8 sm:p-10 lg:order-1"><divaria-hidden="true"className="pointer-events-none absolute inset-0 bg-gradient-aurora opacity-20 blur-3xl"/><div className="relative flex h-full flex-col justify-between gap-12"><div className="flex items-center gap-2.5"><span className="inline-flex size-9 items-center justify-center rounded-xl bg-primary-foreground/15 text-primary-foreground"><ChartColumnIncreasing className="size-4" aria-hidden="true" /></span><span className="font-display text-lg font-semibold text-primary-foreground">Cronus</span></div><figure className="flex flex-col gap-5"><Quote className="size-7 text-primary-foreground/50" aria-hidden="true" /><blockquote className="font-display text-xl font-medium leading-snug text-primary-foreground">“Cronus replaced four tools on day one — and our checkout conversion is up 23%.”</blockquote><figcaption className="flex items-center gap-3"><Avatar><AvatarFallback>DR</AvatarFallback></Avatar><div className="flex flex-col"><span className="text-sm font-medium text-primary-foreground">Dana Reyes</span><span className="text-sm text-primary-foreground/75">Head of Growth, Northwind Labs</span></div></figcaption></figure></div></div></div></div>);}
Create your Cronus workspace.
Already have an account? Sign in
“Cronus replaced four tools on day one — and our checkout conversion is up 23%.”