/* ============================================================================ MOWDEW OWNER — Desktop web "god mode" data + shell Business: Marta Lawn & Pool (Diego, owner-operator) + worker Marco. Garden vertical reads green, Pool vertical reads aqua. Sky-blue stays cross-cutting for location/verified. ========================================================================= */ const BIZ = { name: 'Marta Lawn & Pool', owner: 'Diego Marta', region: 'Bay Area', homes: 38, plan: 'Growth', vertical: 'mixed' }; /* ─── Vertical accent system ───────────────────────────────────────── The business's dominant vertical sets ONE accent token set. Green stays the permanent brand/primary; semantic colors (sky=verified, coral=alert, aqua=chemistry, green=success) never move. Pool-leaning → aqua accent, garden-leaning → green accent, mixed → green primary. Per-property pages can override via accentForVert(c.vert). */ const ACCENTS = { garden: { sidebar: '#0E3D21', rail: '#6FD79A', a: 'var(--green-600,#1B9647)', a700: 'var(--green-800,#15602F)', a50: 'var(--green-50)', a100: 'var(--green-100)', mascot: 'sprout', label: 'Garden' }, pool: { sidebar: '#093C42', rail: '#5FD4DF', a: 'var(--aqua-600,#0E98A3)', a700: 'var(--aqua-text,#0A767F)', a50: 'var(--aqua-50)', a100: 'var(--aqua-100)', mascot: 'dewy', label: 'Pool' }, mixed: { sidebar: '#0E3D21', rail: '#6FD79A', a: 'var(--green-600,#1B9647)', a700: 'var(--green-800,#15602F)', a50: 'var(--green-50)', a100: 'var(--green-100)', mascot: 'both', label: 'Garden & pool' }, }; function accentForVert(v) { return ACCENTS[v] || ACCENTS.mixed; } function accentVars(v) { const a = accentForVert(v); return { '--accent': a.a, '--accent-700': a.a700, '--accent-50': a.a50, '--accent-100': a.a100, '--accent-rail': a.rail, '--accent-sidebar': a.sidebar }; } const WORKERS = [ { id: 'w1', name: 'Diego Marta', role: 'Owner · Pro', color: '#21A84F', today: 5, you: true }, { id: 'w2', name: 'Marco Ruiz', role: 'Pool & garden Pro', color: '#12BCC9', today: 4 }, ]; // each customer: vertical, address, cadence, price (cents), worker, balance, label (name-hidden for pro) // billing schedule: freq (Monthly | Every 3 months | Every 6 months | Yearly | Manual), // billDay (1–28 anchor), nextDue (display), dueNow (in today's billing run) const CUSTOMERS = [ { id: 'c1', name: 'Lucia Miranda', label: 'Oak Ridge Ct garden', addr: '14 Oak Ridge Ct', city: 'Palo Alto', vert: 'garden', svc: 'Mow & edge', cadence: 'Every 2 weeks', price: 5500, worker: 'w1', balance: 0, lastPaid: 'Apr 30', rail: 'venmo', since: '2024', freq: 'Manual' }, { id: 'c2', name: 'Emma Walsh', label: 'Crestline Ave pool', addr: '88 Crestline Ave', city: 'Menlo Park', vert: 'pool', svc: 'Pool service', cadence: 'Weekly', price: 6500, worker: 'w1', balance: 26000, dueLabel: 'May · 4 visits', rail: 'zelle', since: '2023', freq: 'Monthly', billDay: 12, nextDue: 'May 12, 2026', dueNow: true }, { id: 'c3', name: 'Ada Okonkwo', label: 'Brookhaven Ln garden', addr: '3 Brookhaven Ln', city: 'Menlo Park', vert: 'garden', svc: 'Mow & blow', cadence: 'Weekly', price: 4800, worker: 'w2', balance: 9600, dueLabel: 'May · 2 visits', rail: 'venmo', since: '2025', freq: 'Monthly', billDay: 28, nextDue: 'May 28, 2026' }, { id: 'c4', name: 'Sandra Lemoine', label: 'Alameda Pl garden', addr: '27 Alameda Pl', city: 'Atherton', vert: 'garden', svc: 'Hedge & beds', cadence: 'Monthly', price: 9000, worker: 'w1', balance: 0, lastPaid: 'Apr 12', rail: 'paypal', since: '2024', freq: 'Every 3 months', billDay: 12, nextDue: 'May 12, 2026', dueNow: true }, { id: 'c5', name: 'Tom Bauer', label: 'Marin Vista pool', addr: '5 Marin Vista', city: 'Atherton', vert: 'pool', svc: 'Pool service', cadence: 'Weekly', price: 6000, worker: 'w2', balance: 12000, dueLabel: 'May · 2 visits', rail: 'zelle', since: '2025', freq: 'Every 3 months', billDay: 12, nextDue: 'Jul 12, 2026' }, { id: 'c6', name: 'The Cohens', label: 'Laurel Way pool', addr: '12 Laurel Way', city: 'Palo Alto', vert: 'pool', svc: 'Pool service', cadence: 'Weekly', price: 7000, worker: 'w1', balance: 0, lastPaid: 'May 2', rail: 'venmo', since: '2022', freq: 'Every 6 months', billDay: 1, nextDue: 'Aug 1, 2026' }, { id: 'c7', name: 'Raul Delgado', label: 'Pine Hollow garden', addr: '9 Pine Hollow', city: 'Menlo Park', vert: 'garden', svc: 'Full yard', cadence: 'Weekly', price: 5200, worker: 'w2', balance: 0, lastPaid: 'Apr 28', rail: 'zelle', since: '2024', freq: 'Monthly', billDay: 12, nextDue: 'May 12, 2026', dueNow: true }, { id: 'c8', name: 'Mei Lin', label: 'Cypress Ct pool', addr: '7 Cypress Ct', city: 'Palo Alto', vert: 'pool', svc: 'Pool service', cadence: 'Weekly', price: 6500, worker: 'w1', balance: 0, lastPaid: 'May 1', rail: 'paypal', since: '2023', freq: 'Monthly', billDay: 1, nextDue: 'Jun 1, 2026' }, ]; // reschedule requests waiting on owner approval const RESCHEDULES = [ { id: 'r1', cust: 'c2', from: 'Tue May 13', to: 'Thu May 15', reason: 'Pool party Tuesday — could you come Thursday instead?', worker: 'w1', when: '2h ago' }, { id: 'r2', cust: 'c5', from: 'Wed May 14', to: 'Fri May 16', reason: 'Gate will be locked Wednesday.', worker: 'w2', when: '5h ago' }, { id: 'r3', cust: 'c3', from: 'Mon May 12', to: 'skip', reason: 'Out of town — skip this week, resume next.', worker: 'w2', when: 'Yesterday' }, ]; // messaging threads (owner <-> customer) const THREADS = { c2: [ { from: 'cust', t: 'Hi Diego! The pool looked amazing after Monday, thank you.', at: 'Mon 11:04' }, { from: 'owner', t: 'Glad to hear it, Emma! Chlorine was a touch low so I topped it up.', at: 'Mon 11:20' }, { from: 'cust', t: 'Could we move next week to Thursday? We have a party Tuesday.', at: 'Tue 9:15' }, { from: 'sys', t: 'Emma requested a reschedule: Tue May 13 → Thu May 15', at: 'Tue 9:15' }, ], c5: [ { from: 'cust', t: 'Gate code changed to 4417.', at: 'Sun 18:30' }, { from: 'owner', t: 'Got it, updated Marco. Thanks Tom!', at: 'Sun 19:02' }, ], }; const PLANS = [ { id: 'starter', name: 'Starter', price: 1999, homes: 10, blurb: 'Just getting going', features: ['1 worker seat', 'Auto check-in & photos', 'Invoices + ledger'] }, { id: 'growth', name: 'Growth', price: 3499, homes: 50, blurb: 'A growing book', features: ['Up to 5 worker seats', 'Route assignment', 'Messaging + reschedules', 'Pool chemistry log'], current: true }, { id: 'scale', name: 'Scale', price: 4999, homes: 150, blurb: 'A full operation', features: ['Unlimited worker seats', 'Multi-route dispatch', 'Priority support', 'Custom pricing rules'] }, ]; function custWorker(c) { return WORKERS.find(w => w.id === c.worker); } function totalOwed() { return CUSTOMERS.reduce((s, c) => s + c.balance, 0); } Object.assign(window, { BIZ, WORKERS, CUSTOMERS, RESCHEDULES, THREADS, PLANS, custWorker, totalOwed });