// =============================================================
// Design Brains — Shared UI Components
// =============================================================

const { useState, useEffect, useRef, useCallback, useMemo, createContext, useContext } = React;

// -------- Routing context --------
const RouterCtx = createContext(null);
const useRouter = () => useContext(RouterCtx);

function RouterProvider({ children }) {
  const [route, setRoute] = useState(() => {
    const h = window.location.hash.slice(1) || "/";
    return h;
  });
  useEffect(() => {
    const onHash = () => {
      setRoute(window.location.hash.slice(1) || "/");
      window.scrollTo({ top: 0, behavior: "instant" });
    };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);
  const navigate = useCallback((to) => {
    window.location.hash = to;
  }, []);
  return <RouterCtx.Provider value={{ route, navigate }}>{children}</RouterCtx.Provider>;
}

function Link({ to, children, className = "", onClick, ...rest }) {
  const { navigate } = useRouter();
  return (
    <a
      href={"#" + to}
      className={className}
      onClick={(e) => {
        e.preventDefault();
        navigate(to);
        if (onClick) onClick(e);
      }}
      {...rest}
    >
      {children}
    </a>
  );
}

// -------- Button --------
function Button({ children, variant = "primary", to, onClick, className = "", ...rest }) {
  const { navigate } = useRouter();
  const handle = (e) => {
    if (to) { e.preventDefault(); navigate(to); }
    if (onClick) onClick(e);
  };
  const cls = `btn btn-${variant} ${className}`;
  if (to) return <a href={"#" + to} className={cls} onClick={handle} {...rest}>{children}</a>;
  return <button className={cls} onClick={handle} {...rest}>{children}</button>;
}

// -------- Logo (theme-adapting SVG mark + wordmark) --------
function Logo({ size = 36, wordmark = true }) {
  const isDark = (typeof document !== "undefined") && document.documentElement.getAttribute("data-theme") === "dark";
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
      <img
        src="assets/logo-small.png"
        alt="Design Brains"
        width={size}
        height={size}
        style={{ display: "block", height: size, width: "auto", filter: isDark ? "none" : "none" }}
      />
      {wordmark && (
        <span className="font-display" style={{ fontSize: size * 0.55, fontWeight: 700, letterSpacing: "-0.02em", textTransform: "uppercase", lineHeight: 1 }}>
          Design Brains
        </span>
      )}
    </div>
  );
}

// -------- Theme toggle --------
function useTheme() {
  const [theme, setTheme] = useState(() => document.documentElement.getAttribute("data-theme") || "light");
  const apply = useCallback((t) => {
    document.documentElement.setAttribute("data-theme", t);
    try { localStorage.setItem("db-theme", t); } catch (_) {}
    setTheme(t);
  }, []);
  return { theme, toggle: () => apply(theme === "light" ? "dark" : "light") };
}

function ThemeToggle() {
  const { theme, toggle } = useTheme();
  return (
    <button
      aria-label="Toggle theme"
      onClick={toggle}
      style={{
        width: 40, height: 40,
        background: "var(--surface)",
        border: "1px solid var(--border-strong)",
        borderRadius: "var(--radius-sm)",
        color: "var(--fg)",
        display: "grid", placeItems: "center",
        cursor: "pointer",
        transition: "all 0.2s var(--ease)",
      }}
    >
      {theme === "light" ? (
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
          <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      ) : (
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
          <circle cx="12" cy="12" r="4" stroke="currentColor" strokeWidth="1.6"/>
          <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
        </svg>
      )}
    </button>
  );
}

// -------- Reveal on scroll --------
function Reveal({ children, delay = 0, as: Tag = "div", className = "", ...rest }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let done = false;
    const reveal = () => {
      if (done) return;
      done = true;
      setTimeout(() => el && el.classList.add("in"), delay);
    };
    // Fallback timer in case IntersectionObserver doesn't fire (e.g. nested iframes)
    const fallback = setTimeout(reveal, 200 + delay);
    let io;
    try {
      io = new IntersectionObserver(
        (entries) => {
          entries.forEach((e) => {
            if (e.isIntersecting) {
              reveal();
              io.unobserve(el);
            }
          });
        },
        { threshold: 0.05 }
      );
      io.observe(el);
    } catch (_) {
      reveal();
    }
    return () => { clearTimeout(fallback); if (io) io.disconnect(); };
  }, [delay]);
  return (
    <Tag ref={ref} className={`reveal ${className}`} {...rest}>
      {children}
    </Tag>
  );
}

