Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions app/(auth)/sign-up/[[...sign-up]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,17 @@ import { resolveSignedInAppDestination } from '@/lib/public-auth-routing';
function getIntentCopy(intent: string | undefined) {
if (intent === 'pilot') {
return {
label: 'Start Free Pilot',
title: 'Create your account and start pilot onboarding',
label: 'Start 14-Day Pilot',
title: 'Create your account and start your 14-day pilot',
detail:
'This path is for a business owner creating a new CallbackCloser account. If you are already signed in, CallbackCloser will send you to onboarding, your dashboard, or the admin new-business flow based on your role.',
'Create your CallbackCloser account to start pilot setup, test the missed-call text flow, and confirm owner alerts before you go live.',
};
}

return {
label: 'Create Account',
title: 'Create your CallbackCloser account',
detail:
'Create a new owner account here. Founder-operated customer pilot setup is separate and stays inside the admin new-business flow.',
detail: 'Create your owner account to review the demo, pricing, and next steps for your business.',
};
}

Expand All @@ -46,7 +45,7 @@ export default async function SignUpPage({
<h1 className="text-3xl font-semibold tracking-tight">{copy.title}</h1>
<p className="text-muted-foreground">{copy.detail}</p>
<p className="text-sm text-muted-foreground">
Existing users should sign in. CallbackCloser operators setting up a customer pilot should use the admin new-business flow, not public signup.
Already have an account? Sign in to continue your setup.
</p>
</section>
<div className="flex justify-center lg:justify-end">
Expand Down Expand Up @@ -86,7 +85,7 @@ export default async function SignUpPage({
<h1 className="text-3xl font-semibold tracking-tight">{copy.title}</h1>
<p className="text-muted-foreground">{copy.detail}</p>
<p className="text-sm text-muted-foreground">
Existing users should sign in. CallbackCloser operators setting up a customer pilot should use the admin new-business flow, not public signup.
Already have an account? Sign in to continue your setup.
</p>
</section>
<div className="flex justify-center lg:justify-end">
Expand Down
56 changes: 30 additions & 26 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ const planTeasers = [
];

const onboardingSteps = [
'We provision your business texting line and connect routing so missed callers are covered fast.',
'We confirm the first text and lead questions before live traffic starts.',
'We verify owner notifications and run a missed-call test with you before go-live.',
'We set up your business texting line and missed-call follow-up so you can see the full flow clearly.',
'We test the first text, lead questions, and handoff details with you before real callers rely on it.',
'We confirm owner alerts and run a missed-call practice test before you go live.',
];

export default function LandingPage() {
Expand All @@ -147,12 +147,9 @@ export default function LandingPage() {
</div>
<div className="flex flex-wrap gap-3">
<Link className={buttonVariants({ size: 'lg' })} href={PUBLIC_START_FREE_PILOT_PATH}>
Start Free Pilot
Start 14-Day Pilot
</Link>
<Link className={buttonVariants({ size: 'lg', variant: 'outline' })} href={PUBLIC_CREATE_ACCOUNT_PATH}>
Create Account
</Link>
<Link className={buttonVariants({ size: 'lg', variant: 'ghost' })} href="/demo">
<Link className={buttonVariants({ size: 'lg', variant: 'outline' })} href="/demo">
See Demo
</Link>
</div>
Expand All @@ -164,8 +161,14 @@ export default function LandingPage() {
</div>
<p className="text-base font-medium text-foreground">Close one extra job and this can pay for itself.</p>
<p className="max-w-2xl text-sm text-muted-foreground">
Start Free Pilot creates a new account or takes an existing user to the right next step automatically.
Founder-operated customer pilot setup stays separate in the admin new-business flow.
Start a hands-on pilot and we&apos;ll help you get set up, test the missed-call text flow, and confirm owner
alerts before you go live.
</p>
<p className="text-sm text-muted-foreground">
Need a new owner login first?{' '}
<Link className="font-medium text-foreground underline underline-offset-4" href={PUBLIC_CREATE_ACCOUNT_PATH}>
Create account
</Link>
</p>
</div>

Expand Down Expand Up @@ -226,7 +229,7 @@ export default function LandingPage() {
Open the public demo to show the missed-call follow-up, owner alert, and dashboard handoff without login or setup.
</p>
<Link className={buttonVariants({ className: 'mt-4' })} href="/demo">
Open public demo
See Demo
</Link>
</div>
</CardContent>
Expand Down Expand Up @@ -285,8 +288,8 @@ export default function LandingPage() {
<Badge variant="outline">Trust and proof</Badge>
<h2 className="text-3xl font-semibold tracking-tight">Proof that missed calls can still turn into paying work</h2>
<p className="text-muted-foreground">
The public site should make the operational value obvious: faster response, cleaner handoff, and trust pages that are
easy to verify before a business ever goes live.
CallbackCloser helps you reply faster, qualify the lead before you call back, and keep the setup clear before you put
it in front of real customers.
</p>
</div>

Expand All @@ -304,8 +307,8 @@ export default function LandingPage() {

<Card className="border-primary/20 bg-gradient-to-r from-card via-card to-primary/5">
<CardHeader>
<CardTitle>White-glove pilot onboarding</CardTitle>
<CardDescription>Hands-on setup so your missed calls are covered fast and the first test goes cleanly.</CardDescription>
<CardTitle>14-Day Pilot</CardTitle>
<CardDescription>Try CallbackCloser with hands-on setup before you rely on it with real customers.</CardDescription>
</CardHeader>
<CardContent className="grid gap-4 lg:grid-cols-[1.1fr_0.9fr]">
<div className="space-y-3 text-sm text-muted-foreground">
Expand All @@ -317,18 +320,18 @@ export default function LandingPage() {
</div>
))}
<p>
We help you get live fast, cover the missed-call gap, and confirm the first real handoff before your team depends on it.
We help you test missed-call texting, owner alerts, and lead handoff before your team depends on it every day.
</p>
</div>
<div className="rounded-2xl border bg-background/80 p-5 text-sm text-muted-foreground">
<p className="text-xs uppercase tracking-[0.2em] text-muted-foreground">Launch standard</p>
<p className="text-xs uppercase tracking-[0.2em] text-muted-foreground">What the pilot covers</p>
<p className="mt-3 text-lg font-medium text-foreground">
Every rollout is built to give the business a managed texting line, visible trust pages, and a clean first test call.
A short pilot is the fastest way to confirm the system fits your team before you rely on it with real customers.
</p>
<div className="mt-4 space-y-2">
<p>- One business texting number is included in the base service.</p>
<p>- SMS Consent, Privacy Policy, Refund, and Terms &amp; Conditions pages stay public before activation.</p>
<p>- Missed-call texting and lead questions are tested with you.</p>
<p>- Owner alerts and callback summaries are verified before launch.</p>
<p>- Trust pages stay visible before activation.</p>
</div>
</div>
</CardContent>
Expand Down Expand Up @@ -375,7 +378,7 @@ export default function LandingPage() {
<Card className="bg-card/90">
<CardHeader>
<CardTitle>Simple plan choices</CardTitle>
<CardDescription>Visitors should understand the offer in under 20 seconds.</CardDescription>
<CardDescription>Pick the setup that matches your call volume, team size, and rollout pace.</CardDescription>
</CardHeader>
<CardContent className="grid gap-3 text-sm text-muted-foreground">
{planTeasers.map((plan) => (
Expand All @@ -386,24 +389,25 @@ export default function LandingPage() {
))}
<div className="pt-2">
<Link className={buttonVariants({ variant: 'outline' })} href="/pricing">
Start capturing missed leads
See pricing
</Link>
</div>
</CardContent>
</Card>

<Card className="bg-card/90">
<CardHeader>
<CardTitle>Compliance stays visible</CardTitle>
<CardDescription>Trust language remains present without dominating the pitch.</CardDescription>
<CardTitle>Trust stays visible</CardTitle>
<CardDescription>Review the details before you start your pilot or turn it on for customers.</CardDescription>
</CardHeader>
<CardContent className="space-y-3 text-sm text-muted-foreground">
<p>
CallbackCloser keeps pricing, refund, Privacy Policy, Terms &amp; Conditions, contact, and SMS Consent pages visible
before a business ever starts a pilot.
before your business starts a pilot.
</p>
<p>
STOP, START, and HELP support remain part of the product flow, and the public consent page still explains message frequency and message/data rates.
Your customers can also see clear SMS consent language, including STOP, START, HELP, message frequency, and
message/data rates.
</p>
<div className="flex flex-wrap gap-3 pt-2">
<Link className={buttonVariants({ size: 'sm' })} href="/sms-consent">
Expand Down
2 changes: 1 addition & 1 deletion components/public-site-footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { PUBLIC_CREATE_ACCOUNT_PATH, PUBLIC_SIGN_IN_PATH, PUBLIC_START_FREE_PILO

const footerLinks = [
{ href: PUBLIC_CREATE_ACCOUNT_PATH, label: 'Create account' },
{ href: PUBLIC_START_FREE_PILOT_PATH, label: 'Start Free Pilot' },
{ href: PUBLIC_START_FREE_PILOT_PATH, label: 'Start 14-Day Pilot' },
{ href: PUBLIC_SIGN_IN_PATH, label: 'Sign in' },
{ href: '/pricing', label: 'Pricing' },
{ href: '/demo', label: 'Missed-Call Demo' },
Expand Down
4 changes: 2 additions & 2 deletions components/public-site-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ export function PublicSiteNav() {
<Link className={buttonVariants({ size: 'sm', variant: 'ghost' })} href={PUBLIC_SIGN_IN_PATH}>
Sign in
</Link>
<Link className={buttonVariants({ size: 'sm', variant: 'outline' })} href={PUBLIC_CREATE_ACCOUNT_PATH}>
<Link className="text-sm text-muted-foreground transition-colors hover:text-foreground" href={PUBLIC_CREATE_ACCOUNT_PATH}>
Create account
</Link>
<Link className={buttonVariants({ size: 'sm' })} href={PUBLIC_START_FREE_PILOT_PATH}>
Start Free Pilot
Start 14-Day Pilot
</Link>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions tests/public-auth-routing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ test('clerk auth surfaces use explicit path routing and fallback redirects', ()
assert.match(signUpPage, /routing="path"/);
assert.match(signUpPage, /fallbackRedirectUrl=\{DEFAULT_CLERK_AFTER_AUTH_URL\}/);
assert.match(signUpPage, /<SignUp/);
assert.match(signUpPage, /Create your account and start pilot onboarding/);
assert.match(signUpPage, /Create your account and start your 14-day pilot/);
assert.match(signUpPage, /path=\{DEFAULT_CLERK_SIGN_UP_URL\}/);
assert.match(signUpPage, /signInUrl=\{DEFAULT_CLERK_SIGN_IN_URL\}/);
assert.match(signUpPage, /hasRequiredValidClerkEnv/);
assert.match(signUpPage, /Authentication is temporarily unavailable\./);
assert.match(signUpPage, /resolveSignedInAppDestination/);
assert.match(signUpPage, /Founder-operated customer pilot setup is separate/i);
assert.match(signUpPage, /Already have an account\? Sign in to continue your setup\./);
assert.match(pilotEntryPage, /resolvePublicPilotDestination/);
});

Expand Down
Loading