nextui.dev
Home
Docs
Saved
Pricing
Components37
  • Forms & Inputs7
  • Cards13
  • Buttons, Badges & Avatars8
  • Feedback & Display6
  • Effects3
Agents46
  • Input & Context9
  • Thinking & Status6
  • Tools & Execution7
  • Human-in-the-Loop & Safety7
  • Multi-Agent & Workflows4
  • Output & Artifacts8
  • Voice & Memory5
Blocks20
  • Agent chatNew
  • Pill heroNew
  • Grid hero
  • Moodboard generatorNew
  • Waitlist heroNew
  • Intro bannerNew
  • Creative home heroNew
  • Chat heroNew
  • App shelfNew
  • Usage card
  • Design resultsNew
  • Pricing tiers
  • Dashboard home
  • The shiftNew
  • Launch perksNew
  • Testimonials
  • Quote
  • Team
  • Leads tableNew
  • Sign in
Pages16
  • ASCII workspace$49
  • Research agent$49
  • Support agent$49
  • Coding agent$49
  • CRM overviewNew
  • Marketing dashboardNew
  • Developer portfolio$49
  • Particle landing$49
  • Particle story$49
  • Statement converter$49
  • AI photo studio$49
  • Group card launch$49
  • Month-end storyNew
  • Task HubNew
  • Global MediaNew
  • Hexora ecosystem$49
Themes9
  • Default
  • Ember
  • Ocean
  • Forest
  • Grape
  • Rose
  • Amber
  • Clay
  • Brutal
UpgradeDark modeLight modeFeedbackGitHub
nextui.dev

nextui components, blocks and themes you install with one command.

Product

  • Components
  • Blocks
  • Themes
  • Pricing

Resources

  • Docs
  • Roadmap
  • GitHub

Legal

  • License
  • Privacy
  • Terms
  • Refunds

nextUI

[ 200 OK ] · nextui.dev

© 2026 nextui.dev • All rights reserved.

UpgradeDark modeLight modeFeedbackGitHub
PagesTask Hub
Copy promptCopy prompt

Task HubNew

Playful team workspace and CRM landing page with an interactive leads table, pastel bento cards, autonomous sprint checklist, and 3D momentum conveyor.

Installation

Set your access key from API keys as NEXTUI_TOKEN in .env.local and add the @nextui namespace below to components.json once. Then every item installs by name. Each install counts as a copy on a free account.

$pnpm dlx shadcn@latest add @nextui/task-hub
1{
2 "registries": {
3 "@nextui": {
4 "url": "https://nextui.dev/r/{name}.json",
5 "headers": { "Authorization": "Bearer ${NEXTUI_TOKEN}" }
6 }
7 }
8}

Related

All pages
$49

Particle landingNew

$49

Particle storyNew

Free template
components/pages/task-hub.tsx
"use client";

import {
  createContext,
  useContext,
  useEffect,
  useMemo,
  useRef,
  useState,
  type ComponentType,
  type CSSProperties,
  type ReactNode,
  type RefObject,
} from "react";
import {
  AnimatePresence,
  animate,
  motion,
  useAnimationFrame,
  useInView,
  useReducedMotion,
} from "motion/react";
import {
  ArrowDown,
  ArrowRight,
  ArrowUp,
  ArrowUpDown,
  Calendar,
  Check,
  ChevronDown,
  ChevronLeft,
  ChevronRight,
  CircleCheck,
  CircleDollarSign,
  CircleMinus,
  CircleX,
  Clock3,
  Flame,
  FolderKanban,
  LayoutGrid,
  ListChecks,
  Loader,
  Menu,
  MessageCircle,
  MessagesSquare,
  Minus,
  Phone,
  Play,
  Search,
  Sparkles,
  Star,
  Target,
  UserPlus,
  Users,
  Wand2,
  X,
  Zap,
} from "lucide-react";
import { cn } from "@/lib/utils";

/* -------------------------------------------------------------------------- */
/*                               TOKENS & CONTEXT                             */
/* -------------------------------------------------------------------------- */

const ScrollerContext = createContext<RefObject<HTMLDivElement | null>>({ current: null });
const useScroller = () => useContext(ScrollerContext);

const SANS: CSSProperties = {
  fontFamily: '"Plus Jakarta Sans", "Inter", system-ui, -apple-system, sans-serif',
};

const EASE = [0.22, 1, 0.36, 1] as const;
const SPRING = { type: "spring", stiffness: 280, damping: 22 } as const;

/* -------------------------------------------------------------------------- */
/*                     FLOATING DOODLES & CURSOR CALLOUTS                     */
/* -------------------------------------------------------------------------- */

function FloatingSticker({
  children,
  className,
  delay = 0,
  duration = 4.6,
  distance = 8,
}: {
  children: ReactNode;
  className?: string;
  delay?: number;
  duration?: number;
  distance?: number;
}) {
  const reduce = useReducedMotion();
  return (
    <motion.div
      aria-hidden
      className={cn("pointer-events-none absolute select-none", className)}
      animate={
        reduce
          ? undefined
          : {
              y: [0, -distance, 0],
              rotate: [-3, 4, -3],
            }
      }
      transition={{
        duration,
        repeat: Infinity,
        ease: "easeInOut",
        delay,
      }}
    >
      {children}
    </motion.div>
  );
}

function CursorBadge({
  name,
  bg,
  textColor = "#191A23",
  pointerSide = "right",
}: {
  name: string;
  bg: string;
  textColor?: string;
  pointerSide?: "left" | "right";
}) {
  return (
    <div className="relative inline-flex items-center">
      {pointerSide === "left" && (
        <svg
          width="14"
          height="14"
          viewBox="0 0 16 16"
          className="-mr-1 -mt-5 shrink-0"
          fill="#191A23"
        >
          <path d="M2 2L14 6.5L8.5 9L6.5 14.5L2 2Z" />
        </svg>
      )}
      <span
        className="rounded-full px-3.5 py-1 text-[11px] font-extrabold shadow-sm"
        style={{ backgroundColor: bg, color: textColor }}
      >
        {name}
      </span>
      {pointerSide === "right" && (
        <svg
          width="14"
          height="14"
          viewBox="0 0 16 16"
          className="-ml-1 -mt-5 shrink-0 -scale-x-100"
          fill="#191A23"
        >
          <path d="M2 2L14 6.5L8.5 9L6.5 14.5L2 2Z" />
        </svg>
      )}
    </div>
  );
}

function AvatarBubble({
  emoji,
  bg,
  name,
  size = "md",
}: {
  emoji: string;
  bg: string;
  name?: string;
  size?: "xs" | "sm" | "md" | "lg";
}) {
  const cls =
    size === "xs"
      ? "size-6 text-[11px]"
      : size === "sm"
        ? "size-7 text-xs"
        : size === "lg"
          ? "size-10 text-base"
          : "size-8 text-sm";
  return (
    <span
      title={name}
      className={cn(
        "inline-flex shrink-0 items-center justify-center rounded-full border-2 border-white shadow-2xs select-none",
        cls
      )}
      style={{ backgroundColor: bg }}
    >
      {emoji}
    </span>
  );
}

/* -------------------------------------------------------------------------- */
/*                                   HEADER                                   */
/* -------------------------------------------------------------------------- */

const NAV_ITEMS = [
  { label: "Home", id: "top" },
  { label: "Workspace", id: "workspace" },
  { label: "Why Us", id: "different" },
  { label: "Automation", id: "automation" },
  { label: "Workflow", id: "features" },
] as const;