// -------- Nav --------
const NAV_LINKS = [
  { label: "Home", to: "/" },
  { label: "Services", to: "/services" },
  { label: "About", to: "/about" },
  { label: "Blog", to: "/blog" },
  { label: "FAQ", to: "/faq" },
  { label: "Contact", to: "/contact" },
];

function Nav() {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  const { route } = useRouter();

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 16);
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  useEffect(() => {
    document.body.classList.toggle("menu-open", open);
  }, [open]);

  // Close menu on route change
  useEffect(() => { setOpen(false); }, [route]);

  return (
    <header
      style={{
        position: "fixed",
        top: 0, left: 0, right: 0,
        zIndex: 100,
        padding: scrolled ? "12px 0" : "20px 0",
        transition: "padding 0.3s var(--ease), background 0.3s var(--ease), border-color 0.3s var(--ease)",
        background: scrolled && !open ? "var(--nav-bg)" : "transparent",
        backdropFilter: scrolled && !open ? "blur(16px) saturate(140%)" : "none",
        WebkitBackdropFilter: scrolled && !open ? "blur(16px) saturate(140%)" : "none",
        borderBottom: scrolled ? "1px solid var(--border)" : "1px solid transparent",
      }}
    >
      <div className="container" style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 24 }}>
        <Link to="/"><Logo /></Link>
        <button
          aria-label={open ? "Close menu" : "Open menu"}
          onClick={() => setOpen((s) => !s)}
          style={{
            background: "transparent",
            border: "none",
            color: "var(--fg)",
            display: "flex",
            alignItems: "center",
            gap: 12,
            padding: "8px 4px",
            cursor: "pointer",
            fontFamily: "inherit",
            fontSize: 14,
            fontWeight: 500,
            letterSpacing: "0.04em",
            textTransform: "uppercase",
          }}
        >
          <span style={{ width: 22, display: "inline-flex", flexDirection: "column", gap: 5 }}>
            <span style={{ display: "block", height: 2, background: "currentColor", transform: open ? "rotate(45deg) translate(4px, 4px)" : "none", transition: "transform 0.3s var(--ease)" }}></span>
            <span style={{ display: "block", height: 2, background: "currentColor", opacity: open ? 0 : 1, transition: "opacity 0.2s var(--ease)" }}></span>
            <span style={{ display: "block", height: 2, background: "currentColor", transform: open ? "rotate(-45deg) translate(5px, -5px)" : "none", transition: "transform 0.3s var(--ease)" }}></span>
          </span>
          <span>{open ? "Close" : "Menu"}</span>
        </button>
      </div>

      {/* Floating theme toggle — fixed bottom-center of the viewport */}
      <div style={{ position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)", zIndex: 97 }}>
        <ThemeToggle />
      </div>

      {/* Backdrop — click anywhere to close */}
      <div
        onClick={() => setOpen(false)}
        aria-hidden="true"
        style={{
          position: "fixed",
          top: 0, left: 0, right: 0, bottom: 0,
          height: "100vh",
          background: "rgba(0,0,0,0.45)",
          opacity: open ? 1 : 0,
          pointerEvents: open ? "auto" : "none",
          transition: "opacity 0.3s var(--ease)",
          zIndex: 98,
        }}
      />

      {/* Right-aligned drawer */}
      <div
        aria-hidden={!open}
        style={{
          position: "fixed",
          top: 0,
          right: 0,
          height: "100vh",
          width: "min(420px, 100vw)",
          background: "var(--bg)",
          borderLeft: "1px solid var(--border)",
          zIndex: 99,
          padding: "24px 32px 32px",
          display: "flex",
          flexDirection: "column",
          transform: open ? "translateX(0)" : "translateX(100%)",
          transition: "transform 0.45s var(--ease)",
          boxShadow: open ? "-40px 0 80px -20px rgba(0,0,0,0.18)" : "none",
          overflowY: "auto",
          overscrollBehavior: "contain",
        }}
      >
        {/* Drawer header — logo + close */}
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 32 }}>
          <Link to="/" onClick={() => setOpen(false)} style={{ display: "inline-flex" }}>
            <Logo />
          </Link>
          <button
            aria-label="Close menu"
            onClick={() => setOpen(false)}
            style={{
              width: 40, height: 40,
              background: "var(--surface)",
              border: "1px solid var(--border-strong)",
              borderRadius: "var(--radius-sm)",
              color: "var(--fg)",
              display: "grid", placeItems: "center",
              cursor: "pointer",
              transition: "all 0.2s var(--ease)",
            }}
            onMouseEnter={(e) => { e.currentTarget.style.background = "var(--surface-2)"; e.currentTarget.style.color = "var(--brand)"; }}
            onMouseLeave={(e) => { e.currentTarget.style.background = "var(--surface)"; e.currentTarget.style.color = "var(--fg)"; }}
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
              <path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
            </svg>
          </button>
        </div>

        <nav style={{ display: "flex", flexDirection: "column", gap: 0, alignItems: "flex-end", textAlign: "right", marginBottom: 24 }}>
          {NAV_LINKS.map((l, i) => {
            const active = l.to === "/" ? route === "/" : route.startsWith(l.to);
            return (
              <Link
                key={l.to}
                to={l.to}
                onClick={() => setOpen(false)}
                style={{
                  position: "relative",
                  fontFamily: "DM Sans, sans-serif",
                  fontSize: "clamp(32px, 4.4vw, 42px)",
                  fontWeight: 600,
                  letterSpacing: "-0.025em",
                  lineHeight: 1.05,
                  padding: "10px 14px 10px 0",
                  color: active ? "var(--brand)" : "var(--fg)",
                  transition: "color 0.2s var(--ease), transform 0.45s var(--ease), opacity 0.45s var(--ease)",
                  transitionDelay: open ? `${0.08 + i * 0.04}s` : "0s",
                  transform: open ? "translateX(0)" : "translateX(20px)",
                  opacity: open ? 1 : 0,
                  display: "inline-flex",
                  alignItems: "center",
                  alignSelf: "flex-end",
                }}
                onMouseEnter={(e) => { if (!active) e.currentTarget.style.color = "var(--brand)"; }}
                onMouseLeave={(e) => { if (!active) e.currentTarget.style.color = "var(--fg)"; }}
              >
                {l.label}
                <span aria-hidden style={{
                  display: "inline-block",
                  width: 7, height: 7,
                  borderRadius: "50%",
                  background: "var(--brand)",
                  marginLeft: 5,
                  marginBottom: -10,
                  transform: "translateY(12px)",
                  opacity: active ? 1 : 0,
                  transition: "opacity 0.25s var(--ease)",
                  boxShadow: active ? "0 0 16px var(--brand-glow)" : "none",
                }}/>
              </Link>
            );
          })}
        </nav>
        <div style={{ marginTop: "auto", paddingTop: 24, borderTop: "1px solid var(--border)", display: "flex", flexDirection: "column", gap: 10, alignItems: "flex-end" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%" }}>
            <ThemeToggle />
            <div className="font-mono" style={{ fontSize: 11, color: "var(--muted)", letterSpacing: "0.16em", textTransform: "uppercase" }}>Get in touch</div>
          </div>
          <a href="mailto:hello@designbrains.co" style={{ fontSize: 16, fontWeight: 500 }}>hello@designbrains.co</a>
          <a href="tel:+8801704649409" style={{ fontSize: 15, color: "var(--fg-2)" }}>+880 1704 649 409</a>
          <a
            href="#/quote"
            onClick={(e) => { e.preventDefault(); setOpen(false); window.location.hash = "/quote"; }}
            className="btn btn-primary"
            style={{ width: "100%", justifyContent: "center", marginTop: 12 }}
          >
            Get a Quote <span className="arrow">→</span>
          </a>
        </div>
      </div>
    </header>
  );
}

