feat(web): Schedule-First redesign

- Top header bar + narrow sidebar layout
- Dashboard: calendar-style schedule with timeline cards
- Clients: card-based layout with avatar initials and pet count
- Services: grid cards with emoji indicators and pricing
- Bookings: timeline cards with time slots, status chips, inline actions
- Invoices: cards with status badges, action buttons
- All pages: search bars, empty states, modal forms
- Consistent color system: indigo primary, amber alerts, gray hierarchy
This commit is contained in:
Robert Perez
2026-07-14 05:13:04 +00:00
parent cdaf5780e5
commit d8a4e43bcc
31 changed files with 1801 additions and 400 deletions
+18
View File
@@ -0,0 +1,18 @@
## Variant 1: Command Center
### Design stance
Dark terminal-inspired control panel — high information density, fast scanning, keyboard-efficient. Treats the CRM like an operator's dashboard.
### Key choices
- **Layout:** Narrow left sidebar + two-column dashboard with schedule list + alerts
- **Typography:** Inter font, mono for IDs/times, tight letter-spacing
- **Color:** Near-black background (#0a0a0a), zinc grays for hierarchy, indigo accent
- **Interaction:** Border-left active states, subtle hover backgrounds, compact badges
- **Density:** High — small fonts (11-14px), compact spacing, no visual padding waste
### Trade-offs
- **Strong at:** Quick scanning, data density, operator feel, fast navigation
- **Weak at:** Warmth/character, client-facing polish, approachability for non-tech users
### Best for
- Staff who live in the CRM all day, power users who want maximum information per screen
+483
View File
@@ -0,0 +1,483 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Petmaster CRM — Variant 1: Command Center</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
* { box-sizing: border-box; }
body { font-family: 'Inter', -apple-system, sans-serif; background: #0a0a0a; color: #e4e4e7; }
.sidebar { border-right: 1px solid #27272a; }
.card { background: #18181b; border: 1px solid #27272a; }
.card:hover { border-color: #3f3f46; }
.badge { font-size: 11px; padding: 2px 8px; border-radius: 9999px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; }
.badge-scheduled { background: #1c1917; color: #f59e0b; border: 1px solid #44403c; }
.badge-confirmed { background: #0c1a2e; color: #3b82f6; border: 1px solid #1e3a5f; }
.badge-completed { background: #052e16; color: #22c55e; border: 1px solid #14532d; }
.badge-unpaid { background: #1c1917; color: #ef4444; border: 1px solid #44403c; }
.badge-paid { background: #052e16; color: #22c55e; border: 1px solid #14532d; }
.stat-card { transition: all 0.15s ease; }
.stat-card:hover { border-color: #6366f1; transform: translateY(-1px); }
.nav-item { transition: all 0.15s ease; border-left: 2px solid transparent; }
.nav-item:hover { background: #1c1c20; }
.nav-item.active { background: #1c1c20; border-left-color: #6366f1; color: #e4e4e7; }
.modal-overlay { backdrop-filter: blur(4px); }
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #27272a; border-radius: 3px; }
.input { background: #27272a; border: 1px solid #3f3f46; color: #e4e4e7; }
.input:focus { outline: none; border-color: #6366f1; }
.select { appearance: none; background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); background-position: right 0.5rem center; background-repeat: no-repeat; background-size: 1.5em 1.5em; }
.btn-primary { background: #6366f1; color: white; font-weight: 600; transition: all 0.15s; }
.btn-primary:hover { background: #4f46e5; }
.btn-secondary { background: #27272a; color: #a1a1aa; border: 1px solid #3f3f46; font-weight: 500; transition: all 0.15s; }
.btn-secondary:hover { background: #3f3f46; color: #e4e4e7; }
.search-bar { background: #18181b; border: 1px solid #27272a; }
</style>
</head>
<body class="min-h-screen">
<!-- Sidebar -->
<aside class="sidebar fixed left-0 top-0 h-screen w-56 bg-black z-50 flex flex-col">
<div class="p-4 border-b border-zinc-800">
<div class="flex items-center gap-2">
<span class="text-2xl">🐾</span>
<div>
<div class="text-sm font-bold tracking-tight">Petmaster</div>
<div class="text-[10px] text-zinc-500 uppercase tracking-widest">CRM</div>
</div>
</div>
</div>
<nav class="flex-1 p-2 space-y-0.5">
<a href="#" onclick="showPage('dashboard')" class="nav-item active flex items-center gap-3 px-3 py-2 text-sm rounded-r-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zm10 0a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zm10 0a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/></svg>
Dashboard
</a>
<a href="#" onclick="showPage('clients')" class="nav-item flex items-center gap-3 px-3 py-2 text-sm text-zinc-400 rounded-r-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
Clients
</a>
<a href="#" onclick="showPage('services')" class="nav-item flex items-center gap-3 px-3 py-2 text-sm text-zinc-400 rounded-r-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.121 14.121L19 19m-7-7l7-7m-7 7l-2.879 2.879M12 12L9.121 9.121m0 5.758a3 3 0 10-4.243 4.243 3 3 0 004.241-4.241zm0 0V21"/></svg>
Services
</a>
<a href="#" onclick="showPage('bookings')" class="nav-item flex items-center gap-3 px-3 py-2 text-sm text-zinc-400 rounded-r-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
Bookings
</a>
<a href="#" onclick="showPage('invoices')" class="nav-item flex items-center gap-3 px-3 py-2 text-sm text-zinc-400 rounded-r-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 14l6-6m-5.5.5h.01m4.99 5h.01M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16l3.5-2 3.5 2 3.5-2 3.5 2z"/></svg>
Invoices
</a>
<a href="#" onclick="showPage('messages')" class="nav-item flex items-center gap-3 px-3 py-2 text-sm text-zinc-400 rounded-r-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/></svg>
Messages
<span class="ml-auto bg-indigo-500/20 text-indigo-400 text-[10px] px-1.5 py-0.5 rounded-full">3</span>
</a>
<a href="#" onclick="showPage('self-booking')" class="nav-item flex items-center gap-3 px-3 py-2 text-sm text-zinc-400 rounded-r-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>
Self-Booking
</a>
</nav>
<div class="p-3 border-t border-zinc-800">
<div class="flex items-center gap-2 px-3 py-2">
<div class="w-7 h-7 rounded-full bg-indigo-600 flex items-center justify-center text-xs font-bold">E</div>
<div class="flex-1 min-w-0">
<div class="text-xs font-medium truncate">Elliot</div>
<div class="text-[10px] text-zinc-500">Operator</div>
</div>
</div>
</div>
</aside>
<!-- Main Content -->
<main class="ml-56 min-h-screen">
<!-- Dashboard Page -->
<div id="page-dashboard" class="page p-6">
<!-- Top bar -->
<div class="flex items-center justify-between mb-6">
<div>
<h1 class="text-lg font-semibold tracking-tight">Dashboard</h1>
<p class="text-xs text-zinc-500 mt-0.5">Wednesday, July 13, 2026 · 7 bookings today</p>
</div>
<button class="btn-primary px-4 py-2 rounded text-sm flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
New Booking
</button>
</div>
<!-- Stats Row -->
<div class="grid grid-cols-4 gap-3 mb-6">
<div class="stat-card card rounded-lg p-4 border-l-2 border-l-indigo-500">
<div class="text-[10px] uppercase tracking-wider text-zinc-500 font-medium">Active Clients</div>
<div class="text-2xl font-bold mt-1">124</div>
<div class="text-[11px] text-zinc-500 mt-1">+12 this month</div>
</div>
<div class="stat-card card rounded-lg p-4 border-l-2 border-l-amber-500">
<div class="text-[10px] uppercase tracking-wider text-zinc-500 font-medium">Scheduled</div>
<div class="text-2xl font-bold mt-1">7</div>
<div class="text-[11px] text-zinc-500 mt-1">3 today</div>
</div>
<div class="stat-card card rounded-lg p-4 border-l-2 border-l-red-500">
<div class="text-[10px] uppercase tracking-wider text-zinc-500 font-medium">Unpaid</div>
<div class="text-2xl font-bold mt-1">$1,240</div>
<div class="text-[11px] text-zinc-500 mt-1">4 invoices</div>
</div>
<div class="stat-card card rounded-lg p-4 border-l-2 border-l-emerald-500">
<div class="text-[10px] uppercase tracking-wider text-zinc-500 font-medium">Revenue</div>
<div class="text-2xl font-bold mt-1">$8,420</div>
<div class="text-[11px] text-zinc-500 mt-1">This month</div>
</div>
</div>
<!-- Two Column Layout -->
<div class="grid grid-cols-3 gap-3">
<!-- Left: Today's Schedule -->
<div class="card rounded-lg col-span-2">
<div class="p-4 border-b border-zinc-800 flex items-center justify-between">
<h2 class="text-sm font-semibold">Today's Schedule</h2>
<a href="#" class="text-xs text-indigo-400 hover:text-indigo-300">View Calendar →</a>
</div>
<div class="divide-y divide-zinc-800">
<div class="p-3 flex items-center gap-3 hover:bg-zinc-800/50 transition-colors cursor-pointer">
<div class="text-xs font-mono text-zinc-500 w-16">9:00 AM</div>
<div class="w-8 h-8 rounded-full bg-amber-500/20 flex items-center justify-center text-xs">🐕</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium truncate">Alice Johnson</div>
<div class="text-xs text-zinc-500">Full Groom · Max (Golden Retriever)</div>
</div>
<span class="badge badge-scheduled">Scheduled</span>
</div>
<div class="p-3 flex items-center gap-3 hover:bg-zinc-800/50 transition-colors cursor-pointer">
<div class="text-xs font-mono text-zinc-500 w-16">10:30 AM</div>
<div class="w-8 h-8 rounded-full bg-blue-500/20 flex items-center justify-center text-xs">🐈</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium truncate">Bob Smith</div>
<div class="text-xs text-zinc-500">Nail Trim · Luna (Persian Cat)</div>
</div>
<span class="badge badge-confirmed">Confirmed</span>
</div>
<div class="p-3 flex items-center gap-3 hover:bg-zinc-800/50 transition-colors cursor-pointer">
<div class="text-xs font-mono text-zinc-500 w-16">1:00 PM</div>
<div class="w-8 h-8 rounded-full bg-emerald-500/20 flex items-center justify-center text-xs">🐕</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium truncate">Carol Davis</div>
<div class="text-xs text-zinc-500">Boarding · Rex (Labrador)</div>
</div>
<span class="badge badge-completed">Completed</span>
</div>
<div class="p-3 flex items-center gap-3 hover:bg-zinc-800/50 transition-colors cursor-pointer">
<div class="text-xs font-mono text-zinc-500 w-16">2:30 PM</div>
<div class="w-8 h-8 rounded-full bg-purple-500/20 flex items-center justify-center text-xs">🐕</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium truncate">Dave Wilson</div>
<div class="text-xs text-zinc-500">Dog Walking · Buddy (Beagle)</div>
</div>
<span class="badge badge-scheduled">Scheduled</span>
</div>
<div class="p-3 flex items-center gap-3 hover:bg-zinc-800/50 transition-colors cursor-pointer">
<div class="text-xs font-mono text-zinc-500 w-16">4:00 PM</div>
<div class="w-8 h-8 rounded-full bg-pink-500/20 flex items-center justify-center text-xs">🐈</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium truncate">Eve Martinez</div>
<div class="text-xs text-zinc-500">Cat Groom · Whiskers (Siamese)</div>
</div>
<span class="badge badge-scheduled">Scheduled</span>
</div>
</div>
</div>
<!-- Right: Quick Actions + Alerts -->
<div class="space-y-3">
<div class="card rounded-lg">
<div class="p-4 border-b border-zinc-800">
<h2 class="text-sm font-semibold">Quick Actions</h2>
</div>
<div class="p-3 space-y-1.5">
<button class="w-full text-left px-3 py-2 text-sm rounded hover:bg-zinc-800/50 text-zinc-400 hover:text-zinc-200 transition-colors flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"/></svg>
Add Client
</button>
<button class="w-full text-left px-3 py-2 text-sm rounded hover:bg-zinc-800/50 text-zinc-400 hover:text-zinc-200 transition-colors flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 14l6-6m-5.5.5h.01m4.99 5h.01M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16l3.5-2 3.5 2 3.5-2 3.5 2z"/></svg>
Create Invoice
</button>
<button class="w-full text-left px-3 py-2 text-sm rounded hover:bg-zinc-800/50 text-zinc-400 hover:text-zinc-200 transition-colors flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/></svg>
Send Message
</button>
</div>
</div>
<div class="card rounded-lg border-l-2 border-l-amber-500">
<div class="p-4">
<h2 class="text-sm font-semibold flex items-center gap-2">
<svg class="w-4 h-4 text-amber-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"/></svg>
Alerts
</h2>
<div class="mt-3 space-y-2">
<div class="text-xs text-amber-400/80 flex items-start gap-2">
<span class="mt-0.5"></span> 2 invoices overdue
</div>
<div class="text-xs text-zinc-500 flex items-start gap-2">
<span class="mt-0.5"></span> 1 pet vaccination expiring
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Clients Page -->
<div id="page-clients" class="page p-6 hidden">
<div class="flex items-center justify-between mb-6">
<div>
<h1 class="text-lg font-semibold tracking-tight">Clients</h1>
<p class="text-xs text-zinc-500 mt-0.5">124 active clients</p>
</div>
<button class="btn-primary px-4 py-2 rounded text-sm flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
Add Client
</button>
</div>
<div class="search-bar rounded-lg p-2 flex items-center gap-2 mb-4 max-w-sm">
<svg class="w-4 h-4 text-zinc-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
<input type="text" placeholder="Search clients, pets, phones..." class="flex-1 bg-transparent text-sm text-zinc-300 placeholder-zinc-500 outline-none">
</div>
<!-- Client List -->
<div class="card rounded-lg divide-y divide-zinc-800">
<div class="p-4 flex items-center gap-4 hover:bg-zinc-800/50 transition-colors cursor-pointer">
<div class="w-10 h-10 rounded-full bg-indigo-600 flex items-center justify-center text-sm font-bold">AJ</div>
<div class="flex-1">
<div class="text-sm font-medium">Alice Johnson</div>
<div class="text-xs text-zinc-500">alice@email.com · (555) 123-4567</div>
</div>
<div class="text-right">
<div class="text-xs text-zinc-500">Pets</div>
<div class="text-sm font-medium">2</div>
</div>
<div class="text-right">
<div class="text-xs text-zinc-500">Bookings</div>
<div class="text-sm font-medium text-amber-400">3 active</div>
</div>
<div class="text-right">
<div class="text-xs text-zinc-500">Balance</div>
<div class="text-sm font-medium text-emerald-400">$0</div>
</div>
<button class="text-zinc-500 hover:text-zinc-300 ml-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"/></svg>
</button>
</div>
<div class="p-4 flex items-center gap-4 hover:bg-zinc-800/50 transition-colors cursor-pointer">
<div class="w-10 h-10 rounded-full bg-emerald-600 flex items-center justify-center text-sm font-bold">BS</div>
<div class="flex-1">
<div class="text-sm font-medium">Bob Smith</div>
<div class="text-xs text-zinc-500">bob@email.com · (555) 234-5678</div>
</div>
<div class="text-right">
<div class="text-xs text-zinc-500">Pets</div>
<div class="text-sm font-medium">1</div>
</div>
<div class="text-right">
<div class="text-xs text-zinc-500">Bookings</div>
<div class="text-sm font-medium">0</div>
</div>
<div class="text-right">
<div class="text-xs text-zinc-500">Balance</div>
<div class="text-sm font-medium text-amber-400">$45</div>
</div>
<button class="text-zinc-500 hover:text-zinc-300 ml-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"/></svg>
</button>
</div>
<div class="p-4 flex items-center gap-4 hover:bg-zinc-800/50 transition-colors cursor-pointer">
<div class="w-10 h-10 rounded-full bg-rose-600 flex items-center justify-center text-sm font-bold">CD</div>
<div class="flex-1">
<div class="text-sm font-medium">Carol Davis</div>
<div class="text-xs text-zinc-500">carol@email.com · (555) 345-6789</div>
</div>
<div class="text-right">
<div class="text-xs text-zinc-500">Pets</div>
<div class="text-sm font-medium">3</div>
</div>
<div class="text-right">
<div class="text-xs text-zinc-500">Bookings</div>
<div class="text-sm font-medium text-emerald-400">5 active</div>
</div>
<div class="text-right">
<div class="text-xs text-zinc-500">Balance</div>
<div class="text-sm font-medium text-emerald-400">$0</div>
</div>
<button class="text-zinc-500 hover:text-zinc-300 ml-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"/></svg>
</button>
</div>
</div>
</div>
<!-- Messages Page (compact) -->
<div id="page-messages" class="page p-6 hidden">
<div class="flex items-center justify-between mb-6">
<h1 class="text-lg font-semibold tracking-tight">Messages</h1>
</div>
<div class="card rounded-lg h-[calc(100vh-12rem)] flex">
<!-- Conversation List -->
<div class="w-80 border-r border-zinc-800 flex flex-col">
<div class="p-3 border-b border-zinc-800">
<input type="text" placeholder="Search conversations..." class="search-bar w-full rounded px-3 py-2 text-sm outline-none">
</div>
<div class="flex-1 overflow-y-auto">
<div class="p-3 border-l-2 border-indigo-500 bg-zinc-800/50 cursor-pointer">
<div class="flex items-center gap-3">
<div class="w-9 h-9 rounded-full bg-indigo-600 flex items-center justify-center text-xs font-bold">AJ</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium flex items-center gap-2">Alice Johnson <span class="badge bg-red-500/20 text-red-400">2</span></div>
<div class="text-xs text-zinc-500 truncate">Hey, can Max come Friday?</div>
</div>
</div>
</div>
<div class="p-3 border-l-2 border-transparent cursor-pointer hover:bg-zinc-800/30">
<div class="flex items-center gap-3">
<div class="w-9 h-9 rounded-full bg-amber-600 flex items-center justify-center text-xs font-bold">BS</div>
<div class="flex-1 min-w-0">
<div class="text-sm text-zinc-300">Bob Smith</div>
<div class="text-xs text-zinc-500 truncate">Thanks for the update</div>
</div>
</div>
</div>
</div>
</div>
<!-- Chat Area -->
<div class="flex-1 flex flex-col">
<div class="p-4 border-b border-zinc-800 flex items-center gap-3">
<div class="w-9 h-9 rounded-full bg-indigo-600 flex items-center justify-center text-xs font-bold">AJ</div>
<div>
<div class="text-sm font-medium">Alice Johnson</div>
<div class="text-xs text-emerald-400">● Online</div>
</div>
</div>
<div class="flex-1 overflow-y-auto p-4 space-y-3">
<div class="flex justify-start">
<div class="bg-zinc-800 rounded-xl rounded-tl-sm px-4 py-2.5 max-w-md">
<p class="text-sm text-zinc-300">Can Max come for grooming this Friday at 9am?</p>
<p class="text-[10px] text-zinc-600 mt-1">10:30 AM</p>
</div>
</div>
<div class="flex justify-end">
<div class="bg-indigo-600 rounded-xl rounded-tr-sm px-4 py-2.5 max-w-md">
<p class="text-sm text-white">Hi Alice! Yes, Max is all set for Friday at 9am. Full grooming package.</p>
<p class="text-[10px] text-indigo-300 mt-1">10:32 AM</p>
</div>
</div>
<div class="flex justify-start">
<div class="bg-zinc-800 rounded-xl rounded-tl-sm px-4 py-2.5 max-w-md">
<p class="text-sm text-zinc-300">Perfect, thank you! 🙏</p>
<p class="text-[10px] text-zinc-600 mt-1">10:35 AM</p>
</div>
</div>
</div>
<div class="p-4 border-t border-zinc-800">
<div class="flex gap-2">
<input type="text" placeholder="Type a message..." class="input flex-1 rounded-lg px-4 py-2.5 text-sm outline-none">
<button class="btn-primary px-5 rounded-lg">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"/></svg>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Invoices Page -->
<div id="page-invoices" class="page p-6 hidden">
<div class="flex items-center justify-between mb-6">
<h1 class="text-lg font-semibold tracking-tight">Invoices</h1>
<button class="btn-primary px-4 py-2 rounded text-sm flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
New Invoice
</button>
</div>
<div class="card rounded-lg divide-y divide-zinc-800">
<div class="p-4 hover:bg-zinc-800/50 transition-colors">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center gap-3">
<div class="w-8 h-8 rounded-lg bg-amber-500/20 flex items-center justify-center text-sm">📄</div>
<div>
<div class="text-sm font-mono text-zinc-400">INV-0042</div>
<div class="text-xs text-zinc-500">Alice Johnson</div>
</div>
</div>
<div class="text-right">
<div class="text-sm font-bold">$125.00</div>
<span class="badge badge-unpaid">Unpaid</span>
</div>
</div>
<div class="flex items-center gap-4 text-xs text-zinc-500">
<span>Full Grooming · Full Groom · Max</span>
<span>Due: Jul 20, 2026</span>
</div>
<div class="flex gap-2 mt-3">
<button class="btn-secondary px-3 py-1.5 rounded text-xs">Mark Paid</button>
<button class="btn-secondary px-3 py-1.5 rounded text-xs">Stripe</button>
<button class="btn-secondary px-3 py-1.5 rounded text-xs">Email</button>
</div>
</div>
<div class="p-4 hover:bg-zinc-800/50 transition-colors">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center gap-3">
<div class="w-8 h-8 rounded-lg bg-emerald-500/20 flex items-center justify-center text-sm"></div>
<div>
<div class="text-sm font-mono text-zinc-400">INV-0041</div>
<div class="text-xs text-zinc-500">Carol Davis</div>
</div>
</div>
<div class="text-right">
<div class="text-sm font-bold">$210.00</div>
<span class="badge badge-paid">Paid</span>
</div>
</div>
<div class="flex items-center gap-4 text-xs text-zinc-500">
<span>Boarding (3 days) · Rex</span>
<span>Due: Jul 10, 2026</span>
</div>
</div>
<div class="p-4 hover:bg-zinc-800/50 transition-colors">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center gap-3">
<div class="w-8 h-8 rounded-lg bg-amber-500/20 flex items-center justify-center text-sm">📄</div>
<div>
<div class="text-sm font-mono text-zinc-400">INV-0040</div>
<div class="text-xs text-zinc-500">Bob Smith</div>
</div>
</div>
<div class="text-right">
<div class="text-sm font-bold">$45.00</div>
<span class="badge badge-unpaid">Unpaid</span>
</div>
</div>
<div class="flex items-center gap-4 text-xs text-zinc-500">
<span>Nail Trim · Luna</span>
<span>Due: Jul 15, 2026</span>
</div>
<div class="flex gap-2 mt-3">
<button class="btn-secondary px-3 py-1.5 rounded text-xs">Mark Paid</button>
<button class="btn-secondary px-3 py-1.5 rounded text-xs">Stripe</button>
<button class="btn-secondary px-3 py-1.5 rounded text-xs">Email</button>
</div>
</div>
</div>
</div>
<script>
function showPage(page) {
document.querySelectorAll('.page').forEach(p => p.classList.add('hidden'));
document.getElementById('page-' + page).classList.remove('hidden');
document.querySelectorAll('.nav-item').forEach(n => n.classList.remove('active'));
event.currentTarget.classList.add('active');
}
</script>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
## Variant 2: Schedule-First
### Design stance
Calendar-centric — the schedule is the single source of truth. Everything flows from the booking timeline. Warm, professional, like a modern salon management tool.
### Key choices
- **Layout:** Wide calendar header + booking cards below. Calendar is always visible and clickable.
- **Typography:** Inter font, rounded corners (12px), generous spacing for readability
- **Color:** White background, warm indigo accent (#4F46E5), amber for pending, green for completed
- **Interaction:** Drag-able booking cards (simulated), date selector, status dropdowns inline
- **Density:** Medium — comfortable spacing, clear visual hierarchy
### Trade-offs
- **Strong at:** Scheduling overview, day/week/month toggle, easy to see gaps, client-friendly
- **Weak at:** Mobile compactness, data density for power users
### Best for
- Staff who plan their day visually, pet businesses where scheduling is the primary workflow
+369
View File
@@ -0,0 +1,369 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Petmaster CRM — Variant 2: Schedule-First</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
* { box-sizing: border-box; }
body { font-family: 'Inter', -apple-system, sans-serif; background: #FAFBFC; color: #1a1a2e; }
.sidebar { border-right: 1px solid #E5E7EB; }
.nav-item { transition: all 0.15s ease; }
.nav-item:hover { background: #F3F4F6; }
.nav-item.active { background: #EEF2FF; color: #4F46E5; font-weight: 600; }
.calendar-day { transition: all 0.15s; }
.calendar-day:hover { background: #EEF2FF; }
.calendar-day.today { background: #4F46E5; color: white; }
.calendar-day.today:hover { background: #4338CA; }
.booking-card { transition: all 0.2s; border-left: 3px solid transparent; }
.booking-card:hover { border-left-color: #4F46E5; box-shadow: 0 2px 8px rgba(79,70,229,0.08); }
.booking-scheduled { border-left-color: #F59E0B; }
.booking-confirmed { border-left-color: #3B82F6; }
.booking-completed { border-left-color: #22C55E; }
.btn-primary { background: #4F46E5; color: white; font-weight: 600; transition: all 0.15s; }
.btn-primary:hover { background: #4338CA; }
.btn-secondary { background: white; color: #4B5563; border: 1px solid #D1D5DB; font-weight: 500; transition: all 0.15s; }
.btn-secondary:hover { background: #F9FAFB; border-color: #9CA3AF; }
.btn-sm { padding: 6px 12px; font-size: 13px; }
.input { background: white; border: 1px solid #D1D5DB; color: #1a1a2e; }
.input:focus { outline: none; border-color: #4F46E5; box-shadow: 0 0 0 3px rgba(79,70,229,0.1); }
.badge { font-size: 11px; padding: 3px 10px; border-radius: 9999px; font-weight: 600; }
.badge-scheduled { background: #FEF3C7; color: #92400E; }
.badge-confirmed { background: #DBEAFE; color: #1E40AF; }
.badge-completed { background: #D1FAE5; color: #065F46; }
.modal-overlay { background: rgba(0,0,0,0.4); backdrop-filter: blur(2px); }
.tab { padding: 8px 16px; font-size: 14px; font-weight: 500; border-bottom: 2px solid transparent; cursor: pointer; transition: all 0.15s; }
.tab:hover { color: #4F46E5; }
.tab.active { color: #4F46E5; border-bottom-color: #4F46E5; }
.timeline-dot { width: 12px; height: 12px; border-radius: 50%; border: 2px solid #4F46E5; background: white; }
.timeline-dot.connected { background: #4F46E5; }
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #D1D5DB; border-radius: 3px; }
</style>
</head>
<body class="min-h-screen">
<!-- Top Header -->
<header class="bg-white border-b border-gray-200 px-6 py-3 flex items-center justify-between">
<div class="flex items-center gap-3">
<span class="text-2xl">🐾</span>
<div>
<div class="text-base font-bold tracking-tight text-slate-800">Petmaster</div>
<div class="text-[10px] text-gray-400 uppercase tracking-widest">Schedule Management</div>
</div>
</div>
<div class="flex items-center gap-3">
<button class="btn-primary btn-sm flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
New Booking
</button>
<div class="w-8 h-8 rounded-full bg-indigo-600 flex items-center justify-center text-white text-xs font-bold">E</div>
</div>
</header>
<div class="flex min-h-[calc(100vh-52px)]">
<!-- Narrow Sidebar -->
<aside class="sidebar w-48 bg-white flex flex-col flex-shrink-0">
<nav class="flex-1 p-3 space-y-1">
<a href="#" class="nav-item flex items-center gap-2 px-3 py-2 text-sm rounded-lg">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zm10 0a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zm10 0a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/></svg>
Dashboard
</a>
<a href="#" class="nav-item flex items-center gap-2 px-3 py-2 text-sm text-gray-600 rounded-lg">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
Clients
</a>
<a href="#" class="nav-item flex items-center gap-2 px-3 py-2 text-sm text-gray-600 rounded-lg">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.121 14.121L19 19m-7-7l7-7m-7 7l-2.879 2.879M12 12L9.121 9.121m0 5.758a3 3 0 10-4.243 4.243 3 3 0 004.241-4.241zm0 0V21"/></svg>
Services
</a>
<a href="#" class="nav-item active flex items-center gap-2 px-3 py-2 text-sm rounded-lg">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
Schedule
</a>
<a href="#" class="nav-item flex items-center gap-2 px-3 py-2 text-sm text-gray-600 rounded-lg">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 14l6-6m-5.5.5h.01m4.99 5h.01M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16l3.5-2 3.5 2 3.5-2 3.5 2z"/></svg>
Invoices
</a>
<a href="#" class="nav-item flex items-center gap-2 px-3 py-2 text-sm text-gray-600 rounded-lg">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/></svg>
Messages
</a>
<a href="#" class="nav-item flex items-center gap-2 px-3 py-2 text-sm text-gray-600 rounded-lg">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>
Self-Booking
</a>
</nav>
</aside>
<!-- Main Content -->
<main class="flex-1 p-6 overflow-auto">
<!-- Calendar Header -->
<div class="bg-white rounded-xl border border-gray-200 p-4 mb-4">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center gap-4">
<button class="text-gray-400 hover:text-gray-600">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg>
</button>
<h2 class="text-lg font-bold text-slate-800">July 2026</h2>
<button class="text-gray-400 hover:text-gray-600">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>
</button>
</div>
<div class="flex items-center gap-2">
<div class="tab active">Day</div>
<div class="tab" onclick="this.parentElement.querySelector('.active').classList.remove('active'); this.classList.add('active')">Week</div>
<div class="tab" onclick="this.parentElement.querySelector('.active').classList.remove('active'); this.classList.add('active')">Month</div>
<button class="btn-secondary btn-sm ml-3">
<svg class="w-4 h-4 inline mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
Today
</button>
</div>
</div>
<!-- Calendar Grid -->
<div class="grid grid-cols-7 gap-px bg-gray-200 rounded-lg overflow-hidden">
<!-- Day Headers -->
<div class="bg-gray-50 p-2 text-center text-xs font-semibold text-gray-500">Mon</div>
<div class="bg-gray-50 p-2 text-center text-xs font-semibold text-gray-500">Tue</div>
<div class="bg-gray-50 p-2 text-center text-xs font-semibold text-gray-500">Wed</div>
<div class="bg-gray-50 p-2 text-center text-xs font-semibold text-gray-500">Thu</div>
<div class="bg-gray-50 p-2 text-center text-xs font-semibold text-gray-500">Fri</div>
<div class="bg-gray-50 p-2 text-center text-xs font-semibold text-gray-500">Sat</div>
<div class="bg-gray-50 p-2 text-center text-xs font-semibold text-gray-500">Sun</div>
<!-- Week 1 (Jun 29 - Jul 5) -->
<div class="bg-white p-2 min-h-[80px] opacity-40"><span class="text-xs text-gray-400">29</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">30</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">1</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">2</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">3</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">4</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">5</span></div>
<!-- Week 2 (Jul 6-12) -->
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">6</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">7</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">8</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">9</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">10</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">11</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">12</span></div>
<!-- Week 3 (Jul 13-19) - TODAY -->
<div class="bg-white p-2 min-h-[80px] calendar-day today">
<span class="text-sm font-bold">13</span>
<div class="mt-1 space-y-0.5">
<div class="h-1.5 bg-amber-400 rounded-full" style="width:80%"></div>
<div class="h-1.5 bg-blue-400 rounded-full" style="width:60%"></div>
</div>
</div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">14</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">15</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">16</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">17</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">18</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">19</span></div>
<!-- Week 4 -->
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">20</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">21</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">22</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">23</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">24</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">25</span></div>
<div class="bg-white p-2 min-h-[80px]"><span class="text-xs text-gray-500">26</span></div>
</div>
</div>
<!-- Today's Schedule -->
<div class="grid grid-cols-3 gap-4">
<!-- Timeline (2 columns) -->
<div class="col-span-2 bg-white rounded-xl border border-gray-200 p-5">
<div class="flex items-center justify-between mb-4">
<h3 class="text-base font-bold text-slate-800 flex items-center gap-2">
<svg class="w-5 h-5 text-indigo-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
Today's Schedule · July 13
</h3>
<span class="text-xs text-gray-500">5 bookings · $520 total</span>
</div>
<!-- Timeline -->
<div class="space-y-0">
<!-- 9:00 AM -->
<div class="flex gap-4 booking-card booking-scheduled bg-amber-50/50 rounded-lg p-4">
<div class="w-20 flex-shrink-0 pt-1">
<div class="text-sm font-bold text-slate-800">9:00 AM</div>
<div class="text-xs text-gray-400">90 min</div>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<span class="text-lg">🐕</span>
<span class="font-semibold text-slate-800">Full Grooming</span>
<span class="badge badge-scheduled">Scheduled</span>
</div>
<div class="text-sm text-gray-600">
<span class="font-medium">Alice Johnson</span> · <span class="text-gray-500">Max · Golden Retriever</span>
</div>
<div class="flex items-center gap-4 mt-2">
<span class="text-xs text-gray-500">Staff: Elliot</span>
<span class="text-xs text-gray-500">Note: Sensitive skin</span>
</div>
</div>
<div class="flex-shrink-0 space-y-1">
<button class="btn-secondary btn-sm w-full">Confirm</button>
<button class="btn-secondary btn-sm w-full text-xs">Complete</button>
</div>
</div>
<!-- 10:30 AM -->
<div class="flex gap-4 booking-card booking-confirmed bg-blue-50/50 rounded-lg p-4">
<div class="w-20 flex-shrink-0 pt-1">
<div class="text-sm font-bold text-slate-800">10:30 AM</div>
<div class="text-xs text-gray-400">30 min</div>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<span class="text-lg">🐈</span>
<span class="font-semibold text-slate-800">Nail Trim</span>
<span class="badge badge-confirmed">Confirmed</span>
</div>
<div class="text-sm text-gray-600">
<span class="font-medium">Bob Smith</span> · <span class="text-gray-500">Luna · Persian Cat</span>
</div>
</div>
<div class="flex-shrink-0 space-y-1">
<button class="btn-secondary btn-sm w-full text-xs">Complete</button>
</div>
</div>
<!-- 1:00 PM -->
<div class="flex gap-4 booking-card booking-completed bg-emerald-50/50 rounded-lg p-4">
<div class="w-20 flex-shrink-0 pt-1">
<div class="text-sm font-bold text-slate-800">1:00 PM</div>
<div class="text-xs text-gray-400">2 hrs</div>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<span class="text-lg">🐕</span>
<span class="font-semibold text-slate-800">Boarding Check-in</span>
<span class="badge badge-completed">Completed</span>
</div>
<div class="text-sm text-gray-600">
<span class="font-medium">Carol Davis</span> · <span class="text-gray-500">Rex · Labrador</span>
</div>
<div class="text-xs text-emerald-600 mt-1">✓ Checked in · 3-night stay</div>
</div>
</div>
<!-- 3:00 PM -->
<div class="flex gap-4 booking-card rounded-lg p-4 border border-dashed border-gray-300 bg-gray-50/50">
<div class="w-20 flex-shrink-0 pt-1">
<div class="text-sm font-bold text-gray-400">3:00 PM</div>
<div class="text-xs text-gray-300"></div>
</div>
<div class="flex-1 flex items-center justify-center">
<button class="text-sm text-indigo-600 hover:text-indigo-700 font-medium">+ Add Booking</button>
</div>
</div>
<!-- 4:00 PM -->
<div class="flex gap-4 booking-card booking-scheduled bg-amber-50/50 rounded-lg p-4">
<div class="w-20 flex-shrink-0 pt-1">
<div class="text-sm font-bold text-slate-800">4:00 PM</div>
<div class="text-xs text-gray-400">60 min</div>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<span class="text-lg">🐕</span>
<span class="font-semibold text-slate-800">Dog Walking</span>
<span class="badge badge-scheduled">Scheduled</span>
</div>
<div class="text-sm text-gray-600">
<span class="font-medium">Dave Wilson</span> · <span class="text-gray-500">Buddy · Beagle</span>
</div>
</div>
<div class="flex-shrink-0 space-y-1">
<button class="btn-secondary btn-sm w-full">Confirm</button>
<button class="btn-secondary btn-sm w-full text-xs">Complete</button>
</div>
</div>
</div>
</div>
<!-- Right Sidebar: Stats + Upcoming -->
<div class="space-y-4">
<!-- Today Stats -->
<div class="bg-white rounded-xl border border-gray-200 p-4">
<h3 class="text-sm font-bold text-slate-800 mb-3">Today</h3>
<div class="space-y-3">
<div class="flex items-center justify-between">
<span class="text-sm text-gray-600">Bookings</span>
<span class="text-lg font-bold text-slate-800">5</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-gray-600">Revenue</span>
<span class="text-lg font-bold text-emerald-600">$520</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-gray-600">Pending</span>
<span class="text-sm font-semibold text-amber-600">3 to confirm</span>
</div>
</div>
</div>
<!-- Upcoming This Week -->
<div class="bg-white rounded-xl border border-gray-200 p-4">
<h3 class="text-sm font-bold text-slate-800 mb-3">This Week</h3>
<div class="space-y-3">
<div class="flex items-center gap-3 p-2 rounded-lg bg-gray-50">
<div class="w-8 h-8 rounded-lg bg-indigo-100 flex items-center justify-center text-xs font-bold text-indigo-700">J14</div>
<div class="flex-1 min-w-0">
<div class="text-xs font-medium">3 bookings</div>
<div class="text-[10px] text-gray-400">24 more this week</div>
</div>
</div>
<div class="flex items-center gap-3 p-2 rounded-lg bg-gray-50">
<div class="w-8 h-8 rounded-lg bg-amber-100 flex items-center justify-center text-xs font-bold text-amber-700">J15</div>
<div class="flex-1 min-w-0">
<div class="text-xs font-medium">5 bookings</div>
<div class="text-[10px] text-gray-400">Full schedule</div>
</div>
</div>
<div class="flex items-center gap-3 p-2 rounded-lg bg-gray-50">
<div class="w-8 h-8 rounded-lg bg-emerald-100 flex items-center justify-center text-xs font-bold text-emerald-700">J16</div>
<div class="flex-1 min-w-0">
<div class="text-xs font-medium">2 bookings</div>
<div class="text-[10px] text-gray-400">2 open slots</div>
</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="bg-white rounded-xl border border-gray-200 p-4">
<h3 class="text-sm font-bold text-slate-800 mb-3">Quick Actions</h3>
<div class="space-y-2">
<button class="w-full text-left px-3 py-2 text-sm rounded-lg hover:bg-gray-50 text-gray-700 transition-colors">
📋 View All Bookings
</button>
<button class="w-full text-left px-3 py-2 text-sm rounded-lg hover:bg-gray-50 text-gray-700 transition-colors">
📄 Generate Reports
</button>
<button class="w-full text-left px-3 py-2 text-sm rounded-lg hover:bg-gray-50 text-gray-700 transition-colors">
⚙️ Staff Availability
</button>
</div>
</div>
</div>
</div>
</main>
</div>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
## Variant 3: Warm & Playful
### Design stance
Friendly and approachable — the CRM that feels like it belongs at a pet-friendly business. Pastel colors, rounded everything, soft shadows, illustrated icons. Makes scheduling feel fun rather than administrative.
### Key choices
- **Layout:** Centered content, no sidebar (top nav), rounded cards on warm white background
- **Typography:** Nunito (rounded sans-serif), generous line-height, soft colors
- **Color:** Warm palette — peach, mint, lavender, lemon. No harsh blacks.
- **Interaction:** Hover lifts with soft shadows, rounded buttons, emoji-heavy pet indicators
- **Density:** Low — breathing room between elements, big touch targets
### Trade-offs
- **Strong at:** Approachability, brand personality, client-facing self-booking, onboarding new staff
- **Weak at:** Data density, dark mode, quick scanning for power users
### Best for
- Pet businesses with personality, client self-booking experience, teams that value culture and warmth
+268
View File
@@ -0,0 +1,268 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Petmaster CRM — Variant 3: Warm & Playful</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700;800&display=swap');
* { box-sizing: border-box; }
body { font-family: 'Nunito', -apple-system, sans-serif; background: #FFFBF5; color: #4A4035; }
.card { background: white; border: none; border-radius: 20px; box-shadow: 0 2px 12px rgba(74,64,53,0.06); transition: all 0.2s ease; }
.card:hover { box-shadow: 0 8px 25px rgba(74,64,53,0.1); transform: translateY(-2px); }
.nav-pill { transition: all 0.2s; border-radius: 9999px; padding: 8px 16px; font-weight: 600; font-size: 14px; }
.nav-pill:hover { background: rgba(251,191,36,0.15); color: #D97706; }
.nav-pill.active { background: #FBBF24; color: #4A4035; box-shadow: 0 4px 12px rgba(251,191,36,0.3); }
.btn-primary { background: linear-gradient(135deg, #FBBF24, #F59E0B); color: #4A4035; font-weight: 700; border: none; border-radius: 16px; padding: 12px 24px; cursor: pointer; transition: all 0.2s; box-shadow: 0 4px 12px rgba(251,191,36,0.25); }
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(251,191,36,0.35); }
.btn-secondary { background: white; color: #4A4035; border: 2px solid #F3E8D8; border-radius: 16px; font-weight: 600; transition: all 0.2s; }
.btn-secondary:hover { border-color: #FBBF24; background: #FFFBF5; }
.stat-pill { border-radius: 20px; padding: 20px; transition: all 0.2s; }
.stat-pill:hover { transform: translateY(-3px); }
.booking-chip { border-radius: 16px; padding: 16px; transition: all 0.2s; border: 2px solid transparent; }
.booking-chip:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0,0,0,0.08); }
.input { border: 2px solid #F3E8D8; border-radius: 12px; padding: 12px 16px; background: white; color: #4A4035; font-family: 'Nunito', sans-serif; font-weight: 500; transition: all 0.2s; }
.input:focus { outline: none; border-color: #FBBF24; box-shadow: 0 0 0 4px rgba(251,191,36,0.15); }
.badge { font-size: 11px; padding: 4px 12px; border-radius: 9999px; font-weight: 700; font-family: 'Nunito', sans-serif; }
.badge-amber { background: #FEF3C7; color: #92400E; }
.badge-blue { background: #DBEAFE; color: #1E40AF; }
.badge-green { background: #D1FAE5; color: #065F46; }
.pet-icon { font-size: 24px; width: 48px; height: 48px; border-radius: 16px; display: flex; align-items: center; justify-content: center; }
.header-gradient { background: linear-gradient(135deg, #FBBF24 0%, #F59E0B 50%, #D97706 100%); }
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #E5D5C0; border-radius: 4px; }
.service-card { border-radius: 24px; padding: 24px; transition: all 0.3s; border: 2px solid transparent; cursor: pointer; }
.service-card:hover { border-color: #FBBF24; transform: translateY(-4px); }
</style>
</head>
<body>
<!-- Top Header (pill nav) -->
<header class="bg-white border-b-2 border-amber-100 px-8 py-4">
<div class="max-w-6xl mx-auto flex items-center justify-between">
<div class="flex items-center gap-4">
<div class="header-gradient w-12 h-12 rounded-2xl flex items-center justify-center text-2xl shadow-lg">🐾</div>
<div>
<h1 class="text-xl font-extrabold text-amber-600 tracking-tight">Petmaster</h1>
<p class="text-[10px] text-amber-400 font-semibold uppercase tracking-widest">Happy Pets, Happy Staff!</p>
</div>
</div>
<nav class="flex items-center gap-1">
<a href="#" class="nav-pill active">🏠 Home</a>
<a href="#" class="nav-pill">👥 Clients</a>
<a href="#" class="nav-pill">✂️ Services</a>
<a href="#" class="nav-pill">📅 Bookings</a>
<a href="#" class="nav-pill">💰 Invoices</a>
<a href="#" class="nav-pill">💬 Messages</a>
<a href="#" class="nav-pill">🐕 Self-Book</a>
</nav>
<div class="flex items-center gap-3">
<button class="btn-primary flex items-center gap-2 text-sm">
<span class="text-lg"></span> New Booking
</button>
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-amber-400 to-orange-500 flex items-center justify-center text-white font-bold shadow-md">
🐶
</div>
</div>
</div>
</header>
<!-- Main Content -->
<main class="max-w-6xl mx-auto px-8 py-8">
<!-- Dashboard Stats -->
<div class="grid grid-cols-4 gap-4 mb-8">
<div class="stat-pill bg-gradient-to-br from-blue-50 to-blue-100">
<div class="text-3xl mb-2">👥</div>
<div class="text-2xl font-extrabold text-blue-700">124</div>
<div class="text-sm text-blue-500 font-semibold">Happy Clients</div>
</div>
<div class="stat-pill bg-gradient-to-br from-amber-50 to-amber-100">
<div class="text-3xl mb-2">📅</div>
<div class="text-2xl font-extrabold text-amber-700">7</div>
<div class="text-sm text-amber-500 font-semibold">Today's Bookings</div>
</div>
<div class="stat-pill bg-gradient-to-br from-green-50 to-green-100">
<div class="text-3xl mb-2">💰</div>
<div class="text-2xl font-extrabold text-green-700">$8,420</div>
<div class="text-sm text-green-500 font-semibold">This Month</div>
</div>
<div class="stat-pill bg-gradient-to-br from-rose-50 to-rose-100">
<div class="text-3xl mb-2"></div>
<div class="text-2xl font-extrabold text-rose-700">2</div>
<div class="text-sm text-rose-500 font-semibold">Needs Attention</div>
</div>
</div>
<!-- Today's Schedule - Playful Cards -->
<div class="card p-6 mb-8">
<div class="flex items-center justify-between mb-6">
<div>
<h2 class="text-xl font-extrabold text-amber-600 flex items-center gap-2">
<span class="text-2xl">📋</span> Today's Schedule
</h2>
<p class="text-sm text-amber-400 font-semibold">Wednesday, July 13 · Let's make it a great day! 🌟</p>
</div>
<div class="flex gap-2">
<button class="btn-secondary px-4 py-2 text-sm">📅 Calendar View</button>
<button class="btn-secondary px-4 py-2 text-sm">📊 Reports</button>
</div>
</div>
<!-- Timeline -->
<div class="space-y-4">
<!-- 9:00 AM - Scheduled -->
<div class="booking-chip bg-amber-50 border-amber-200">
<div class="flex items-center gap-4">
<div class="text-center min-w-[80px]">
<div class="text-lg font-extrabold text-amber-700">9:00 AM</div>
<div class="text-xs text-amber-400 font-semibold">90 min</div>
</div>
<div class="pet-icon bg-amber-100">🐕</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-1">
<span class="font-extrabold text-amber-800 text-lg">Max's Full Groom</span>
<span class="badge badge-amber">Scheduled</span>
</div>
<div class="text-sm text-amber-600 font-semibold">
Alice Johnson · Golden Retriever
</div>
<div class="flex items-center gap-4 mt-2 text-xs text-amber-500 font-semibold">
<span>👨‍💼 Elliot</span>
<span>⚠️ Sensitive skin</span>
<span>💵 $125</span>
</div>
</div>
<div class="flex gap-2">
<button class="btn-primary text-sm px-4 py-2">✅ Confirm</button>
</div>
</div>
</div>
<!-- 10:30 AM - Confirmed -->
<div class="booking-chip bg-blue-50 border-blue-200">
<div class="flex items-center gap-4">
<div class="text-center min-w-[80px]">
<div class="text-lg font-extrabold text-blue-700">10:30 AM</div>
<div class="text-xs text-blue-400 font-semibold">30 min</div>
</div>
<div class="pet-icon bg-blue-100">🐈</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-1">
<span class="font-extrabold text-blue-800 text-lg">Luna's Nail Trim</span>
<span class="badge badge-blue">Confirmed</span>
</div>
<div class="text-sm text-blue-600 font-semibold">
Bob Smith · Persian Cat
</div>
<div class="flex items-center gap-4 mt-2 text-xs text-blue-500 font-semibold">
<span>👨‍💼 Elliot</span>
<span>💵 $45</span>
</div>
</div>
<div class="flex gap-2">
<button class="btn-primary text-sm px-4 py-2 bg-gradient-to-br from-blue-400 to-blue-600">🎉 Complete</button>
</div>
</div>
</div>
<!-- 1:00 PM - Completed -->
<div class="booking-chip bg-green-50 border-green-200 opacity-75">
<div class="flex items-center gap-4">
<div class="text-center min-w-[80px]">
<div class="text-lg font-extrabold text-green-700">1:00 PM</div>
<div class="text-xs text-green-400 font-semibold">2 hrs</div>
</div>
<div class="pet-icon bg-green-100">🐕</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-1">
<span class="font-extrabold text-green-800 text-lg">Rex's Boarding</span>
<span class="badge badge-green">Completed ✓</span>
</div>
<div class="text-sm text-green-600 font-semibold">
Carol Davis · Labrador
</div>
<div class="flex items-center gap-4 mt-2 text-xs text-green-500 font-semibold">
<span>✅ Checked in</span>
<span>🏠 3-night stay</span>
<span>💵 $350</span>
</div>
</div>
</div>
</div>
<!-- 4:00 PM - Open -->
<div class="booking-chip bg-gray-50 border-dashed border-2 border-gray-200">
<div class="flex items-center gap-4">
<div class="text-center min-w-[80px]">
<div class="text-lg font-extrabold text-gray-400">4:00 PM</div>
<div class="text-xs text-gray-300 font-semibold"></div>
</div>
<div class="pet-icon bg-gray-100"></div>
<div class="flex-1 flex items-center">
<button class="btn-secondary px-6 py-3 text-sm font-bold text-amber-600">
✨ Book This Slot
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Services Grid (Playful) -->
<div class="card p-6">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-extrabold text-amber-600 flex items-center gap-2">
<span class="text-2xl">✂️</span> Our Services
</h2>
<button class="btn-primary text-sm"> Add Service</button>
</div>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<div class="service-card bg-gradient-to-br from-blue-50 to-blue-100 text-center">
<div class="text-4xl mb-3">✂️</div>
<div class="font-extrabold text-blue-800">Full Grooming</div>
<div class="text-sm text-blue-500 font-semibold">90 min · $125</div>
</div>
<div class="service-card bg-gradient-to-br from-amber-50 to-amber-100 text-center">
<div class="text-4xl mb-3">🐾</div>
<div class="font-extrabold text-amber-800">Nail Trim</div>
<div class="text-sm text-amber-500 font-semibold">30 min · $45</div>
</div>
<div class="service-card bg-gradient-to-br from-green-50 to-green-100 text-center">
<div class="text-4xl mb-3">🏠</div>
<div class="font-extrabold text-green-800">Boarding</div>
<div class="text-sm text-green-500 font-semibold">1 night · $120</div>
</div>
<div class="service-card bg-gradient-to-br from-rose-50 to-rose-100 text-center">
<div class="text-4xl mb-3">🚶</div>
<div class="font-extrabold text-rose-800">Dog Walking</div>
<div class="text-sm text-rose-500 font-semibold">60 min · $80</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="grid grid-cols-3 gap-4 mt-8">
<button class="card p-6 text-center hover:border-amber-300 border-2 border-transparent transition-all">
<div class="text-4xl mb-3">👥</div>
<div class="font-extrabold text-amber-700">Add Client</div>
<div class="text-sm text-amber-400 font-semibold">Welcome a new furry friend!</div>
</button>
<button class="card p-6 text-center hover:border-amber-300 border-2 border-transparent transition-all">
<div class="text-4xl mb-3">💰</div>
<div class="font-extrabold text-amber-700">Send Invoice</div>
<div class="text-sm text-amber-400 font-semibold">Get paid faster ✨</div>
</button>
<button class="card p-6 text-center hover:border-amber-300 border-2 border-transparent transition-all">
<div class="text-4xl mb-3">💬</div>
<div class="font-extrabold text-amber-700">Message Client</div>
<div class="text-sm text-amber-400 font-semibold">Stay in touch 💌</div>
</button>
</div>
</main>
</body>
</html>