From 7009342ce194c56dc5d83fdca321ec43dd3c742e Mon Sep 17 00:00:00 2001 From: Mohit Mittal Date: Wed, 17 Jun 2026 21:24:58 -0400 Subject: [PATCH] wip(home): local marketing-copy pass on landing/home surfaces Snapshot of uncommitted landing + home-page copy edits (hero, task feed, how-it-works, why-taskly, the-problem, landing-2 sections, taskers) plus new landing2 sections (AskAnyWay, BuiltForToronto, ClosingCta, ProblemBeat, TrustByDesign). Captured to a branch so main can fast-forward to the incoming home-page redesign; reconcile the two afterward. Co-Authored-By: Claude Opus 4.8 (1M context) --- app/join/page.tsx | 69 ++-- app/landing-2/page.tsx | 4 +- app/landing-2/sections.tsx | 159 ++++----- app/layout.tsx | 12 +- app/login/page.tsx | 2 +- app/onboarding/page.tsx | 8 +- app/page.tsx | 16 +- app/pro/[handle]/ProfileView.tsx | 2 +- .../TasklyAdvantagesClient.tsx | 24 +- components/Footer.tsx | 2 +- components/HeroPostTask.tsx | 55 ++- components/HowItWorks.tsx | 66 ++-- components/NavBar.tsx | 9 +- components/TheProblem.tsx | 53 +-- components/WhyTaskly.tsx | 36 +- components/landing2/AskAnyWay.tsx | 126 +++++++ components/landing2/BuiltForToronto.tsx | 53 +++ components/landing2/ClosingCta.tsx | 51 +++ components/landing2/EarnAsTasker.tsx | 31 +- components/landing2/HeroJourney.tsx | 315 ++++++++++-------- components/landing2/OpenForAll.tsx | 6 +- components/landing2/ProblemBeat.tsx | 92 +++++ components/landing2/TaskFeed.tsx | 167 +++++----- components/landing2/TrustByDesign.tsx | 74 ++++ components/taskers/TaskersFaq.tsx | 2 +- components/taskers/TaskersFounderNote.tsx | 2 +- 26 files changed, 935 insertions(+), 501 deletions(-) create mode 100644 components/landing2/AskAnyWay.tsx create mode 100644 components/landing2/BuiltForToronto.tsx create mode 100644 components/landing2/ClosingCta.tsx create mode 100644 components/landing2/ProblemBeat.tsx create mode 100644 components/landing2/TrustByDesign.tsx diff --git a/app/join/page.tsx b/app/join/page.tsx index 54cd74c1..10259ad6 100644 --- a/app/join/page.tsx +++ b/app/join/page.tsx @@ -28,33 +28,35 @@ function Counter({ value, suffix = '', prefix = '' }: { value: number; suffix?: /* ─── Data ─── */ const benefits = [ - { icon: DollarSign, title: 'Earn More', stat: '$35-55', statLabel: '/hr avg', desc: 'Top pros earn $55+/hr. No middleman cuts. Keep what you earn.' }, - { icon: Calendar, title: 'Your Schedule', stat: '100', statLabel: '% flexible', desc: 'Work when you want. No minimum hours. No forced shifts.' }, - { icon: Zap, title: 'Instant Pay', stat: '24', statLabel: 'hr payouts', desc: 'Get paid within 24 hours. No waiting for bi-weekly checks.' }, - { icon: Shield, title: 'Full Coverage', stat: '$2M', statLabel: 'insured', desc: 'You\'re covered by our $2M liability insurance on every job.' }, - { icon: Smartphone, title: 'Smart App', stat: '1', statLabel: 'tap to accept', desc: 'Jobs pushed to you. Accept with one tap. GPS navigation built in.' }, - { icon: TrendingUp, title: 'Grow', stat: '4.9', statLabel: '★ avg rating', desc: 'Build your reputation. Top-rated pros get priority bookings.' }, + { icon: DollarSign, title: 'Keep ~80%', stat: '80', statLabel: '% you keep', desc: 'No subscriptions, no lead fees. Taskly takes a commission only when you get paid — never before.' }, + { icon: Calendar, title: 'Your Schedule', stat: '100', statLabel: '% flexible', desc: 'Work when you want. No minimum hours, no forced shifts. You choose every job you take.' }, + { icon: Shield, title: 'Protected Pay', stat: '$0', statLabel: 'for leads', desc: 'Every job is funded into escrow before you start — so the money is already there when you finish.' }, + { icon: Zap, title: 'You Set the Price', stat: 'You', statLabel: 'name the rate', desc: 'Make your offer at the price you choose. No platform-set rate, no race to the bottom.' }, + { icon: Smartphone, title: 'Business in a Box', stat: '1', statLabel: 'shareable profile', desc: 'A profile, reviews, payments and a QR code that win you work — on Taskly and off it.' }, + { icon: Star, title: 'Experience Counts', stat: 'Day 1', statLabel: 'start earning', desc: 'Bring the skills you already have. Build a reputation that follows you, from your very first job.' }, ]; const steps = [ - { num: '01', title: 'Apply', desc: 'Fill out a 2-minute application. Tell us about your skills and experience.' }, - { num: '02', title: 'Get Verified', desc: 'We run a CPIC background check, verify your ID, and check references.' }, - { num: '03', title: 'Get Equipped', desc: 'Download the Taskly Pro app. Complete onboarding training (30 min).' }, - { num: '04', title: 'Start Earning', desc: 'Go live and start accepting jobs in your area. It\'s that simple.' }, + { num: '01', title: 'Sign up', desc: 'Create your free account in a couple of minutes. Tell us what you\'re great at.' }, + { num: '02', title: 'Get approved', desc: 'We review every applicant and verify your details before you can take work.' }, + { num: '03', title: 'Set up payouts', desc: 'Connect secure payouts through Stripe, so your earnings land straight in your bank.' }, + { num: '04', title: 'Start earning', desc: 'Make offers on local tasks, get hired, and get paid when the job\'s done. That simple.' }, ]; +// Not testimonials — honest "who it's for" personas (no invented people, +// earnings or ratings). Maps to the JTBD tasker situations in the strategy. const testimonials = [ - { name: 'Marcus T.', role: 'Cleaner, 8 months', area: 'North York', text: 'I left my agency job and doubled my income. The flexibility is unmatched.', earnings: '$4,200/mo' }, - { name: 'Priya K.', role: 'Cleaner, 1 year', area: 'Mississauga', text: 'As a student, I can work between classes. The instant pay is a lifesaver.', earnings: '$2,800/mo' }, - { name: 'James O.', role: 'Handyman, 6 months', area: 'Scarborough', text: 'Best platform I\'ve worked with. Jobs come to me, I don\'t chase them.', earnings: '$5,100/mo' }, + { name: 'New to the GTA', role: 'Your experience counts here', area: 'Newcomers', text: 'Bring the trade you trained for back home. On Taskly, real skills earn from day one — no Canadian-experience catch-22.', earnings: 'Day 1' }, + { name: 'Between things', role: 'Work around your life', area: 'Students & side-hustlers', text: 'Pick up tasks between classes or shifts. No minimum hours and no forced schedule — you take only what fits.', earnings: 'Flexible' }, + { name: 'Done chasing leads', role: 'Stop paying to maybe get work', area: 'Trades & pros', text: 'No subscriptions, no pay-per-lead. Customers come to you, you keep about 80%, and you\'re paid only when the job\'s done.', earnings: 'No lead fees' }, ]; const faqs = [ - { q: 'What are the requirements?', a: 'You need to be 18+, have valid Canadian ID, pass a CPIC background check, and have relevant experience or certification in your service area.' }, - { q: 'How much can I earn?', a: 'Average pros earn $35-45/hr. Top-rated pros with consistent availability earn $55+/hr. You set your own rates within our platform range.' }, - { q: 'When do I get paid?', a: 'Payouts are processed within 24 hours of job completion directly to your bank account. No waiting for bi-weekly checks.' }, - { q: 'Do I need my own supplies?', a: 'For cleaning, Taskly provides a supplies kit on your first day. For maintenance/handyman work, you use your own professional tools.' }, - { q: 'Can I choose my own schedule?', a: 'Absolutely. You set your availability in the app. No minimum hours, no forced shifts. Work as much or as little as you want.' }, + { q: 'What are the requirements?', a: 'You need to be 18+, have a valid Canadian ID and the right to work here, and real experience or skill in what you offer. We review every applicant before approving them.' }, + { q: 'How much can I earn?', a: 'You set your own price on every task you make an offer on. Taskly takes a commission only when you get paid — you keep about 80% — with no subscriptions and no lead fees.' }, + { q: 'When do I get paid?', a: 'Once you mark a job done and the customer confirms, your earnings are released from escrow and paid out securely through Stripe to your bank account.' }, + { q: 'Do I need my own supplies?', a: 'That depends on the task. For most work you bring your own tools and supplies — and the task details spell out exactly what\'s expected before you ever make an offer.' }, + { q: 'Can I choose my own schedule?', a: 'Absolutely. You set your own availability. No minimum hours, no forced shifts. Work as much or as little as you want.' }, { q: 'What areas do you serve?', a: 'We currently operate across Toronto and the Greater Toronto Area — North York, Scarborough, Etobicoke, Mississauga, Brampton, and more.' }, ]; @@ -354,8 +356,9 @@ export default function JoinPage() { transition={{ duration: 0.6, delay: 0.8 }} className="font-sans text-[15px] md:text-[17px] font-400 text-cream/80 leading-[1.7] max-w-[480px] mt-8" > - Stop working for less than you're worth. Join Toronto's fastest-growing - home services platform and earn on your own terms. + Stop working for less than you're worth — and stop paying for leads + that ghost. Turn your skills into steady income, and get paid only when + the job's done. {[ - { val: 500, suffix: '+', label: 'Active Pros' }, - { val: 35, suffix: '-55', label: '$/hr Average' }, - { val: 4200, suffix: '+', label: 'Jobs/Month' }, + { val: 0, prefix: '$', suffix: '', label: 'Paid for leads' }, + { val: 80, prefix: '', suffix: '%', label: 'You keep' }, + { val: 0, prefix: '', suffix: '', label: 'Forced shifts' }, ].map((s, i) => (
- +
{s.label} @@ -546,7 +549,7 @@ export default function JoinPage() { className="mb-6" > - From Our Pros + Who it’s for @@ -556,7 +559,7 @@ export default function JoinPage() { viewport={{ once: true }} className="font-display text-[32px] sm:text-[48px] md:text-[80px] font-800 leading-[0.88] tracking-[-0.03em] mb-16 md:mb-24 max-w-[700px]" > - They made
the switch. + Built for
your skills.
@@ -571,18 +574,16 @@ export default function JoinPage() { > {/* Earnings badge */}
-
- {[...Array(5)].map((_, s) => ( - - ))} -
+ + Could be you + {t.earnings}

- “{t.text}” + {t.text}

@@ -682,7 +683,7 @@ export default function JoinPage() { Start earning.

- Join 500+ verified professionals across the GTA who chose better pay, flexible hours, and a platform that respects their work. + Join the GTA locals turning real skills into real income — better pay, your own hours, and no fees until you get paid.

@@ -711,7 +712,7 @@ export default function JoinPage() { taskly. - © 2025 Taskly.ca · Toronto & GTA + © 2026 Taskly.ca · Toronto & the GTA
diff --git a/app/landing-2/page.tsx b/app/landing-2/page.tsx index 4a266c3c..095f56e8 100644 --- a/app/landing-2/page.tsx +++ b/app/landing-2/page.tsx @@ -26,9 +26,9 @@ import { } from './sections'; export const metadata = { - title: 'Taskly — Your home, handled. Toronto cleaners on tap.', + title: 'Taskly — Anything on your list, handled. Toronto & the GTA.', description: - 'Vetted, insured cleaners across Toronto and the GTA. Flat prices from $99. Book in 30 seconds or message us on WhatsApp. Built right here.', + 'Post anything on your list — type it, say it, or snap a photo — and vetted local Taskers send you offers. You only pay once the work is done. No hidden fees. Built in Toronto for the GTA.', }; export default function LandingV2() { diff --git a/app/landing-2/sections.tsx b/app/landing-2/sections.tsx index 81e9cf46..01f2c413 100644 --- a/app/landing-2/sections.tsx +++ b/app/landing-2/sections.tsx @@ -2079,29 +2079,29 @@ interface Pro { const PROS: ReadonlyArray = [ { - slug: 'anika', - name: 'Anika Patel', - initials: 'AP', - neighbourhood: 'Liberty Village', - specialty: 'Cleaning · Standard + Deep', - badges: ['Verified ID', 'GTA-based', '4.97★'], - jobs: 312, - rating: 4.97, + slug: 'aanya', + name: 'Aanya Mehta', + initials: 'AM', + neighbourhood: 'North York', + specialty: 'AI for Work · ChatGPT & automations', + badges: ['Remote · GTA', 'AI & automation'], + jobs: 96, + rating: 4.98, years: 3, - quote: 'My favourite cleans are the empty condos before move-in. Quiet, perfect light, two hours of flow.', + quote: 'Most people don’t need more apps — they need their two hours back. I set the AI up once, and email stops eating their evening.', gradient: 'bg-gradient-to-br from-rich-black via-rich-black to-rich-black/85', }, { - slug: 'raj', - name: 'Raj Singh', - initials: 'RS', - neighbourhood: 'Vaughan', - specialty: 'Electrician · 309A licensed', - badges: ['309A licence', 'ESA permits', '4.95★'], - jobs: 142, - rating: 4.95, - years: 12, - quote: 'I pull permits on every job. The receipts are yours, not mine. That’s the difference.', + slug: 'simran', + name: 'Simran Kaur', + initials: 'SK', + neighbourhood: 'Brampton', + specialty: 'Mehndi artist · Bridal & party', + badges: ['Brampton', 'Bridal specialist'], + jobs: 210, + rating: 4.99, + years: 7, + quote: 'A bride’s hands tell the story of the whole night. I show up early, put on her favourite playlist, and we make it perfect.', gradient: 'bg-gradient-to-br from-cream-dark via-cream-dark/95 to-cream', }, { @@ -2109,8 +2109,8 @@ const PROS: ReadonlyArray = [ name: 'Sophie Chen', initials: 'SC', neighbourhood: 'Yorkville', - specialty: 'Mobile RMT · 60 / 90 min', - badges: ['Registered RMT', 'Verified ID', '4.99★'], + specialty: 'Mobile RMT · Massage at home', + badges: ['Registered RMT', 'Mobile · at-home'], jobs: 156, rating: 4.99, years: 5, @@ -2118,68 +2118,68 @@ const PROS: ReadonlyArray = [ gradient: 'bg-gradient-to-br from-rich-black via-rich-black/95 to-rich-black/80', }, { - slug: 'jamal', - name: 'Jamal Williams', - initials: 'JW', - neighbourhood: 'Etobicoke', - specialty: 'Handyman · Furniture assembly', - badges: ['Verified ID', 'GTA-based', '4.96★'], - jobs: 224, - rating: 4.96, + slug: 'omar', + name: 'Omar Haddad', + initials: 'OH', + neighbourhood: 'Scarborough', + specialty: 'Newcomer mentor · Career & settlement', + badges: ['Bilingual', 'Settlement coach'], + jobs: 134, + rating: 4.97, years: 6, - quote: 'I keep three Allen keys, a label maker, and a level in my truck. Those three things solve 80% of jobs.', + quote: 'I arrived with two suitcases and a degree nobody recognised. Now I help newcomers skip the lost year of confusion I had to live through.', gradient: 'bg-gradient-to-br from-cream-dark via-cream-dark/90 to-cream', }, { - slug: 'priya', - name: 'Priya Sharma', - initials: 'PS', - neighbourhood: 'Mississauga', - specialty: 'Personal chef · Specialty cuisines', - badges: ['Food Handler', 'Verified ID', '4.98★'], - jobs: 78, + slug: 'grace', + name: 'Grace Okafor', + initials: 'GO', + neighbourhood: 'Downtown', + specialty: 'Career coach · Interviews & resumes', + badges: ['Remote · GTA', 'Ex-recruiter'], + jobs: 188, rating: 4.98, - years: 4, - quote: 'Sundays I cook five meals for one family. Monday morning their week is already sorted.', + years: 8, + quote: 'We run the interview until the nervous answer becomes the confident one. By the real thing, they’ve already done it ten times.', gradient: 'bg-gradient-to-br from-rich-black via-rich-black/90 to-rich-black/75', }, { - slug: 'david', - name: 'David Nguyen', - initials: 'DN', - neighbourhood: 'North York', - specialty: 'Snow removal · Lawn care', - badges: ['Seasonal pro', 'GTA-based', '4.93★'], - jobs: 312, - rating: 4.93, - years: 7, - quote: 'I’m at your driveway by 5:30 a.m. before the salt trucks. Coffee in the truck. You sleep in.', + slug: 'wei', + name: 'Wei Zhang', + initials: 'WZ', + neighbourhood: 'Markham', + specialty: 'Coding for kids · Scratch & Python', + badges: ['Markham', 'Kids 8–14'], + jobs: 142, + rating: 4.99, + years: 5, + quote: 'The moment a ten-year-old’s game actually runs, they look up like they’ve discovered fire. That look is the whole job.', gradient: 'bg-gradient-to-br from-cream-dark via-cream to-cream-dark/95', }, { - slug: 'maria', - name: 'Maria Lopez', - initials: 'ML', - neighbourhood: 'Brampton', - specialty: 'PSW · Companion + dementia', - badges: ['NACC PSW', 'GPA-trained', '4.99★'], - jobs: 189, - rating: 4.99, - years: 9, - quote: 'My clients call me the daughter who shows up on time. That’s the highest compliment.', + slug: 'jordan', + name: 'Jordan Brooks', + initials: 'JB', + neighbourhood: 'Leslieville', + specialty: 'Creator coach · YouTube & short-form', + badges: ['Remote · GTA', 'Editor & strategist'], + jobs: 117, + rating: 4.96, + years: 4, + quote: 'Everyone thinks they need a better camera. They need a better first three seconds — we fix that before anything else.', gradient: 'bg-gradient-to-br from-rich-black via-rich-black/90 to-rich-black/70', }, { - slug: 'marco', - name: 'Marco Rossi', - initials: 'MR', - neighbourhood: 'King West', - specialty: 'Plumbing · 306A licensed', - badges: ['306A licence', 'Verified ID', 'GTA-based'], - jobs: 89, - rating: 4.94, - years: 8, - quote: 'I’d rather catch a leak under your sink at 11pm than have you wake up to a flooded kitchen at 6am.', + slug: 'priya', + name: 'Priya Sharma', + initials: 'PS', + neighbourhood: 'Mississauga', + specialty: 'Personal chef · Weekly meal prep', + badges: ['Specialty cuisines', 'Mississauga'], + jobs: 84, + rating: 4.98, + years: 4, + quote: 'Sundays I cook five meals for one family. Monday morning their whole week is already sorted.', gradient: 'bg-gradient-to-br from-cream-dark via-cream to-cream-dark', }, ]; @@ -2219,9 +2219,9 @@ export function MeetOurPros() { return (
- +
{/* Vetting badge ribbon — credentials + ID only, no ★ratings. */} @@ -2709,10 +2709,10 @@ function SlatContent({ layer, expanded }: { layer: VaultLayer; expanded: boolean export function Trust() { const layers = [ - { n: '01', t: 'Verified identity', d: 'Government ID collected before any pro is listed.', icon: FileCheck }, - { n: '02', t: 'Trade licence', d: 'Trade licence details collected at onboarding.', icon: Award }, - { n: '03', t: 'Live GPS', d: 'Live GPS so you know exactly when your pro arrives.', icon: MapPin }, - { n: '04', t: 'Before / after photos', d: 'Every job, photo-documented.', icon: Camera }, + { n: '01', t: 'Held in escrow', d: 'You don’t pay until you confirm the job’s done.', icon: FileCheck }, + { n: '02', t: 'Reviewed & approved', d: 'Every Tasker is reviewed and approved before they can work.', icon: Award }, + { n: '03', t: 'Number stays private', d: 'Calls and chat run through Taskly — your real number is never shared.', icon: MapPin }, + { n: '04', t: 'A code at the door', d: 'A 4-digit code confirms the right person showed up.', icon: Camera }, { n: '05', t: 'Two-way ratings', d: 'Both sides accountable. Honest signal, every job.', icon: Eye }, ]; @@ -2733,8 +2733,9 @@ export function Trust() { We take that seriously.

- We check every provider before they’re ever in your home — and you - see exactly who’s coming, track them live, and rate every job. + Your money stays in escrow until you say it’s done, every Tasker is + reviewed before they can work, and your number stays private — so + you’re covered, not just hopeful.

diff --git a/app/layout.tsx b/app/layout.tsx index 9a1fe34f..ad8835cb 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -39,8 +39,8 @@ const manrope = Manrope({ }); export const metadata: Metadata = { - title: 'Taskly.ca — Home Services, Reimagined', - description: 'The premium managed home services marketplace for Toronto & the GTA. Vetted professionals. Fixed prices. Effortless booking.', + title: 'Taskly — Anything on your list, handled | Toronto & the GTA', + description: 'Post any task — type it, say it, or snap a photo — and vetted local Taskers send you offers. You only pay once the work is done, with your money held safe the whole way. No hidden fees, ever. Built in Toronto for the GTA.', // Icons auto-wired by App Router conventions: // /icon.svg → favicon / browser tab // /apple-icon.tsx → iOS home-screen (180×180 rendered at the edge) @@ -49,15 +49,15 @@ export const metadata: Metadata = { // and break if a file is renamed, so we leave the icons block off. metadataBase: new URL('https://www.taskly.ca'), openGraph: { - title: 'Taskly.ca — Home Services, Reimagined', - description: 'The premium managed home services marketplace for Toronto & the GTA. Vetted professionals. Fixed prices. Effortless booking.', + title: 'Taskly — Anything on your list, handled | Toronto & the GTA', + description: 'Post any task — type it, say it, or snap a photo — and vetted local Taskers send you offers. You only pay once the work is done, with your money held safe the whole way. No hidden fees, ever. Built in Toronto for the GTA.', siteName: 'Taskly.ca', type: 'website', }, twitter: { card: 'summary_large_image', - title: 'Taskly.ca — Home Services, Reimagined', - description: 'The premium managed home services marketplace for Toronto & the GTA. Vetted professionals. Fixed prices. Effortless booking.', + title: 'Taskly — Anything on your list, handled | Toronto & the GTA', + description: 'Post any task — type it, say it, or snap a photo — and vetted local Taskers send you offers. You only pay once the work is done, with your money held safe the whole way. No hidden fees, ever. Built in Toronto for the GTA.', }, }; diff --git a/app/login/page.tsx b/app/login/page.tsx index 814309ca..86250dcf 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -798,7 +798,7 @@ function LoginContent() { {[ { icon: MapPin, label: 'Toronto & GTA', desc: 'Active coverage' }, { icon: Shield, label: 'Secure Payments', desc: 'Held until done' }, - { icon: Clock, label: 'Fast Matching', desc: 'Real local pros' }, + { icon: Clock, label: 'Real Offers', desc: 'From local Taskers' }, ].map((item, i) => ( diff --git a/app/onboarding/page.tsx b/app/onboarding/page.tsx index 3ebff426..ba99e982 100644 --- a/app/onboarding/page.tsx +++ b/app/onboarding/page.tsx @@ -496,7 +496,7 @@ function Step1({ d, u, errors, otpSent, onSendOtp, otpVerified, otpSending, otpV

- Taskly Pros earn $35–55/hr with flexible scheduling + You set your price and keep ~80% — paid only when the job’s done

@@ -2275,12 +2275,12 @@ function Step4({ d, u, errors, updateMultiple }: {

- High demand in your area + Your coverage area

{isRadiusMode - ? `Pros within ${radius}km are earning $40-55/hr on average` - : `${d.selectedLocations.length} areas selected — great coverage for bookings` + ? `A ${radius}km radius puts plenty of tasks within reach` + : `${d.selectedLocations.length} areas selected — great coverage for tasks` }

diff --git a/app/page.tsx b/app/page.tsx index 8a47263e..148960e2 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -8,10 +8,14 @@ import { getProfileRole } from '@/lib/api/auth'; import { landingFor } from '@/lib/auth/post-auth'; import { NavBar } from '@/components/NavBar'; import { HeroPostTask } from '@/components/HeroPostTask'; +import { ProblemBeat } from '@/components/landing2/ProblemBeat'; +import { AskAnyWay } from '@/components/landing2/AskAnyWay'; import { TaskFeed } from '@/components/landing2/TaskFeed'; -import { OpenForAll } from '@/components/landing2/OpenForAll'; import { HowItWorks } from '@/components/HowItWorks'; +import { TrustByDesign } from '@/components/landing2/TrustByDesign'; import { EarnAsTasker } from '@/components/landing2/EarnAsTasker'; +import { BuiltForToronto } from '@/components/landing2/BuiltForToronto'; +import { ClosingCta } from '@/components/landing2/ClosingCta'; import { Footer } from '@/components/Footer'; import { MeetOurPros } from './landing-2/sections'; @@ -39,11 +43,15 @@ export default async function Home({
- + - - + + + + + +
); diff --git a/app/pro/[handle]/ProfileView.tsx b/app/pro/[handle]/ProfileView.tsx index 9b919075..2ddef0fd 100644 --- a/app/pro/[handle]/ProfileView.tsx +++ b/app/pro/[handle]/ProfileView.tsx @@ -656,7 +656,7 @@ export function ProfileView({ Ready to work with {p.firstName}?

- Save or share {p.firstName}’s card — vetted, insured, and backed by our 48-hour guarantee. + Save or share {p.firstName}’s card — reviewed, approved, and paid only when the job’s done.

diff --git a/app/the-taskly-advantages/TasklyAdvantagesClient.tsx b/app/the-taskly-advantages/TasklyAdvantagesClient.tsx index 48960f2a..a6aef1d1 100644 --- a/app/the-taskly-advantages/TasklyAdvantagesClient.tsx +++ b/app/the-taskly-advantages/TasklyAdvantagesClient.tsx @@ -43,18 +43,18 @@ function AnimatedNumber({ value, suffix = '' }: { value: number; suffix?: string } const trustStack = [ - { icon: Fingerprint, title: 'Verified Identity', desc: 'Government ID collected for every provider before they’re listed' }, - { icon: FileCheck, title: 'Trade Licence Details', desc: 'Licence details collected at onboarding where relevant' }, - { icon: Navigation, title: 'Real-Time GPS Tracking', desc: 'Know exactly when your professional arrives' }, - { icon: Camera, title: 'Before/After Photos', desc: 'Every job documented with photo evidence' }, - { icon: Users, title: 'Two-Way Ratings', desc: 'Both parties are held accountable' }, + { icon: Lock, title: 'Money Held in Escrow', desc: 'You don’t pay until you confirm the job’s done — your money is held safe the whole way' }, + { icon: BadgeCheck, title: 'Reviewed & Approved', desc: 'Every Tasker is manually reviewed and approved before they can take a single job' }, + { icon: Shield, title: 'Your Number Stays Private', desc: 'Calls and messages run through Taskly, so your real number is never shared' }, + { icon: Fingerprint, title: 'A Code at the Door', desc: 'A 4-digit code confirms the right person showed up, every single time' }, + { icon: Users, title: 'Everything Stays on Taskly', desc: 'Chat, payments and history stay on-platform — so if something’s off, you’re covered' }, ]; const stats = [ - { value: 4.9, display: '4.9', suffix: '★', label: 'Avg Rating' }, - { value: 50000, display: '50,000+', suffix: '+', label: 'Bookings' }, - { value: 0, display: '$0', suffix: '', label: 'Hidden Fees' }, - { value: 100, display: '100%', suffix: '%', label: 'Local GTA' }, + { value: 0, display: '$0', suffix: '', label: 'Hidden fees' }, + { value: 0, display: '$0', suffix: '', label: 'Until it’s done' }, + { value: 100, display: '100%', suffix: '', label: 'Held in escrow' }, + { value: 100, display: '100%', suffix: '', label: 'Local & GTA-built' }, ]; export default function TasklyAdvantagesClient() { @@ -188,13 +188,13 @@ export default function TasklyAdvantagesClient() { Ready to experience
the difference?

- We check every professional before they ever enter your home — and you see who’s coming, track them live, and rate every job. + Your money stays in escrow until you confirm the job’s done. Every Tasker is reviewed and approved before they can work. And the price you see is the price you pay.

- Book Your First Clean + Post your first task diff --git a/components/Footer.tsx b/components/Footer.tsx index 361e1ed5..ca027cd4 100644 --- a/components/Footer.tsx +++ b/components/Footer.tsx @@ -74,7 +74,7 @@ export function Footer() { taskly.

- Toronto’s vetted cleaners and tradespeople. Flat prices. Booked in 30 seconds — or on WhatsApp. Built right here. + Anything on your list, handled by a vetted local — and you only pay when it’s done. Your money stays safe in escrow the whole way. Built in Toronto, for the GTA.

- Any task. One tap. + Have your time back. )} @@ -1075,7 +1075,7 @@ export function HeroPostTask() { animate={reduced ? undefined : { backgroundPositionX: ['210%', '-110%'] }} transition={{ duration: 3, ease: EASE, repeat: Infinity, repeatDelay: 4.5, delay: 2.9 }} > - Post any task. + Have your - Get it{' '} + time{' '} {/* "done" carries its OWN shine clip — a positioned wrapper is lifted out of the parent's background-clip:text, so it needs its own or the text renders invisible. */} @@ -1099,7 +1099,7 @@ export function HeroPostTask() { animate={reduced ? undefined : { backgroundPositionX: ['210%', '-110%'] }} transition={{ duration: 3, ease: EASE, repeat: Infinity, repeatDelay: 4.5, delay: 3.15 }} > - done + back {/* gold underline — a clean straight bar that draws left→right */} - Describe what you need in plain words. Vetted GTA pros send real, fixed quotes in minutes — you pick, they show up. + From cooking to coding — get anything done. {/* ── Composer — task input is the star; location demoted; one black CTA ── */} @@ -1809,7 +1809,7 @@ export function HeroPostTask() { ) : ( <> - Get it done + Get offers )} @@ -1835,7 +1835,7 @@ export function HeroPostTask() { transition={{ duration: 0.6, delay: d(2.5) }} className="flex flex-wrap items-center gap-x-5 gap-y-2 mt-7" > - {['Flat upfront pricing', 'Pay when it’s done', 'Real GTA pros'].map((badge) => ( + {['Pay only when it’s done', 'Vetted local pros', 'No hidden fees'].map((badge) => ( {badge} @@ -1843,19 +1843,19 @@ export function HeroPostTask() { ))} - {/* Mobile proof token (
- ↳ Handyman · 3 offers nearby -
- JA - - Jamal - Etobicoke - - $120 - Hired + ↳ What happens next +
+ {['Describe it', 'Compare offers', 'Pay when done'].map((step, i) => ( + + {step} + {i < 2 && } + + ))}
@@ -1877,6 +1877,25 @@ export function HeroPostTask() {
+ + {/* Scroll cue — for visitors not ready to act yet (the "engage later" + path). Fades out as the hero scrolls away. Desktop only; phones + scroll by instinct. */} + { if (typeof window !== 'undefined') window.scrollBy({ top: Math.round(window.innerHeight * 0.92), behavior: 'smooth' }); }} + style={{ opacity: contentOpacity }} + aria-label="See how it works" + className="hidden lg:flex absolute bottom-6 left-1/2 -translate-x-1/2 z-10 flex-col items-center gap-1.5 text-rich-black/45 hover:text-rich-black transition-colors cursor-pointer" + > + See how it works + + + + diff --git a/components/HowItWorks.tsx b/components/HowItWorks.tsx index 5a15f860..e034455a 100644 --- a/components/HowItWorks.tsx +++ b/components/HowItWorks.tsx @@ -9,50 +9,50 @@ import { MapPin, Search, Shield, Clock, Camera, CreditCard, CheckCircle2, ArrowR const steps = [ { id: '01', - title: 'Choose', + title: 'Describe', subtitle: 'Tell us what you need', - body: 'Pick your service, enter your address, and see the exact price upfront. No quotes, no callbacks, no waiting games.', + body: 'Post your task in plain words and our AI prices it in seconds — no forms, no phone tag, no waiting on callbacks.', image: '/assets/CHOOSE.jpg', color: 'from-blue-500/20 to-cyan-500/10', features: [ - { icon: MapPin, text: 'Enter your address' }, - { icon: Search, text: 'Browse 40+ services' }, - { icon: CreditCard, text: 'See exact price upfront' }, + { icon: Camera, text: 'Even a photo works' }, + { icon: Search, text: 'Anything you need done' }, + { icon: Clock, text: 'Posted in under a minute' }, ], stat: '30s', - statLabel: 'Average booking time', + statLabel: 'to post a task', mockup: 'choose', }, { id: '02', - title: 'Book', - subtitle: 'We handle the matching', - body: 'Instantly matched with a local professional near you. We collect ID and licence details from every pro before they’re listed.', + title: 'Compare', + subtitle: 'Vetted locals make you offers', + body: 'Local Taskers send you real offers — with their prices, profiles and reviews. Every Tasker is reviewed and approved before they can work.', image: '/assets/BOOK.jpg', color: 'from-emerald-500/20 to-green-500/10', features: [ - { icon: Shield, text: 'ID & licence on file' }, - { icon: CheckCircle2, text: 'Real GTA professionals' }, - { icon: Clock, text: 'Auto-matched in seconds' }, + { icon: Shield, text: 'Reviewed & approved' }, + { icon: CheckCircle2, text: 'Profiles, ratings & reviews' }, + { icon: Clock, text: 'Offers, not callbacks' }, ], stat: '$0', - statLabel: 'To get matched', + statLabel: 'to post & compare', mockup: 'book', }, { id: '03', title: 'Done', - subtitle: 'Sit back, we\'ve got this', - body: 'Track your pro in real-time via GPS. Review before/after photos. Pay only when the job’s done.', + subtitle: 'Pay only when it\'s done', + body: 'Your money is held safe in escrow the whole way — and only released when you confirm the job\'s done right. The price you agreed is the price you pay.', image: '/assets/DONE.jpg', color: 'from-violet-500/20 to-purple-500/10', features: [ - { icon: Smartphone, text: 'Real-time GPS tracking' }, - { icon: Camera, text: 'Before/after photo proof' }, + { icon: Shield, text: 'Held safe in escrow' }, + { icon: CreditCard, text: 'Pay only when it\'s done' }, { icon: CheckCircle2, text: 'Rate every job' }, ], - stat: 'Live', - statLabel: 'GPS tracking', + stat: '100%', + statLabel: 'held in escrow', mockup: 'done', }, ]; @@ -87,7 +87,7 @@ function PhoneMockup({ step, className = '' }: { step: string; className?: strin
{/* Service options */}
- {['Standard Clean', 'Deep Clean', 'Plumbing'].map((s, i) => ( + {['Deep clean', 'Math tutor', 'Mehndi artist'].map((s, i) => ( - Total + Your budget - Book Now + Get offers
@@ -405,9 +405,9 @@ function PhoneMockup({ step, className = '' }: { step: string; className?: strin transition={{ duration: 2, repeat: Infinity, ease: 'linear' }} className="w-3 h-3 border border-white/40 border-t-white rounded-full" /> - Matching you... + Collecting offers...
- Finding the best pro nearby + Local Taskers are responding
@@ -418,9 +418,9 @@ function PhoneMockup({ step, className = '' }: { step: string; className?: strin transition={{ delay: 0.8 }} className="bg-white/95 backdrop-blur-sm p-3 rounded-lg" > - Pro details + Your Tasker
- {['ID on file', 'Licence on file', 'Local pro'].map((item, i) => ( + {['Reviewed & approved', 'Real reviews', 'Local Tasker'].map((item, i) => ( - Pro Matched + Offer Accepted
@@ -481,7 +481,7 @@ function PhoneMockup({ step, className = '' }: { step: string; className?: strin Complete -

Standard Clean

+

Deep clean

{/* Content */} @@ -580,7 +580,7 @@ function PhoneMockup({ step, className = '' }: { step: string; className?: strin Invoice
- Standard Clean (2.5 hrs) + Deep clean (2.5 hrs) $89.00
@@ -689,7 +689,7 @@ export function HowItWorks() { That's it.

- We engineered the friction out of home services. From choosing a service to job completion — everything happens on one seamless platform. + We took the friction out of getting things done. Describe it, pick from real offers, and pay only when it’s done — all in one place.

@@ -821,15 +821,15 @@ export function HowItWorks() { className="mt-24 flex flex-col items-center text-center" > - Experience It Now + Post your first task

- Book in under 30 seconds + Free to post · pay only when it’s done

diff --git a/components/NavBar.tsx b/components/NavBar.tsx index 039e3f88..a4e1d939 100644 --- a/components/NavBar.tsx +++ b/components/NavBar.tsx @@ -11,7 +11,6 @@ import { AuthMenu } from '@/components/AuthMenu'; const navLinks: { label: string; href: string }[] = [ { label: 'How It Works', href: '#how-it-works' }, { label: 'Browse Tasks', href: '/browse-tasks' }, - { label: 'Post a Task', href: '/post-task' }, ]; const specialLinks = [{ label: 'Become a Tasker', href: '/join-auth' }]; @@ -87,12 +86,12 @@ export function NavBar({ variant = 'light', minimal = false }: { variant?: 'ligh {/* Right side */}
- Book Now + Post a Task {/* Auth-aware: a Login link when signed out, the profile menu when in. */} @@ -146,11 +145,11 @@ export function NavBar({ variant = 'light', minimal = false }: { variant?: 'ligh Login setMobileOpen(false)} className="bg-rich-black text-cream eyebrow px-6 py-4 text-center rounded-lg hover:bg-warm-gray active:bg-warm-gray/80 transition-all duration-400 min-h-[48px] flex items-center justify-center" > - Book Now + Post a Task )} diff --git a/components/TheProblem.tsx b/components/TheProblem.tsx index 46517bed..5f6961ce 100644 --- a/components/TheProblem.tsx +++ b/components/TheProblem.tsx @@ -5,38 +5,41 @@ import { Clock, Ghost, Star, AlertTriangle, X, PhoneOff, Ban, MessageSquareX } f const painPoints = [ { - stat: '6.2', + stat: '7.6', unit: 'hrs', - label: 'Average time wasted finding a reliable cleaner in the GTA', + label: 'The paid + unpaid work the average Canadian adult carries every day — a second full-time job (StatCan)', icon: Clock, }, { - stat: '43', + stat: '34.8', unit: '%', - label: 'Of Torontonians have been ghosted by a service provider', - icon: Ghost, + label: 'Of working-age adults report high time pressure — never enough hours in the day (StatCan)', + icon: AlertTriangle, }, { - stat: '3.1', - unit: '★', - label: 'Average rating of home service providers on Google', - icon: Star, + stat: '2.5', + unit: 'hrs', + label: 'A day full-time-employed women still spend on housework, on top of their paid jobs (StatCan)', + icon: Clock, }, { - stat: '$340', - unit: '', - label: 'Average cost of damage from unvetted service providers', - icon: AlertTriangle, + stat: '$23K', + unit: '/yr', + label: 'What StatCan values one household’s unpaid work at — the chores you could finally hand off', + icon: Star, }, ]; +// Illustrative of the everyday risks of the off-platform "anything" market +// (Kijiji / Facebook / cash deals) — not attributed quotes. The strategy is +// explicit: no invented reviews or sourced statistics. const horrorStories = [ - { text: 'Booked a cleaner online. They never showed up. No refund.', source: 'Reddit r/Toronto', upvotes: '2.4k' }, - { text: 'The handyman scratched our hardwood floors. No insurance. $1,800 in damage.', source: 'Google Review', upvotes: '847' }, - { text: 'Got quoted $80 on the phone, charged $240 at the door. Zero recourse.', source: 'Reddit r/askTO', upvotes: '1.9k' }, - { text: 'Three different plumbers from a listing site. Three no-shows in one week.', source: 'Twitter/X', upvotes: '3.1k' }, - { text: 'Found my cleaner going through my drawers on my security camera.', source: 'Reddit r/Toronto', upvotes: '5.7k' }, - { text: 'Hired from a marketplace app. They used bleach on my marble counters.', source: 'Google Review', upvotes: '412' }, + { text: 'You book someone online. They never show. There’s no refund.', source: 'Booked online', upvotes: 'No refund' }, + { text: 'A handyman scratches the hardwood. No insurance — the damage is yours.', source: 'Hired a stranger', upvotes: 'No recourse' }, + { text: 'Quoted $80 on the phone. Charged $240 at the door. Take it or leave it.', source: 'Phone quote', upvotes: 'Bait & switch' }, + { text: 'Three pros from a listing site. Three no-shows in one week.', source: 'Listing site', upvotes: 'No-shows' }, + { text: 'You hand a stranger your address and your number, and hope for the best.', source: 'Off the books', upvotes: 'No privacy' }, + { text: 'Wrong person, wrong supplies, ruined countertops — and nobody to call.', source: 'Marketplace app', upvotes: 'No backup' }, ]; export function TheProblem() { @@ -68,12 +71,12 @@ export function TheProblem() { className="mb-20 md:mb-24" >

- Finding reliable
home help shouldn't
feel like{' '} - gambling + Getting it off your
plate shouldn't feel{' '} + like a gamble .

- The GTA home services market is broken. Unvetted providers, surprise pricing, and zero accountability. Sound familiar? + Greater Toronto runs on borrowed time — and the usual ways to get help mean unvetted strangers, surprise pricing, and zero recourse. Sound familiar?

@@ -87,7 +90,7 @@ export function TheProblem() {
@@ -106,7 +109,7 @@ export function TheProblem() { {story.source} - ▲ {story.upvotes} + {story.upvotes}
@@ -127,7 +130,7 @@ export function TheProblem() { {story.source} - ▲ {story.upvotes} + {story.upvotes}
diff --git a/components/WhyTaskly.tsx b/components/WhyTaskly.tsx index 4f497593..d341b708 100644 --- a/components/WhyTaskly.tsx +++ b/components/WhyTaskly.tsx @@ -33,47 +33,47 @@ function AnimatedCounter({ value, suffix = '', prefix = '' }: { value: number; s const comparisons = [ { label: 'Vetting', - others: 'Self-reported profiles', - taskly: 'ID and licence details on file before listing', + others: 'Self-reported profiles. Anyone can claim anything.', + taskly: 'Every Tasker is reviewed and approved before they can work.', icon: ShieldCheck, }, { label: 'Pricing', others: 'Quote after quote. Hidden fees at the door.', - taskly: 'Fixed price shown before you book. $0 hidden fees.', + taskly: 'The price you agree is the price you pay. $0 hidden customer fees.', icon: DollarSign, }, { - label: 'Tracking', - others: '"They\'ll be there between 9am and 5pm"', - taskly: 'Real-time GPS. Know exactly when they arrive.', + label: 'Arrival', + others: '"They\'ll be there between 9am and 5pm."', + taskly: 'A 4-digit code at the door confirms the right person showed up.', icon: MapPin, }, { - label: 'Accountability', - others: 'No photos. No proof. Your word vs theirs.', - taskly: 'Before/after photos for every single job.', + label: 'Privacy', + others: 'Strangers get your number. Deals happen off the books.', + taskly: 'Calls and chat stay on Taskly — your real number is never shared.', icon: Camera, }, { label: 'Guarantee', - others: 'Good luck getting a callback.', - taskly: 'Re-done free in 48h or full refund. Period.', + others: 'Cash up front, then hope for the best.', + taskly: 'You don\'t pay until you confirm it\'s done. Money held safe in escrow.', icon: Star, }, { label: 'Speed', others: 'Days of calling around, comparing, waiting.', - taskly: '30 seconds to book. Auto-matched instantly.', + taskly: 'Post in seconds. Real offers from locals — not callbacks.', icon: Clock, }, ]; const stats = [ - { value: 10, suffix: '', label: 'Security Layers', prefix: '' }, - { value: 30, suffix: 's', label: 'To Book', prefix: '' }, - { value: 0, suffix: '', label: 'Hidden Fees', prefix: '$' }, - { value: 48, suffix: 'h', label: 'Guarantee', prefix: '' }, + { value: 0, suffix: '', label: 'Hidden fees', prefix: '$' }, + { value: 0, suffix: '', label: 'To post a task', prefix: '$' }, + { value: 100, suffix: '%', label: 'Held in escrow', prefix: '' }, + { value: 100, suffix: '%', label: 'Built in the GTA', prefix: '' }, ]; export function WhyTaskly() { @@ -254,10 +254,10 @@ export function WhyTaskly() { Ready to switch?

- Book Your First Clean + Post your first task diff --git a/components/landing2/AskAnyWay.tsx b/components/landing2/AskAnyWay.tsx new file mode 100644 index 00000000..c6999b10 --- /dev/null +++ b/components/landing2/AskAnyWay.tsx @@ -0,0 +1,126 @@ +'use client'; + +// "Type it. Say it. Or just snap a photo." — a feature beat that showcases +// Taskly's multimodal AI intake (the same text/voice/photo composer that lives +// in the hero), as its own editorial triptych. The "only-on-Taskly" wedge vs +// handyman/cleaning marketplaces. Cream + gold styling to match the landing. + +import { motion } from 'motion/react'; +import { Keyboard, Mic, Camera, ArrowRight, Sparkles } from 'lucide-react'; + +const EASE = [0.16, 1, 0.3, 1] as const; + +function toTop() { + if (typeof window !== 'undefined') window.scrollTo({ top: 0, behavior: 'smooth' }); +} + +type Mode = { icon: typeof Mic; title: string; body: string; example: string }; + +const MODES: Mode[] = [ + { + icon: Keyboard, + title: 'Type it', + body: 'A sentence is enough. Our AI reads it and sorts out the category, the details and a fair price.', + example: '“My kitchen tap’s been dripping for a week.”', + }, + { + icon: Mic, + title: 'Say it', + body: 'On the go? Tap the mic and just talk — we’ll write the whole task up for you, in any language.', + example: 'Tap · speak · we transcribe it', + }, + { + icon: Camera, + title: 'Snap it', + body: 'Not sure what to even call it? Photograph it, and our AI suggests exactly what you need done.', + example: 'Photo → suggested service', + }, +]; + +function ModeCard({ m, i }: { m: Mode; i: number }) { + const Icon = m.icon; + return ( + + {/* gold hairline on hover — the landing's signature flourish */} + + + {/* numeral + icon chip */} +
+ + + + 0{i + 1} +
+ +

+ {m.title} +

+

+ {m.body} +

+ + {/* example chip */} +
+ + {m.example} +
+
+ ); +} + +export function AskAnyWay() { + return ( +
+
+ {/* Header */} + + Asking is the easy part +

+ Type it. Say it.
Or just snap a photo. +

+

+ Saw something you need? Skip the menus and categories — describe it however’s easiest, and our AI turns it into a clear, priced task in seconds. +

+
+ + {/* Three modes */} +
+ {MODES.map((m, i) => ( + + ))} +
+ + {/* Footer line + CTA */} + +

+ Powered by AI — but it’s the ease you’ll notice, not the tech. +

+ +
+
+
+ ); +} diff --git a/components/landing2/BuiltForToronto.tsx b/components/landing2/BuiltForToronto.tsx new file mode 100644 index 00000000..9620a0e2 --- /dev/null +++ b/components/landing2/BuiltForToronto.tsx @@ -0,0 +1,53 @@ +'use client'; + +// The "why" / movement beat — the brand belief that connects both sides: +// GTA's underused talent ↔ its time-poor households. Honest, local, +// founder-grounded. No fabricated stats, no fake reviews. + +import { motion } from 'motion/react'; +import { MapPin } from 'lucide-react'; + +const EASE = [0.16, 1, 0.3, 1] as const; + +export function BuiltForToronto() { + return ( +
+
+ {/* Left — the belief */} + + Why we built Taskly +

+ No skill wasted.
No one drowning. +

+

+ Toronto is the busiest, most diverse city there is — full of people with more on their plate than hours in the day, and people with real skills and not enough work. Taskly connects them. That’s the whole idea. +

+

+ No call centres. No franchises. Built right here in the GTA — for a safer, simpler way to hand off the list, and a fairer way for skilled people to earn. +

+
+ + {/* Right — made-in-the-GTA emblem + honest founder note */} + +
+ + + Made in the GTA + +
+ “A safer, simpler way to hand off anything on your list — and a fairer way for skilled people to earn. A product I’d want my own family to use.” +
+

— Founder, Taskly

+ +
+
+ ); +} diff --git a/components/landing2/ClosingCta.tsx b/components/landing2/ClosingCta.tsx new file mode 100644 index 00000000..89a44b2c --- /dev/null +++ b/components/landing2/ClosingCta.tsx @@ -0,0 +1,51 @@ +'use client'; + +// Closing bookend — repeats the distinctive brand asset (Byron Sharp): "Have +// your time back." One clear action: post. The whole page rises to this. + +import Link from 'next/link'; +import { motion } from 'motion/react'; +import { ArrowRight } from 'lucide-react'; + +const EASE = [0.16, 1, 0.3, 1] as const; +function toTop() { if (typeof window !== 'undefined') window.scrollTo({ top: 0, behavior: 'smooth' }); } + +export function ClosingCta() { + return ( +
+
+ + +

+ Have your
time back. +

+

+ Post your first task free. See who can help in minutes. +

+
+ + + Or earn as a Tasker → + +
+

+ Greater Toronto Area · Free to post · Pay only when it’s done +

+
+
+ ); +} diff --git a/components/landing2/EarnAsTasker.tsx b/components/landing2/EarnAsTasker.tsx index bba81f07..56eed9c1 100644 --- a/components/landing2/EarnAsTasker.tsx +++ b/components/landing2/EarnAsTasker.tsx @@ -19,29 +19,29 @@ import { } from 'motion/react'; import { Check, ArrowRight, TrendingUp, Star, BadgeCheck, Bell, - Paintbrush, Wrench, Sparkles, Hammer, Leaf, Truck, + Bot, PartyPopper, MessageSquare, Flower2, GraduationCap, ChefHat, } from 'lucide-react'; const EASE = [0.16, 1, 0.3, 1] as const; const HERO_IMG = '/assets/tasker/earn.png'; // ← your generated image -const HERO_FALLBACK = '/assets/pros/maria.png'; // until it's added +const HERO_FALLBACK = '/assets/pros/jordan.png'; // until it's added const PERKS = [ - 'Thousands of jobs, right in your area', - 'No subscriptions, no lead fees — keep what you earn', - 'Get paid fast and securely, every time', + 'Real local work, matched to your skills', + 'No subscriptions, no lead fees — you only pay when you get paid', + 'Get paid securely — escrow protects your pay too', 'Work the hours that fit your life', ]; type Job = { id: string; Icon: ComponentType<{ className?: string; strokeWidth?: number }>; title: string; pay: number }; const JOBS: Job[] = [ - { id: 'tap', Icon: Wrench, title: 'Fix a leaking tap', pay: 95 }, - { id: 'paint', Icon: Paintbrush, title: 'Paint a feature wall', pay: 180 }, - { id: 'clean', Icon: Sparkles, title: 'Deep-clean a condo', pay: 150 }, - { id: 'assemble', Icon: Hammer, title: 'Assemble a wardrobe', pay: 80 }, - { id: 'garden', Icon: Leaf, title: 'Mow & tidy a backyard', pay: 110 }, - { id: 'move', Icon: Truck, title: 'Help move a sofa', pay: 130 }, + { id: 'ai', Icon: Bot, title: 'Set up an AI workflow', pay: 120 }, + { id: 'mehndi', Icon: PartyPopper, title: 'Mehndi for a party', pay: 220 }, + { id: 'interview', Icon: MessageSquare, title: 'Run a mock interview', pay: 80 }, + { id: 'soundbath', Icon: Flower2, title: 'Host a sound bath', pay: 150 }, + { id: 'tutor', Icon: GraduationCap, title: 'Tutor Grade 9 math', pay: 55 }, + { id: 'chef', Icon: ChefHat, title: 'Cook a dinner party', pay: 260 }, ]; // ── Count-up, fires once in view ──────────────────────────────────────────── @@ -179,8 +179,9 @@ export function EarnAsTasker() { viewport={{ once: true }} transition={{ duration: 0.7, ease: EASE, delay: 0.12 }} className="mt-5 max-w-[42ch] font-sans text-[15.5px] sm:text-[17px] font-500 leading-[1.6] text-cream/60" > - Whether you’re a meticulous cleaner or a master carpenter, Taskly turns - your skills into steady, flexible income — on your terms. + Coach, chef, tutor, creator, cleaner — whatever you’re great at, + Toronto needs it. Turn your skills into steady income, on your own + schedule. New here? Your experience counts.
    @@ -206,7 +207,7 @@ export function EarnAsTasker() { > - Free to join · Matched in minutes + Free to join · Keep ~80% of every job @@ -263,7 +264,7 @@ export function EarnAsTasker() {
    - Verified Tasker + Approved Tasker diff --git a/components/landing2/HeroJourney.tsx b/components/landing2/HeroJourney.tsx index 8cf247f1..e611e035 100644 --- a/components/landing2/HeroJourney.tsx +++ b/components/landing2/HeroJourney.tsx @@ -20,7 +20,7 @@ import { useEffect, useRef, useState } from 'react'; import { motion, AnimatePresence, useReducedMotion } from 'motion/react'; -import { Sparkles, Check, MapPin, TrendingUp, Wallet } from 'lucide-react'; +import { Sparkles, Check, ShieldCheck, Clock } from 'lucide-react'; const GOLD = '#A88654'; const GOLD_LT = '#C9A878'; @@ -29,68 +29,48 @@ const INK = '#0D0D0D'; const CREAM = '#F4EFE7'; const EASE = [0.16, 1, 0.3, 1] as const; -type Act = 'post' | 'offers' | 'hire' | 'route' | 'done' | 'earn'; +type Act = 'post' | 'offers' | 'hire' | 'finding' | 'arrive' | 'relax'; const TIMELINE: { act: Act; dur: number }[] = [ { act: 'post', dur: 2300 }, { act: 'offers', dur: 1900 }, { act: 'hire', dur: 1700 }, - { act: 'route', dur: 3000 }, - { act: 'done', dur: 1900 }, - { act: 'earn', dur: 2600 }, + { act: 'finding', dur: 2000 }, + { act: 'arrive', dur: 2800 }, + { act: 'relax', dur: 2600 }, ]; -const SCENE: Record = { post: 0, offers: 0, hire: 0, route: 1, done: 1, earn: 2 }; +const SCENE: Record = { post: 0, offers: 0, hire: 0, finding: 1, arrive: 1, relax: 2 }; interface Job { q: string; cat: string; pro: string; area: string; price: string; week: string; others: { who: string; price: string }[]; } +// Diverse, premium, in-person GTA tasks (in-person keeps the "on the way" +// scene coherent) — never handyman. This is the post-"Get offers" payoff. const JOBS: Job[] = [ - { q: 'Mount a 65" TV', cat: 'Handyman', pro: 'Marcus', area: 'North York', price: '$190', week: '$1,240', - others: [{ who: 'Dev', price: '$175' }, { who: 'Liam', price: '$210' }] }, - { q: 'Build an IKEA wardrobe', cat: 'Assembly', pro: 'Jamal', area: 'Etobicoke', price: '$120', week: '$980', - others: [{ who: 'Sara', price: '$140' }, { who: 'Tom', price: '$110' }] }, - { q: 'Walk Bella twice a day', cat: 'Pet care', pro: 'Grace', area: 'Leslieville', price: '$140', week: '$1,060', - others: [{ who: 'Noah', price: '$155' }, { who: 'Aisha', price: '$130' }] }, + { q: 'Mehndi for our sangeet', cat: 'Celebrations', pro: 'Simran', area: 'Brampton', price: '$220', week: '$1,180', + others: [{ who: 'Anjali', price: '$240' }, { who: 'Priya', price: '$205' }] }, + { q: 'Sound bath for my team', cat: 'Wellness', pro: 'Maya', area: 'Don Mills', price: '$260', week: '$1,020', + others: [{ who: 'Leo', price: '$245' }, { who: 'Sara', price: '$280' }] }, + { q: 'Personal chef, date night', cat: 'Personal chef', pro: 'Daniel', area: 'Downtown', price: '$240', week: '$1,300', + others: [{ who: 'Mei', price: '$220' }, { who: 'Omar', price: '$255' }] }, +]; + +// Per-job tracking routes — each starts from a DIFFERENT corner and follows the +// road grid (orthogonal turns) to YOU at (178,145). The gold trail and the dot +// both use the SAME path string, so they stay in lock-step. viewBox 0 0 360 240. +const ROUTES = [ + 'M300 82 L186 82 Q178 82 178 90 L178 145', // from the NE + 'M263 205 L263 153 Q263 145 255 145 L178 145', // from the S + 'M41 82 L80 82 Q88 82 88 90 L88 137 Q88 145 96 145 L178 145', // from the NW (zig-zag) ]; function initials(name: string) { return name.slice(0, 2).toUpperCase(); } -/* ── The courier van (the animated character) ───────────────────────────── */ -function Van({ moving }: { moving: boolean }) { - return ( - - {/* speed lines */} - {moving && ( - - - - - - )} - {/* body */} - - {/* gold parcel on roof */} - - - {/* cabin window + driver head */} - - - {/* side accent stripe */} - - {/* wheels */} - {[34, 86].map((cx) => ( - - - - - - - ))} - - ); -} +/* (The courier-van scene was replaced by a mode-agnostic "secured & confirmed" + escrow beat — see Scene 2 — so remote tasks like AI coaching or a mock + interview fit the story too, not just physical "someone drives to you" jobs.) */ export function HeroJourney({ warm = false }: { warm?: boolean }) { const reduced = !!useReducedMotion(); @@ -101,6 +81,7 @@ export function HeroJourney({ warm = false }: { warm?: boolean }) { const act = TIMELINE[step].act; const scene = SCENE[act]; const job = JOBS[loop % JOBS.length]; + const route = ROUTES[loop % ROUTES.length]; // Drive the timeline (one chained timeout per step; loops forever). useEffect(() => { @@ -146,14 +127,6 @@ export function HeroJourney({ warm = false }: { warm?: boolean }) { - - {/* Panel shell */}
    - {/* ── SCENE 2 · ON THE WAY ───────────────────────────── */} + {/* ── SCENE 2 · FIND & TRACK (live map) ──────────────── */}

    - {act === 'done' ? 'Arrived · job done' : `${job.pro} is on the way`} + {act === 'finding' ? 'Finding Taskers nearby' : `${job.pro} is on the way`}

    - {/* map stage */} + {/* live map — a local ping finds Taskers in Downtown, then the + matched one tracks in to you. The Uber-familiar bit people love: + predictability + live tracking. */}
    - {/* faint streets */} - - - {/* drawn route */} - - - + {/* Uber-style map base — matches the "02 Compare" mockup: + warm off-white, soft blocks, white major roads, a park and + a transit marker. Decorative; the ping + tracking sit on top. */} + + + {/* parks */} + + + + {/* blocks */} + + + + + + + + + + {/* building footprints */} + + + + + {/* major roads (white) */} + + + + + + {/* secondary streets */} + + + + + {/* a quiet street label */} + QUEEN ST W + {/* transit marker */} + + + M + + {/* coffee POI */} + + - {/* origin pin */} - - - - + {/* Downtown tag */} + + + {job.area} · GTA - {/* destination — home */} - - - - - {/* arrival burst */} - - {act === 'done' && !reduced && [...Array(7)].map((_, k) => ( - - ))} - - - - {/* the van character — drives the route (px keyframes tuned to - the ~360x230 map; transform-based for GPU) */} - - - - - + {/* route + live tracking — same viewBox + slice as the base map + so they align. The matched Tasker drives the ROADS to you; + the gold trail draws in lock-step with the dot (one shared + path → the dot rides the drawing tip). */} + + {/* faint planned route */} + + {/* gold trail — pathLength draws in sync with the dot below */} + + + {/* two other nearby Taskers — ping while finding */} + {[{ x: 95, y: 188, d: 0 }, { x: 288, y: 168, d: 0.25 }].map((p) => ( + + ))} + + {/* YOU — destination; the local ping originates here */} + {!reduced && act === 'finding' && [0, 1, 2].map((k) => ( + + ))} + {act === 'arrive' && !reduced && [...Array(8)].map((_, k) => ( + + ))} + + + + {/* the matched Tasker — rides the route in lock-step with the trail */} + + + + + - {/* ETA / done tag */} + {/* status (bottom-left) */} - - {act === 'done' ? <> Paid {job.price} : 'ETA 12 min'} + + {act === 'finding' ? <> 3 nearby : <>ETA 9 min} + + {/* escrow trust chip (bottom-right) — keeps "safe" in frame */} + + + {job.price} held safe +
    - {/* ── SCENE 3 · EARN / BECOME A TASKER ───────────────── */} + {/* ── SCENE 3 · IT'S HANDLED (customer payoff) ───────── */}

    - The other side + And you?

    -
    - + + + {/* the relief — a calm gold check lands */} + + + + +

    + It’s handled. +

    +

    + Paid securely · {job.price} +

    - - You earned + {/* the payoff — the whole brand promise, made literal */} + + + Your evening’s yours again - -
    - - {job.price} - - this job -
    - - {/* week earnings ticker bars */} -
    -
    - This week - - +18% - -
    -
    - {[0.4, 0.55, 0.45, 0.7, 0.6, 0.85, 1].map((h, i) => ( - - ))} -
    -
    {job.week}
    -
    - -
    - Become a tasker -
    diff --git a/components/landing2/OpenForAll.tsx b/components/landing2/OpenForAll.tsx index 4d2741c6..54e8c43b 100644 --- a/components/landing2/OpenForAll.tsx +++ b/components/landing2/OpenForAll.tsx @@ -41,9 +41,9 @@ const COL_B: Job[] = [ // The post-a-task flow, three editorial beats — Airtasker's idea, our craft. const STEPS: { n: string; title: string; desc: string }[] = [ - { n: '01', title: 'Describe what you need', desc: 'A sentence is enough — add a photo or two if it helps.' }, - { n: '02', title: 'Set your budget', desc: 'Name your price, or open it up and let local pros quote you.' }, - { n: '03', title: 'Pick your Tasker', desc: 'Compare offers, ratings and reviews — then book the one you like.' }, + { n: '01', title: 'Describe what you need', desc: 'A sentence is enough. Type it, say it, or snap a photo — our AI sorts out the rest.' }, + { n: '02', title: 'Set your budget', desc: 'Name your price, or leave it open and let local Taskers make you offers.' }, + { n: '03', title: 'Pick your Tasker', desc: 'Compare offers, profiles and reviews, then book — your money stays safe until it\'s done.' }, ]; function toTop() { diff --git a/components/landing2/ProblemBeat.tsx b/components/landing2/ProblemBeat.tsx new file mode 100644 index 00000000..39eeb838 --- /dev/null +++ b/components/landing2/ProblemBeat.tsx @@ -0,0 +1,92 @@ +'use client'; + +// StoryBrand "problem" stage — agitate time-poverty, then resolve into the +// promise ("Have your time back"). A diverse to-do list clears itself, item by +// item, so the visitor *feels* the relief before they're asked to act. + +import { motion } from 'motion/react'; +import { Check, ArrowRight } from 'lucide-react'; + +const EASE = [0.16, 1, 0.3, 1] as const; +function toTop() { if (typeof window !== 'undefined') window.scrollTo({ top: 0, behavior: 'smooth' }); } + +// Deliberately diverse — never just home/handyman. +const LIST = [ + 'Deep clean before the in-laws land', + 'Set up that AI thing for work', + 'Mehndi booked for Diwali', + 'Pick Mom up from Pearson', + 'Finally sort the dripping tap', + 'Meals prepped for the week', +]; + +export function ProblemBeat() { + return ( +
    +
    + {/* Left — agitate, then resolve */} + + The real problem +

    + You clock out.
    The list doesn’t. +

    +

    + It’s not just doing the list — it’s carrying it: the mental tabs that never close, the weekends gone before they start. The average Torontonian loses close to a full workday’s worth of hours, every day to errands and upkeep — on top of the job they already have. +

    +

    + What if you could just hand it off? +

    + +
    + + {/* Right — the list clearing itself */} + +
    + Your list + Handled → +
    +
      + {LIST.map((item, i) => ( + + + + + + {item} + + + + ))} +
    +
    +
    +
    + ); +} diff --git a/components/landing2/TaskFeed.tsx b/components/landing2/TaskFeed.tsx index 889673e6..15eaa830 100644 --- a/components/landing2/TaskFeed.tsx +++ b/components/landing2/TaskFeed.tsx @@ -1,79 +1,80 @@ 'use client'; -// /2 — "Happening right now" live task feed. Airtasker's social-proof section, -// reimagined as a living thing: two opposite-direction marquees of editorial -// task cards flowing across the screen (pause on hover), with real GTA flavour -// and "matched in N min" speed proof. Monochrome, not the generic blue grid. +// /2 — "See what you can get done" — capability showcase, not a live feed. +// Two opposite-direction marquees of editorial idea-cards flowing across the +// screen (pause on hover). These are INSPIRATION — real things you can hand off +// on Taskly — deliberately weighted toward the surprising/modern/under-served +// categories (AI, celebrations, newcomer, wellness, life-admin) that set Taskly +// apart from handyman/cleaning marketplaces. No fake posters, timestamps, or +// offer counts: honest by design. import { useMemo } from 'react'; import { motion } from 'motion/react'; import { - Sparkles, Wrench, ChefHat, Snowflake, PawPrint, Archive, Scissors, - GraduationCap, HeartHandshake, Users, ArrowRight, + Sparkles, Wrench, Archive, Bot, Rocket, PartyPopper, Plane, Flower2, + Lightbulb, MapPin, ArrowRight, } from 'lucide-react'; const EASE = [0.16, 1, 0.3, 1] as const; -type CatKey = 'cleaning' | 'maintenance' | 'cooking' | 'seasonal' | 'pet' | 'organizing' | 'salon' | 'tutoring' | 'psw'; +type CatKey = + | 'cleaning' | 'maintenance' | 'organizing' // familiar (reframed) + | 'ai' | 'coaching' | 'events' | 'newcomer' | 'wellness' | 'life'; // the differentiators + const ICON: Record = { - cleaning: Sparkles, maintenance: Wrench, cooking: ChefHat, seasonal: Snowflake, - pet: PawPrint, organizing: Archive, salon: Scissors, tutoring: GraduationCap, psw: HeartHandshake, + cleaning: Sparkles, maintenance: Wrench, organizing: Archive, + ai: Bot, coaching: Rocket, events: PartyPopper, newcomer: Plane, + wellness: Flower2, life: Lightbulb, }; // Per-category accent — soft tinted chip + saturated icon/label, so each card // reads distinctly without going loud. (Literal class strings so Tailwind's -// scanner keeps them.) +// scanner keeps them.) New categories get their own distinct hues. const ACCENT: Record = { - cleaning: { chip: 'bg-teal-500/[0.10]', text: 'text-teal-700', icon: 'text-teal-600' }, - maintenance: { chip: 'bg-blue-500/[0.10]', text: 'text-blue-700', icon: 'text-blue-600' }, - cooking: { chip: 'bg-amber-500/[0.12]', text: 'text-amber-700', icon: 'text-amber-600' }, - seasonal: { chip: 'bg-sky-500/[0.10]', text: 'text-sky-700', icon: 'text-sky-600' }, - pet: { chip: 'bg-green-500/[0.10]', text: 'text-green-700', icon: 'text-green-600' }, - organizing: { chip: 'bg-violet-500/[0.10]', text: 'text-violet-700', icon: 'text-violet-600' }, - salon: { chip: 'bg-pink-500/[0.10]', text: 'text-pink-700', icon: 'text-pink-600' }, - tutoring: { chip: 'bg-indigo-500/[0.10]', text: 'text-indigo-700', icon: 'text-indigo-600' }, - psw: { chip: 'bg-rose-500/[0.10]', text: 'text-rose-700', icon: 'text-rose-600' }, + cleaning: { chip: 'bg-teal-500/[0.10]', text: 'text-teal-700', icon: 'text-teal-600' }, + maintenance: { chip: 'bg-blue-500/[0.10]', text: 'text-blue-700', icon: 'text-blue-600' }, + organizing: { chip: 'bg-violet-500/[0.10]', text: 'text-violet-700', icon: 'text-violet-600' }, + ai: { chip: 'bg-fuchsia-500/[0.10]', text: 'text-fuchsia-700', icon: 'text-fuchsia-600' }, + coaching: { chip: 'bg-cyan-500/[0.10]', text: 'text-cyan-700', icon: 'text-cyan-600' }, + events: { chip: 'bg-orange-500/[0.12]', text: 'text-orange-700', icon: 'text-orange-600' }, + newcomer: { chip: 'bg-emerald-500/[0.10]', text: 'text-emerald-700', icon: 'text-emerald-600' }, + wellness: { chip: 'bg-purple-500/[0.10]', text: 'text-purple-700', icon: 'text-purple-600' }, + life: { chip: 'bg-slate-500/[0.10]', text: 'text-slate-700', icon: 'text-slate-600' }, }; -interface Task { - name: string; img: number; cat: CatKey; catLabel: string; - title: string; area: string; ago: string; price: string; offers: number; +interface Idea { + cat: CatKey; catLabel: string; title: string; area: string; price: string; } -const ROW_A: Task[] = [ - { name: 'Priya', img: 5, cat: 'cleaning', catLabel: 'Cleaning', title: 'Deep clean before move-out', area: 'Etobicoke', ago: '4 min ago', price: '$260', offers: 9 }, - { name: 'Marcus', img: 12, cat: 'maintenance', catLabel: 'Repairs', title: 'Mount 3 TVs + hide the cables', area: 'North York', ago: 'just now', price: '$190', offers: 6 }, - { name: 'Aisha', img: 24, cat: 'cooking', catLabel: 'Cooking', title: 'Personal chef, dinner for 8', area: 'Liberty Village', ago: '12 min ago', price: '$340', offers: 12 }, - { name: 'Dev', img: 33, cat: 'seasonal', catLabel: 'Seasonal', title: 'Clear the driveway after the storm', area: 'Scarborough', ago: '2 min ago', price: '$80', offers: 4 }, - { name: 'Grace', img: 45, cat: 'pet', catLabel: 'Pet care', title: 'Dog walk, twice a day this week', area: 'Leslieville', ago: '8 min ago', price: '$140', offers: 7 }, - { name: 'Tom', img: 51, cat: 'organizing', catLabel: 'Organizing', title: 'Declutter & reset the garage', area: 'Mississauga', ago: '18 min ago', price: '$300', offers: 5 }, +// Row A — leads with the "I didn't know I could ask for that" categories. +const ROW_A: Idea[] = [ + { cat: 'ai', catLabel: 'AI for work', title: 'Set up an AI system so I stop drowning in email', area: 'Liberty Village', price: '$120' }, + { cat: 'life', catLabel: 'Tech help', title: 'Teach my dad to actually use his new iPhone', area: 'Scarborough', price: '$40' }, + { cat: 'events', catLabel: 'Celebrations', title: "Mehndi for my sister's sangeet — 12 guests", area: 'Brampton', price: '$220' }, + { cat: 'newcomer', catLabel: 'Newcomer', title: 'Pick up my parents from Pearson at 11pm', area: 'Mississauga', price: '$70' }, + { cat: 'wellness', catLabel: 'Wellness', title: 'Sound bath for my burnt-out team of 6', area: 'Downtown', price: '$260' }, + { cat: 'coaching', catLabel: 'Coaching', title: 'Coach me to launch my YouTube channel', area: 'Remote · GTA', price: '$90' }, + { cat: 'life', catLabel: 'Life admin', title: 'Plant doctor — my monstera is dying, send help', area: 'Leslieville', price: '$45' }, + { cat: 'ai', catLabel: 'No-code', title: 'Build me a simple app to run my side hustle', area: 'Remote · GTA', price: '$150' }, + { cat: 'events', catLabel: 'Ceremony', title: 'Puja at our new condo before we move in', area: 'Vaughan', price: '$120' }, ]; -const ROW_B: Task[] = [ - { name: 'Sara', img: 9, cat: 'salon', catLabel: 'Salon', title: 'Blowout + makeup, at home', area: 'Yorkville', ago: '5 min ago', price: '$120', offers: 8 }, - { name: 'Leo', img: 14, cat: 'tutoring', catLabel: 'Tutoring', title: 'Grade 10 math, twice weekly', area: 'Markham', ago: '9 min ago', price: '$55/hr', offers: 5 }, - { name: 'Nina', img: 26, cat: 'psw', catLabel: 'Senior care', title: 'Companion care for mom', area: 'Oakville', ago: '22 min ago', price: '$34/hr', offers: 6 }, - { name: 'Raj', img: 31, cat: 'maintenance', catLabel: 'Repairs', title: 'Fix a leaking kitchen tap', area: 'Brampton', ago: 'just now', price: '$140', offers: 11 }, - { name: 'Mia', img: 47, cat: 'cleaning', catLabel: 'Cleaning', title: 'Weekly condo clean', area: 'Downtown', ago: '14 min ago', price: '$110', offers: 7 }, - { name: 'Omar', img: 56, cat: 'cooking', catLabel: 'Cooking', title: 'Meal prep for the whole week', area: 'East York', ago: '6 min ago', price: '$220', offers: 9 }, +// Row B — more ideas, blending modern + a couple of familiar tasks, reframed. +const ROW_B: Idea[] = [ + { cat: 'coaching', catLabel: 'Coaching', title: 'Mock interview — final round at a bank Thursday', area: 'Remote · GTA', price: '$80' }, + { cat: 'newcomer', catLabel: 'Newcomer', title: 'Help me pass my Canadian citizenship test', area: 'Remote · GTA', price: '$50' }, + { cat: 'events', catLabel: 'Celebrations', title: 'Sing happy birthday to my mom in Tagalog', area: 'North York', price: '$30' }, + { cat: 'life', catLabel: 'Tech help', title: 'Set up my smart home — lights, doorbell, locks', area: 'Markham', price: '$130' }, + { cat: 'coaching', catLabel: 'Coaching', title: 'Resume + LinkedIn glow-up — I just got laid off', area: 'Remote · GTA', price: '$80' }, + { cat: 'organizing', catLabel: 'Organizing', title: 'Declutter my closet, Marie-Kondo style', area: 'Yorkville', price: '$120' }, + { cat: 'cleaning', catLabel: 'Home refresh', title: 'Get my place guest-ready before my in-laws land', area: 'Etobicoke', price: '$160' }, + { cat: 'wellness', catLabel: 'Just for fun', title: 'Tarot reading for my 30th birthday', area: 'Downtown', price: '$60' }, + { cat: 'maintenance',catLabel: 'Assembly', title: "Assemble the IKEA wardrobe I've dodged for a month", area: 'East York', price: '$90' }, ]; -function OffersBadge({ n }: { n: number }) { - return ( - - - - {n} offers - - - ); -} - -function TaskCard({ t }: { t: Task }) { +function IdeaCard({ t }: { t: Idea }) { const Icon = ICON[t.cat]; const a = ACCENT[t.cat]; - const fresh = t.ago === 'just now'; - // Hourly vs flat — label the numeral like a dispatch ticket. const isRate = t.price.includes('/hr'); return (
    @@ -85,58 +86,45 @@ function TaskCard({ t }: { t: Task }) { />
    - {/* Eyebrow — prominent category chip (the primary signal) + timestamp */} -
    + {/* Eyebrow — category chip (the primary signal) */} +
    {t.catLabel} - - {fresh && ( - - - - - )} - {t.ago} -
    - {/* Title — the focal line, given room to breathe */} -

    + {/* Title — the idea, given room to breathe */} +

    {t.title}

    - {/* Posted-by — readable sentence case, not shouty caps */} -
    - {/* eslint-disable-next-line @next/next/no-img-element */} - {t.name} - {t.name} · {t.area} -
    - - {/* Footer — budget (left anchor) + live offer count (demand, right) */} -
    - + {/* Footer — location (left) + suggested budget (right) */} +
    + + + {t.area} + + {isRate ? 'Rate' : 'Budget'} - {t.price} + {t.price} -
    ); } -function Row({ tasks, dir }: { tasks: Task[]; dir: 'left' | 'right' }) { +function Row({ ideas, dir }: { ideas: Idea[]; dir: 'left' | 'right' }) { // Duplicate the set so the -50% translate loops seamlessly. - const doubled = useMemo(() => [...tasks, ...tasks], [tasks]); + const doubled = useMemo(() => [...ideas, ...ideas], [ideas]); return (
    {doubled.map((t, i) => ( - + ))}
    {/* edge fades */} @@ -168,24 +156,21 @@ export function TaskFeed() { viewport={{ once: true, margin: '-80px' }} transition={{ duration: 0.6, ease: EASE }} >
    - - - - - Live · across the GTA + + 1,000+ kinds of tasks · across the GTA

    - See what’s getting
    done. + See what you can
    get done.

    -

    - Real tasks, real pros — matched across Toronto every few minutes. Yours could be next. +

    + From the everyday to the unexpected — just a few of the thousands of things you can hand off on Taskly. See one you need? Describe it and post in seconds.

    - 1,200+ - tasks this week + $0 + to post & compare
    @@ -193,8 +178,8 @@ export function TaskFeed() { {/* Marquee rows (full-bleed) — hovering the stage pauses both rows */}
    - - + +
    {/* CTA */} @@ -206,7 +191,7 @@ export function TaskFeed() { Post your task — free - No account needed to see offers · cancel anytime + Free to post · describe it by text, voice, or photo
    ); diff --git a/components/landing2/TrustByDesign.tsx b/components/landing2/TrustByDesign.tsx new file mode 100644 index 00000000..26cebc1b --- /dev/null +++ b/components/landing2/TrustByDesign.tsx @@ -0,0 +1,74 @@ +'use client'; + +// The "safe" half of broad-AND-safe — the single biggest differentiator vs +// Kijiji (no protection) and TaskRabbit (hidden fees). Structural, demonstrable +// trust ONLY — every claim here is true today (escrow, manual approval, masked +// calls, door OTP, on-platform recourse, transparent price). No insurance / +// background-check / guarantee claims. Dark section for gravitas. + +import { motion } from 'motion/react'; +import { ShieldCheck, BadgeCheck, PhoneCall, KeyRound, MessageSquare, Tag } from 'lucide-react'; + +const EASE = [0.16, 1, 0.3, 1] as const; + +const PILLARS = [ + { icon: ShieldCheck, title: 'Pay only when it’s done', body: 'Your money waits safe in escrow.' }, + { icon: BadgeCheck, title: 'Every Tasker’s vetted', body: 'Reviewed and approved before they work.' }, + { icon: PhoneCall, title: 'Your number stays private', body: 'Calls route through Taskly, never shared.' }, + { icon: KeyRound, title: 'A code confirms it’s them', body: '4 digits at the door, or online.' }, + { icon: MessageSquare, title: 'It all stays on Taskly', body: 'Chat, pay and help — one place.' }, + { icon: Tag, title: 'One honest price', body: 'What you see is what you pay.' }, +]; + +export function TrustByDesign() { + return ( +
    +
    + +
    + + Safe by design +

    + Safe isn’t a promise.
    It’s how Taskly is built. +

    +

    + We don’t ask you to just trust a stranger. The safety is built into every booking, by default — not sold to you as an add-on. +

    +
    + +
    + {PILLARS.map((p, i) => { + const Icon = p.icon; + return ( + + + + +

    {p.title}

    +

    {p.body}

    +
    + ); + })} +
    + + + No hidden fees. No risky cash deals. No guessing who turns up. + +
    +
    + ); +} diff --git a/components/taskers/TaskersFaq.tsx b/components/taskers/TaskersFaq.tsx index 0ccd503b..28d3a47c 100644 --- a/components/taskers/TaskersFaq.tsx +++ b/components/taskers/TaskersFaq.tsx @@ -17,7 +17,7 @@ const FAQ: ReadonlyArray<{ q: string; a: string }> = [ { q: 'What if a customer doesn’t show up?', a: 'If they cancel 24+ hours before, there’s no fee — but no kill fee either. If they cancel less than 24 hours before, 50% of your accepted bid is paid to you as a kill fee, and Taskly takes no commission on it. A complete no-show pays the same kill fee.' }, { q: 'What if a customer disputes the work?', a: 'Funds stay frozen. Both sides submit evidence within 48 hours, and a real person at Taskly mediates within 72 — full release, partial release, or refund. There’s never a dispute fee.' }, { q: 'How do I get my first job?', a: 'After verification, your profile goes live within a few hours. We match you to local tasks by category, location, and availability — and during the Founding phase we hand-match many first jobs to make sure each Pro’s first booking goes well.' }, - { q: 'Do I need to be insured already?', a: 'No. Taskly’s platform insurance covers liability on every Taskly job. If you already carry trade insurance, even better — it doesn’t replace ours, it stacks.' }, + { q: 'Do I carry my own insurance?', a: 'Taskly doesn’t provide liability insurance, so carrying your own trade insurance is smart — and customers can see when you do. What every job does have: payment held in escrow and released only when the work’s confirmed, masked contact details, and a real person to mediate any dispute.' }, { q: 'Can I set my own prices?', a: 'Within the published fair-price range for each task type, yes. The range is calibrated against real GTA market data, with room for premium pricing if your reviews support it. The floor stops new or amateur Pros from undercutting you.' }, { q: 'What categories can I work in?', a: 'Cleaning, cooking, maintenance & repairs, seasonal work, senior support, organizing, salon & spa, pet care, and tutoring — plus anything else customers post in the open marketplace.' }, { q: 'How is Taskly different from TaskRabbit, Jiffy, HomeStars?', a: 'TaskRabbit: ~30% effective combined fees and a weak Canadian presence. Jiffy: a rumoured 30–40%, no published schedule. HomeStars: lead fees of $15–50 per lead — charged whether you win the job or not — with no escrow or booking guarantee. Taskly: 23%, no customer-side fees, fair-price ranges, and zero lead fees. You pay only when you earn.' }, diff --git a/components/taskers/TaskersFounderNote.tsx b/components/taskers/TaskersFounderNote.tsx index d1225c4d..f4e4f4cd 100644 --- a/components/taskers/TaskersFounderNote.tsx +++ b/components/taskers/TaskersFounderNote.tsx @@ -45,7 +45,7 @@ export function TaskersFounderNote() { Taskly is the platform I wished existed.

    - The take rate is published. The customers are vetted. The payment is guaranteed. + The take rate is published. The money is in escrow before you start. You’re paid the moment the work’s confirmed.

    {/* the standout promise */}