+ Set up {BRAND.name} with a clean privacy line.
+
+
+ The first admin keeps the app healthy. The first user owns the money data. Those roles stay separate from the start.
+
+
+
+
+
+ Create accounts, reset passwords, notification plumbing, and login mode settings.
+
+
+ Admin tools do not expose bills, payments, spending history, or personal settings.
+
+
+ A restrained setup flow that matches the tracker, settings, and security surfaces.
+
+
+
+
+
+
+ {[0, 1].map(i => (
+
+ ))}
+
{step === 0 && (
-
+
- Welcome, Administrator
-
- Before creating your first user, please understand what your admin account can and cannot do.
-
+
+
+
+ Welcome, Administrator
+
+ Before creating your first user, review the admin boundary.
+
+
+
@@ -78,8 +132,8 @@ export default function OnboardingWizard({ onComplete }: { onComplete: () => voi
{ can: false, text: 'Cannot access user settings or history' },
].map(({ can, text }) => (
-
- {can ? '✓' : '✗'}
+
+ {can ? : }
{text}
@@ -87,7 +141,7 @@ export default function OnboardingWizard({ onComplete }: { onComplete: () => voi
@@ -96,12 +150,17 @@ export default function OnboardingWizard({ onComplete }: { onComplete: () => voi
)}
{step === 1 && (
-
+
- Create first user
-
- This account will be used to access the bill tracker.
-
+
+
+
+ Create first user
+
+ This account will own the tracker, bills, and personal settings.
+
+
+
+
+
+ Use a strong password now. The account can add two-factor authentication after first sign-in.
+
)}
+
);
diff --git a/client/pages/LoginPage.tsx b/client/pages/LoginPage.tsx
index bd7ed5a..c01a87a 100644
--- a/client/pages/LoginPage.tsx
+++ b/client/pages/LoginPage.tsx
@@ -1,5 +1,6 @@
-import { useState, useEffect } from 'react';
+import { useState, useEffect, type ComponentType, type ReactNode } from 'react';
import { Link, useNavigate, useLocation } from 'react-router-dom';
+import { Gauge, KeyRound, LockKeyhole, ShieldCheck } from 'lucide-react';
import { toast } from 'sonner';
import { api } from '@/api';
import { errMessage } from '@/lib/utils';
@@ -9,7 +10,7 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { APP_VERSION } from '@/lib/version';
import { BRAND } from '@/lib/brand';
-import { BrandMark } from '@/components/brand/Brand';
+import { BrandGlyph, BrandMark } from '@/components/brand/Brand';
import {
Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter,
} from '@/components/ui/dialog';
@@ -28,6 +29,28 @@ const LANDING_ROUTES: Record = {
tracker: '/', calendar: '/calendar', summary: '/summary', spending: '/spending',
};
+function TrustItem({
+ icon: Icon,
+ title,
+ children,
+}: {
+ icon: ComponentType<{ className?: string }>;
+ title: string;
+ children: ReactNode;
+}) {
+ return (
+
+ {BRAND.tagline} Built for fast bill scanning, clear household decisions, and private defaults.
+
+
-
+
+
+ Admins can manage access, but they cannot inspect personal bills or spending history.
+
+
+ Dense tracker views, tabular money, and calm status cues stay front and center.
+
+
+ Local login, SSO, and two-factor flows share one clean entry point.
+
+
+
+
+
+
{/* Logo / Brand */}
-
+
{BRAND.tagline}
@@ -208,11 +254,14 @@ export default function LoginPage() {
{/* TOTP step — shown after password is accepted */}
{totpChallenge && (
-
-
Two-factor authentication
-
- {useRecovery ? 'Enter one of your recovery codes.' : 'Enter the 6-digit code from your authenticator app.'}
-
+
+
+
+
Two-factor authentication
+
+ {useRecovery ? 'Enter one of your recovery codes.' : 'Enter the 6-digit code from your authenticator app.'}
+