/* Mereka v2 — Public web pages */

/* =================== HOME =================== */
function WebHomePage() {
  return (
    <PublicShell route="/web">
      <HeroSection />
      <ExpertsSection />
      <ExpertiseSection />
      <ExperiencesSection />
      <JobsSection />
      <ReviewsSection />
      <MarketplaceCTA />
      <CorporateCTA />
    </PublicShell>
  );
}

function HeroSection() {
  const items = [
    { icon: 'user', title: 'Experts', desc: 'Schedule 1-on-1 sessions', to: '/web/experts' },
    { icon: 'award', title: 'Expertise', desc: 'Browse services by our Experts', to: '/web/expertise' },
    { icon: 'briefcase', title: 'Jobs', desc: 'View available jobs', to: '/web/jobs' },
    { icon: 'compass', title: 'Experiences', desc: 'Browse activities by Hubs', to: '/web/experiences' },
  ];
  return (
    <section className="relative overflow-hidden">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 pt-12 pb-16 lg:pt-20 lg:pb-24 grid lg:grid-cols-2 gap-12 items-center">
        <div>
          <h1 className="text-[40px] lg:text-[56px] font-bold leading-[1.05] tracking-tight text-neutral-900">
            Book Leading <span className="heading-accent">Experts &amp; Services</span>
          </h1>
          <p className="mt-5 text-lg text-neutral-600 leading-relaxed max-w-xl">
            Mereka connects you to leading experts and services to solve your most pressing challenges.
            Gain insights from vetted professionals and organisations to work on your business, career, or personal well-being.
          </p>
          <p className="mt-3 text-sm text-neutral-500">
            Are you an Expert? <Link to="/web/jobs" className="text-primary font-medium hover:underline">Explore Job Opportunities</Link>
          </p>
          <div className="mt-8 grid grid-cols-1 sm:grid-cols-2 gap-3 max-w-md">
            {items.map(it => (
              <Link key={it.title} to={it.to} className="group p-5 rounded-2xl bg-white border border-neutral-200 hover:border-neutral-900 transition-colors">
                <div className="w-10 h-10 mb-3 rounded-xl bg-neutral-100 flex items-center justify-center group-hover:bg-primary group-hover:text-white transition-colors">
                  <Icon name={it.icon} size={18} />
                </div>
                <h3 className="text-base font-semibold text-neutral-900">{it.title}</h3>
                <p className="text-xs text-neutral-500 mt-0.5 leading-snug">{it.desc}</p>
              </Link>
            ))}
            <a href="#" className="col-span-2 group p-5 rounded-2xl bg-neutral-900 text-white hover:bg-neutral-800 flex items-center gap-4 transition-colors">
              <div className="w-10 h-10 rounded-xl bg-white/10 flex items-center justify-center">
                <Icon name="building" size={18} />
              </div>
              <div className="flex-1">
                <h3 className="text-base font-semibold">Corporate</h3>
                <p className="text-xs text-white/70 mt-0.5">Course creation, event management &amp; funding opportunities.</p>
              </div>
              <Icon name="arrowUpRight" size={16} />
            </a>
          </div>
        </div>

        <div className="hidden lg:block">
          <div className="relative aspect-square max-w-[480px] mx-auto">
            <div className="absolute inset-0 rounded-[40px] ph-grad" />
            <div className="absolute top-8 left-6 w-44 bg-white rounded-2xl shadow-md p-4 border border-neutral-100">
              <div className="flex items-center gap-2 mb-2">
                <Avatar name="Hanna Yusof" size={32} />
                <div>
                  <div className="text-xs font-semibold">Dr. Hanna Yusof</div>
                  <div className="text-[11px] text-neutral-500">Brand Strategist</div>
                </div>
              </div>
              <Stars rating={4.9} size={11} showNumber />
              <div className="mt-2 text-[11px] text-neutral-500">142 sessions</div>
            </div>
            <div className="absolute top-32 right-4 w-52 bg-white rounded-2xl shadow-md overflow-hidden border border-neutral-100">
              <ImageBlock aspect="4/3" seed={3} />
              <div className="p-3">
                <div className="text-xs font-semibold">Sourdough Bread Class</div>
                <div className="text-[11px] text-neutral-500 mt-1">Mill &amp; Crust · KL</div>
              </div>
            </div>
            <div className="absolute bottom-6 left-8 w-56 bg-white rounded-2xl shadow-md p-4 border border-neutral-100">
              <Badge tone="success" className="mb-2">Active</Badge>
              <div className="text-sm font-semibold">Brand Identity Sprint</div>
              <div className="text-xs text-neutral-500 mt-1">2 weeks · Online + 1 in-person</div>
              <div className="mt-2 flex items-center justify-between">
                <span className="text-sm font-bold">RM 8,500</span>
                <Stars rating={4.9} size={11} />
              </div>
            </div>
            <div className="absolute bottom-24 right-6 w-32 h-32 rounded-2xl bg-primary text-white p-4 flex flex-col justify-between">
              <Icon name="spark" size={18} />
              <div className="text-xs font-semibold leading-tight">Trusted by<br/>4,200+ businesses</div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

function ExperiencesSection() {
  return (
    <section className="py-16 lg:py-20 bg-white">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8">
        <div className="flex items-end justify-between mb-8">
          <SectionHeading accent="Experiences">Discover</SectionHeading>
          <Link to="/web/experiences" className="hidden md:inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline">View all <Icon name="arrowRight" size={14} /></Link>
        </div>
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 lg:gap-5">
          {EXPERIENCES.slice(0, 4).map((e, i) => <ExperienceCard key={e.id} experience={e} seed={i} />)}
        </div>
        <div className="mt-8 flex justify-center md:hidden">
          <Link to="/web/experiences"><Button variant="primary" size="lg" rightIcon="arrowRight">View all Experiences</Button></Link>
        </div>
      </div>
    </section>
  );
}

function ExperienceCard({ experience: e, seed }) {
  return (
    <Link to={`/web/experiences/${e.slug}`} className="block group">
      <div className="relative">
        <ImageBlock aspect="4/3" seed={seed + 1} />
        <button onClick={(ev) => ev.preventDefault()} className="absolute top-3 right-3 w-8 h-8 rounded-full bg-white/90 hover:bg-white flex items-center justify-center">
          <Icon name="heart" size={15} />
        </button>
        <Badge tone="dark" className="absolute bottom-3 left-3">{e.badge}</Badge>
      </div>
      <div className="mt-3">
        <div className="flex items-start justify-between gap-2">
          <h3 className="text-sm font-semibold text-neutral-900 line-clamp-2 group-hover:underline">{e.title}</h3>
          <Stars rating={e.rating} size={12} />
        </div>
        <p className="text-xs text-neutral-500 mt-1">{e.host}</p>
        <p className="text-sm font-bold text-neutral-900 mt-1.5">{e.price} <span className="text-xs font-normal text-neutral-500">{e.priceUnit}</span></p>
      </div>
    </Link>
  );
}

function ExpertsSection() {
  return (
    <section className="py-16 lg:py-20 bg-neutral-50">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8">
        <div className="flex items-end justify-between mb-8">
          <SectionHeading accent="Experts">Book Leading</SectionHeading>
          <Link to="/web/experts" className="hidden md:inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline">View all <Icon name="arrowRight" size={14} /></Link>
        </div>
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 lg:gap-5">
          {EXPERTS.slice(0, 4).map(x => <ExpertCard key={x.id} expert={x} />)}
        </div>
      </div>
    </section>
  );
}

function ExpertCard({ expert: x }) {
  return (
    <Link to={`/web/experts/${x.id}`} className="block">
      <Card className="hover:border-neutral-900 transition-colors">
        <div className="flex flex-col items-center text-center">
          <Avatar name={x.name} size={72} />
          <h3 className="mt-3 text-sm font-semibold text-neutral-900">{x.name}</h3>
          <p className="text-xs text-neutral-500">{x.role}</p>
          <div className="mt-2 flex items-center gap-2">
            <Stars rating={x.rating} size={12} />
            <span className="text-xs text-neutral-400">({x.reviews})</span>
          </div>
          <div className="mt-3 flex flex-wrap gap-1 justify-center">
            {x.skills.slice(0, 2).map(s => <Badge key={s} tone="neutral">{s}</Badge>)}
          </div>
          <div className="mt-3 text-xs font-semibold text-neutral-900">{x.hourly}</div>
        </div>
      </Card>
    </Link>
  );
}

function ExpertiseSection() {
  return (
    <section className="py-16 lg:py-20 bg-white">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8">
        <div className="flex items-end justify-between mb-8">
          <SectionHeading accent="Expertise">Featured</SectionHeading>
          <Link to="/web/expertise" className="hidden md:inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline">View all <Icon name="arrowRight" size={14} /></Link>
        </div>
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
          {EXPERTISE.slice(0, 3).map((p, i) => <ExpertiseCard key={p.id} expertise={p} seed={i} />)}
        </div>
      </div>
    </section>
  );
}

function ExpertiseCard({ expertise: p, seed }) {
  return (
    <Link to={`/web/expertise/${p.slug}`}>
      <Card className="hover:border-neutral-900 transition-colors h-full flex flex-col">
        <ImageBlock aspect="16/9" seed={seed + 5} className="mb-4" />
        <Badge tone="purple" className="self-start">{p.category}</Badge>
        <h3 className="mt-2 text-base font-semibold text-neutral-900 line-clamp-2">{p.title}</h3>
        <p className="text-sm text-neutral-500 mt-1">by {p.host} · {p.delivery}</p>
        <div className="mt-3 flex items-center justify-between pt-3 border-t border-neutral-100">
          <Stars rating={p.rating} size={13} />
          <span className="text-sm font-bold">{p.price}</span>
        </div>
      </Card>
    </Link>
  );
}

function JobsSection() {
  return (
    <section className="py-16 lg:py-20 bg-neutral-50">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8">
        <div className="flex items-end justify-between mb-8">
          <SectionHeading accent="Jobs">Open</SectionHeading>
          <Link to="/web/jobs" className="hidden md:inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline">View all <Icon name="arrowRight" size={14} /></Link>
        </div>
        <div className="grid md:grid-cols-2 gap-4">
          {JOBS.slice(0, 4).map(j => <JobCard key={j.id} job={j} />)}
        </div>
      </div>
    </section>
  );
}

function JobCard({ job: j }) {
  return (
    <Link to={`/web/jobs/${j.id}`}>
      <Card className="hover:border-neutral-900 transition-colors h-full">
        <div className="flex items-start justify-between gap-3 mb-3">
          <div>
            <h3 className="text-base font-semibold text-neutral-900">{j.title}</h3>
            <p className="text-xs text-neutral-500 mt-1">{j.client} · Posted {j.posted}</p>
          </div>
          <Badge tone={j.type === 'Fixed' ? 'info' : j.type === 'Hourly' ? 'purple' : 'success'}>{j.type}</Badge>
        </div>
        <div className="flex items-center gap-3 text-sm">
          <span className="font-semibold">{j.budget}</span>
          <span className="text-neutral-400">·</span>
          <span className="text-neutral-600">{j.duration}</span>
        </div>
        <div className="mt-3 flex flex-wrap gap-1.5">
          {j.skills.map(s => <Badge key={s} tone="neutral">{s}</Badge>)}
        </div>
        <div className="mt-3 pt-3 border-t border-neutral-100 flex items-center justify-between text-xs text-neutral-500">
          <span>{j.proposals} proposals</span>
          <span className="text-primary font-medium">View details →</span>
        </div>
      </Card>
    </Link>
  );
}

function ReviewsSection() {
  return (
    <section className="py-16 lg:py-20 bg-primary text-white">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8">
        <h2 className="text-3xl md:text-4xl font-bold mb-2">What people say</h2>
        <p className="text-white/70 mb-10">Real businesses, real outcomes.</p>
        <div className="grid md:grid-cols-2 lg:grid-cols-4 gap-5">
          {REVIEWS.map(r => (
            <div key={r.id} className="bg-white/5 backdrop-blur p-5 rounded-2xl border border-white/10">
              <div className="flex items-center gap-1 mb-3">
                {[...Array(5)].map((_, i) => <Icon key={i} name="star" size={14} fill="#fbbf24" strokeWidth={0} />)}
              </div>
              <p className="text-sm leading-relaxed text-white/90 mb-4">"{r.quote}"</p>
              <div className="flex items-center gap-2 pt-4 border-t border-white/10">
                <Avatar name={r.name} size={36} />
                <div>
                  <div className="text-sm font-semibold">{r.name}</div>
                  <div className="text-xs text-white/60">{r.role}</div>
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function MarketplaceCTA() {
  return (
    <section className="py-16 lg:py-20 bg-white">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 grid md:grid-cols-2 gap-6">
        <div className="rounded-3xl p-10 bg-neutral-900 text-white relative overflow-hidden">
          <div className="absolute -top-20 -right-20 w-72 h-72 rounded-full bg-purple-500/30 blur-3xl" />
          <div className="relative">
            <Badge tone="purple" className="mb-4">For Hubs &amp; Studios</Badge>
            <h3 className="text-3xl font-bold mb-3 leading-tight">List a service.<br/>Reach 4,200+ clients.</h3>
            <p className="text-white/70 mb-6 max-w-md">Set up your hub in 10 minutes. Bookings, payouts, and reviews — all in one place.</p>
            <Link to="/app/onboarding/hub/welcome"><Button variant="secondary" rightIcon="arrowRight">Become a Hub</Button></Link>
          </div>
        </div>
        <div className="rounded-3xl p-10 bg-purple-50 relative overflow-hidden">
          <div className="absolute -bottom-20 -right-20 w-72 h-72 rounded-full bg-purple-200 blur-3xl opacity-60" />
          <div className="relative">
            <Badge tone="primaryLight" className="mb-4">For Experts</Badge>
            <h3 className="text-3xl font-bold mb-3 leading-tight">Lend your expertise.<br/>Build your practice.</h3>
            <p className="text-neutral-600 mb-6 max-w-md">Apply to vetted jobs, host workshops, and grow a portfolio of work that pays.</p>
            <Link to="/app/onboarding/expert/welcome"><Button variant="primary" rightIcon="arrowRight">Become an Expert</Button></Link>
          </div>
        </div>
      </div>
    </section>
  );
}

function CorporateCTA() {
  return (
    <section className="py-16 lg:py-20 bg-neutral-50">
      <div className="max-w-[min(1480px,88vw)] mx-auto px-4 lg:px-8 text-center">
        <Badge tone="dark" className="mb-4">Corporate Solutions</Badge>
        <h2 className="text-3xl md:text-4xl font-bold mb-4">Run workshops, courses and events at scale</h2>
        <p className="text-lg text-neutral-600 max-w-2xl mx-auto mb-6">Curated for teams of 50+. Custom programmes, dedicated success managers, and consolidated invoicing.</p>
        <Button size="lg" variant="dark" rightIcon="arrowUpRight">Talk to our team</Button>
      </div>
    </section>
  );
}

/* =================== EXPERIENCES LIST =================== */
function WebExperiencesPage() {
  const [query, setQuery] = useState('');
  const [fmt, setFmt] = useState('All');
  const [sort, setSort] = useState('Recommended');
  const q = query.trim().toLowerCase();
  const FILTERS = ['All', 'In-person', 'Online'];
  const results = EXPERIENCES.filter(e =>
    (fmt === 'All' || e.badge === fmt) &&
    (q === '' || (e.title + ' ' + e.host + ' ' + e.location).toLowerCase().includes(q))
  );
  const _num = (v) => parseFloat(String(v).replace(/[^0-9.]/g, "")) || 0;
  let view = results;
  if (sort === 'Price: low to high') view = [...results].sort((a, b) => _num(a.price) - _num(b.price));
  else if (sort === 'Price: high to low') view = [...results].sort((a, b) => _num(b.price) - _num(a.price));
  else if (sort === 'Rating') view = [...results].sort((a, b) => b.rating - a.rating);
  else if (sort === 'Duration') view = [...results].sort((a, b) => _num(a.duration) - _num(b.duration));
  return (
    <PublicShell route="/web/experiences">
      {/* Hero / search */}
      <section className="bg-[#f5f5f5] border-b border-neutral-200/70">
        <div className="max-w-[min(2560px,95vw)] mx-auto px-5 lg:px-20 py-12 lg:py-16">
          <h1 className="text-3xl lg:text-[40px] leading-tight font-bold text-zinc-900" style={{ fontFamily: _la }}>
            Discover <AccentText italic>Experiences</AccentText>
          </h1>
          <p className="text-neutral-600 mt-3 max-w-2xl text-base lg:text-lg" style={{ fontFamily: _la }}>
            Hands-on workshops, classes and tours hosted by Mereka hubs across Malaysia and beyond.
          </p>
          <div className="mt-6 relative max-w-xl">
            <Icon name="search" size={20} className="absolute left-4 top-1/2 -translate-y-1/2 text-neutral-400" />
            <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search experiences by title, host or location…"
              className="w-full h-13 pl-12 pr-4 py-3.5 rounded-full bg-white border border-neutral-300 text-[15px] placeholder:text-neutral-400 focus:outline-none focus:border-zinc-900 transition-colors"
              style={{ fontFamily: _la }} />
          </div>
        </div>
      </section>

      <div className="max-w-[min(2560px,95vw)] mx-auto px-5 lg:px-20 py-8 lg:py-10">
        {/* Format pills */}
        <div className="flex items-center justify-between gap-4 flex-wrap mb-6">
          <div className="flex items-center gap-2 overflow-x-auto scrollbar-thin pb-1">
            {FILTERS.map(c => (
              <button key={c} onClick={() => setFmt(c)}
                className={`px-5 py-2 rounded-full text-sm font-bold border transition-colors whitespace-nowrap ${fmt === c ? 'bg-zinc-900 text-white border-zinc-900' : 'bg-white text-zinc-900 border-neutral-300 hover:border-zinc-900'}`}
                style={{ fontFamily: _la }}>{c}</button>
            ))}
          </div>
          <select value={sort} onChange={e => setSort(e.target.value)} className="h-9 px-3 rounded-full border border-neutral-300 bg-white text-sm text-zinc-900" style={{ fontFamily: _la }}>
            {['Recommended', 'Price: low to high', 'Price: high to low', 'Rating', 'Duration'].map(o => <option key={o} value={o}>Sort: {o}</option>)}
          </select>
        </div>

        <p className="text-sm text-neutral-500 mb-6" style={{ fontFamily: _la }}>{results.length} experience{results.length === 1 ? '' : 's'}{fmt !== 'All' ? ` · ${fmt}` : ''}</p>

        {results.length === 0 ? (
          <div className="py-20 text-center">
            <div className="w-14 h-14 rounded-full bg-neutral-100 grid place-items-center mx-auto mb-4"><Icon name="search" size={24} className="text-neutral-400" /></div>
            <h3 className="text-lg font-bold text-zinc-900" style={{ fontFamily: _la }}>No experiences found</h3>
            <p className="text-sm text-neutral-500 mt-1" style={{ fontFamily: _la }}>Try a different search or filter.</p>
          </div>
        ) : (
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-5 gap-y-8">
            {view.map((e, i) => (
              <Link key={e.id} to={`/web/experiences/${e.slug}`} className="flex flex-col gap-3 group">
                <div className="relative">
                  <PhotoPlaceholder seed={e.hue % 8} aspect="4/3" className="w-full" rounded="rounded-2xl" />
                  <HeartOverlay />
                  <span className="absolute bottom-3 left-3 px-3 py-1 rounded-full bg-zinc-900 text-white text-xs font-bold" style={{ fontFamily: _la }}>{e.badge}</span>
                </div>
                <div>
                  <h3 className="text-base font-bold text-zinc-900 leading-snug line-clamp-2 group-hover:underline" style={{ fontFamily: _la }}>{e.title}</h3>
                  <p className="mt-1 text-sm text-neutral-500" style={{ fontFamily: _la }}>{e.host}</p>
                </div>
                <div className="flex flex-wrap items-center gap-1.5">
                  <span className="px-3 py-1 bg-gray-200 rounded-[20px] text-xs text-neutral-800 inline-flex items-center gap-1" style={{ fontFamily: _la }}><Icon name="pin" size={11} /> {e.location}</span>
                  <span className="px-3 py-1 bg-gray-200 rounded-[20px] text-xs text-neutral-800 inline-flex items-center gap-1" style={{ fontFamily: _la }}><Icon name="clock" size={11} /> {e.duration}</span>
                </div>
                <div className="flex items-center justify-between pt-1" style={{ fontFamily: _la }}>
                  <span className="text-sm font-bold text-zinc-900">{e.price} <span className="text-xs font-normal text-neutral-500">{e.priceUnit}</span></span>
                  <span className="inline-flex items-center gap-1 text-sm"><Icon name="star" size={14} fill="#18181b" strokeWidth={0} /><span className="font-bold">{e.rating}</span><span className="text-neutral-400">({e.reviews})</span></span>
                </div>
              </Link>
            ))}
          </div>
        )}
      </div>
    </PublicShell>
  );
}

/* =================== EXPERIENCE DETAIL =================== */
function WebExperienceDetailPage({ slug }) {
  const exp = EXPERIENCES.find(e => e.slug === slug) || EXPERIENCES[0];
  return (
    <PublicShell route="/web/experiences">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 py-6">
        <Link to="/web/experiences" className="inline-flex items-center gap-1 text-sm text-neutral-500 hover:text-neutral-900 mb-4">
          <Icon name="chevronLeft" size={14} /> Back to experiences
        </Link>

        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 mb-8">
          <div className="col-span-4 lg:col-span-2 lg:row-span-2">
            <PhotoPlaceholder seed={exp.hue % 8} aspect="4/3" className="!rounded-2xl h-full" rounded="rounded-2xl" />
          </div>
          <PhotoPlaceholder seed={(exp.hue + 1) % 8} aspect="1/1" className="hidden lg:block" rounded="rounded-xl" />
          <PhotoPlaceholder seed={(exp.hue + 2) % 8} aspect="1/1" className="hidden lg:block" rounded="rounded-xl" />
          <PhotoPlaceholder seed={(exp.hue + 3) % 8} aspect="1/1" className="hidden lg:block" rounded="rounded-xl" />
          <PhotoPlaceholder seed={(exp.hue + 4) % 8} aspect="1/1" className="hidden lg:block" rounded="rounded-xl" />
        </div>

        <div className="grid lg:grid-cols-3 gap-10">
          <div className="lg:col-span-2 space-y-10">
            <div>
              <div className="flex items-center gap-2 mb-3">
                <Badge tone="dark">{exp.badge}</Badge>
                <Badge tone="neutral">{exp.category}</Badge>
              </div>
              <h1 className="text-3xl md:text-4xl font-bold tracking-tight text-zinc-900" style={{ fontFamily: _la }}>{exp.title}</h1>
              <div className="mt-3 flex items-center gap-4 text-sm text-neutral-600" style={{ fontFamily: _la }}>
                <span className="inline-flex items-center gap-1"><Icon name="star" size={14} fill="#18181b" strokeWidth={0} /><span className="font-bold">{exp.rating}</span></span>
                <span>·</span>
                <span>{exp.reviews} reviews</span>
                <span>·</span>
                <span className="flex items-center gap-1"><Icon name="pin" size={14} /> {exp.location}</span>
              </div>
            </div>

            <Card>
              <div className="flex items-center gap-4">
                <Link to={`/web/hubs/${exp.hubSlug}`} className="flex items-center gap-4 group">
                  <Avatar name={exp.host} size={56} />
                  <div>
                    <p className="text-xs text-neutral-500">Hosted by</p>
                    <h3 className="font-semibold text-neutral-900 group-hover:text-primary transition-colors">{exp.host}</h3>
                    <div className="flex items-center gap-2 text-xs text-neutral-500 mt-0.5">
                      <Stars rating={4.9} size={11} showNumber />
                      <span>· Verified Host</span>
                    </div>
                  </div>
                </Link>
                <Link to={`/web/hubs/${exp.hubSlug}`} className="ml-auto"><Button variant="secondary" size="sm">View hub</Button></Link>
              </div>
            </Card>

            <section>
              <h2 className="text-xl font-bold mb-3">About this experience</h2>
              {exp.about.map((para, i) => (
                <p key={i} className={(i === 0 ? '' : 'mt-3 ') + 'text-neutral-700 leading-relaxed'}>{para}</p>
              ))}
            </section>

            <section>
              <h2 className="text-xl font-bold mb-4">What's included</h2>
              <div className="grid sm:grid-cols-2 gap-3">
                {exp.included.map(it => (
                  <div key={it} className="flex items-center gap-2 text-sm">
                    <Icon name="check" size={16} className="text-green-600" /> {it}
                  </div>
                ))}
              </div>
            </section>

            <section>
              <h2 className="text-xl font-bold mb-4">Location</h2>
              <div className="rounded-xl border border-neutral-200 overflow-hidden">
                <div className="aspect-[2/1] ph-grad relative">
                  <div className="absolute inset-0 flex items-center justify-center">
                    <div className="w-12 h-12 rounded-full bg-primary text-white flex items-center justify-center shadow-lg">
                      <Icon name="pin" size={20} />
                    </div>
                  </div>
                </div>
                <div className="p-4 flex items-center justify-between text-sm">
                  <span className="font-medium">{exp.location}</span>
                  <Button variant="ghost" size="sm" rightIcon="arrowUpRight">Open in Maps</Button>
                </div>
              </div>
            </section>

            <section>
              <div className="flex items-center justify-between mb-4">
                <h2 className="text-xl font-bold">Reviews ({exp.reviews})</h2>
                <Stars rating={exp.rating} size={16} />
              </div>
              <div className="space-y-4">
                {REVIEWS.slice(0, 3).map(r => (
                  <div key={r.id} className="pb-4 border-b border-neutral-100 last:border-0">
                    <div className="flex items-center gap-3 mb-2">
                      <Avatar name={r.name} size={36} />
                      <div>
                        <div className="text-sm font-semibold">{r.name}</div>
                        <div className="text-xs text-neutral-500">2 weeks ago</div>
                      </div>
                    </div>
                    <p className="text-sm text-neutral-700">{r.quote}</p>
                  </div>
                ))}
              </div>
            </section>
          </div>

          <aside className="lg:col-span-1">
            <Card className="lg:sticky lg:top-24">
              <div className="text-2xl font-bold">{exp.price} <span className="text-sm font-normal text-neutral-500">{exp.priceUnit}</span></div>
              <div className="mt-3 grid grid-cols-1 sm:grid-cols-2 gap-2">
                <div className="border border-neutral-200 rounded-lg p-3">
                  <div className="text-[11px] text-neutral-500 uppercase tracking-wide">Date</div>
                  <div className="text-sm font-medium">Sat, May 23</div>
                </div>
                <div className="border border-neutral-200 rounded-lg p-3">
                  <div className="text-[11px] text-neutral-500 uppercase tracking-wide">Time</div>
                  <div className="text-sm font-medium">2:00 PM</div>
                </div>
              </div>
              <div className="mt-3 border border-neutral-200 rounded-lg p-3">
                <div className="text-[11px] text-neutral-500 uppercase tracking-wide">Guests</div>
                <div className="flex items-center justify-between mt-1">
                  <div className="text-sm font-medium">1 guest</div>
                  <div className="flex items-center gap-1">
                    <button className="w-7 h-7 rounded-full border border-neutral-300 text-sm">−</button>
                    <span className="px-2 text-sm">1</span>
                    <button className="w-7 h-7 rounded-full border border-neutral-300 text-sm">+</button>
                  </div>
                </div>
              </div>
              <Button variant="primary" size="lg" className="w-full mt-4">Reserve</Button>
              <p className="text-xs text-neutral-500 text-center mt-2">You won't be charged yet</p>
              <div className="mt-5 pt-4 border-t border-neutral-100 space-y-2 text-sm">
                <Row label={`1 × ${exp.price}`}>{exp.price}</Row>
                <Row label="Service fee">RM {Math.round(exp.priceVal * 0.1)}</Row>
                <div className="flex items-center justify-between pt-2 border-t border-neutral-100 font-semibold">
                  <span>Total</span><span>RM {exp.priceVal + Math.round(exp.priceVal * 0.1)}</span>
                </div>
              </div>
            </Card>
          </aside>
        </div>
      </div>
    </PublicShell>
  );
}

function Row({ label, children }) {
  return <div className="flex items-center justify-between text-sm"><span className="text-neutral-500">{label}</span><span className="font-medium">{children}</span></div>;
}

/* =================== EXPERTS LIST =================== */
function WebExpertsPage() {
  const [query, setQuery] = useState('');
  const [cat, setCat] = useState('All');
  const [sort, setSort] = useState('Recommended');
  const q = query.trim().toLowerCase();
  const results = EXPERTS.filter(x =>
    (cat === 'All' || x.category === cat) &&
    (q === '' || (x.name + ' ' + x.role + ' ' + x.desc + ' ' + x.skills.join(' ')).toLowerCase().includes(q))
  );
  const _num = (v) => parseFloat(String(v).replace(/[^0-9.]/g, "")) || 0;
  let view = results;
  if (sort === 'Rating') view = [...results].sort((a, b) => b.rating - a.rating);
  else if (sort === 'Rate: low to high') view = [...results].sort((a, b) => _num(a.hourly) - _num(b.hourly));
  else if (sort === 'Rate: high to low') view = [...results].sort((a, b) => _num(b.hourly) - _num(a.hourly));
  return (
    <PublicShell route="/web/experts">
      {/* Hero / search */}
      <section className="bg-[#f5f5f5] border-b border-neutral-200/70">
        <div className="max-w-[min(2560px,95vw)] mx-auto px-5 lg:px-20 py-12 lg:py-16">
          <h1 className="text-3xl lg:text-[40px] leading-tight font-bold text-zinc-900" style={{ fontFamily: _la }}>
            Browse <AccentText cyan>Experts</AccentText>
          </h1>
          <p className="text-neutral-600 mt-3 max-w-2xl text-base lg:text-lg" style={{ fontFamily: _la }}>
            Schedule 1-on-1 sessions with vetted professionals across branding, design, engineering, marketing and more.
          </p>
          <div className="mt-6 relative max-w-xl">
            <Icon name="search" size={20} className="absolute left-4 top-1/2 -translate-y-1/2 text-neutral-400" />
            <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search experts by name, role or skill…"
              className="w-full h-13 pl-12 pr-4 py-3.5 rounded-full bg-white border border-neutral-300 text-[15px] placeholder:text-neutral-400 focus:outline-none focus:border-zinc-900 transition-colors"
              style={{ fontFamily: _la }} />
          </div>
        </div>
      </section>

      <div className="max-w-[min(2560px,95vw)] mx-auto px-5 lg:px-20 py-8 lg:py-10">
        {/* Category pills */}
        <div className="flex items-center justify-between gap-4 flex-wrap mb-6">
          <div className="flex items-center gap-2 overflow-x-auto scrollbar-thin pb-1">
          {EXPERT_CATEGORIES.map(c => (
            <button key={c} onClick={() => setCat(c)}
              className={`px-5 py-2 rounded-full text-sm font-bold border transition-colors whitespace-nowrap ${cat === c ? 'bg-zinc-900 text-white border-zinc-900' : 'bg-white text-zinc-900 border-neutral-300 hover:border-zinc-900'}`}
              style={{ fontFamily: _la }}>{c}</button>
          ))}
          </div>
          <select value={sort} onChange={e => setSort(e.target.value)} className="h-9 px-3 rounded-full border border-neutral-300 bg-white text-sm text-zinc-900" style={{ fontFamily: _la }}>
            {['Recommended', 'Rating', 'Rate: low to high', 'Rate: high to low'].map(o => <option key={o} value={o}>Sort: {o}</option>)}
          </select>
        </div>

        <p className="text-sm text-neutral-500 mb-6" style={{ fontFamily: _la }}>{results.length} expert{results.length === 1 ? '' : 's'}{cat !== 'All' ? ` in ${cat}` : ''}</p>

        {results.length === 0 ? (
          <div className="py-20 text-center">
            <div className="w-14 h-14 rounded-full bg-neutral-100 grid place-items-center mx-auto mb-4"><Icon name="search" size={24} className="text-neutral-400" /></div>
            <h3 className="text-lg font-bold text-zinc-900" style={{ fontFamily: _la }}>No experts found</h3>
            <p className="text-sm text-neutral-500 mt-1" style={{ fontFamily: _la }}>Try a different search or category.</p>
          </div>
        ) : (
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-5 gap-y-8">
            {view.map((x, i) => (
              <Link key={x.id} to={`/web/experts/${x.id}`} className="flex flex-col gap-3 group">
                <div className="relative">
                  <PhotoPlaceholder person={x.name} seed={x.hue % 8} className="w-full h-72" rounded="rounded-2xl" />
                  <HeartOverlay />
                </div>
                <div className="flex flex-col gap-0.5">
                  <h3 className="text-base font-bold text-zinc-900 group-hover:underline" style={{ fontFamily: _la }}>{x.name}</h3>
                  <p className="text-sm font-bold text-zinc-900" style={{ fontFamily: _la }}>{x.role}</p>
                  <p className="text-sm text-neutral-500 leading-6 line-clamp-3 mt-0.5" style={{ fontFamily: _la }}>{x.desc}</p>
                </div>
                <div className="flex flex-wrap items-center gap-1.5">
                  {x.skills.slice(0, 3).map(s => (
                    <span key={s} className="px-3 py-1 bg-gray-200 rounded-[20px] text-xs text-neutral-800" style={{ fontFamily: _la }}>{s}</span>
                  ))}
                </div>
                <div className="flex items-center justify-between pt-1" style={{ fontFamily: _la }}>
                  <span className="inline-flex items-center gap-1 text-sm"><Icon name="star" size={14} fill="#18181b" strokeWidth={0} /><span className="font-bold">{x.rating}</span><span className="text-neutral-400">({x.reviews})</span></span>
                  <span className="text-sm font-bold text-zinc-900">{x.hourly}</span>
                </div>
              </Link>
            ))}
          </div>
        )}
      </div>
    </PublicShell>
  );
}

/* =================== EXPERT DETAIL =================== */
function WebExpertDetailPage({ id }) {
  const x = EXPERTS.find(x => x.id === id) || EXPERTS[0];
  return (
    <PublicShell route="/web/experts">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 py-6">
        <Link to="/web/experts" className="inline-flex items-center gap-1 text-sm text-neutral-500 hover:text-neutral-900 mb-4">
          <Icon name="chevronLeft" size={14} /> Back to experts
        </Link>
        <div className="grid lg:grid-cols-3 gap-10">
          <div className="lg:col-span-2 space-y-8">
            <div className="flex flex-col sm:flex-row items-start gap-6">
              <PhotoPlaceholder person={x.name} seed={x.hue % 8} className="w-full sm:w-56 h-64 flex-shrink-0" rounded="rounded-2xl" />
              <div className="flex-1">
                <h1 className="text-2xl lg:text-3xl font-bold text-zinc-900" style={{ fontFamily: _la }}>{x.name}</h1>
                <p className="text-base font-bold text-zinc-900 mt-0.5" style={{ fontFamily: _la }}>{x.role}</p>
                <div className="mt-2 flex items-center gap-3 text-sm text-neutral-600" style={{ fontFamily: _la }}>
                  <span className="inline-flex items-center gap-1"><Icon name="star" size={14} fill="#18181b" strokeWidth={0} /><span className="font-bold">{x.rating}</span></span>
                  <span>· {x.reviews} reviews</span>
                  <span>·</span>
                  <span className="flex items-center gap-1"><Icon name="pin" size={14} /> {x.location}</span>
                </div>
                <p className="mt-3 text-sm text-neutral-500 leading-6" style={{ fontFamily: _la }}>{x.desc}</p>
                <div className="mt-4 flex gap-2">
                  <Button variant="primary" size="sm">Book a session</Button>
                  <Button variant="secondary" size="sm" leftIcon="chat">Message</Button>
                </div>
              </div>
            </div>

            <section>
              <h2 className="text-xl font-bold mb-3" style={{ fontFamily: _la }}>About</h2>
              <p className="text-neutral-700 leading-relaxed" style={{ fontFamily: _la }}>
                {x.desc} Based in {x.location}, {x.name.split(' ')[0]} has spent over a decade
                helping companies clarify their positioning, ship product, and grow with intention.
                Past clients include scale-ups across Southeast Asia and several Fortune 500 brand teams.
              </p>
            </section>

            <section>
              <h2 className="text-xl font-bold mb-3">Skills &amp; tools</h2>
              <div className="flex flex-wrap gap-2">
                {[...new Set([...x.skills, 'Figma', 'Notion', 'Miro', 'Workshops', 'Mentoring'])].map(s => <Badge key={s} tone="neutral">{s}</Badge>)}
              </div>
            </section>

            <section>
              <h2 className="text-xl font-bold mb-3">Recent work</h2>
              <div className="grid sm:grid-cols-3 gap-3">
                {[0, 1, 2].map(i => (
                  <div key={i}>
                    <ImageBlock aspect="4/3" seed={i + x.hue % 5} />
                    <p className="text-xs text-neutral-500 mt-2">Project {i + 1}</p>
                  </div>
                ))}
              </div>
            </section>

            <section>
              <h2 className="text-xl font-bold mb-4">Reviews</h2>
              <div className="space-y-4">
                {REVIEWS.slice(0, 2).map(r => (
                  <div key={r.id} className="pb-4 border-b border-neutral-100 last:border-0">
                    <div className="flex items-center gap-3 mb-2">
                      <Avatar name={r.name} size={36} />
                      <div className="flex-1">
                        <div className="text-sm font-semibold">{r.name}</div>
                        <div className="text-xs text-neutral-500">{r.role}</div>
                      </div>
                      <Stars rating={5} size={12} />
                    </div>
                    <p className="text-sm text-neutral-700">{r.quote}</p>
                  </div>
                ))}
              </div>
            </section>
          </div>

          <aside className="lg:col-span-1 space-y-4">
            <Card>
              <div className="text-2xl font-bold">{x.hourly}</div>
              <p className="text-sm text-neutral-500 mt-1">Avg session 60 min</p>
              <Button variant="primary" size="lg" className="w-full mt-4">Book session</Button>
              <Button variant="secondary" size="lg" className="w-full mt-2">Send proposal</Button>
              <div className="mt-5 pt-4 border-t border-neutral-100 space-y-2 text-sm">
                <Row label="Response time">Within 2h</Row>
                <Row label="Languages">EN, BM</Row>
                <Row label="Availability">Mon–Fri</Row>
              </div>
            </Card>
            <Card>
              <h3 className="font-semibold mb-3 text-sm">Verifications</h3>
              <div className="space-y-2 text-sm">
                {['Email verified', 'Identity verified', 'Phone verified', 'Portfolio reviewed'].map(v => (
                  <div key={v} className="flex items-center gap-2"><Icon name="check" size={14} className="text-green-600" /> {v}</div>
                ))}
              </div>
            </Card>
          </aside>
        </div>
      </div>
    </PublicShell>
  );
}

/* =================== EXPERTISE LIST =================== */
function WebExpertisePage() {
  const [query, setQuery] = useState('');
  const [cat, setCat] = useState('All');
  const [sort, setSort] = useState('Recommended');
  const q = query.trim().toLowerCase();
  const results = EXPERTISE.filter(p =>
    (cat === 'All' || p.category === cat) &&
    (q === '' || (p.title + ' ' + p.host + ' ' + p.desc + ' ' + p.category).toLowerCase().includes(q))
  );
  const _num = (v) => parseFloat(String(v).replace(/[^0-9.]/g, "")) || 0;
  let view = results;
  if (sort === 'Price: low to high') view = [...results].sort((a, b) => _num(a.price) - _num(b.price));
  else if (sort === 'Price: high to low') view = [...results].sort((a, b) => _num(b.price) - _num(a.price));
  else if (sort === 'Rating') view = [...results].sort((a, b) => b.rating - a.rating);
  return (
    <PublicShell route="/web/expertise">
      <section className="bg-[#f5f5f5] border-b border-neutral-200/70">
        <div className="max-w-[min(2560px,95vw)] mx-auto px-5 lg:px-20 py-12 lg:py-16">
          <h1 className="text-3xl lg:text-[40px] leading-tight font-bold text-zinc-900" style={{ fontFamily: _la }}>
            Browse their <AccentText italic>Expertise</AccentText>
          </h1>
          <p className="text-neutral-600 mt-3 max-w-2xl text-base lg:text-lg" style={{ fontFamily: _la }}>
            Packaged services from our experts and hubs — clear scopes, fixed pricing, ready to book.
          </p>
          <div className="mt-6 relative max-w-xl">
            <Icon name="search" size={20} className="absolute left-4 top-1/2 -translate-y-1/2 text-neutral-400" />
            <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search expertise by service, skill or hub…"
              className="w-full h-13 pl-12 pr-4 py-3.5 rounded-full bg-white border border-neutral-300 text-[15px] placeholder:text-neutral-400 focus:outline-none focus:border-zinc-900 transition-colors"
              style={{ fontFamily: _la }} />
          </div>
        </div>
      </section>

      <div className="max-w-[min(2560px,95vw)] mx-auto px-5 lg:px-20 py-8 lg:py-10">
        <div className="flex items-center justify-between gap-4 flex-wrap mb-6">
          <div className="flex items-center gap-2 overflow-x-auto scrollbar-thin pb-1">
          {EXPERTISE_CATEGORIES.map(c => (
            <button key={c} onClick={() => setCat(c)}
              className={`px-5 py-2 rounded-full text-sm font-bold border transition-colors whitespace-nowrap ${cat === c ? 'bg-zinc-900 text-white border-zinc-900' : 'bg-white text-zinc-900 border-neutral-300 hover:border-zinc-900'}`}
              style={{ fontFamily: _la }}>{c}</button>
          ))}
          </div>
          <select value={sort} onChange={e => setSort(e.target.value)} className="h-9 px-3 rounded-full border border-neutral-300 bg-white text-sm text-zinc-900" style={{ fontFamily: _la }}>
            {['Recommended', 'Price: low to high', 'Price: high to low', 'Rating'].map(o => <option key={o} value={o}>Sort: {o}</option>)}
          </select>
        </div>

        <p className="text-sm text-neutral-500 mb-6" style={{ fontFamily: _la }}>{results.length} service{results.length === 1 ? '' : 's'}{cat !== 'All' ? ` in ${cat}` : ''}</p>

        {results.length === 0 ? (
          <div className="py-20 text-center">
            <div className="w-14 h-14 rounded-full bg-neutral-100 grid place-items-center mx-auto mb-4"><Icon name="search" size={24} className="text-neutral-400" /></div>
            <h3 className="text-lg font-bold text-zinc-900" style={{ fontFamily: _la }}>No expertise found</h3>
            <p className="text-sm text-neutral-500 mt-1" style={{ fontFamily: _la }}>Try a different search or category.</p>
          </div>
        ) : (
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-5 gap-y-8">
            {view.map((p, i) => (
              <Link key={p.id} to={`/web/expertise/${p.slug}`} className="flex flex-col gap-3 group">
                <div className="relative">
                  <PhotoPlaceholder seed={p.hue % 8} aspect="16/10" className="w-full" rounded="rounded-2xl" />
                  <HeartOverlay />
                </div>
                <div>
                  <h3 className="text-base font-bold text-zinc-900 group-hover:underline leading-snug" style={{ fontFamily: _la }}>{p.title}</h3>
                  <p className="mt-1 text-sm text-neutral-500 leading-6 line-clamp-2" style={{ fontFamily: _la }}>{p.desc}</p>
                </div>
                <div className="flex flex-wrap items-center gap-1.5">
                  {[p.category, p.delivery].map(s => (
                    <span key={s} className="px-3 py-1 bg-gray-200 rounded-[20px] text-xs text-neutral-800" style={{ fontFamily: _la }}>{s}</span>
                  ))}
                </div>
                <div className="flex items-center justify-between pt-1" style={{ fontFamily: _la }}>
                  <span className="inline-flex items-center gap-1 text-sm"><Icon name="star" size={14} fill="#18181b" strokeWidth={0} /><span className="font-bold">{p.rating}</span><span className="text-neutral-400">({p.reviews})</span></span>
                  <span className="text-sm font-bold text-zinc-900">{p.price}</span>
                </div>
              </Link>
            ))}
          </div>
        )}
      </div>
    </PublicShell>
  );
}

/* =================== EXPERTISE DETAIL =================== */
function WebExpertiseDetailPage({ slug }) {
  const p = EXPERTISE.find(p => p.slug === slug || p.id === slug) || EXPERTISE[0];
  return (
    <PublicShell route="/web/expertise">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 py-6">
        <Link to="/web/expertise" className="inline-flex items-center gap-1 text-sm text-neutral-500 hover:text-neutral-900 mb-4">
          <Icon name="chevronLeft" size={14} /> Back to expertise
        </Link>
        <div className="grid lg:grid-cols-3 gap-10">
          <div className="lg:col-span-2 space-y-8">
            <PhotoPlaceholder seed={p.hue % 8} aspect="16/9" className="w-full" rounded="rounded-2xl" />
            <div>
              <Badge tone="purple" className="mb-3">{p.category}</Badge>
              <h1 className="text-3xl md:text-4xl font-bold tracking-tight text-zinc-900" style={{ fontFamily: _la }}>{p.title}</h1>
              <div className="mt-3 flex items-center gap-3 text-sm text-neutral-600" style={{ fontFamily: _la }}>
                <span className="inline-flex items-center gap-1"><Icon name="star" size={14} fill="#18181b" strokeWidth={0} /><span className="font-bold">{p.rating}</span></span>
                <span>· {p.reviews} reviews</span>
                <span>·</span>
                <span>By {p.host}</span>
              </div>
            </div>

            <section>
              <h2 className="text-xl font-bold mb-3" style={{ fontFamily: _la }}>What you get</h2>
              <p className="text-neutral-700 leading-relaxed mb-4" style={{ fontFamily: _la }}>
                {p.desc}
              </p>
              <div className="grid sm:grid-cols-2 gap-3">
                {p.deliverables.map(it => (
                  <div key={it} className="flex items-start gap-2 text-sm"><Icon name="check" size={16} className="text-green-600 mt-0.5" /><span>{it}</span></div>
                ))}
              </div>
            </section>

            <section>
              <h2 className="text-xl font-bold mb-4">Timeline</h2>
              <div className="space-y-3">
                {p.timeline.map((s, i) => (
                  <div key={i} className="flex gap-4">
                    <div className="w-20 flex-shrink-0 text-xs text-neutral-500">{s.w}</div>
                    <div className="w-px bg-neutral-200" />
                    <div>
                      <div className="font-semibold text-sm">{s.t}</div>
                      <div className="text-sm text-neutral-500">{s.d}</div>
                    </div>
                  </div>
                ))}
              </div>
            </section>
          </div>

          <aside className="lg:col-span-1">
            <Card className="lg:sticky lg:top-24">
              <div className="text-2xl font-bold">{p.price}</div>
              <p className="text-sm text-neutral-500 mt-1">{p.delivery}</p>
              <Button variant="primary" size="lg" className="w-full mt-4">Request a call</Button>
              <Button variant="secondary" size="lg" className="w-full mt-2">Send a brief</Button>
              <div className="mt-5 pt-4 border-t border-neutral-100 space-y-2 text-sm">
                <Row label="Duration">{p.duration}</Row>
                <Row label="Format">{p.delivery}</Row>
                <Row label="Revisions">{p.revisions}</Row>
              </div>
            </Card>
          </aside>
        </div>
      </div>
    </PublicShell>
  );
}

/* =================== JOBS LIST =================== */
function WebJobsPage() {
  const [query, setQuery] = useState('');
  const [type, setType] = useState(() => new Set());
  const [budget, setBudget] = useState(() => new Set());
  const [dur, setDur] = useState(() => new Set());
  const [skills, setSkills] = useState(() => new Set());
  const [sort, setSort] = useState('Most recent');
  const q = query.trim().toLowerCase();
  const toggle = (setter) => (v) => setter(p => { const n = new Set(p); n.has(v) ? n.delete(v) : n.add(v); return n; });
  const inBudget = (j) => budget.size === 0 || [...budget].some(b =>
    (b === 'Under RM 5k' && j.budgetVal < 5000) ||
    (b === 'RM 5k\u201320k' && j.budgetVal >= 5000 && j.budgetVal <= 20000) ||
    (b === 'RM 20k+' && j.budgetVal > 20000));
  const inDur = (j) => dur.size === 0 || [...dur].some(d =>
    (d === '< 1 month' && j.durMonths < 1) ||
    (d === '1\u20133 months' && j.durMonths >= 1 && j.durMonths <= 3) ||
    (d === '3+ months' && j.durMonths > 3));
  let results = JOBS.filter(j =>
    (type.size === 0 || type.has(j.type)) && inBudget(j) && inDur(j) &&
    (skills.size === 0 || j.skills.some(sk => skills.has(sk))) &&
    (q === '' || (j.title + ' ' + j.client + ' ' + j.skills.join(' ')).toLowerCase().includes(q))
  );
  if (sort === 'Highest budget') results = [...results].sort((a, b) => b.budgetVal - a.budgetVal);
  else if (sort === 'Fewest proposals') results = [...results].sort((a, b) => a.proposals - b.proposals);
  const anyFilter = type.size || budget.size || dur.size || skills.size || q;
  const reset = () => { setQuery(''); setType(new Set()); setBudget(new Set()); setDur(new Set()); setSkills(new Set()); setSort('Most recent'); };
  return (
    <PublicShell route="/web/jobs">
      <div className="bg-white border-b border-neutral-100">
        <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 py-10">
          <h1 className="text-3xl md:text-4xl font-bold tracking-tight">Jobs</h1>
          <p className="text-neutral-600 mt-2 max-w-2xl">Open briefs from clients across Southeast Asia. Apply, get hired, get paid.</p>
          <div className="mt-5 relative max-w-xl">
            <Icon name="search" size={18} className="absolute left-4 top-1/2 -translate-y-1/2 text-neutral-400" />
            <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search jobs by title, client or skill..."
              className="w-full h-11 pl-11 pr-4 rounded-full border border-neutral-300 bg-white text-sm focus:outline-none focus:border-zinc-900" />
          </div>
        </div>
      </div>
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 py-8 grid lg:grid-cols-4 gap-6">
        <aside className="hidden lg:block">
          <Card padding="p-4">
            <div className="flex items-center justify-between mb-3">
              <h3 className="font-semibold text-sm">Filters</h3>
              {anyFilter ? <button onClick={reset} className="text-xs font-medium text-[#2563eb] hover:underline">Reset</button> : null}
            </div>
            <FilterGroup title="Type" items={['Fixed', 'Hourly', 'Retainer']} selected={type} onToggle={toggle(setType)} />
            <FilterGroup title="Budget" items={['Under RM 5k', 'RM 5k\u201320k', 'RM 20k+']} selected={budget} onToggle={toggle(setBudget)} />
            <FilterGroup title="Duration" items={['< 1 month', '1\u20133 months', '3+ months']} selected={dur} onToggle={toggle(setDur)} />
            <FilterGroup title="Skills" items={['Brand', 'Angular', 'Figma', 'Editing', 'SEO', 'Data']} selected={skills} onToggle={toggle(setSkills)} />
          </Card>
        </aside>
        <div className="lg:col-span-3">
          <div className="flex items-center justify-between mb-4">
            <p className="text-sm text-neutral-500">{results.length} open job{results.length === 1 ? '' : 's'}</p>
            <select value={sort} onChange={e => setSort(e.target.value)} className="text-sm border border-neutral-300 rounded-full px-4 py-1.5 bg-white">
              {['Most recent', 'Highest budget', 'Fewest proposals'].map(o => <option key={o} value={o}>{o}</option>)}
            </select>
          </div>
          {results.length === 0 ? (
            <div className="py-16 text-center">
              <div className="w-14 h-14 rounded-full bg-neutral-100 grid place-items-center mx-auto mb-4"><Icon name="search" size={24} className="text-neutral-400" /></div>
              <h3 className="text-lg font-bold text-zinc-900">No jobs found</h3>
              <p className="text-sm text-neutral-500 mt-1">Try clearing a filter or searching differently.</p>
            </div>
          ) : (
            <div className="space-y-3">
              {results.map(j => <JobCard key={j.id} job={j} />)}
            </div>
          )}
        </div>
      </div>
    </PublicShell>
  );
}

function FilterGroup({ title, items, selected, onToggle }) {
  return (
    <div className="mb-5 last:mb-0">
      <div className="text-xs font-semibold text-neutral-900 mb-2">{title}</div>
      <div className="space-y-1.5">
        {items.map(it => (
          <label key={it} className="flex items-center gap-2 text-sm text-neutral-700 cursor-pointer">
            <input type="checkbox" checked={selected ? selected.has(it) : false} onChange={() => onToggle && onToggle(it)} className="rounded border-neutral-300" /> {it}
          </label>
        ))}
      </div>
    </div>
  );
}

/* =================== JOB DETAIL =================== */
function WebJobDetailPage({ id }) {
  const j = JOBS.find(j => j.id === id) || JOBS[0];
  return (
    <PublicShell route="/web/jobs">
      <div className="max-w-[min(1480px,88vw)] mx-auto px-4 lg:px-8 py-6">
        <Link to="/web/jobs" className="inline-flex items-center gap-1 text-sm text-neutral-500 hover:text-neutral-900 mb-4">
          <Icon name="chevronLeft" size={14} /> Back to jobs
        </Link>
        <Card padding="p-8">
          <div className="flex items-start justify-between gap-4 flex-wrap">
            <div>
              <Badge tone={j.type === 'Fixed' ? 'info' : 'purple'} className="mb-3">{j.type}</Badge>
              <h1 className="text-3xl font-bold">{j.title}</h1>
              <p className="text-neutral-500 mt-2">{j.client} · Posted {j.posted}</p>
            </div>
            <div className="flex gap-2">
              <Button variant="secondary" size="md" leftIcon="bookmark">Save</Button>
              <Button variant="primary" size="md" rightIcon="arrowRight">Submit proposal</Button>
            </div>
          </div>

          <div className="mt-6 grid sm:grid-cols-3 gap-4 p-5 rounded-xl bg-neutral-50">
            <Stat label="Budget" value={j.budget} />
            <Stat label="Duration" value={j.duration} />
            <Stat label="Proposals received" value={j.proposals} />
          </div>

          <section className="mt-8">
            <h2 className="text-xl font-bold mb-3">About the project</h2>
            <p className="text-neutral-700 leading-relaxed">
              We're launching a clean-beauty skincare line and need a creative partner to develop our brand identity from scratch.
              You'll work directly with the founders to define positioning, name our SKUs, design our logo system, and produce
              packaging artwork for our first three products.
            </p>
            <p className="mt-3 text-neutral-700 leading-relaxed">
              We have rough mood boards, customer interviews and a working name to share at kickoff. Looking for senior brand
              talent who's shipped at least three D2C consumer brands previously.
            </p>
          </section>

          <section className="mt-8">
            <h2 className="text-xl font-bold mb-3">Skills required</h2>
            <div className="flex flex-wrap gap-2">
              {j.skills.concat(['Packaging', 'Print', 'Adobe Illustrator', 'Figma']).map(s => <Badge key={s} tone="neutral">{s}</Badge>)}
            </div>
          </section>

          <section className="mt-8">
            <h2 className="text-xl font-bold mb-3">About the client</h2>
            <div className="flex items-center gap-3">
              <Avatar name={j.client} size={48} />
              <div>
                <div className="font-semibold">{j.client}</div>
                <div className="text-sm text-neutral-500">Member since 2024 · 4 jobs posted · 100% payout rate</div>
              </div>
            </div>
          </section>
        </Card>
      </div>
    </PublicShell>
  );
}

function Stat({ label, value }) {
  return (
    <div>
      <div className="text-xs text-neutral-500 uppercase tracking-wide">{label}</div>
      <div className="text-lg font-bold mt-1">{value}</div>
    </div>
  );
}

/* =================== HUBS LIST =================== */
function WebHubsPage() {
  const [query, setQuery] = useState('');
  const [sort, setSort] = useState('Recommended');
  const q = query.trim().toLowerCase();
  let results = HUBS.filter(h => q === '' || (h.name + ' ' + h.focus + ' ' + h.city).toLowerCase().includes(q));
  if (sort === 'Rating') results = [...results].sort((a, b) => b.rating - a.rating);
  else if (sort === 'Most members') results = [...results].sort((a, b) => b.members - a.members);
  else if (sort === 'Name: A-Z') results = [...results].sort((a, b) => a.name.localeCompare(b.name));
  return (
    <PublicShell route="/web/hubs">
      <div className="bg-white border-b border-neutral-100">
        <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 py-10">
          <h1 className="text-3xl md:text-4xl font-bold tracking-tight">Hubs</h1>
          <p className="text-neutral-600 mt-2 max-w-2xl">Studios, makerspaces and collectives across Southeast Asia.</p>
          <div className="mt-5 relative max-w-xl">
            <Icon name="search" size={18} className="absolute left-4 top-1/2 -translate-y-1/2 text-neutral-400" />
            <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search hubs by name, focus or city..."
              className="w-full h-11 pl-11 pr-4 rounded-full border border-neutral-300 bg-white text-sm focus:outline-none focus:border-zinc-900" />
          </div>
        </div>
      </div>
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 py-8">
        <div className="flex items-center justify-between mb-4">
          <p className="text-sm text-neutral-500">{results.length} hub{results.length === 1 ? '' : 's'}</p>
          <select value={sort} onChange={e => setSort(e.target.value)} className="text-sm border border-neutral-300 rounded-full px-4 py-1.5 bg-white">
            {['Recommended', 'Rating', 'Most members', 'Name: A-Z'].map(o => <option key={o} value={o}>Sort: {o}</option>)}
          </select>
        </div>
        {results.length === 0 ? (
          <div className="py-16 text-center">
            <div className="w-14 h-14 rounded-full bg-neutral-100 grid place-items-center mx-auto mb-4"><Icon name="search" size={24} className="text-neutral-400" /></div>
            <h3 className="text-lg font-bold text-zinc-900">No hubs found</h3>
            <p className="text-sm text-neutral-500 mt-1">Try a different search.</p>
          </div>
        ) : (
          <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-5">
            {results.map((h, i) => (
              <Link key={h.id} to={`/web/hubs/${h.id}`}>
                <Card className="hover:border-neutral-900 transition-colors h-full">
                  <ImageBlock aspect="16/9" seed={i + 2} className="mb-4" />
                  <div className="flex items-start justify-between">
                    <div>
                      <h3 className="text-lg font-semibold">{h.name}</h3>
                      <p className="text-sm text-neutral-500">{h.focus} \u00b7 {h.city}</p>
                    </div>
                    <Stars rating={h.rating} size={13} />
                  </div>
                  <div className="mt-3 pt-3 border-t border-neutral-100 flex items-center justify-between text-xs text-neutral-500">
                    <span>{h.members} members</span>
                    <span className="text-primary font-medium">Visit hub \u2192</span>
                  </div>
                </Card>
              </Link>
            ))}
          </div>
        )}
      </div>
    </PublicShell>
  );
}

function WebHubDetailPage({ id }) {
  const h = HUBS.find(h => h.id === id) || HUBS[0];
  return (
    <PublicShell route="/web/hubs">
      <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 py-6">
        <Link to="/web/hubs" className="inline-flex items-center gap-1 text-sm text-neutral-500 hover:text-neutral-900 mb-4">
          <Icon name="chevronLeft" size={14} /> Back to hubs
        </Link>
        <ImageBlock aspect="3/1" seed={2} className="!rounded-2xl mb-6" />
        <div className="flex items-start justify-between gap-4 flex-wrap mb-8">
          <div>
            <h1 className="text-3xl font-bold">{h.name}</h1>
            <div className="mt-2 flex items-center gap-3 text-sm text-neutral-600">
              <span>{h.focus}</span><span>·</span>
              <span className="flex items-center gap-1"><Icon name="pin" size={14} /> {h.city}</span>
              <span>·</span><span>{h.members} members</span>
              <span>·</span><Stars rating={h.rating} size={14} />
            </div>
          </div>
          <div className="flex gap-2">
            <Button variant="secondary" leftIcon="chat">Message hub</Button>
            <Button variant="primary" rightIcon="arrowRight">Follow</Button>
          </div>
        </div>

        <Tabs items={[
          { value: 'experiences', label: 'Experiences', count: 8 },
          { value: 'expertise', label: 'Expertise', count: 3 },
          { value: 'about', label: 'About' },
          { value: 'reviews', label: 'Reviews', count: 128 },
        ]} value="experiences" onChange={() => {}} className="mb-6" />

        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 lg:gap-5">
          {EXPERIENCES.slice(0, 4).map((e, i) => <ExperienceCard key={e.id} experience={e} seed={i} />)}
        </div>
      </div>
    </PublicShell>
  );
}

/* =================== PROGRAMS (AI Fundamentals) =================== */
function WebProgramsPage() {
  return (
    <PublicShell route="/web/programs">
      <section className="relative overflow-hidden bg-gradient-to-br from-primary via-[#2d2348] to-primary text-white">
        <div className="absolute inset-0">
          <div className="absolute top-20 left-1/4 w-96 h-96 rounded-full bg-purple-500/20 blur-3xl" />
          <div className="absolute bottom-0 right-1/4 w-96 h-96 rounded-full bg-blue-500/20 blur-3xl" />
        </div>
        <div className="relative max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 py-20 lg:py-28">
          <Badge tone="purple" className="mb-5">Programs</Badge>
          <h1 className="text-4xl lg:text-6xl font-bold tracking-tight max-w-3xl">
            Guided learning journeys, built around your goals.
          </h1>
          <p className="mt-6 text-lg text-white/80 max-w-2xl">
            Mereka Programs combine courses, experiences, and expertise from Mereka hubs into structured journeys —
            for individuals, teams, and entire organisations.
          </p>
          <div className="mt-8 flex flex-wrap gap-3">
            <Button variant="secondary" size="lg" rightIcon="arrowRight">Browse programs</Button>
            <Button variant="ghost" size="lg" className="!text-white hover:!bg-white/10">Talk to our team</Button>
          </div>
        </div>
      </section>

      <section className="py-16 lg:py-20 bg-white">
        <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8">
          <h2 className="text-3xl font-bold mb-2">Featured programs</h2>
          <p className="text-neutral-600 mb-10">Built with Mereka hubs and industry partners.</p>
          <div className="grid md:grid-cols-3 gap-6">
            {[
              { title: 'AI Fundamentals for Teams', desc: '6-week journey from zero to deploying your first AI workflow.', tag: 'Live cohort', n: 240 },
              { title: 'Founder Brand Sprint', desc: '4 weeks. Position, name, identity and launch website — together.', tag: 'Self-paced', n: 86 },
              { title: 'Sustainability for SMEs', desc: 'ESG basics, carbon audits, reporting and certification readiness.', tag: 'Hybrid', n: 142 },
            ].map((p, i) => (
              <Card key={p.title} className="overflow-hidden !p-0">
                <ImageBlock aspect="16/9" seed={i + 4} />
                <div className="p-6">
                  <Badge tone="purple" className="mb-3">{p.tag}</Badge>
                  <h3 className="text-lg font-semibold mb-2">{p.title}</h3>
                  <p className="text-sm text-neutral-600 mb-4">{p.desc}</p>
                  <div className="flex items-center justify-between pt-4 border-t border-neutral-100 text-xs text-neutral-500">
                    <span>{p.n} learners</span>
                    <span className="text-primary font-medium">Learn more →</span>
                  </div>
                </div>
              </Card>
            ))}
          </div>
        </div>
      </section>

      <section className="py-16 lg:py-20 bg-neutral-50">
        <div className="max-w-[min(2560px,95vw)] mx-auto px-4 lg:px-8 grid lg:grid-cols-2 gap-12 items-center">
          <div>
            <h2 className="text-3xl font-bold mb-4">How programs work</h2>
            <div className="space-y-5 mt-6">
              {[
                { t: '1 · Match a goal', d: 'Tell us what you want to learn or what your team needs.' },
                { t: '2 · Curated journey', d: 'We assemble courses, experts and experiences into a plan.' },
                { t: '3 · Run it', d: 'Live sessions, async modules, and hub visits — tracked together.' },
                { t: '4 · Certify', d: 'Get a Mereka-verified certificate at the end of each track.' },
              ].map((s, i) => (
                <div key={i} className="flex gap-4">
                  <div className="w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center font-bold flex-shrink-0">{i + 1}</div>
                  <div>
                    <h3 className="font-semibold">{s.t.split(' · ')[1]}</h3>
                    <p className="text-sm text-neutral-600">{s.d}</p>
                  </div>
                </div>
              ))}
            </div>
          </div>
          <Card padding="p-0" className="overflow-hidden">
            <ImageBlock aspect="4/3" seed={6} />
          </Card>
        </div>
      </section>
    </PublicShell>
  );
}

Object.assign(window, {
  WebHomePage, WebExperiencesPage, WebExperienceDetailPage,
  WebExpertsPage, WebExpertDetailPage,
  WebExpertisePage, WebExpertiseDetailPage,
  WebJobsPage, WebJobDetailPage,
  WebHubsPage, WebHubDetailPage,
  WebProgramsPage,
});
