-
+
Password
setPassword(e.target.value)}
required
- className="border-slate-700 bg-slate-800 text-white placeholder:text-slate-500 focus-visible:border-primary focus-visible:ring-primary/20"
+ className="border-border bg-muted text-foreground placeholder:text-muted-foreground focus-visible:border-primary focus-visible:ring-primary/20"
/>
@@ -141,7 +141,7 @@ function LoginPageInner() {
-
+
Don't have an account?{" "}
-
+
+
-
+
Check your email
-
+
We've sent a confirmation link to{" "}
- {email} . Please check your
+ {email} . Please check your
inbox and click the link to verify your account.
@@ -116,7 +116,7 @@ function SignupPageInner() {
>
Back to sign in
@@ -128,8 +128,8 @@ function SignupPageInner() {
}
return (
-
-
+
+
{inviteToken ? (
@@ -138,10 +138,10 @@ function SignupPageInner() {
)}
-
+
{inviteToken ? "Create account & join" : "Create account"}
-
+
{inviteToken
? "Verify your email, then accept the invitation to join your team."
: "Get started with CRM Template for WhatsApp"}
@@ -156,7 +156,7 @@ function SignupPageInner() {
)}
-
+
Full name
setFullName(e.target.value)}
required
- className="border-slate-700 bg-slate-800 text-white placeholder:text-slate-500 focus-visible:border-primary focus-visible:ring-primary/20"
+ className="border-border bg-muted text-foreground placeholder:text-muted-foreground focus-visible:border-primary focus-visible:ring-primary/20"
/>
-
+
Email
setEmail(e.target.value)}
required
- className="border-slate-700 bg-slate-800 text-white placeholder:text-slate-500 focus-visible:border-primary focus-visible:ring-primary/20"
+ className="border-border bg-muted text-foreground placeholder:text-muted-foreground focus-visible:border-primary focus-visible:ring-primary/20"
/>
-
+
Password
setPassword(e.target.value)}
required
- className="border-slate-700 bg-slate-800 text-white placeholder:text-slate-500 focus-visible:border-primary focus-visible:ring-primary/20"
+ className="border-border bg-muted text-foreground placeholder:text-muted-foreground focus-visible:border-primary focus-visible:ring-primary/20"
/>
-
+
Confirm password
setConfirmPassword(e.target.value)}
required
- className="border-slate-700 bg-slate-800 text-white placeholder:text-slate-500 focus-visible:border-primary focus-visible:ring-primary/20"
+ className="border-border bg-muted text-foreground placeholder:text-muted-foreground focus-visible:border-primary focus-visible:ring-primary/20"
/>
@@ -224,7 +224,7 @@ function SignupPageInner() {
-
+
Already have an account?{" "}
router.push("/automations")}
- className="flex h-8 w-8 items-center justify-center rounded-md text-slate-400 transition-colors hover:bg-slate-800 hover:text-white"
+ className="flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
aria-label="Back"
>
-
{automation.name}
-
Execution logs
+
{automation.name}
+
Execution logs
{logs.length === 0 ? (
-
-
No executions yet
-
+
+
No executions yet
+
Trigger this automation to see runs here.
@@ -112,7 +112,7 @@ export default function AutomationLogsPage({
return (
{isOpen ? (
-
+
) : (
-
+
)}
-
+
{log.contact?.name ?? log.contact?.phone ?? "Unknown contact"}
-
+
{log.trigger_event} · {log.steps_executed?.length ?? 0} step
{log.steps_executed?.length === 1 ? "" : "s"}
-
+
{formatRelative(log.created_at)}
{isOpen && (
-
+
{log.error_message && (
{log.error_message}
@@ -150,7 +150,7 @@ export default function AutomationLogsPage({
))}
{(log.steps_executed ?? []).length === 0 && (
-
No steps recorded.
+
No steps recorded.
)}
@@ -196,9 +196,9 @@ function StepRow({ result }: { result: AutomationLogStepResult }) {
>
{ok ?
:
}
-
{result.step_type}
+
{result.step_type}
{result.detail && (
-
— {result.detail}
+
— {result.detail}
)}
)
diff --git a/src/app/(dashboard)/automations/page.tsx b/src/app/(dashboard)/automations/page.tsx
index ac5eaad..28760ae 100644
--- a/src/app/(dashboard)/automations/page.tsx
+++ b/src/app/(dashboard)/automations/page.tsx
@@ -160,8 +160,8 @@ export default function AutomationsPage() {
-
Automations
-
+
Automations
+
Build workflows that react to WhatsApp® events automatically.
@@ -178,7 +178,7 @@ export default function AutomationsPage() {
{showTemplates && (
- Quick-start templates
+ Quick-start templates
{TEMPLATE_ORDER.map((slug) => {
const t = AUTOMATION_TEMPLATES[slug]
@@ -187,13 +187,13 @@ export default function AutomationsPage() {
startFromTemplate(slug)}
- className="group flex flex-col items-start rounded-xl border border-slate-800 bg-slate-900 p-4 text-left transition-colors hover:border-primary/50 hover:bg-slate-900/80"
+ className="group flex flex-col items-start rounded-xl border border-border bg-card p-4 text-left transition-colors hover:border-primary/50 hover:bg-card/80"
>
- {t.name}
- {t.description}
+ {t.name}
+ {t.description}
)
})}
@@ -202,12 +202,12 @@ export default function AutomationsPage() {
)}
{automations.length === 0 ? (
-
+
-
No automations yet
-
+
No automations yet
+
Pick a template above or create one from scratch.
@@ -233,7 +233,7 @@ export default function AutomationsPage() {
Delete automation
This permanently removes{" "}
- {pendingDelete?.name} and its execution
+ {pendingDelete?.name} and its execution
history. This cannot be undone.
@@ -277,7 +277,7 @@ function AutomationCard({
}) {
const meta = triggerMeta(automation.trigger_type)
return (
-
+
-
+
{automation.name}
{automation.is_active && (
@@ -303,9 +303,9 @@ function AutomationCard({
)}
{automation.description && (
-
{automation.description}
+
{automation.description}
)}
-
+
diff --git a/src/app/(dashboard)/broadcasts/[id]/page.tsx b/src/app/(dashboard)/broadcasts/[id]/page.tsx
index 7511806..7449d51 100644
--- a/src/app/(dashboard)/broadcasts/[id]/page.tsx
+++ b/src/app/(dashboard)/broadcasts/[id]/page.tsx
@@ -50,15 +50,15 @@ interface StatCardProps {
function StatCard({ label, value, total, icon, color }: StatCardProps) {
const pct = total > 0 ? Math.round((value / total) * 100) : 0;
return (
-
+
-
{value.toLocaleString()}
-
{label}
+
{value.toLocaleString()}
+
{label}
);
}
@@ -77,8 +77,8 @@ interface FunnelStep {
function FunnelChart({ steps }: { steps: FunnelStep[] }) {
const max = Math.max(...steps.map((s) => s.value), 1);
return (
-
-
Funnel
+
+
Funnel
{steps.map((step) => {
const pctOfMax = Math.max(5, Math.round((step.value / max) * 100));
@@ -88,17 +88,17 @@ function FunnelChart({ steps }: { steps: FunnelStep[] }) {
: 0;
return (
-
+
{step.label}
-
+
-
+
{step.value.toLocaleString()}
-
+
({pctOfSent}%)
@@ -280,20 +280,20 @@ export default function BroadcastDetailPage() {
variant="outline"
size="icon"
onClick={() => router.push('/broadcasts')}
- className="border-slate-700"
+ className="border-border"
>
-
{broadcast.name}
+ {broadcast.name}
{status.label}
-
+
Template: {broadcast.template_name}
-
@@ -315,7 +315,7 @@ export default function BroadcastDetailPage() {
size="sm"
onClick={() => setConfirmDelete(false)}
disabled={deleting}
- className="h-7 border-slate-700 bg-transparent text-slate-300 hover:bg-slate-800"
+ className="h-7 border-border bg-transparent text-muted-foreground hover:bg-muted"
>
Cancel
@@ -354,7 +354,7 @@ export default function BroadcastDetailPage() {
value={broadcast.total_recipients}
total={broadcast.total_recipients}
icon={ }
- color="bg-slate-800 text-slate-300"
+ color="bg-muted text-muted-foreground"
/>
{/* Recipients Table */}
-
-
-
+
+
+
Recipients ({filteredRecipients.length}
{statusFilter !== 'all' ? ` of ${recipients.length}` : ''})
@@ -409,7 +409,7 @@ export default function BroadcastDetailPage() {
}
>
@@ -419,11 +419,11 @@ export default function BroadcastDetailPage() {
: getRecipientStatus(statusFilter).label}
-
+
setStatusFilter('all')}
className={
- statusFilter === 'all' ? 'text-primary' : 'text-slate-300'
+ statusFilter === 'all' ? 'text-primary' : 'text-popover-foreground'
}
>
All statuses
@@ -435,7 +435,7 @@ export default function BroadcastDetailPage() {
className={
statusFilter === s
? 'text-primary'
- : 'text-slate-300'
+ : 'text-popover-foreground'
}
>
{getRecipientStatus(s).label}
@@ -449,7 +449,7 @@ export default function BroadcastDetailPage() {
size="sm"
onClick={handleExport}
disabled={recipients.length === 0}
- className="border-slate-700 text-slate-300 hover:bg-slate-800"
+ className="border-border text-muted-foreground hover:bg-muted"
>
Export CSV
@@ -459,7 +459,7 @@ export default function BroadcastDetailPage() {
{filteredRecipients.length === 0 ? (
-
+
{recipients.length === 0
? 'No recipients found.'
: 'No recipients match this filter.'}
@@ -469,25 +469,25 @@ export default function BroadcastDetailPage() {
-
- Contact
- Phone
- Status
- Sent
- Delivered
- Read
- Error
+
+ Contact
+ Phone
+ Status
+ Sent
+ Delivered
+ Read
+ Error
{filteredRecipients.map((recipient) => {
const rStatus = getRecipientStatus(recipient.status);
return (
-
-
+
+
{recipient.contact?.name ?? 'Unknown'}
-
+
{recipient.contact?.phone ?? '-'}
@@ -497,17 +497,17 @@ export default function BroadcastDetailPage() {
{rStatus.label}
-
+
{recipient.sent_at
? new Date(recipient.sent_at).toLocaleString()
: '-'}
-
+
{recipient.delivered_at
? new Date(recipient.delivered_at).toLocaleString()
: '-'}
-
+
{recipient.read_at
? new Date(recipient.read_at).toLocaleString()
: '-'}
diff --git a/src/app/(dashboard)/broadcasts/new/page.tsx b/src/app/(dashboard)/broadcasts/new/page.tsx
index 9763620..bcbbb57 100644
--- a/src/app/(dashboard)/broadcasts/new/page.tsx
+++ b/src/app/(dashboard)/broadcasts/new/page.tsx
@@ -129,8 +129,8 @@ export default function NewBroadcastPage() {
{/* Header */}
-
New Broadcast
-
+
New Broadcast
+
Create and send a broadcast message to your contacts.
@@ -150,14 +150,14 @@ export default function NewBroadcastPage() {
? 'bg-primary text-primary-foreground'
: isActive
? 'border-2 border-primary bg-primary/10 text-primary'
- : 'border border-slate-700 bg-slate-800 text-slate-500'
+ : 'border border-border bg-muted text-muted-foreground'
}`}
>
{isCompleted ?
: index + 1}
{step.label}
@@ -166,7 +166,7 @@ export default function NewBroadcastPage() {
{index < steps.length - 1 && (
)}
diff --git a/src/app/(dashboard)/broadcasts/page.tsx b/src/app/(dashboard)/broadcasts/page.tsx
index 2583dd2..986000e 100644
--- a/src/app/(dashboard)/broadcasts/page.tsx
+++ b/src/app/(dashboard)/broadcasts/page.tsx
@@ -43,10 +43,10 @@ function RateCell({
const pct = percent(value, total);
return (