function Header({ onNavigate }: { onNavigate: (id: string) => void }) {
  const [mobileOpen, setMobileOpen] = useState(false);
  const headerRef = useRef<HTMLElement>(null);

  useEffect(() => {
    if (!mobileOpen) return;
    const handlePointerDown = (e: PointerEvent) => {
      if (!headerRef.current?.contains(e.target as Node)) {
        setMobileOpen(false);
      }
    };
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Escape") setMobileOpen(false);
    };
    document.addEventListener("pointerdown", handlePointerDown);
    document.addEventListener("keydown", handleKeyDown);
    return () => {
      document.removeEventListener("pointerdown", handlePointerDown);
      document.removeEventListener("keydown", handleKeyDown);
    };
  }, [mobileOpen]);

  const handleSelect = (id: string) => {
    setMobileOpen(false);
    onNavigate(id);
  };

  return (
    <header ref={headerRef} className="sticky top-0 z-40 mx-auto max-w-6xl px-4 pt-4 sm:px-8">
      <div className="relative flex items-center justify-between rounded-2xl border border-black/[0.05] bg-white/85 px-4 py-3 shadow-[0_8px_30px_-12px_rgba(0,0,0,0.06)] backdrop-blur-md sm:px-5">
        <button
          type="button"
          onClick={() => handleSelect("top")}
          className="group flex cursor-pointer items-center gap-2.5 text-left"
        >
          <motion.div
            whileHover={{ rotate: 90, scale: 1.08 }}
            transition={SPRING}
            className="grid size-8 place-items-center rounded-xl bg-[#6842FF] text-white shadow-[0_6px_16px_-4px_rgba(104,66,255,0.55)]"
          >
            <LayoutGrid className="size-4" />
          </motion.div>
          <span className="text-base font-extrabold tracking-tight text-[#191A23]">
            Task<span className="text-[#6842FF]">Hub</span>
          </span>
        </button>

        <nav className="hidden items-center gap-7 text-[13px] font-semibold text-[#6E7180] md:flex">
          {NAV_ITEMS.map((item) => (
            <button
              key={item.label}
              type="button"
              onClick={() => handleSelect(item.id)}
              className="cursor-pointer transition-colors hover:text-[#191A23]"
            >
              {item.label}
            </button>
          ))}
        </nav>

        <div className="flex items-center gap-2 sm:gap-3">
          <button
            type="button"
            onClick={() => handleSelect("cta")}
            className="hidden sm:inline-flex cursor-pointer items-center justify-center px-3 py-1.5 text-xs font-bold text-[#191A23] transition-colors hover:text-[#6842FF]"
          >
            Login
          </button>
          <button
            type="button"
            onClick={() => handleSelect("cta")}
            className="hidden sm:inline-flex cursor-pointer items-center gap-1.5 rounded-full bg-[#191A23] px-5 py-2.5 text-xs font-bold text-white shadow-xs transition-all hover:bg-[#6842FF] active:scale-95"
          >
            <span>Start Your Free Trial</span>
          </button>

          {/* Mobile Hamburger Menu Button */}
          <button
            type="button"
            aria-label={mobileOpen ? "Close navigation menu" : "Open navigation menu"}
            aria-expanded={mobileOpen}
            onClick={() => setMobileOpen((prev) => !prev)}
            className={cn(
              "inline-flex size-9 cursor-pointer items-center justify-center rounded-xl border border-black/[0.06] transition-colors md:hidden",
              mobileOpen
                ? "bg-[#6842FF] text-white"
                : "bg-[#FAF8FF] text-[#191A23] hover:bg-[#F3F0FF] hover:text-[#6842FF]"
            )}
          >
            <AnimatePresence mode="wait" initial={false}>
              <motion.span
                key={mobileOpen ? "close" : "open"}
                initial={{ opacity: 0, rotate: -90, scale: 0.8 }}
                animate={{ opacity: 1, rotate: 0, scale: 1 }}
                exit={{ opacity: 0, rotate: 90, scale: 0.8 }}
                transition={{ duration: 0.16 }}
              >
                {mobileOpen ? <X className="size-4" /> : <Menu className="size-4" />}
              </motion.span>
            </AnimatePresence>
          </button>
        </div>
      </div>

      {/* Mobile Dropdown Navigation Drawer */}
      <AnimatePresence>
        {mobileOpen && (
          <motion.div
            initial={{ opacity: 0, y: -10, scale: 0.98 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            exit={{ opacity: 0, y: -8, scale: 0.98 }}
            transition={{ duration: 0.22, ease: EASE }}
            className="mt-2 overflow-hidden rounded-2xl border border-black/[0.06] bg-white/95 p-3 shadow-[0_20px_40px_-15px_rgba(25,26,35,0.12)] backdrop-blur-md md:hidden"
          >
            <nav className="flex flex-col gap-1">
              {NAV_ITEMS.map((item) => (
                <button
                  key={item.label}
                  type="button"
                  onClick={() => handleSelect(item.id)}
                  className="flex w-full cursor-pointer items-center justify-between rounded-xl px-3.5 py-2.5 text-left text-xs font-extrabold text-[#191A23] transition-colors hover:bg-[#FAF8FF] hover:text-[#6842FF]"
                >
                  <span>{item.label}</span>
                  <ArrowRight className="size-3.5 text-[#6E7180]" />
                </button>
              ))}
            </nav>

            <div className="mt-3 flex flex-col gap-2 border-t border-black/[0.05] pt-3 sm:hidden">
              <button
                type="button"
                onClick={() => handleSelect("cta")}
                className="w-full cursor-pointer rounded-xl bg-[#FAF8FF] py-2.5 text-center text-xs font-bold text-[#191A23] transition-colors hover:bg-[#F3F0FF] hover:text-[#6842FF]"
              >
                Login
              </button>
              <button
                type="button"
                onClick={() => handleSelect("cta")}
                className="w-full cursor-pointer rounded-full bg-[#6842FF] py-2.5 text-center text-xs font-bold text-white shadow-xs transition-all hover:bg-[#FF5484] active:scale-95"
              >
                Start Your Free Trial
              </button>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </header>
  );
}

/* -------------------------------------------------------------------------- */
/*              LEADS TABLE COMPONENT (FROM /blocks/leads-table)              */
/* -------------------------------------------------------------------------- */

type LeadStatus =
  | "Won"
  | "Call Booked"
  | "Qualified"
  | "In Contact"
  | "New Lead"
  | "No Show"
  | "Unqualified - No Money"
  | "Unqualified - Ghosted"
  | "Lost - Financials";

type Tone = "amber" | "blue" | "violet" | "rose" | "green" | "pink" | "gray" | "teal";

type Lead = {
  id: number;
  name: string;
  email: string;
  tone: Tone;
  messages?: number;
  status: LeadStatus;
  value?: number | null;
  assignee: string;
  role: "C" | "S";
  interacted: number;
  payment: string;
  added: number;
};

type SortKey = "value" | "interacted" | "added";
type Sort = { key: SortKey; dir: "asc" | "desc" } | null;

const DOT: Record<Tone, string> = {
  amber: "bg-[#FFB81C]",
  blue: "bg-blue-500",
  violet: "bg-[#6842FF]",
  rose: "bg-[#FF5484]",
  green: "bg-lime-500",
  pink: "bg-pink-500",
  gray: "bg-zinc-400",
  teal: "bg-emerald-500",
};

const STATUS: Record<LeadStatus, { icon: ComponentType<{ className?: string }>; className: string }> = {
  Won: { icon: CircleCheck, className: "text-emerald-500" },
  "Call Booked": { icon: Phone, className: "text-blue-500" },
  Qualified: { icon: Star, className: "fill-[#FFB81C] text-[#FFB81C]" },
  "In Contact": { icon: MessagesSquare, className: "text-[#6842FF]" },
  "New Lead": { icon: UserPlus, className: "text-[#FF5484]" },
  "No Show": { icon: CircleMinus, className: "text-zinc-400" },
  "Unqualified - No Money": { icon: CircleX, className: "text-[#FF5484]" },
  "Unqualified - Ghosted": { icon: CircleX, className: "text-[#FF5484]" },
  "Lost - Financials": { icon: CircleX, className: "text-[#FF5484]" },
};

const TEAM: Record<string, { tone: Tone; role: "C" | "S" }> = {
  "Minh T.": { tone: "amber", role: "C" },
  "Rafael O.": { tone: "rose", role: "C" },
  "Lena K.": { tone: "violet", role: "S" },
  "Theo B.": { tone: "green", role: "C" },
  "Hana S.": { tone: "gray", role: "S" },
};

const SEED: Array<[string, Tone, LeadStatus, number | null | undefined, keyof typeof TEAM, number, string, number, number?]> = [
  ["Camille Laurent", "amber", "Won", 2500, "Minh T.", 2880, "Full Payment", 30, 3],
  ["Bao Tran", "blue", "Call Booked", null, "Rafael O.", 180, "N/A", 5],
  ["Aisha Rahman", "violet", "Unqualified - No Money", undefined, "Lena K.", 10080, "N/A", 14],
  ["Felix Wagner", "amber", "Won", 5000, "Theo B.", 5760, "$1K Deposit", 6],
  ["Marta Novak", "rose", "No Show", null, "Hana S.", 15, "N/A", 1, 5],
  ["Kai Nakamura", "blue", "Won", 3000, "Minh T.", 10080, "Installments: 2/6", 21],
  ["Rosa Delgado", "blue", "Qualified", null, "Lena K.", 1440, "N/A", 7],
  ["Arjun Mehta", "violet", "Lost - Financials", undefined, "Theo B.", 8640, "N/A", 30],
  ["Sienna Brooks", "pink", "New Lead", null, "Hana S.", 30, "N/A", 0],
  ["Tobias Lind", "green", "Call Booked", null, "Rafael O.", 2880, "N/A", 10, 1],
  ["Leila Haddad", "amber", "Won", 1500, "Theo B.", 7200, "Full Payment", 60],
  ["Nico Ferraro", "pink", "Unqualified - Ghosted", undefined, "Lena K.", 20160, "N/A", 14],
  ["June Park", "teal", "In Contact", null, "Hana S.", 60, "N/A", 4],
  ["Ezra Cohen", "amber", "Qualified", null, "Lena K.", 8640, "N/A", 21, 2],
  ["Freya Olsen", "violet", "Won", 4200, "Minh T.", 4320, "Installments: 1/4", 18],
  ["Mateus Costa", "blue", "In Contact", null, "Rafael O.", 420, "N/A", 3, 4],
  ["Thanh Le", "rose", "New Lead", null, "Hana S.", 5, "N/A", 0],
  ["Ingrid Holm", "green", "Won", 7800, "Theo B.", 2880, "Full Payment", 45],
  ["Rami Aziz", "pink", "Call Booked", null, "Minh T.", 1080, "N/A", 2],
  ["Chiara Bianchi", "gray", "No Show", null, "Rafael O.", 4320, "N/A", 9],
  ["Oscar Nyberg", "teal", "Qualified", null, "Lena K.", 240, "N/A", 6, 1],
  ["Amara Obi", "amber", "Lost - Financials", undefined, "Theo B.", 30240, "N/A", 40],
  ["Jonas Weber", "violet", "Won", 2200, "Minh T.", 1440, "$500 Deposit", 12],
  ["Vy Pham", "blue", "Unqualified - No Money", undefined, "Hana S.", 12960, "N/A", 25],
  ["Sami Kaya", "rose", "In Contact", null, "Rafael O.", 90, "N/A", 2, 2],
  ["Elif Demir", "green", "Call Booked", null, "Theo B.", 720, "N/A", 8],
  ["Hugo Martin", "pink", "Won", 6400, "Minh T.", 20160, "Installments: 4/6", 75],
  ["Nadia Petrova", "teal", "New Lead", null, "Lena K.", 45, "N/A", 1],
  ["Luca Moretti", "amber", "Qualified", null, "Rafael O.", 2160, "N/A", 11],
  ["Zara Khan", "gray", "Unqualified - Ghosted", undefined, "Hana S.", 25920, "N/A", 33],
  ["Ivo Horvat", "violet", "Won", 3600, "Theo B.", 600, "Full Payment", 16, 6],
  ["Mei Lin", "blue", "No Show", null, "Minh T.", 2880, "N/A", 4],
];

const FIRST = ["Alba", "Bilal", "Clara", "Dario", "Esme", "Farid", "Greta", "Hiro", "Ilse", "Jamal", "Kira", "Lars", "Mila", "Nils", "Odette", "Pablo", "Quinn", "Rhea", "Soren", "Talia", "Umar", "Vera", "Wen", "Ximena", "Yara", "Zane", "Anh", "Bruno", "Celine", "Dmitri", "Emre", "Flora", "Goran", "Hoa", "Ivan", "Jade", "Kofi", "Lucia", "Malik", "Noor"];
const LAST = ["Andersen", "Bakker", "Castillo", "Duarte", "Eriksen", "Fontaine", "Grimaldi", "Hoang", "Ivanova", "Jansen", "Kaur", "Lindqvist", "Mendes", "Nakagawa", "Osei", "Peralta", "Quach", "Rahimi", "Sato", "Toivonen", "Ueda", "Varga", "Wojcik", "Yilmaz", "Zamora", "Dinh", "Fuchs", "Navarro", "Okoro", "Romano"];
const TONES: Tone[] = ["amber", "blue", "violet", "rose", "green", "pink", "gray", "teal"];
const STATUS_POOL: LeadStatus[] = ["New Lead", "New Lead", "New Lead", "Call Booked", "Call Booked", "Call Booked", "In Contact", "In Contact", "Qualified", "Qualified", "Won", "Won", "Won", "No Show", "No Show", "Unqualified - No Money", "Unqualified - Ghosted", "Lost - Financials"];
const MINUTES = [2, 5, 12, 15, 30, 45, 60, 90, 120, 180, 300, 480, 720, 1440, 2160, 2880, 4320, 5760, 7200, 8640, 10080, 14400, 20160, 30240];
const PAYMENT_POOL = ["Full Payment", "Full Payment", "$1K Deposit", "$500 Deposit", "$2K Deposit", "Installments: 1/3", "Installments: 2/6", "Installments: 3/4", "Installments: 5/6", "Installments: 1/12"];

function rng(seed: number) {
  return () => {
    seed = (seed + 0x6d2b79f5) | 0;
    let t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

function generate(count: number, seed: number): typeof SEED {
  const rand = rng(seed);
  const pick = <T,>(list: readonly T[]) => list[Math.floor(rand() * list.length)];
  const team = Object.keys(TEAM) as Array<keyof typeof TEAM>;
  return Array.from({ length: count }, () => {
    const status = pick(STATUS_POOL);
    const interacted = pick(MINUTES);
    const added = Math.ceil(interacted / 1440) + Math.floor(rand() * 75);
    const won = status === "Won";
    const open = !won && !status.startsWith("Unqualified") && !status.startsWith("Lost");
    const value = won ? Math.round((800 + rand() * 11_200) / 250) * 250 : open ? null : undefined;
    const messages = rand() < 0.22 ? 1 + Math.floor(rand() * 9) : undefined;
    return [`${pick(FIRST)} ${pick(LAST)}`, pick(TONES), status, value, pick(team), interacted, won ? pick(PAYMENT_POOL) : "N/A", added, messages];
  });
}

const LEADS: Lead[] = [...SEED, ...generate(118, 7)].map(([name, tone, status, value, assignee, interacted, payment, added, messages], i) => ({
  id: i + 1,
  name,
  email: `${name.toLowerCase().replace(/\s+/g, ".")}@mail.com`,
  tone,
  messages,
  status,
  value,
  assignee,
  role: TEAM[assignee].role,
  interacted,
  payment,
  added,
}));

const RANGES = [
  { label: "Last 24 hours", minutes: 1440 },
  { label: "Last 7 days", minutes: 10080 },
  { label: "Last 30 days", minutes: 43200 },
  { label: "All time", minutes: Infinity },
];
const PAYMENTS = ["All Payments", "Full Payment", "Deposit", "Installments", "N/A"];
const DEFAULT_RANGE = "Last 30 days";
const COLS = ["5%", "19%", "17%", "12%", "14%", "11%", "12%", "10%"];

function ago(minutes: number) {
  const unit = (n: number, word: string) => `${n} ${word}${n === 1 ? "" : "s"} ago`;
  if (minutes < 60) return unit(minutes, "min");
  if (minutes < 1440) return unit(Math.round(minutes / 60), "hour");
  if (minutes < 10080) return unit(Math.round(minutes / 1440), "day");
  if (minutes < 43200) return unit(Math.round(minutes / 10080), "week");
  return unit(Math.round(minutes / 43200), "month");
}

function addedAgo(days: number) {
  return days === 0 ? "Today" : ago(days * 1440);
}

function sortValue(lead: Lead, key: SortKey) {
  if (key === "value") return typeof lead.value === "number" ? lead.value : null;
  return lead[key];
}

function HeroLeadsTable({ leads = LEADS }: { leads?: Lead[] }) {
  const reduce = useReducedMotion();
  const ref = useRef<HTMLDivElement>(null);
  const inView = useInView(ref, { once: true, amount: 0.15 });
  const shown = inView || !!reduce;

  const [range, setRange] = useState(DEFAULT_RANGE);
  const [user, setUser] = useState("All Users");
  const [status, setStatus] = useState("Any Status");
  const [payment, setPayment] = useState("All Payments");
  const [query, setQuery] = useState("");
  const [sort, setSort] = useState<Sort>(null);
  const [sorted, setSorted] = useState(false);
  const [pageSize, setPageSize] = useState(10);
  const [page, setPage] = useState(1);
  const [selected, setSelected] = useState<Set<number>>(new Set());

  const filtered = useMemo(() => {
    const max = RANGES.find((r) => r.label === range)?.minutes ?? Infinity;
    const q = query.trim().toLowerCase();
    const rows = leads.filter(
      (l) =>
        l.interacted <= max &&
        (user === "All Users" || l.assignee === user) &&
        (status === "Any Status" || l.status === status) &&
        (payment === "All Payments" || l.payment.startsWith(payment) || (payment === "Deposit" && l.payment.endsWith("Deposit"))) &&
        (!q || l.name.toLowerCase().includes(q) || l.email.includes(q)),
    );
    if (!sort) return rows;
    const sign = sort.dir === "asc" ? 1 : -1;
    return [...rows].sort((a, b) => {
      const x = sortValue(a, sort.key);
      const y = sortValue(b, sort.key);
      if (x === null || y === null) return x === y ? 0 : x === null ? 1 : -1;
      return (x - y) * sign;
    });
  }, [leads, range, user, status, payment, query, sort]);

  const pages = Math.max(1, Math.ceil(filtered.length / pageSize));
  const current = Math.min(page, pages);
  const rows = filtered.slice((current - 1) * pageSize, current * pageSize);
  const viewKey = `${range}|${user}|${status}|${payment}|${query}|${pageSize}|${current}`;
  const [firstKey] = useState(viewKey);
  const intro = viewKey === firstKey && !sorted;

  useEffect(() => {
    if (reduce || pages <= 1) return;
    const id = setInterval(() => {
      setPage((p) => (p >= pages ? 1 : p + 1));
    }, 30000);
    return () => clearInterval(id);
  }, [reduce, pages]);

  const resetPage = <T,>(set: (v: T) => void) => (v: T) => {
    set(v);
    setPage(1);
  };

  const toggleSort = (key: SortKey) => {
    setSorted(true);
    setSort((s) => (s?.key !== key ? { key, dir: "desc" } : s.dir === "desc" ? { key, dir: "asc" } : null));
  };

  const allOnPage = rows.length > 0 && rows.every((r) => selected.has(r.id));
  const someOnPage = rows.some((r) => selected.has(r.id));
  const toggleAll = () =>
    setSelected((s) => {
      const next = new Set(s);
      rows.forEach((r) => (allOnPage ? next.delete(r.id) : next.add(r.id)));
      return next;
    });
  const toggleOne = (id: number) =>
    setSelected((s) => {
      const next = new Set(s);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });

  const filtersOn = user !== "All Users" || status !== "Any Status" || payment !== "All Payments" || query !== "" || range !== DEFAULT_RANGE;
  const clear = () => {
    setRange(DEFAULT_RANGE);
    setUser("All Users");
    setStatus("Any Status");
    setPayment("All Payments");
    setQuery("");
    setPage(1);
  };

  const enter = (delay: number) =>
    reduce
      ? {}
      : {
          initial: { opacity: 0, y: 10, filter: "blur(6px)" },
          animate: shown ? { opacity: 1, y: 0, filter: "blur(0px)" } : undefined,
          transition: { duration: 0.6, ease: EASE, delay },
        };

  return (
    <div ref={ref} className="w-full text-[#191A23]">
      {/* Toolbar */}
      <motion.div {...enter(0)} className="relative z-20 mb-4 flex flex-wrap items-center gap-2">
        <Dropdown icon={Calendar} value={range} options={RANGES.map((r) => r.label)} onChange={resetPage(setRange)} />
        <span aria-hidden className="mx-1 hidden h-5 w-px bg-black/[0.08] sm:block" />
        <Dropdown
          icon={Users}
          value={user}
          options={["All Users", ...Object.keys(TEAM)]}
          onChange={resetPage(setUser)}
          render={(o) => (o === "All Users" ? o : <Person name={o} />)}
        />
        <Dropdown
          icon={Loader}
          value={status}
          options={["Any Status", ...(Object.keys(STATUS) as LeadStatus[])]}
          onChange={resetPage(setStatus)}
          render={(o) => (o === "Any Status" ? o : <StatusLabel status={o as LeadStatus} />)}
        />
        <Dropdown icon={CircleDollarSign} value={payment} options={PAYMENTS} onChange={resetPage(setPayment)} />
        <AnimatePresence>
          {filtersOn && (
            <motion.button
              type="button"
              onClick={clear}
              initial={{ opacity: 0, scale: 0.9 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.9 }}
              className="inline-flex h-8 cursor-pointer items-center gap-1 rounded-lg px-2.5 text-xs font-semibold text-[#6E7180] transition-colors hover:bg-[#FFF0F5] hover:text-[#FF5484]"
            >
              <X className="size-3.5" /> Reset
            </motion.button>
          )}
        </AnimatePresence>
        <label className="relative ml-auto w-full sm:w-64">
          <span className="sr-only">Search leads</span>
          <Search className="pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-[#6E7180]" />
          <input
            value={query}
            onChange={(e) => resetPage(setQuery)(e.target.value)}
            placeholder="Search leads by name, email..."
            className="h-8 w-full rounded-lg border border-black/[0.08] bg-[#FAF8FF]/60 pr-3 pl-8 text-xs text-[#191A23] outline-none transition-all placeholder:text-[#6E7180] focus:border-[#6842FF]/40 focus:bg-white focus:ring-2 focus:ring-[#6842FF]/15"
          />
        </label>
      </motion.div>

      {/* Table */}
      <motion.div
        initial={reduce ? false : { opacity: 0, y: 24, scale: 0.985, clipPath: "inset(0 0 100% 0 round 16px)" }}
        animate={shown ? { opacity: 1, y: 0, scale: 1, clipPath: "inset(0 0 0% 0 round 16px)" } : undefined}
        transition={{ duration: 0.9, ease: EASE, delay: 0.1 }}
        className="overflow-hidden rounded-2xl border border-black/[0.07] bg-white shadow-[0_1px_2px_rgba(0,0,0,0.03),0_8px_24px_-12px_rgba(104,66,255,0.08)]"
      >
        <div className="overflow-hidden">
          <table className="w-full table-fixed border-collapse text-[13px]">
            <colgroup>
              {COLS.map((w, i) => (
                <col key={i} style={{ width: w }} />
              ))}
            </colgroup>
            <thead>
              <tr className="bg-[#FAF8FF] text-left text-xs font-semibold text-[#6E7180]">
                <Th className="pl-4">
                  <Checkbox checked={allOnPage} mixed={!allOnPage && someOnPage} onChange={toggleAll} label="Select all rows on this page" />
                </Th>
                <Th>Lead name</Th>
                <Th>Status</Th>
                <SortTh label="Deal Value" k="value" sort={sort} onSort={toggleSort} />
                <Th>Assigned To</Th>
                <SortTh label="Interacted" k="interacted" sort={sort} onSort={toggleSort} />
                <Th>Payment Status</Th>
                <SortTh label="Date Added" k="added" sort={sort} onSort={toggleSort} />
              </tr>
            </thead>
            <tbody key={viewKey}>
              {rows.map((lead, i) => (
                <motion.tr
                  key={lead.id}
                  layout={reduce ? false : "position"}
                  initial={reduce ? false : { opacity: 0, x: -14, filter: "blur(4px)" }}
                  animate={shown ? { opacity: 1, x: 0, filter: "blur(0px)" } : undefined}
                  transition={{
                    duration: 0.5,
                    ease: EASE,
                    delay: intro ? 0.35 + i * 0.04 : i * 0.025,
                    layout: { duration: 0.45, ease: EASE },
                  }}
                  data-selected={selected.has(lead.id) || undefined}
                  className="group border-t border-black/[0.06] transition-colors hover:bg-[#FAF8FF]/80 data-[selected]:bg-[#F3F0FF]/70"
                >
                  <Td className="pl-4">
                    <Checkbox checked={selected.has(lead.id)} onChange={() => toggleOne(lead.id)} label={`Select ${lead.name}`} />
                  </Td>
                  <Td>
                    <span className="flex items-center gap-2.5">
                      <span className={cn("size-4 shrink-0 rounded-full", DOT[lead.tone])} />
                      <span className="font-semibold text-[#191A23]">{lead.name}</span>
                      {lead.messages ? (
                        <span className="inline-flex items-center gap-0.5 rounded-full bg-[#FF5484] px-1.5 py-px text-[10px] font-bold text-white">
                          <MessageCircle className="size-2.5 fill-current" />
                          {lead.messages}
                        </span>
                      ) : null}
                    </span>
                  </Td>
                  <Td>
                    <StatusLabel status={lead.status} />
                  </Td>
                  <Td>
                    <DealValue value={lead.value} shown={shown} count={intro && !reduce} />
                  </Td>
                  <Td>
                    <span className="flex items-center justify-between gap-3 pr-2">
                      <Person name={lead.assignee} />
                      <span className="font-mono text-[11px] font-semibold text-[#6E7180]">[{lead.role}]</span>
                    </span>
                  </Td>
                  <Td className="text-[#6E7180]">{ago(lead.interacted)}</Td>
                  <Td className={cn(lead.payment === "N/A" ? "text-[#6E7180]" : "font-medium text-[#191A23]")}>{lead.payment}</Td>
                  <Td className="text-[#6E7180]">{addedAgo(lead.added)}</Td>
                </motion.tr>
              ))}
              {rows.length === 0 && (
                <tr className="border-t border-black/[0.06]">
                  <td colSpan={8} className="py-14 text-center">
                    <p className="text-sm font-bold text-[#191A23]">No leads match these filters</p>
                    <button
                      type="button"
                      onClick={clear}
                      className="mt-2 cursor-pointer text-xs font-semibold text-[#6842FF] underline underline-offset-4 hover:text-[#FF5484]"
                    >
                      Clear filters
                    </button>
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </motion.div>
    </div>
  );
}

function Th({ children, className }: { children?: ReactNode; className?: string }) {
  return <th className={cn("h-10 border-r border-black/[0.06] px-3 font-semibold last:border-r-0", className)}>{children}</th>;
}

function Td({ children, className }: { children?: ReactNode; className?: string }) {
  return <td className={cn("h-11 truncate border-r border-black/[0.06] px-3 whitespace-nowrap last:border-r-0", className)}>{children}</td>;
}

function SortTh({ label, k, sort, onSort }: { label: string; k: SortKey; sort: Sort; onSort: (k: SortKey) => void }) {
  const active = sort?.key === k ? sort.dir : null;
  const Icon = active === "asc" ? ArrowUp : active === "desc" ? ArrowDown : ArrowUpDown;
  return (
    <th aria-sort={active === "asc" ? "ascending" : active === "desc" ? "descending" : "none"} className="h-10 border-r border-black/[0.06] p-0 font-semibold last:border-r-0">
      <button
        type="button"
        onClick={() => onSort(k)}
        className={cn(
          "flex h-10 w-full cursor-pointer items-center justify-between gap-2 px-3 text-left transition-colors hover:bg-[#F3F0FF]/60 hover:text-[#191A23]",
          active && "text-[#6842FF]",
        )}
      >
        {label}
        <AnimatePresence mode="wait" initial={false}>
          <motion.span
            key={active ?? "none"}
            initial={{ opacity: 0, y: active === "asc" ? 4 : -4 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: active === "asc" ? -4 : 4 }}
            transition={{ duration: 0.15 }}
          >
            <Icon className={cn("size-3.5", !active && "opacity-60")} />
          </motion.span>
        </AnimatePresence>
      </button>
    </th>
  );
}

function StatusLabel({ status }: { status: LeadStatus }) {
  const { icon: Icon, className } = STATUS[status];
  return (
    <span className="flex items-center gap-2 font-medium text-[#191A23]">
      <Icon className={cn("size-4 shrink-0", className)} />
      {status}
    </span>
  );
}

function Person({ name }: { name: string }) {
  return (
    <span className="flex items-center gap-2 font-medium text-[#191A23]">
      <span className={cn("size-4 shrink-0 rounded-full", DOT[TEAM[name]?.tone ?? "gray"])} />
      {name}
    </span>
  );
}

function DealValue({ value, shown, count }: { value: Lead["value"]; shown: boolean; count: boolean }) {
  const [n, setN] = useState(count && typeof value === "number" ? 0 : (value ?? 0));
  useEffect(() => {
    if (!count || !shown || typeof value !== "number") return;
    const controls = animate(0, value, { duration: 1.1, ease: EASE, delay: 0.45, onUpdate: setN });
    return () => controls.stop();
  }, [value, shown, count]);

  if (value === undefined) return <span className="text-[#6E7180]">N/A</span>;
  if (value === null)
    return (
      <span className="flex items-center justify-between text-[#6E7180]">
        Pending... <Minus className="size-3" />
      </span>
    );
  return (
    <span className="flex items-center justify-between font-semibold text-[#191A23] tabular-nums">
      <span className="text-[#6E7180]">$</span>
      {n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
    </span>
  );
}

function Checkbox({ checked, mixed, onChange, label }: { checked: boolean; mixed?: boolean; onChange: () => void; label: string }) {
  return (
    <button
      type="button"
      role="checkbox"
      aria-checked={mixed ? "mixed" : checked}
      aria-label={label}
      onClick={onChange}
      className={cn(
        "grid size-4 cursor-pointer place-items-center rounded-[4px] border border-black/[0.15] bg-white transition-colors focus-visible:ring-2 focus-visible:ring-[#6842FF]/30 focus-visible:outline-none",
        (checked || mixed) && "border-[#6842FF] bg-[#6842FF] text-white",
      )}
    >
      <AnimatePresence initial={false}>
        {(checked || mixed) && (
          <motion.span initial={{ scale: 0.4, opacity: 0 }} animate={{ scale: 1, opacity: 1 }} exit={{ scale: 0.4, opacity: 0 }} transition={{ duration: 0.15 }}>
            {mixed ? <Minus className="size-3" strokeWidth={3} /> : <Check className="size-3" strokeWidth={3} />}
          </motion.span>
        )}
      </AnimatePresence>
    </button>
  );
}

function Dropdown({
  icon: Icon,
  value,
  options,
  onChange,
  render = (o) => o,
  up,
}: {
  icon?: ComponentType<{ className?: string }>;
  value: string;
  options: string[];
  onChange: (v: string) => void;
  render?: (o: string) => ReactNode;
  up?: boolean;
}) {
  const [open, setOpen] = useState(false);
  const [active, setActive] = useState(0);
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!open) return;
    const close = (e: PointerEvent) => !ref.current?.contains(e.target as Node) && setOpen(false);
    document.addEventListener("pointerdown", close);
    return () => document.removeEventListener("pointerdown", close);
  }, [open]);

  const show = () => {
    setActive(Math.max(0, options.indexOf(value)));
    setOpen(true);
  };
  const pick = (o: string) => {
    onChange(o);
    setOpen(false);
  };

  return (
    <div
      ref={ref}
      className="relative"
      onKeyDown={(e) => {
        if (e.key === "Escape") setOpen(false);
        if (!open && (e.key === "ArrowDown" || e.key === "ArrowUp")) {
          e.preventDefault();
          show();
        } else if (open && e.key === "ArrowDown") {
          e.preventDefault();
          setActive((a) => (a + 1) % options.length);
        } else if (open && e.key === "ArrowUp") {
          e.preventDefault();
          setActive((a) => (a - 1 + options.length) % options.length);
        } else if (open && e.key === "Enter") {
          e.preventDefault();
          pick(options[active]);
        }
      }}
    >
      <button
        type="button"
        aria-haspopup="listbox"
        aria-expanded={open}
        onClick={() => (open ? setOpen(false) : show())}
        className={cn(
          "inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-lg border border-black/[0.08] bg-white px-2.5 text-xs font-semibold text-[#191A23] shadow-2xs transition-colors hover:bg-[#FAF8FF]",
          open && "border-[#6842FF]/30 bg-[#FAF8FF]",
        )}
      >
        {Icon && <Icon className="size-3.5 text-[#6842FF]" />}
        {value}
        <motion.span animate={{ rotate: open ? 180 : 0 }} transition={{ duration: 0.2 }}>
          <ChevronDown className="size-3.5 text-[#6E7180]" />
        </motion.span>
      </button>
      <AnimatePresence>
        {open && (
          <motion.ul
            role="listbox"
            initial={{ opacity: 0, y: up ? 6 : -6, scale: 0.97 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            exit={{ opacity: 0, y: up ? 4 : -4, scale: 0.98 }}
            transition={{ duration: 0.16, ease: EASE }}
            className={cn(
              "absolute left-0 z-30 min-w-full overflow-hidden rounded-xl border border-black/[0.08] bg-white p-1 text-xs text-[#191A23] shadow-xl",
              up ? "bottom-full mb-1 origin-bottom" : "top-full mt-1 origin-top",
            )}
          >
            {options.map((o, i) => (
              <li key={o} role="option" aria-selected={o === value}>
                <button
                  type="button"
                  onMouseEnter={() => setActive(i)}
                  onClick={() => pick(o)}
                  className={cn(
                    "flex w-full cursor-pointer items-center gap-3 rounded-lg px-2.5 py-1.5 text-left font-medium whitespace-nowrap",
                    i === active && "bg-[#F3F0FF] text-[#6842FF]",
                  )}
                >
                  <span className="flex-1">{render(o)}</span>
                  <Check className={cn("size-3.5 text-[#6842FF]", o === value ? "opacity-100" : "opacity-0")} />
                </button>
              </li>
            ))}
          </motion.ul>
        )}
      </AnimatePresence>
    </div>
  );
}

/* -------------------------------------------------------------------------- */
/*           HERO SECTION + LEADS TABLE WORKSPACE & FLOATING SIDE CARDS       */
/* -------------------------------------------------------------------------- */

const HERO_WORDS = [
  { text: "living motion.", bg: "#6842FF", shadow: "rgba(104,66,255,0.38)", angle: -1.8 },
  { text: "remote teams.", bg: "#FF5484", shadow: "rgba(255,84,132,0.38)", angle: 1.5 },
  { text: "fast startups.", bg: "#FFB81C", shadow: "rgba(255,184,28,0.42)", angle: -1.2 },
];

function HeroSection({ onNavigate }: { onNavigate: (id: string) => void }) {
  const reduce = useReducedMotion();
  const [wordIdx, setWordIdx] = useState(0);
  const [sprintPct, setSprintPct] = useState(56);

  useEffect(() => {
    if (reduce) return;
    const id = setInterval(() => {
      setWordIdx((prev) => (prev + 1) % HERO_WORDS.length);
    }, 3400);
    return () => clearInterval(id);
  }, [reduce]);

  const activeWord = HERO_WORDS[wordIdx];

  const triggerQuickAction = (_msg: string, _newGauge: number, newSprint: number) => {
    setSprintPct(newSprint);
  };

  return (
    <section
      data-section="top"
      className="relative overflow-hidden pt-10 pb-16 sm:pt-14"
    >
      {/* Subtle Pastel Radial Backdrop */}
      <div
        aria-hidden
        className="pointer-events-none absolute inset-x-0 top-8 mx-auto h-[540px] max-w-5xl rounded-full bg-gradient-to-b from-[#FFF0F5]/80 via-[#F3F0FF]/60 to-transparent blur-3xl"
      />

      {/* Playful Floating Stickers & Cursor Callouts in Signature Palette */}
      <FloatingSticker className="left-[8%] top-12 hidden lg:block" delay={0.1} distance={9}>
        <div className="flex items-center gap-2 rounded-2xl border border-[#FF5484]/15 bg-white px-3.5 py-2 shadow-[0_12px_28px_-8px_rgba(255,84,132,0.18)] -rotate-6">
          <span className="flex size-6 items-center justify-center rounded-lg bg-[#FFF0F5] text-xs">
            🎨
          </span>
          <span className="text-[11px] font-bold text-[#191A23]">Zero-code shaders</span>
        </div>
      </FloatingSticker>

      <FloatingSticker className="right-[8%] top-14 hidden lg:block" delay={0.6} distance={8}>
        <div className="flex items-center gap-2 rounded-2xl border border-[#6842FF]/15 bg-white px-3.5 py-2 shadow-[0_12px_28px_-8px_rgba(104,66,255,0.18)] rotate-6">
          <span className="size-2 rounded-full bg-[#FF5484] animate-ping" />
          <span className="text-[11px] font-bold text-[#191A23]">60 FPS Spring Engine</span>
        </div>
      </FloatingSticker>

      <FloatingSticker className="left-[13%] top-48 hidden lg:block" delay={0.3} distance={7}>
        <CursorBadge name="Maya" bg="#FF5484" textColor="#FFFFFF" pointerSide="right" />
      </FloatingSticker>

      <FloatingSticker className="right-[14%] top-52 hidden lg:block" delay={0.8} distance={8}>
        <CursorBadge name="Leo" bg="#6842FF" textColor="#FFFFFF" pointerSide="left" />
      </FloatingSticker>

      <div className="relative mx-auto max-w-6xl px-4 text-center sm:px-8">
        {/* Top Signature Pink Pill Badge */}
        <motion.div
          initial={reduce ? false : { opacity: 0, y: 12 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.6, ease: EASE }}
          className="inline-flex items-center gap-2.5 rounded-full border border-[#FF5484]/15 bg-[#FFF0F5] px-4 py-1.5 text-xs font-bold text-[#FF5484]"
        >
          <Wand2 className="size-3.5" />
          <span>TaskHub 2.0 · Team &amp; Motion Workspace</span>
        </motion.div>

        {/* Main Kinetic Headline */}
        <motion.h1
          initial={reduce ? false : { opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.7, delay: 0.06, ease: EASE }}
          className="mt-6 text-4xl font-extrabold leading-[1.14] tracking-[-0.03em] text-[#191A23] sm:text-6xl md:text-[64px]"
        >
          Turn wild sparks
          <br />
          <span>into </span>
          <span className="relative inline-block">
            <AnimatePresence mode="wait">
              <motion.button
                key={activeWord.text}
                type="button"
                onClick={() => setWordIdx((prev) => (prev + 1) % HERO_WORDS.length)}
                initial={reduce ? false : { opacity: 0, y: 18, rotate: -6, scale: 0.92 }}
                animate={{ opacity: 1, y: 0, rotate: activeWord.angle, scale: 1 }}
                exit={{ opacity: 0, y: -16, rotate: 6, scale: 0.92 }}
                transition={SPRING}
                style={{
                  backgroundColor: activeWord.bg,
                  boxShadow: `0 16px 34px -10px ${activeWord.shadow}`,
                }}
                className="inline-block cursor-pointer rounded-2xl px-4 py-1 text-white"
                title="Click to switch focus"
              >
                {activeWord.text}
              </motion.button>
            </AnimatePresence>
          </span>
        </motion.h1>

        {/* Subtitle */}
        <motion.p
          initial={reduce ? false : { opacity: 0, y: 14 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.7, delay: 0.14, ease: EASE }}
          className="mx-auto mt-6 max-w-lg text-xs leading-relaxed text-[#6E7180] sm:text-sm"
        >
          Sketch vector worlds, choreograph tactile spring physics, and jam with your crew
          on a single sunlit canvas—without touching a complex timeline.
        </motion.p>

        {/* Dual CTA Buttons in Signature Palette */}
        <motion.div
          initial={reduce ? false : { opacity: 0, y: 14 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.7, delay: 0.22, ease: EASE }}
          className="mt-8 flex flex-wrap items-center justify-center gap-5"
        >
          <button
            type="button"
            onClick={() => onNavigate("workspace")}
            className="group inline-flex cursor-pointer items-center gap-2.5 rounded-full bg-[#191A23] px-7 py-3.5 text-xs font-bold text-white shadow-md transition-all hover:scale-105 hover:bg-[#6842FF] active:scale-95"
          >
            <span>Explore Workspace</span>
            <Sparkles className="size-3.5 transition-transform group-hover:rotate-45" />
          </button>

          <button
            type="button"
            onClick={() => {
              setWordIdx((prev) => (prev + 1) % HERO_WORDS.length);
              triggerQuickAction("Remixed workspace theme & metrics!", 92, 74);
            }}
            className="group relative flex cursor-pointer items-center gap-3 text-xs font-bold text-[#191A23]"
          >
            <span className="relative flex size-10 items-center justify-center">
              <span className="absolute inset-0 scale-150 rounded-full bg-[#FF5484]/25 blur-md transition-transform group-hover:scale-175" />
              <span className="relative flex size-8 items-center justify-center rounded-full bg-white text-[#FF5484] shadow-sm ring-1 ring-[#FF5484]/20 transition-transform group-hover:scale-110">
                <Play className="size-3.5 fill-current ml-0.5" />
              </span>
            </span>
            <span>Watch Live Demo</span>
          </button>
        </motion.div>

        {/* ==================================================================== */}
        {/*   INTERACTIVE HERO WORKSPACE DASHBOARD + FLOATING SIDE CARDS         */}
        {/* ==================================================================== */}
        <div id="workspace" data-section="workspace" className="relative mt-12 sm:mt-16">
          {/* Hand-drawn Callout Annotations above the Workspace Frame (appear after table finishes unfolding) */}
          <div
            aria-hidden
            className="pointer-events-none mx-auto mb-3 hidden max-w-4xl items-end justify-between px-6 md:flex"
          >
            <motion.div
              initial={reduce ? false : { opacity: 0, y: 10, scale: 0.92 }}
              animate={{ opacity: 1, y: 0, scale: 1 }}
              transition={{ duration: 0.5, delay: 1.25, ease: EASE }}
              className="flex items-center gap-2 -rotate-6"
            >
              <span className="text-xs font-extrabold leading-tight text-[#191A23]">
                Quick Action
                <br />
                Buttons
              </span>
              <svg width="48" height="28" viewBox="0 0 48 28" fill="none">
                <motion.path
                  d="M2 6C18 2 34 8 42 24M42 24L35 21M42 24L45 17"
                  stroke="#191A23"
                  strokeWidth="2"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  initial={reduce ? false : { pathLength: 0, opacity: 0 }}
                  animate={{ pathLength: 1, opacity: 1 }}
                  transition={{ duration: 0.55, delay: 1.35, ease: EASE }}
                />
              </svg>
            </motion.div>

            <motion.div
              initial={reduce ? false : { opacity: 0, y: 10, scale: 0.92 }}
              animate={{ opacity: 1, y: 0, scale: 1 }}
              transition={{ duration: 0.5, delay: 1.4, ease: EASE }}
              className="flex items-center gap-2 rotate-6"
            >
              <svg width="48" height="28" viewBox="0 0 48 28" fill="none">
                <motion.path
                  d="M46 22C32 6 18 4 6 16M6 16L13 16M6 16L7 9"
                  stroke="#191A23"
                  strokeWidth="2"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  initial={reduce ? false : { pathLength: 0, opacity: 0 }}
                  animate={{ pathLength: 1, opacity: 1 }}
                  transition={{ duration: 0.55, delay: 1.5, ease: EASE }}
                />
              </svg>
              <span className="text-xs font-extrabold leading-tight text-[#191A23]">
                Clean and
                <br />
                Minimal Layout
              </span>
            </motion.div>
          </div>

          {/* FLOATING LEFT PEEK CARD */}
          <motion.div
            animate={reduce ? undefined : { y: [0, -8, 0] }}
            transition={{ duration: 5, repeat: Infinity, ease: "easeInOut" }}
            className="pointer-events-none absolute -left-10 bottom-10 z-20 hidden w-60 rounded-3xl border border-[#FF5484]/15 bg-white/95 p-5 text-left shadow-[0_24px_48px_-12px_rgba(255,84,132,0.16)] backdrop-blur-md xl:block"
          >
            <div className="flex items-start justify-between">
              <div>
                <div className="text-xs font-extrabold text-[#191A23]">Refresh the web design</div>
                <p className="mt-1 text-[10px] leading-relaxed text-[#6E7180]">
                  Reflect the latest motion tokens and spring curves.
                </p>
              </div>
              <span className="text-xl font-extrabold text-[#FF5484]">{sprintPct}%</span>
            </div>
            <div className="mt-3 h-2 w-full overflow-hidden rounded-full bg-[#FFF0F5]">
              <motion.div
                animate={{ width: `${sprintPct}%` }}
                className="h-full rounded-full bg-[#FF5484]"
              />
            </div>
            <div className="mt-4 flex items-center justify-between">
              <div className="flex gap-1.5">
                <span className="rounded-full bg-[#FFF0F5] px-2.5 py-0.5 text-[9px] font-extrabold text-[#FF5484]">
                  UI/UX
                </span>
                <span className="rounded-full bg-[#FFF9EB] px-2.5 py-0.5 text-[9px] font-extrabold text-[#D97706]">
                  Motion
                </span>
              </div>
              <div className="flex -space-x-1.5">
                <AvatarBubble emoji="👩🏻" bg="#FBCFE8" size="xs" />
                <AvatarBubble emoji="🧑🏽" bg="#FDE68A" size="xs" />
                <AvatarBubble emoji="🧔🏼" bg="#DDD6FE" size="xs" />
              </div>
            </div>
          </motion.div>

          {/* FLOATING RIGHT PEEK CARD */}
          <motion.div
            animate={reduce ? undefined : { y: [0, 8, 0] }}
            transition={{ duration: 5.5, repeat: Infinity, ease: "easeInOut", delay: 0.5 }}
            className="pointer-events-none absolute -right-10 bottom-14 z-20 hidden w-60 rounded-3xl border border-[#6842FF]/15 bg-white/95 p-5 text-left shadow-[0_24px_48px_-12px_rgba(104,66,255,0.16)] backdrop-blur-md xl:block"
          >
            <div className="text-xs font-extrabold text-[#191A23]">Brand Motion System</div>
            <div className="text-[10px] text-[#6E7180]">Studio: TaskHub Lab</div>
            <div className="mt-3 flex items-center justify-between">
              <div>
                <div className="text-[10px] font-bold text-[#6E7180]">Team Members</div>
                <div className="mt-1 flex items-center -space-x-1.5">
                  <AvatarBubble emoji="🧑🏻" bg="#DDD6FE" size="xs" />
                  <AvatarBubble emoji="👩🏽" bg="#FDE68A" size="xs" />
                  <AvatarBubble emoji="🧔🏻" bg="#FBCFE8" size="xs" />
                  <span className="inline-flex size-6 items-center justify-center rounded-full border-2 border-white bg-[#6842FF] text-[10px] font-bold text-white">
                    +
                  </span>
                </div>
              </div>
              <div className="text-right">
                <div className="text-xl font-extrabold text-[#6842FF]">84%</div>
                <div className="mt-1 h-1.5 w-14 overflow-hidden rounded-full bg-[#F3F0FF]">
                  <div className="h-full w-[84%] rounded-full bg-[#6842FF]" />
                </div>
              </div>
            </div>
          </motion.div>

          {/* MAIN WORKSPACE APPLICATION SHELL (LEADS TABLE COMPONENT) */}
          <motion.div
            initial={reduce ? false : { opacity: 0, y: 28 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.85, delay: 0.25, ease: EASE }}
            className="mx-auto max-w-5xl rounded-[32px] border border-[#6842FF]/10 bg-white p-4 sm:p-7 text-left shadow-[0_32px_80px_-24px_rgba(104,66,255,0.14)]"
          >
            <HeroLeadsTable />
          </motion.div>
        </div>

        {/* ==================================================================== */}
        {/*              TRUSTED BY WORLD'S INNOVATIVE TEAMS STRIP               */}
        {/* ==================================================================== */}
        <div className="mt-16 pt-4">
          <p className="text-xs font-bold text-[#76798A] sm:text-sm">
            Trusted by creative teams &amp; fast-moving studios worldwide
          </p>
          <div className="mt-7 flex flex-wrap items-center justify-center gap-8 sm:gap-14">
            {[
              { name: "Netdot", color: "#6842FF", glyph: "N" },
              { name: "Sparkweb", color: "#FF5484", glyph: "S" },
              { name: "Webgear", color: "#FFB81C", glyph: "W" },
              { name: "Digitech", color: "#6842FF", glyph: "D" },
              { name: "Codelink", color: "#FF5484", glyph: "C" },
            ].map((brand) => (
              <div
                key={brand.name}
                className="flex items-center gap-2.5 opacity-85 transition-opacity hover:opacity-100"
              >
                <span
                  className="grid size-6 place-items-center rounded-lg text-xs font-black text-white"
                  style={{ backgroundColor: brand.color }}
                >
                  {brand.glyph}
                </span>
                <span className="text-sm font-extrabold tracking-tight text-[#191A23] sm:text-base">
                  {brand.name}
                </span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

/* -------------------------------------------------------------------------- */
/*          SECTION 2: "WHAT MAKES US DIFFERENT" (FROM SAMPLE IMAGE 3)        */
/* -------------------------------------------------------------------------- */

const DATES = [
  { label: "Thu, November 5, 2026", pct: 56 },
  { label: "Fri, November 6, 2026", pct: 72 },
  { label: "Mon, November 9, 2026", pct: 89 },
];

const COLLAB_MEMBERS = [
  { name: "Darrell Steward", role: "Design Lead", emoji: "🧑🏻", bg: "#E0E7FF", tilted: false },
  { name: "Maya Lin", role: "Motion Architect", emoji: "👩🏽", bg: "#FCE7F3", tilted: true },
  { name: "Liam Vance", role: "Product Engineer", emoji: "🧔🏼", bg: "#FEF3C7", tilted: false },
];

function WhatMakesUsDifferentSection() {
  const [dateIdx, setDateIdx] = useState(0);
  const [todayTasks, setTodayTasks] = useState(15);
  const [inProgressTasks, setInProgressTasks] = useState(23);
  const [teamPct, setTeamPct] = useState(84);
  const [pingedMember, setPingedMember] = useState<string | null>(null);

  const activeDate = DATES[dateIdx];

  const handleAddPriorityTask = () => {
    setTodayTasks((t) => t + 1);
    setInProgressTasks((p) => p + 1);
    setTeamPct((pct) => (pct >= 98 ? 84 : pct + 2));
  };

  const handlePing = (name: string, action: string) => {
    setPingedMember(`${action} ${name}...`);
    setTimeout(() => setPingedMember(null), 1800);
  };

  return (
    <section
      id="different"
      data-section="different"
      className="relative mx-auto max-w-6xl px-4 py-20 sm:px-8 sm:py-24"
    >
      {/* Section Heading with Tilted Signature Pink/Amber Sticker */}
      <div className="text-center">
        <div className="relative inline-block">
          <motion.span
            whileHover={{ rotate: -6, scale: 1.06 }}
            transition={SPRING}
            className="absolute -top-6 left-[52%] -translate-x-1/2 -rotate-[12deg] rounded-full bg-[#FFB81C] px-3.5 py-1 text-[11px] font-extrabold text-white shadow-xs"
          >
            Why choose us
          </motion.span>
          <h2 className="text-3xl font-extrabold tracking-tight text-[#191A23] sm:text-5xl">
            What makes us different
          </h2>
        </div>
        <p className="mx-auto mt-4 max-w-md text-xs leading-relaxed text-[#6E7180] sm:text-sm">
          Simplify project planning, streamline collaboration, and boost productivity
          all with TaskHub task &amp; motion management.
        </p>
      </div>

      {/* 3 Signature Pastel Bento Cards (Pink / Amber / Purple) */}
      <div className="mt-14 grid gap-6 lg:grid-cols-3">
        {/* CARD 1: Activity tracking & insights (Soft Rose Pink Tint) */}
        <motion.div
          whileHover={{ y: -5 }}
          transition={SPRING}
          className="relative flex flex-col justify-between overflow-hidden rounded-[28px] bg-[#FFF0F5]/85 p-7"
          style={{
            backgroundImage: "radial-gradient(rgba(255,84,132,0.12) 1px, transparent 1px)",
            backgroundSize: "14px 14px",
          }}
        >
          <div>
            <div className="grid size-12 place-items-center rounded-2xl bg-[#FF5484] text-white shadow-[0_10px_20px_-6px_rgba(255,84,132,0.45)]">
              <Clock3 className="size-5" />
            </div>

            <h3 className="mt-6 text-lg font-extrabold text-[#191A23]">
              Activity tracking &amp; insights
            </h3>
            <p className="mt-2 text-xs leading-relaxed text-[#6E7180]">
              Built to work seamlessly across devices, ensuring your creative crew stays
              connected and informed.
            </p>
          </div>

          <div className="mt-7 space-y-3.5">
            {/* Crisp White Inner Card */}
            <div className="rounded-2xl bg-white p-5 shadow-[0_14px_30px_-12px_rgba(255,84,132,0.12)]">
              <div className="flex items-start justify-between gap-2">
                <div>
                  <div className="text-xs font-extrabold text-[#191A23]">User Research</div>
                  <p className="mt-1 text-[10px] leading-relaxed text-[#6E7180]">
                    Ensure all marketing strategies and promotional materials...
                  </p>
                </div>
                <div className="text-right">
                  <span className="text-2xl font-extrabold text-[#FF5484] tabular-nums">
                    {activeDate.pct}%
                  </span>
                  <div className="mt-1.5 h-1.5 w-14 overflow-hidden rounded-full bg-[#FFF0F5]">
                    <motion.div
                      animate={{ width: `${activeDate.pct}%` }}
                      className="h-full rounded-full bg-[#FF5484]"
                    />
                  </div>
                </div>
              </div>

              <div className="mt-5 flex items-center justify-between">
                <span className="rounded-full bg-[#FFF0F5] px-3 py-1 text-[10px] font-extrabold text-[#FF5484]">
                  Web UI
                </span>
                <div className="flex -space-x-1.5">
                  <AvatarBubble emoji="👩🏻" bg="#FBCFE8" size="xs" />
                  <AvatarBubble emoji="🧔🏽" bg="#FDE68A" size="xs" />
                  <AvatarBubble emoji="🧑🏼" bg="#DDD6FE" size="xs" />
                </div>
              </div>
            </div>

            {/* Tilted Interactive Date Switcher Pill */}
            <motion.div
              whileHover={{ rotate: 0, scale: 1.02 }}
              className="flex -rotate-[2deg] items-center justify-between rounded-2xl bg-white px-4 py-2.5 shadow-[0_12px_24px_-10px_rgba(255,84,132,0.14)]"
            >
              <span className="text-[11px] font-bold text-[#6E7180]">
                {activeDate.label}
              </span>
              <div className="flex items-center gap-1.5">
                <button
                  type="button"
                  aria-label="Previous day"
                  onClick={() => setDateIdx((i) => (i - 1 + DATES.length) % DATES.length)}
                  className="grid size-6 cursor-pointer place-items-center rounded-lg text-[#6E7180] hover:bg-[#FFF0F5] hover:text-[#FF5484]"
                >
                  <ChevronLeft className="size-3.5" />
                </button>
                <button
                  type="button"
                  aria-label="Next day"
                  onClick={() => setDateIdx((i) => (i + 1) % DATES.length)}
                  className="grid size-6 cursor-pointer place-items-center rounded-lg text-[#6E7180] hover:bg-[#FFF0F5] hover:text-[#FF5484]"
                >
                  <ChevronRight className="size-3.5" />
                </button>
                <span className="grid size-7 place-items-center rounded-lg bg-[#FF5484] text-white">
                  <Calendar className="size-3.5" />
                </span>
              </div>
            </motion.div>
          </div>
        </motion.div>

        {/* CARD 2: Task prioritization (Soft Sunny Amber Tint) */}
        <motion.div
          whileHover={{ y: -5 }}
          transition={SPRING}
          className="relative flex flex-col justify-between overflow-hidden rounded-[28px] bg-[#FFF9EB] p-7"
          style={{
            backgroundImage: "radial-gradient(rgba(255,184,28,0.16) 1px, transparent 1px)",
            backgroundSize: "14px 14px",
          }}
        >
          <div>
            <div className="grid size-12 place-items-center rounded-2xl bg-[#FFB81C] text-white shadow-[0_10px_20px_-6px_rgba(255,184,28,0.5)]">
              <FolderKanban className="size-5" />
            </div>

            <h3 className="mt-6 text-lg font-extrabold text-[#191A23]">
              Task prioritization
            </h3>
            <p className="mt-2 text-xs leading-relaxed text-[#6E7180]">
              Organize your tasks by priority levels to make sure your team focuses on
              what matters most.
            </p>
          </div>

          {/* Layered White Card with Sub-boxes */}
          <div className="relative mt-7">
            <div className="mx-3 h-3 rounded-t-2xl bg-white/60" />
            <div className="rounded-2xl bg-white p-5 shadow-[0_14px_30px_-12px_rgba(255,184,28,0.14)]">
              <div className="flex items-center justify-between">
                <div>
                  <div className="text-xs font-extrabold text-[#191A23]">Team Members</div>
                  <div className="mt-2 flex items-center -space-x-1.5">
                    <AvatarBubble emoji="🧑🏻" bg="#DDD6FE" size="xs" />
                    <AvatarBubble emoji="👩🏽" bg="#FDE68A" size="xs" />
                    <AvatarBubble emoji="🧔🏻" bg="#FBCFE8" size="xs" />
                    <AvatarBubble emoji="👩🏼" bg="#F3E8FF" size="xs" />
                    <button
                      type="button"
                      onClick={handleAddPriorityTask}
                      title="Click to assign priority task"
                      className="inline-flex size-6 cursor-pointer items-center justify-center rounded-full border-2 border-white bg-[#FFB81C] text-xs font-bold text-white transition-transform hover:scale-110 active:scale-95"
                    >
                      +
                    </button>
                  </div>
                </div>

                <div className="text-right">
                  <span className="text-2xl font-extrabold text-[#191A23] tabular-nums">
                    {teamPct}%
                  </span>
                  <div className="mt-1.5 h-1.5 w-16 overflow-hidden rounded-full bg-[#FFF9EB]">
                    <motion.div
                      animate={{ width: `${teamPct}%` }}
                      className="h-full rounded-full bg-[#FFB81C]"
                    />
                  </div>
                </div>
              </div>

              <div className="mt-5 grid grid-cols-2 gap-3">
                <div className="rounded-xl bg-[#FFF9EB]/70 p-3">
                  <div className="flex items-center gap-1.5 text-[10px] font-semibold text-[#6E7180]">
                    <Zap className="size-3 text-[#FFB81C]" />
                    <span>Task Today</span>
                  </div>
                  <div className="mt-2 flex items-baseline gap-1">
                    <span className="text-xl font-extrabold text-[#191A23] tabular-nums">
                      {todayTasks}
                    </span>
                    <span className="text-[10px] font-semibold text-[#6E7180]">Tasks</span>
                  </div>
                </div>

                <div className="rounded-xl bg-[#F3F0FF]/70 p-3">
                  <div className="flex items-center gap-1.5 text-[10px] font-semibold text-[#6E7180]">
                    <Sparkles className="size-3 text-[#6842FF]" />
                    <span>In Progress</span>
                  </div>
                  <div className="mt-2 flex items-baseline gap-1">
                    <span className="text-xl font-extrabold text-[#191A23] tabular-nums">
                      {inProgressTasks}
                    </span>
                    <span className="text-[10px] font-semibold text-[#6E7180]">Tasks</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </motion.div>

        {/* CARD 3: Team collaboration (Soft Iris Purple Tint) */}
        <motion.div
          whileHover={{ y: -5 }}
          transition={SPRING}
          className="relative flex flex-col justify-between overflow-hidden rounded-[28px] bg-[#F3F0FF]/90 p-7"
          style={{
            backgroundImage: "radial-gradient(rgba(104,66,255,0.12) 1px, transparent 1px)",
            backgroundSize: "14px 14px",
          }}
        >
          <div>
            <div className="grid size-12 place-items-center rounded-2xl bg-[#6842FF] text-white shadow-[0_10px_20px_-6px_rgba(104,66,255,0.45)]">
              <MessageCircle className="size-5" />
            </div>

            <div className="mt-6 flex items-center justify-between">
              <h3 className="text-lg font-extrabold text-[#191A23]">
                Team collaboration
              </h3>
              {pingedMember && (
                <span className="rounded-full bg-[#6842FF]/15 px-2.5 py-0.5 text-[10px] font-bold text-[#6842FF]">
                  {pingedMember}
                </span>
              )}
            </div>
            <p className="mt-2 text-xs leading-relaxed text-[#6E7180]">
              Collaborate effortlessly with your team, no matter where they are in
              real-time.
            </p>
          </div>

          {/* 3 Stacked & Tilted Teammate Contact Pills */}
          <div className="mt-7 space-y-3">
            {COLLAB_MEMBERS.map((m) => (
              <motion.div
                key={m.name}
                whileHover={{ rotate: 0, scale: 1.03 }}
                transition={SPRING}
                className={cn(
                  "flex items-center justify-between rounded-2xl bg-white px-4 py-3 shadow-[0_12px_26px_-10px_rgba(104,66,255,0.12)]",
                  m.tilted && "rotate-[3.5deg] shadow-[0_18px_34px_-10px_rgba(104,66,255,0.2)]"
                )}
              >
                <div className="flex items-center gap-3">
                  <AvatarBubble emoji={m.emoji} bg={m.bg} size="sm" />
                  <div>
                    <div className="text-xs font-extrabold text-[#191A23]">{m.name}</div>
                    <div className="text-[10px] text-[#6E7180]">{m.role}</div>
                  </div>
                </div>

                <div className="flex items-center gap-1.5">
                  <button
                    type="button"
                    aria-label={`Message ${m.name}`}
                    onClick={() => handlePing(m.name.split(" ")[0], "Messaged")}
                    className="grid size-7 cursor-pointer place-items-center rounded-full bg-[#FFF0F5] text-[#FF5484] transition-transform hover:scale-110 active:scale-95"
                  >
                    <MessageCircle className="size-3.5" />
                  </button>
                  <button
                    type="button"
                    aria-label={`Call ${m.name}`}
                    onClick={() => handlePing(m.name.split(" ")[0], "Calling")}
                    className="grid size-7 cursor-pointer place-items-center rounded-full bg-[#F3F0FF] text-[#6842FF] transition-transform hover:scale-110 active:scale-95"
                  >
                    <Phone className="size-3.5" />
                  </button>
                </div>
              </motion.div>
            ))}
          </div>
        </motion.div>
      </div>
    </section>
  );
}

/* -------------------------------------------------------------------------- */
/*     SECTION 3: CUSTOMIZED NEXTUI.DEV COMPONENTS (CHECKLIST & CONVEYOR)     */
/* -------------------------------------------------------------------------- */

const AGENT_STEPS = [
  { label: "Sync design tokens with Figma & Tailwind" },
  { label: "Generate spring physics for hero cards" },
  { label: "Optimize SVG keyframes for 60 FPS mobile" },
  { label: "Deploy live preview link to team channel" },
];

const CONVEYOR_ROWS = [
  { value: "6.5 hrs", label: "Deep flow", icon: Clock3, colors: "from-cyan-400 to-blue-500" },
  { value: "28", label: "Tasks shipped", icon: ListChecks, colors: "from-amber-400 to-orange-500" },
  { value: "14 days", label: "Sprint streak", icon: Flame, colors: "from-pink-500 to-rose-500" },
  { value: "+5", label: "Motion kits", icon: FolderKanban, colors: "from-emerald-400 to-teal-500" },
  { value: "96%", label: "Velocity score", icon: Target, colors: "from-violet-500 to-purple-600" },
];

function NextUIShowcaseSection() {
  const reduce = useReducedMotion();

  // 1. State for Customized AgentTaskChecklist (from registry/components/task-checklist.tsx)
  const [activeStep, setActiveStep] = useState(1);
  const [stepPct, setStepPct] = useState(67);

  useEffect(() => {
    if (reduce) return;
    const id = setInterval(() => {
      setStepPct((prev) => {
        if (prev < 100) return prev + 33 > 100 ? 100 : prev + 33;
        setActiveStep((s) => (s + 1) % (AGENT_STEPS.length + 1));
        return 34;
      });
    }, 950);
    return () => clearInterval(id);
  }, [reduce]);

  // 2. Refs for Customized AnimatedMetricsCard conveyor (from registry/components/animated-metrics-card.tsx)
  const pillRefs = useRef<(HTMLLIElement | null)[]>([]);
  const H = 76;
  const GAP = 12;
  const VIEW = 320;

  useAnimationFrame((time) => {
    if (reduce) return;
    const offset = (time / 1000) * 38;
    const step = H + GAP;
    const loop = CONVEYOR_ROWS.length * step;
    const focus = VIEW * 0.5;

    pillRefs.current.forEach((el, i) => {
      if (!el) return;
      const top = ((((i * step - offset) % loop) + loop) % loop) - step;
      const dist = Math.min(Math.abs(top + H / 2 - focus) / (VIEW / 2), 1);
      const scale = 1 - 0.32 * dist ** 1.4;
      const opacity = 1 - 0.8 * dist ** 2.6;
      el.style.transform = `translateY(${top}px) scale(${scale})`;
      el.style.opacity = String(opacity);
    });
  });

  return (
    <section
      id="automation"
      data-section="automation"
      className="relative mx-auto max-w-6xl px-4 py-12 sm:px-8 sm:py-20"
    >
      <div className="grid items-stretch gap-8 lg:grid-cols-12">
        {/* LEFT (6 cols): Customized NextUI AgentTaskChecklist Card */}
        <div className="flex flex-col justify-between rounded-[32px] border border-black/[0.06] bg-[#FAF8FF] p-7 sm:p-9 lg:col-span-6">
          <div>
            <div className="inline-flex items-center gap-2 rounded-full bg-[#6842FF]/10 px-3.5 py-1 text-xs font-bold text-[#6842FF]">
              <Wand2 className="size-3.5" />
              <span>Autonomous Sprint Co-Pilot</span>
            </div>
            <h3 className="mt-4 text-2xl font-extrabold tracking-tight text-[#191A23] sm:text-3xl">
              Hands-free task execution.
            </h3>
            <p className="mt-2 text-xs leading-relaxed text-[#6E7180] sm:text-sm">
              Watch TaskHub break down your release checklist and tick off each step
              in real time—click any row to jump directly to that stage.
            </p>
          </div>

          {/* Interactive Collapsible Ring Checklist Component */}
          <div className="mt-7 rounded-2xl bg-white p-2 shadow-[0_18px_40px_-15px_rgba(104,66,255,0.14)] ring-1 ring-black/[0.05]">
            <div className="flex items-center justify-between border-b border-black/[0.05] px-3.5 py-3">
              <div className="flex items-center gap-2.5">
                <span className="grid size-6 place-items-center rounded-full bg-[#6842FF] text-white">
                  <Sparkles className="size-3.5" />
                </span>
                <span className="text-xs font-extrabold text-[#191A23]">
                  Q4 Product Launch Pipeline
                </span>
              </div>
              <span className="rounded-full bg-[#F4F1FF] px-2.5 py-0.5 text-[11px] font-extrabold text-[#6842FF] tabular-nums">
                {Math.min(activeStep, AGENT_STEPS.length)}/{AGENT_STEPS.length} done
              </span>
            </div>

            <ol className="divide-y divide-black/[0.04] px-2 py-1">
              {AGENT_STEPS.map((st, idx) => {
                const isDone = idx < activeStep;
                const isCurrent = idx === activeStep;
                return (
                  <li
                    key={st.label}
                    onClick={() => {
                      setActiveStep(idx);
                      setStepPct(67);
                    }}
                    className="flex cursor-pointer items-center justify-between gap-3 rounded-xl px-2.5 py-3 transition-colors hover:bg-slate-50"
                  >
                    <div className="flex items-center gap-3">
                      {isDone ? (
                        <motion.span
                          initial={{ scale: 0.6 }}
                          animate={{ scale: 1 }}
                          className="grid size-5 place-items-center rounded-full bg-emerald-500 text-white"
                        >
                          <Check className="size-3 stroke-[3]" />
                        </motion.span>
                      ) : isCurrent ? (
                        <span className="relative grid size-5 place-items-center">
                          <span className="absolute inset-0 animate-ping rounded-full bg-[#6842FF]/30" />
                          <span className="size-3 rounded-full border-2 border-[#6842FF] bg-white" />
                        </span>
                      ) : (
                        <span className="size-5 rounded-full border-2 border-slate-200" />
                      )}

                      <span
                        className={cn(
                          "text-xs font-bold transition-all",
                          isDone
                            ? "text-[#6E7180] line-through"
                            : isCurrent
                              ? "text-[#191A23]"
                              : "text-[#6E7180]"
                        )}
                      >
                        {st.label}
                      </span>
                    </div>

                    <span
                      className={cn(
                        "text-[11px] font-extrabold tabular-nums",
                        isDone
                          ? "text-emerald-600"
                          : isCurrent
                            ? "text-[#6842FF]"
                            : "text-slate-300"
                      )}
                    >
                      {isDone ? "100%" : isCurrent ? `${stepPct}%` : "Queued"}
                    </span>
                  </li>
                );
              })}
            </ol>
          </div>
        </div>

        {/* RIGHT (6 cols): Customized NextUI AnimatedMetricsCard Conveyor */}
        <div className="grid grid-cols-1 items-center gap-6 overflow-hidden rounded-[32px] border border-black/[0.06] bg-[#FFF9EE] p-7 sm:grid-cols-[1fr_0.95fr] sm:p-9 lg:col-span-6">
          <div>
            <div className="inline-flex items-center gap-2 rounded-full bg-[#FFDA66]/50 px-3.5 py-1 text-xs font-bold text-[#191A23]">
              <span className="size-2 rounded-full bg-emerald-500" />
              <span>Live Team Momentum</span>
            </div>
            <h3 className="mt-4 text-2xl font-extrabold leading-tight tracking-tight text-[#191A23] sm:text-3xl">
              Small steps.
              <br />
              Real momentum.
            </h3>
            <p className="mt-3 text-xs leading-relaxed text-[#6E7180] sm:text-sm">
              Make space for focused creative work, finish what matters, and watch your
              team&apos;s weekly velocity add up automatically.
            </p>
          </div>

          {/* 3D Vertical Conveyor of Colorful Gradient Pills */}
          <ul
            aria-label="Weekly progress metrics"
            className="relative mx-auto w-full max-w-[270px] overflow-hidden"
            style={{
              height: VIEW,
              maskImage: "linear-gradient(to bottom, transparent, #000 16%, #000 84%, transparent)",
              WebkitMaskImage:
                "linear-gradient(to bottom, transparent, #000 16%, #000 84%, transparent)",
            }}
          >
            {CONVEYOR_ROWS.map((row, i) => {
              const Icon = row.icon;
              return (
                <li
                  key={row.label}
                  ref={(el) => {
                    pillRefs.current[i] = el;
                  }}
                  className={cn(
                    "absolute inset-x-0 top-0 flex w-full items-center gap-3 rounded-full bg-gradient-to-r p-2 pr-5 text-white shadow-lg shadow-black/10 will-change-transform",
                    row.colors
                  )}
                  style={{ height: H }}
                >
                  <span className="grid aspect-square h-full shrink-0 place-items-center rounded-full bg-white text-[#191A23] shadow-2xs">
                    <Icon className="size-5" />
                  </span>
                  <div className="min-w-0 flex-1">
                    <div className="truncate text-lg font-extrabold leading-none">
                      {row.value}
                    </div>
                    <div className="mt-1 truncate text-xs font-medium text-white/90">
                      {row.label}
                    </div>
                  </div>
                </li>
              );
            })}
          </ul>
        </div>
      </div>
    </section>
  );
}

/* -------------------------------------------------------------------------- */
/*          SECTION 4: "PROJECTS THAT WORK." 3-COLUMN FEATURE SWITCHER        */
/* -------------------------------------------------------------------------- */

const FEATURE_TABS = [
  {
    id: "dashboard",
    title: "Dashboard",
    sub: "Everything in one calm place",
    ringColor: "#FF5484",
    dotColor: "#FF5484",
    cardBg: "#FFF5F7",
    cardAccent: "#FF5484",
    headerTitle: "Team Overview",
    activeRow: 0,
    rows: [
      { title: "Q4 Design System Launch", tag: "On Track", width: "w-36" },
      { title: "Mobile App Onboarding", tag: "In Review", width: "w-28" },
      { title: "Customer Feedback Loop", tag: "Synced", width: "w-32" },
    ],
  },
  {
    id: "project",
    title: "Project",
    sub: "Clear overview, full efficiency",
    ringColor: "#FFB81C",
    dotColor: "#FFB81C",
    cardBg: "#FFF9EE",
    cardAccent: "#F59E0B",
    headerTitle: "Manage Project",
    activeRow: 1,
    rows: [
      { title: "Brand Guidelines Refresh", tag: "Done", width: "w-32" },
      { title: "Interactive Prototype Sprint", tag: "Active", width: "w-40" },
      { title: "Stakeholder Demo Deck", tag: "Next", width: "w-28" },
    ],
  },
  {
    id: "task",
    title: "Task",
    sub: "Where focused work gets done",
    ringColor: "#6842FF",
    dotColor: "#6842FF",
    cardBg: "#F4F1FF",
    cardAccent: "#6842FF",
    headerTitle: "Sprint Tasks",
    activeRow: 2,
    rows: [
      { title: "Ship new navigation header", tag: "Merged", width: "w-36" },
      { title: "Polish card spring animations", tag: "Testing", width: "w-32" },
      { title: "Finalize mobile breakpoints", tag: "Priority", width: "w-40" },
    ],
  },
  {
    id: "agenda",
    title: "Agenda",
    sub: "Your own personal board",
    ringColor: "#10B981",
    dotColor: "#10B981",
    cardBg: "#ECFDF5",
    cardAccent: "#10B981",
    headerTitle: "Daily Agenda",
    activeRow: 0,
    rows: [
      { title: "10:00 AM · Design Crit Sync", tag: "Live", width: "w-36" },
      { title: "01:30 PM · Roadmap Planning", tag: "Upcoming", width: "w-32" },
      { title: "04:00 PM · Async Wrap-up", tag: "Scheduled", width: "w-28" },
    ],
  },
];

function FeaturesSection() {
  const reduce = useReducedMotion();
  const [activeIdx, setActiveIdx] = useState(1);
  const [paused, setPaused] = useState(false);
  const [selectedTaskRow, setSelectedTaskRow] = useState<number | null>(null);

  useEffect(() => {
    if (reduce || paused) return;
    const id = setInterval(() => {
      setActiveIdx((prev) => (prev + 1) % FEATURE_TABS.length);
      setSelectedTaskRow(null);
    }, 4200);
    return () => clearInterval(id);
  }, [reduce, paused]);

  const current = FEATURE_TABS[activeIdx];
  const highlightedRow = selectedTaskRow ?? current.activeRow;

  return (
    <section
      id="features"
      data-section="features"
      onMouseEnter={() => setPaused(true)}
      onMouseLeave={() => setPaused(false)}
      className="relative mx-auto max-w-6xl px-4 py-16 sm:px-8 sm:py-24"
    >
      <div className="grid items-center gap-12 lg:grid-cols-12">
        <div className="lg:col-span-4">
          <div className="inline-flex items-center rounded-full bg-[#FFF0F5] px-4 py-1.5 text-xs font-bold text-[#FF5484]">
            Management with TaskHub
          </div>

          <h2 className="mt-5 text-3xl font-extrabold leading-[1.15] tracking-tight text-[#191A23] sm:text-4xl">
            Projects That
            <br />
            Work.
          </h2>

          <p className="mt-5 text-xs leading-relaxed text-[#6E7180] sm:text-sm">
            Whether you&apos;re managing your next big launch or organizing daily sprints,
            everyone knows who&apos;s doing what, when.
          </p>
        </div>

        <div className="lg:col-span-5">
          <AnimatePresence mode="wait">
            <motion.div
              key={current.id}
              initial={{ opacity: 0, y: 14, scale: 0.98 }}
              animate={{ opacity: 1, y: 0, scale: 1 }}
              exit={{ opacity: 0, y: -12, scale: 0.98 }}
              transition={{ duration: 0.4, ease: EASE }}
              className="relative rounded-[32px] p-7 sm:p-9 shadow-[0_24px_60px_-24px_rgba(25,26,35,0.08)]"
              style={{ backgroundColor: current.cardBg }}
            >
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2.5">
                  <span
                    className="grid size-7 place-items-center rounded-lg text-white"
                    style={{ backgroundColor: current.cardAccent }}
                  >
                    <Sparkles className="size-3.5 fill-current" />
                  </span>
                  <span
                    className="text-base font-extrabold tracking-tight"
                    style={{ color: current.cardAccent }}
                  >
                    {current.headerTitle}
                  </span>
                </div>

                <div className="flex -space-x-1.5">
                  <AvatarBubble emoji="🧑🏻" bg="#FFE4B5" size="sm" />
                  <AvatarBubble emoji="👩🏽" bg="#FFD1DC" size="sm" />
                  <AvatarBubble emoji="🧔🏼" bg="#E0E7FF" size="sm" />
                </div>
              </div>

              <div className="mt-7 space-y-3.5">
                {current.rows.map((row, rIdx) => {
                  const isHighlighted = highlightedRow === rIdx;
                  return (
                    <motion.div
                      key={row.title}
                      onClick={() => setSelectedTaskRow(rIdx)}
                      layout
                      transition={SPRING}
                      className={cn(
                        "flex cursor-pointer items-center gap-4 rounded-2xl p-3.5 transition-colors",
                        isHighlighted
                          ? "bg-white shadow-sm ring-2"
                          : "bg-white/55 hover:bg-white/80"
                      )}
                      style={{
                        borderColor: isHighlighted ? current.cardAccent : "transparent",
                        boxShadow: isHighlighted
                          ? `0 10px 25px -10px ${current.cardAccent}40`
                          : undefined,
                      }}
                    >
                      <div
                        className="flex size-7 shrink-0 items-center justify-center rounded-lg transition-colors"
                        style={{
                          backgroundColor: isHighlighted ? `${current.cardAccent}22` : "#FFFFFF",
                        }}
                      >
                        {isHighlighted && (
                          <Check
                            className="size-4 stroke-[3]"
                            style={{ color: current.cardAccent }}
                          />
                        )}
                      </div>

                      <div className="flex-1 space-y-2">
                        <div className="flex items-center justify-between">
                          <span className="text-xs font-bold text-[#191A23]">
                            {row.title}
                          </span>
                          <span
                            className="rounded-full px-2 py-0.5 text-[10px] font-bold"
                            style={{
                              backgroundColor: isHighlighted
                                ? `${current.cardAccent}18`
                                : "rgba(0,0,0,0.04)",
                              color: isHighlighted ? current.cardAccent : "#6E7180",
                            }}
                          >
                            {row.tag}
                          </span>
                        </div>
                        <div className="flex gap-2">
                          <div
                            className={cn("h-2 rounded-full", row.width)}
                            style={{
                              backgroundColor: isHighlighted
                                ? `${current.cardAccent}40`
                                : "rgba(25,26,35,0.08)",
                            }}
                          />
                          <div className="h-2 w-10 rounded-full bg-black/[0.05]" />
                        </div>
                      </div>
                    </motion.div>
                  );
                })}
              </div>
            </motion.div>
          </AnimatePresence>
        </div>

        <div className="space-y-6 lg:col-span-3 lg:pl-4">
          {FEATURE_TABS.map((tab, idx) => {
            const isActive = activeIdx === idx;
            return (
              <button
                key={tab.id}
                type="button"
                onClick={() => {
                  setActiveIdx(idx);
                  setSelectedTaskRow(null);
                }}
                className="group block w-full cursor-pointer text-left"
              >
                <div className="flex items-center gap-3.5">
                  <motion.span
                    animate={{ scale: isActive ? 1.18 : 1 }}
                    transition={SPRING}
                    className="size-4 shrink-0 rounded-full border-[2.5px] bg-white"
                    style={{ borderColor: tab.ringColor }}
                  />
                  <span
                    className={cn(
                      "text-base font-extrabold transition-colors",
                      isActive
                        ? "text-[#191A23]"
                        : "text-[#191A23]/70 group-hover:text-[#191A23]"
                    )}
                  >
                    {tab.title}
                  </span>
                </div>

                <div className="mt-1.5 flex items-center gap-2 pl-7 text-xs text-[#6E7180]">
                  <span
                    className="size-1.5 rounded-full"
                    style={{ backgroundColor: tab.dotColor }}
                  />
                  <span>{tab.sub}</span>
                </div>
              </button>
            );
          })}
        </div>
      </div>
    </section>
  );
}

/* -------------------------------------------------------------------------- */
/*               SECTION 5: WARM GRID CTA BANNER & MINIMAL FOOTER             */
/* -------------------------------------------------------------------------- */

function CtaAndFooterSection({ onNavigate }: { onNavigate: (id: string) => void }) {
  const [joined, setJoined] = useState(false);
  const [email, setEmail] = useState("");

  return (
    <footer id="cta" data-section="cta" className="mx-auto max-w-6xl px-4 pt-8 pb-20 sm:px-8">
      <div
        className="relative overflow-hidden rounded-[36px] bg-[#FAF8FF] px-6 py-14 text-center sm:px-14 sm:py-16"
        style={{
          backgroundImage:
            "linear-gradient(to right, rgba(104,66,255,0.04) 1px, transparent 1px), linear-gradient(to bottom, rgba(104,66,255,0.04) 1px, transparent 1px)",
          backgroundSize: "36px 36px",
        }}
      >
        <div className="inline-flex items-center gap-2 rounded-full bg-[#FFF0F5] px-4 py-1.5 text-xs font-bold text-[#FF5484]">
          <span className="rounded-full bg-[#FF5484] px-2 py-0.5 text-[10px] font-extrabold text-white">
            New
          </span>
          <span>The Essential Creative Powerhouse</span>
        </div>

        <h3 className="mx-auto mt-5 max-w-xl text-3xl font-extrabold tracking-tight text-[#191A23] sm:text-5xl">
          Your go-to motion powerhouse for{" "}
          <span className="inline-block -rotate-1 rounded-xl bg-[#FFB81C] px-3 py-0.5 text-white shadow-xs">
            remote teams
          </span>
        </h3>

        <p className="mx-auto mt-4 max-w-md text-xs leading-relaxed text-[#6E7180] sm:text-sm">
          Free forever for small crews. Set up your shared workspace in under a minute.
        </p>

        <form
          onSubmit={(e) => {
            e.preventDefault();
            setJoined(true);
          }}
          className="mx-auto mt-8 flex max-w-md flex-col gap-3 sm:flex-row"
        >
          <input
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="Enter your email"
            className="flex-1 rounded-full border border-[#6842FF]/15 bg-white px-6 py-3.5 text-xs font-medium text-[#191A23] shadow-2xs outline-none focus:border-[#6842FF]"
          />
          <button
            type="submit"
            className="cursor-pointer rounded-full bg-[#6842FF] px-8 py-3.5 text-xs font-extrabold text-white shadow-[0_12px_24px_-8px_rgba(104,66,255,0.45)] transition-all hover:scale-105 hover:bg-[#FF5484] active:scale-95"
          >
            {joined ? "Invite Sent ✓" : "Get Started"}
          </button>
        </form>
      </div>

      <div className="mt-12 flex flex-col items-center justify-between gap-4 text-xs text-[#6E7180] sm:flex-row">
        <button
          type="button"
          onClick={() => onNavigate("top")}
          className="flex cursor-pointer items-center gap-2 font-extrabold text-[#191A23]"
        >
          <span className="grid size-7 place-items-center rounded-lg bg-[#6842FF] text-white">
            <Sparkles className="size-3.5 fill-current" />
          </span>
          <span>TaskHub</span>
        </button>

        <p>© 2026 TaskHub Studio. Light, joyful teamwork &amp; motion for modern crews.</p>
      </div>
    </footer>
  );
}

/* -------------------------------------------------------------------------- */
/*                                MAIN COMPONENT                              */
/* -------------------------------------------------------------------------- */

export function TaskHub({ className }: { className?: string }) {
  const scroller = useRef<HTMLDivElement>(null);
  const reduce = useReducedMotion();

  const goTo = (id: string) => {
    const root = scroller.current;
    if (!root) return;
    if (id === "top") {
      root.scrollTo({ top: 0, behavior: reduce ? "auto" : "smooth" });
      return;
    }
    const section = root.querySelector<HTMLElement>(`[data-section="${id}"]`);
    if (!section) return;
    const top =
      root.scrollTop +
      section.getBoundingClientRect().top -
      root.getBoundingClientRect().top -
      32;
    root.scrollTo({ top, behavior: reduce ? "auto" : "smooth" });
  };

  return (
    <ScrollerContext value={scroller}>
      <div
        className={cn(
          "relative h-svh overflow-hidden bg-white text-[#191A23] antialiased selection:bg-[#6842FF] selection:text-white",
          className
        )}
        style={SANS}
      >
        <div
          ref={scroller}
          className="relative h-full overflow-y-auto overflow-x-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
        >
          <Header onNavigate={goTo} />
          <main>
            <HeroSection onNavigate={goTo} />
            <WhatMakesUsDifferentSection />
            <NextUIShowcaseSection />
            <FeaturesSection />
          </main>
          <CtaAndFooterSection onNavigate={goTo} />
        </div>
      </div>
    </ScrollerContext>
  );
}

export const CyberNeoGenesis = TaskHub;

export default function TaskHubPreview() {
  return <TaskHub />;
}
Sign in