// -------- Footer --------
function Footer() {
  return (
    <footer style={{ borderTop: "1px solid var(--border)", paddingTop: 80, paddingBottom: 40, marginTop: 80, position: "relative" }}>
      <div className="container">
        {/* CTA Banner */}
        <div
          className="card"
          style={{
            padding: "clamp(40px, 6vw, 72px)",
            marginBottom: 80,
            borderRadius: "var(--radius-xl)",
            background: "linear-gradient(135deg, rgba(108,191,0,0.12), rgba(108,191,0,0.02) 60%), var(--card)",
            border: "1px solid rgba(108,191,0,0.2)",
            display: "grid",
            gridTemplateColumns: "1.4fr auto",
            alignItems: "center",
            gap: 32,
          }}
        >
          <div>
            <div className="eyebrow" style={{ marginBottom: 16 }}>Let's build</div>
            <h2 className="h-section" style={{ marginBottom: 16 }}>
              Have a project in mind?<br/>
              <span style={{ color: "var(--brand)" }}>Let's make it real.</span>
            </h2>
            <p className="lead">From a 2-week landing page to a multi-month AI rollout — tell us what you need and we'll send a clear plan within 24 hours.</p>
          </div>
          <div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
            <Button to="/quote">Start a project →</Button>
            <Button variant="ghost" to="/contact">Book a call</Button>
          </div>
        </div>

        <div
          style={{
            display: "grid",
            gridTemplateColumns: "1.4fr 1fr 1fr 1fr",
            gap: 48,
            marginBottom: 64,
          }}
          className="footer-grid"
        >
          <div>
            <Logo />
            <p style={{ marginTop: 20, color: "var(--muted)", maxWidth: 320, fontSize: 14 }}>
              A Bogra-based digital studio building thoughtful websites, apps, and AI automations for teams that care about the details.
            </p>
            <div style={{ display: "flex", gap: 10, marginTop: 24 }}>
              {["IG", "X", "IN", "GH"].map((s) => (
                <a key={s} href="#" style={{
                  width: 38, height: 38, display: "grid", placeItems: "center",
                  borderRadius: 10, border: "1px solid var(--border)", background: "var(--card)",
                  fontSize: 11, fontFamily: "JetBrains Mono, monospace", color: "var(--fg-2)",
                }}>{s}</a>
              ))}
            </div>
          </div>
          <FooterCol title="Services" links={[
            ["Website Development", "/services/web"],
            ["App Development", "/services/app"],
            ["AI Automation", "/services/ai"],
            ["All services", "/services"],
          ]} />
          <FooterCol title="Company" links={[
            ["About", "/about"],
            ["Blog", "/blog"],
            ["FAQ", "/faq"],
            ["Contact", "/contact"],
            ["Get a quote", "/quote"],
          ]} />
          <FooterCol title="Reach us" links={[
            ["hello@designbrains.co", "#"],
            ["+880 1704 649 409", "tel:+8801704649409"],
            ["WhatsApp", "#"],
            ["Bogra, Bangladesh", "#"],
          ]} />
        </div>
        <div className="divider"></div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", paddingTop: 24, gap: 16, flexWrap: "wrap" }}>
          <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: "var(--muted)" }}>
            © 2026 Design Brains. All systems operational.
          </div>
          <div style={{ display: "flex", gap: 24, fontSize: 13, color: "var(--muted)" }}>
            <a href="#">Privacy</a>
            <a href="#">Terms</a>
            <a href="#">Cookies</a>
          </div>
        </div>
      </div>
      <style>{`
        @media (max-width: 880px) {
          .footer-grid { grid-template-columns: 1fr 1fr !important; }
          .card[style*="grid-template-columns: 1.4fr auto"] { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </footer>
  );
}

function FooterCol({ title, links }) {
  return (
    <div>
      <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 12, letterSpacing: "0.16em", textTransform: "uppercase", color: "var(--muted)", marginBottom: 16 }}>
        {title}
      </div>
      <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 10 }}>
        {links.map(([label, to]) => (
          <li key={label}>
            {to.startsWith("/") ? (
              <Link to={to} style={{ color: "var(--fg-2)", fontSize: 14 }}>{label}</Link>
            ) : (
              <a href={to} style={{ color: "var(--fg-2)", fontSize: 14 }}>{label}</a>
            )}
          </li>
        ))}
      </ul>
    </div>
  );
}

// -------- Section header --------
function SectionHeader({ eyebrow, title, subtitle, align = "left" }) {
  return (
    <Reveal>
      <div className="section-header" style={{ alignItems: align === "center" ? "center" : "flex-start", textAlign: align, margin: align === "center" ? "0 auto 64px" : undefined }}>
        {eyebrow && <div className="eyebrow">{eyebrow}</div>}
        <h2 className="h-section">{title}</h2>
        {subtitle && <p className="lead">{subtitle}</p>}
      </div>
    </Reveal>
  );
}

// -------- Page hero (for sub-pages) --------
function PageHero({ eyebrow, title, subtitle, children }) {
  return (
    <section style={{ paddingTop: 180, paddingBottom: 60, position: "relative", overflow: "hidden" }}>
      <div aria-hidden style={{ position: "absolute", inset: 0, pointerEvents: "none", overflow: "hidden" }}>
        <svg width="600" height="600" viewBox="0 0 600 600" style={{ position: "absolute", right: "-160px", top: "-100px", opacity: 0.5 }} className="page-hero-disc">
          <defs>
            <linearGradient id={`page-hero-grad-${Math.random().toString(36).slice(2,7)}`} x1="0" y1="0" x2="1" y2="1">
              <stop offset="0" stopColor="var(--brand)" stopOpacity="0.18"/>
              <stop offset="1" stopColor="var(--brand)" stopOpacity="0"/>
            </linearGradient>
          </defs>
          <path d="M 300 50 A 250 250 0 0 1 300 550 L 300 50 Z" fill="var(--brand)" opacity="0.10"/>
        </svg>
        <div className="page-hero-dot" style={{ position: "absolute", right: "8%", top: "60%", width: 12, height: 12, borderRadius: "50%", background: "var(--brand)", boxShadow: "0 0 40px var(--brand-glow)" }}/>
      </div>
      <div className="container" style={{ position: "relative", zIndex: 2 }}>
        <Reveal>
          <div className="eyebrow" style={{ marginBottom: 20 }}>{eyebrow}</div>
        </Reveal>
        <Reveal delay={80}>
          <h1 className="h-display" style={{ fontSize: "clamp(40px, 6vw, 76px)", maxWidth: 1100, marginBottom: 24 }}>
            {title}
          </h1>
        </Reveal>
        {subtitle && (
          <Reveal delay={160}>
            <p className="lead" style={{ fontSize: 19, maxWidth: 680 }}>{subtitle}</p>
          </Reveal>
        )}
        {children && <Reveal delay={220}><div style={{ marginTop: 32 }}>{children}</div></Reveal>}
      </div>
      <style>{`
        @keyframes page-hero-drift { from { transform: translateX(40px); opacity: 0; } to { transform: translateX(0); opacity: 0.5; } }
        @keyframes page-hero-pulse { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.4); opacity: 0.6; } }
        .page-hero-disc { animation: page-hero-drift 1s var(--ease) both; }
        .page-hero-dot { animation: page-hero-pulse 3.6s ease-in-out infinite; }
        @media (prefers-reduced-motion: reduce) { .page-hero-disc, .page-hero-dot { animation: none !important; } }
      `}</style>
    </section>
  );
}

// -------- Service icon (geometric, original) --------
function ServiceIcon({ kind, size = 56 }) {
  const stroke = "var(--brand)";
  const sw = 1.6;
  if (kind === "web") {
    return (
      <svg width={size} height={size} viewBox="0 0 56 56" fill="none">
        <rect x="6" y="10" width="44" height="32" rx="3" stroke={stroke} strokeWidth={sw}/>
        <path d="M6 18H50" stroke={stroke} strokeWidth={sw}/>
        <circle cx="11" cy="14" r="1" fill={stroke}/>
        <circle cx="15" cy="14" r="1" fill={stroke}/>
        <circle cx="19" cy="14" r="1" fill={stroke}/>
        <path d="M14 26L20 32L14 38" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
        <path d="M24 38H34" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
      </svg>
    );
  }
  if (kind === "app") {
    return (
      <svg width={size} height={size} viewBox="0 0 56 56" fill="none">
        <rect x="16" y="6" width="24" height="44" rx="4" stroke={stroke} strokeWidth={sw}/>
        <circle cx="28" cy="44" r="1.6" fill={stroke}/>
        <path d="M22 12H34" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
        <rect x="20" y="18" width="16" height="6" rx="1.5" stroke={stroke} strokeWidth={sw}/>
        <rect x="20" y="27" width="7" height="7" rx="1.5" stroke={stroke} strokeWidth={sw}/>
        <rect x="29" y="27" width="7" height="7" rx="1.5" stroke={stroke} strokeWidth={sw}/>
      </svg>
    );
  }
  if (kind === "ai") {
    return (
      <svg width={size} height={size} viewBox="0 0 56 56" fill="none">
        <circle cx="28" cy="28" r="8" stroke={stroke} strokeWidth={sw}/>
        <circle cx="28" cy="28" r="3" fill={stroke}/>
        <path d="M28 8V18" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
        <path d="M28 38V48" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
        <path d="M8 28H18" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
        <path d="M38 28H48" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
        <path d="M14 14L21 21" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
        <path d="M35 35L42 42" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
        <path d="M42 14L35 21" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
        <path d="M21 35L14 42" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
      </svg>
    );
  }
  return null;
}

// -------- Service catalog (shared) --------
const SERVICES = {
  web: {
    slug: "web",
    icon: "web",
    name: "Website Development",
    tagline: "Sites that load fast, rank high, and convert.",
    description: "From marketing pages to full-stack web apps — built with modern stacks, polished motion, and SEO baked in from day one.",
    subServices: [
      { slug: "business", name: "Business Websites", desc: "Brand-led marketing sites with a CMS your team will actually use.",
        long: "A business website should sell while you sleep — and stay editable while you're awake. We design brand-led marketing sites that win the hero scroll, rank in search, and load instantly on a mid-range Android. CMS-powered so your team can ship a campaign without a Slack message to us.",
        deliverables: ["6–10 pages of polished, branded design", "Headless CMS with role-based editing", "SEO + structured data + sitemap", "Analytics + conversion tracking", "30-day post-launch support"],
        timeline: "3–6 weeks",
        priceFrom: "from $6k",
      },
      { slug: "ecom", name: "E-Commerce Websites", desc: "High-converting storefronts on Shopify, WooCommerce or headless.",
        long: "We build storefronts that move product. Whether it's Shopify for speed, headless for performance, or a custom commerce stack for a specific catalog problem — we tune the funnel from landing through checkout, and instrument every step so you know what's working.",
        deliverables: ["Custom theme with on-brand product templates", "Cart, checkout & payment integration", "Inventory & order management", "Conversion-rate tracking & A/B test setup", "Email + SMS lifecycle templates"],
        timeline: "5–10 weeks",
        priceFrom: "from $10k",
      },
      { slug: "landing", name: "Landing Pages", desc: "Single-purpose pages built for paid campaigns and product launches.",
        long: "When a single page has to carry the whole campaign, it needs to be obsessive about one outcome. We build focused landing pages with one job — that one conversion — and design every section, copy line, and motion cue to serve it.",
        deliverables: ["Custom 1-page design + responsive variants", "Hero copy + benefit framing collaboration", "Form / booking integration", "A/B test variants", "Analytics & heatmap tracking"],
        timeline: "1.5–3 weeks",
        priceFrom: "from $2.5k",
      },
      { slug: "portfolio", name: "Portfolio Websites", desc: "Editorial showcases for designers, photographers, and studios.",
        long: "Your portfolio is the work. The site is the frame. We design editorial showcases that get out of the way — letting the photography, design, or product itself be the loudest thing on the page. Slow loads aren't allowed.",
        deliverables: ["Editorial layout system, custom-tuned", "Case study templates", "Image optimization pipeline", "Subtle motion that respects reduced-motion", "CMS for adding work yourself"],
        timeline: "3–5 weeks",
        priceFrom: "from $5k",
      },
      { slug: "webapp", name: "Custom Web Applications", desc: "SaaS dashboards, internal tools, and bespoke product experiences.",
        long: "When off-the-shelf doesn't fit — a SaaS product, an internal tool, a bespoke workflow that lives in your business — we design and build the custom web app you need. Clean UX, tight performance, and a code handoff your engineers won't curse.",
        deliverables: ["Product UX & UI, end to end", "Auth, roles & permissions", "Database design & API layer", "Testing & observability", "Documented handoff to your team"],
        timeline: "8–16 weeks",
        priceFrom: "from $25k",
      },
    ],
    features: [
      "Pixel-perfect, motion-rich design",
      "SEO + Core Web Vitals as a baseline",
      "Accessible to WCAG AA",
      "CMS-powered editing for non-devs",
      "Analytics & conversion tracking wired in",
      "Hosting + ongoing care plans",
    ],
    tools: ["Next.js", "Astro", "React", "Tailwind", "Framer Motion", "Sanity", "Shopify", "Vercel"],
  },
  app: {
    slug: "app",
    icon: "app",
    name: "App Development",
    tagline: "Native-feel mobile apps, shipped on schedule.",
    description: "We design and build production mobile apps for iOS and Android — with a focus on performance, polish, and tight feedback loops with your users.",
    subServices: [
      { slug: "android", name: "Android App Development", desc: "Kotlin & Jetpack Compose apps tuned for the Android ecosystem.",
        long: "Android isn't a smaller iPhone. We build apps the right way for the platform — Material You where it makes sense, Compose where it pays off, and tested across the long tail of Android devices that actually matter for your audience.",
        deliverables: ["Native Kotlin + Jetpack Compose codebase", "Material 3 design system, themed", "Play Store launch & assets", "Crashlytics & performance monitoring", "Modular architecture for fast iteration"],
        timeline: "10–16 weeks",
        priceFrom: "from $20k",
      },
      { slug: "ios", name: "iOS App Development", desc: "Swift apps that feel right at home on iPhone and iPad.",
        long: "iOS users notice the details. We build Swift apps with native feel — proper haptics, system gestures, accessibility, and a launch animation that does the right thing. Submitted to the App Store with screenshots and copy that don't get sent back.",
        deliverables: ["Swift + SwiftUI codebase", "iOS-native design language", "App Store launch & ASO", "TestFlight beta program", "Push notifications & deep links"],
        timeline: "10–16 weeks",
        priceFrom: "from $20k",
      },
      { slug: "cross", name: "Cross-Platform Apps", desc: "One codebase across iOS, Android & web with React Native or Flutter.",
        long: "When time-to-market matters and you don't have a 10-person mobile team, cross-platform earns its keep. We pick React Native or Flutter based on your needs and ship one codebase that feels native on both platforms — and updates twice as fast.",
        deliverables: ["React Native or Flutter codebase", "Shared design system, platform-tuned", "Both stores submitted", "OTA updates configured", "Web target if applicable"],
        timeline: "8–14 weeks",
        priceFrom: "from $18k",
      },
      { slug: "biz", name: "Business Management Apps", desc: "Field-ops, inventory, and back-office tools, built for your workflow.",
        long: "The most valuable apps don't end up in the App Store. Internal tools for field teams, inventory, dispatch, ops dashboards — things that take a 15-minute task to 30 seconds. We build them, fast, and they live where your team works.",
        deliverables: ["Custom workflow design", "Offline-first architecture", "Role-based access", "Reports & exports", "Internal distribution (MDM-ready)"],
        timeline: "8–12 weeks",
        priceFrom: "from $15k",
      },
      { slug: "custom", name: "Custom Mobile Solutions", desc: "When the off-the-shelf doesn't fit — we design from first principles.",
        long: "Sometimes your problem doesn't look like an app. Sometimes it's a hardware integration, a complex permissions story, or a category that doesn't exist yet. We've shipped weird things successfully — happy to talk about yours.",
        deliverables: ["Discovery & technical spike", "Custom architecture proposal", "Phased delivery plan", "Production app, end to end", "Long-term roadmap"],
        timeline: "12+ weeks",
        priceFrom: "scoped per project",
      },
    ],
    features: [
      "Native performance, native feel",
      "Offline-first architecture",
      "App Store / Play Store launch support",
      "Analytics, crashes, and feature flags",
      "Push notifications + deep links",
      "Post-launch iteration sprints",
    ],
    tools: ["Swift", "Kotlin", "React Native", "Flutter", "Expo", "Firebase", "Supabase", "Sentry"],
  },
  ai: {
    slug: "ai",
    icon: "ai",
    name: "AI Automation",
    tagline: "Cut the busywork. Compound the team.",
    description: "We embed AI into the workflows your team runs every day — chat support, lead routing, internal ops, document handling — and measure the hours saved.",
    subServices: [
      { slug: "chatbots", name: "AI Chatbots", desc: "On-brand assistants for sales, support and onboarding flows.",
        long: "An AI chatbot worth deploying knows your product, escalates gracefully, and doesn't hallucinate prices. We build assistants grounded in your real docs, with proper guardrails, and a hand-off to a human when it matters.",
        deliverables: ["Knowledge base ingestion + retrieval", "Tone-of-voice tuned prompting", "Human handoff workflow", "Conversation logging & quality review", "Eval suite to catch regressions"],
        timeline: "3–6 weeks",
        priceFrom: "from $8k",
      },
      { slug: "workflow", name: "Workflow Automation", desc: "Stitch your tools together with reliable, observable pipelines.",
        long: "Most teams have 30+ tools and three Notion docs explaining how to glue them together. We replace those docs with reliable, observable automations — n8n, Make, or custom code where it earns its keep.",
        deliverables: ["Workflow audit & ROI map", "Production automations with monitoring", "Error handling + retry logic", "Dashboards for time saved", "Documentation + handoff"],
        timeline: "2–6 weeks",
        priceFrom: "from $5k",
      },
      { slug: "crm", name: "CRM Automation", desc: "Lead scoring, enrichment, and routing inside your CRM of choice.",
        long: "Your CRM is only as smart as the data going in and the rules running on top. We build lead enrichment, scoring, and routing automations directly into HubSpot, Pipedrive, or Salesforce — so your sales team works the right leads first.",
        deliverables: ["Data enrichment integrations", "Custom scoring model", "Routing & SLA automations", "Reporting dashboards", "Sales team enablement"],
        timeline: "3–5 weeks",
        priceFrom: "from $7k",
      },
      { slug: "support", name: "Customer Support Automation", desc: "Triage, draft replies, and escalate — with a human in the loop.",
        long: "Tier-1 support is mostly the same questions in different sentences. We build AI triage that classifies, drafts, and routes — with humans in the loop on anything customer-facing. Your queue goes from anxious to boring.",
        deliverables: ["Ticket classification model", "AI-drafted reply system", "Escalation rules", "Quality review dashboard", "Cost & accuracy tracking"],
        timeline: "4–8 weeks",
        priceFrom: "from $10k",
      },
      { slug: "integration", name: "AI Integration Solutions", desc: "Bring LLMs into your existing product, safely and reversibly.",
        long: "Adding AI features to a product you already shipped is a different problem from greenfield. We help you scope the right places to add intelligence, prototype them, evaluate, and roll out behind feature flags — reversibly.",
        deliverables: ["AI opportunity audit", "Prototype + evaluation suite", "Production integration with feature flags", "Cost & latency guardrails", "Rollback playbook"],
        timeline: "scoped per project",
        priceFrom: "from $12k",
      },
    ],
    features: [
      "Model-agnostic — pick what fits",
      "Human-in-the-loop by default",
      "Observability + cost guardrails",
      "Eval suites before you ship",
      "Private deployment options",
      "Quarterly model & cost reviews",
    ],
    tools: ["OpenAI", "Anthropic", "LangChain", "n8n", "Zapier", "Pinecone", "Supabase", "Make"],
  },
};

// -------- Toast --------
function Toast({ message, onClose }) {
  useEffect(() => {
    if (!message) return;
    const t = setTimeout(onClose, 3500);
    return () => clearTimeout(t);
  }, [message, onClose]);
  if (!message) return null;
  return (
    <div style={{
      position: "fixed",
      bottom: 28,
      left: "50%",
      transform: "translateX(-50%)",
      zIndex: 200,
      background: "var(--brand)",
      color: "#0A0C09",
      padding: "14px 22px",
      borderRadius: 999,
      fontWeight: 600,
      boxShadow: "0 20px 50px -10px rgba(108,191,0,0.6)",
      animation: "pageEnter 0.3s var(--ease)",
    }}>
      {message}
    </div>
  );
}

Object.assign(window, {
  RouterProvider, RouterCtx, useRouter, Link, Button, Logo,
  Reveal, Nav, Footer, SectionHeader, PageHero, ServiceIcon,
  SERVICES, Toast, ThemeToggle, useTheme,
});
