/* HeroIllustration.jsx — 3D-style isometric stacked UI cards. 3 variations. */ const Icon = ({ name, size = 18, style }) => ; /* ── Reusable mini app card pieces ───────────────────────────────────── */ const MiniJobsCard = ({ style }) =>
Today's jobs
Today Week
RV
Riverside Plaza
09:00 · Office
Done
MK
Maple Kitchen
11:30 · Resi
In progress
CR
Crescent Clinic
14:00 · Medical
Soon
HV
Harbour View Suites
16:30 · Office
Queued
; const MiniStatCard = ({ style, label = 'Jobs this week', value = '128', delta = '+12%' }) =>
{label}
{value}
{delta} vs last
{/* mini sparkline */}
; const MiniNotifCard = ({ style }) =>
Job completed
Maya signed off Crescent Clinic — 2 min ago
; const MiniCalendarCard = ({ style }) => { const days = ['M', 'T', 'W', 'T', 'F', 'S', 'S']; const cells = Array.from({ length: 28 }, (_, i) => i); const filled = new Set([2, 5, 7, 9, 12, 14, 16, 19, 22, 25]); const highlight = new Set([9, 14, 22]); return (
May 2026
{days.map((d, i) =>
{d}
)}
{cells.map((i) =>
{i + 1}
)}
); }; const MiniMessageCard = ({ style }) =>
JL
Jordan L.
Crew lead
● online
Heading to Maple Kitchen now 🧹
Great — supply restock is in the van.
; const MiniInvoiceCard = ({ style }) =>
Invoice
#LP-2412
Paid
Riverside Plaza
$1,240
Stripe · Apr 28
; /* ── Phone frame (for PWA variation) ─────────────────────────────────── */ const PhoneMock = ({ style }) =>
{/* notch */}
{/* status bar */}
9:41
{/* header */}
Good morning
Maya, 4 jobs today.
{/* job card */}
NEXT · 11:30
Maple Kitchen
14 Maple Ave · Residential
{/* list */}
Up next
{[ { name: 'Crescent Clinic', time: '14:00', chip: 'Medical' }, { name: 'Harbour View', time: '16:30', chip: 'Office' }, { name: 'Westgate Bakery', time: '18:00', chip: 'Retail' }]. map((j, i) =>
{j.time.slice(0, 2)}
{j.name}
{j.chip}
)}
; /* ── HERO VARIATION 1 — TOWER (Dashboard stack with floating mini cards) */ function HeroTower() { // Apply isometric tilt via CSS variable in transform return (
{/* floor sphere accent */}
{/* main dashboard card — back */}
luppy
BC
Dashboard
Good morning, Sam
+ Add Job
{/* stat row */}
{[ { l: 'Today', v: '12', c: 'var(--color-primary)' }, { l: 'In progress', v: '4', c: 'var(--color-warning)' }, { l: 'Completed', v: '8', c: 'var(--color-success)' }]. map((s, i) =>
{s.l}
{s.v}
)}
{/* mini chart */}
Jobs this week
+18% ↑
{/* floating mini cards over the dashboard */}
{/* sparkles */}
); } /* ── HERO VARIATION 2 — PWA (phone + desktop) ───────────────────────── */ function HeroPwa() { return (
{/* desktop in back */}
app.luppy.app/jobs
{['solar:home-angle-linear', 'solar:case-round-linear', 'solar:calendar-linear', 'solar:users-group-rounded-linear', 'solar:map-point-linear', 'solar:bill-list-linear'].map((ic, i) =>
)}
Jobs
All jobs
{[ { n: 'Riverside Plaza', t: '09:00', c: 'chip-success', s: 'Completed' }, { n: 'Maple Kitchen', t: '11:30', c: 'chip-primary', s: 'In progress' }, { n: 'Crescent Clinic', t: '14:00', c: 'chip-warning', s: 'Soon' }, { n: 'Harbour View', t: '16:30', c: 'chip-info', s: 'Queued' }]. map((j, i) =>
{j.n.slice(0, 2)}
{j.n}
{j.t}
{j.s}
)}
{/* phone in front */}
{/* floating cube + shapes */}
{/* "install" badge */}
Works right in the browser
No app to install · 0 MB
{/* sparkles */}
); } /* ── HERO VARIATION 3 — LAYERS (exploded parallel planes) ───────────── */ function HeroLayers() { return (
{/* Calendar — back-left */}
{/* Jobs — back-right (largest) */}
{/* Stat card — mid-left */}
{/* Invoice — front-center */}
{/* Notif — top floating */}
{/* Shapes */}
{/* sparkles */}
); } /* ── Phone frame with a live text-message thread (for Texting variation) ── */ const PhoneChatMock = ({ style }) =>
{/* notch */}
{/* status bar */}
9:41
{/* thread header */}
JL
Jordan · Crew lead
● Active now
{/* message thread */}
Heading to Maple Kitchen now 🧹
Got it — supply restock is in the van.
On it. Done by 11:15!
Job auto-marked complete
Maple Kitchen marked done
{/* input row */}
Text a job update…
; /* ── HERO VARIATION 4 — TEXTING (chat-thread hero, no app to install) ── */ function HeroTexting() { return (
{/* phone with live text thread — front and center */}
{/* supporting proof cards floating either side */}
{/* sparkles */}
); } function HeroIllustration({ variant }) { if (variant === 'pwa') return ; if (variant === 'layers') return ; if (variant === 'texting') return ; return ; } Object.assign(window, { HeroIllustration, HeroTower, HeroPwa, HeroLayers, HeroTexting, MiniJobsCard, MiniStatCard, MiniCalendarCard, MiniNotifCard, MiniMessageCard, MiniInvoiceCard, Icon });