/* dev.NoNames — nav, hero variants, marquee */

function Icon({ name, size = 22 }) {
  const s = { width: size, height: size, fill: "none", stroke: "currentColor", strokeWidth: 1.7, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (name) {
    case "web": return (<svg viewBox="0 0 24 24" {...s}><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M3 9h18"/><path d="M7 6.5h.01M10 6.5h.01"/></svg>);
    case "cart": return (<svg viewBox="0 0 24 24" {...s}><path d="M3 4h2l2.4 12.5a1 1 0 0 0 1 .8h8.7a1 1 0 0 0 1-.8L21 8H6"/><circle cx="9" cy="20" r="1.3"/><circle cx="18" cy="20" r="1.3"/></svg>);
    case "code": return (<svg viewBox="0 0 24 24" {...s}><path d="M8 7l-5 5 5 5M16 7l5 5-5 5M13 5l-2 14"/></svg>);
    case "arrow": return (<svg viewBox="0 0 24 24" {...s}><path d="M5 12h14M13 6l6 6-6 6"/></svg>);
    case "external": return (<svg viewBox="0 0 24 24" {...s}><path d="M7 17L17 7M9 7h8v8"/></svg>);
    case "mail": return (<svg viewBox="0 0 24 24" {...s}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M4 7l8 6 8-6"/></svg>);
    case "chat": return (<svg viewBox="0 0 24 24" {...s}><path d="M21 12a8 8 0 0 1-11.5 7.2L4 20l1-4.5A8 8 0 1 1 21 12z"/></svg>);
    case "check": return (<svg viewBox="0 0 24 24" {...s} strokeWidth="2"><path d="M5 12.5l4.5 4.5L19 7"/></svg>);
    case "spark": return (<svg viewBox="0 0 24 24" {...s}><path d="M12 3v4M12 17v4M3 12h4M17 12h4M6 6l2.5 2.5M15.5 15.5L18 18M18 6l-2.5 2.5M8.5 15.5L6 18"/></svg>);
    default: return null;
  }
}

function Nav({ scrolled }) {
  const links = [["Services", "#services"], ["Work", "#work"], ["Process", "#process"], ["Pricing", "#pricing"], ["FAQ", "#faq"]];
  return (
    <nav className="nav" data-scrolled={scrolled ? "1" : "0"}>
      <div className="container nav-inner">
        <a href="#top" className="brand">
          <span className="dot"></span>
          <span>dev<span className="lo">.</span><b>NoNames</b></span>
        </a>
        <div className="nav-links">
          {links.map(([l, h]) => <a key={h} href={h}>{l}</a>)}
        </div>
        <div className="nav-cta">
          <a href="https://nonames.lk" className="btn btn-ghost btn-sm nav-cross">Creative Agency <span className="arr"><Icon name="external" size={15}/></span></a>
          <a href="#contact" className="btn btn-primary btn-sm">Start a project <span className="arr"><Icon name="arrow" size={16}/></span></a>
        </div>
      </div>
    </nav>
  );
}

/* ---------- shared hero copy block ---------- */
function HeroCopy({ centered }) {
  return (
    <React.Fragment>
      <h1 className="display hero-h1">
        <span className="w" style={{ "--i": 0 }}>We</span>{" "}
        <span className="w" style={{ "--i": 1 }}>build</span>{" "}
        <span className="w" style={{ "--i": 2 }}>the</span>{" "}
        <span className="w" style={{ "--i": 3 }}>web</span><br/>
        <span className="w" style={{ "--i": 4 }}>you'll</span>{" "}
        <span className="w" style={{ "--i": 5 }}>take</span>{" "}
        <span className="w" style={{ "--i": 6 }}>credit</span>{" "}
        <span className="w" style={{ "--i": 7 }}>for.</span>
      </h1>
      <p className="hero-sub reveal" style={{ "--d": "140ms" }}>
        dev.NoNames is a studio for businesses that need to ship: websites, online stores and custom software, engineered fast and built to last. Your brand out front. Us in the engine room.
      </p>
      <div className="hero-cta reveal" style={{ "--d": "220ms" }}>
        <a href="#work" className="btn btn-primary">See our work <span className="arr"><Icon name="arrow" size={17}/></span></a>
        <a href="#contact" className="btn btn-ghost">Start a project</a>
      </div>
    </React.Fragment>
  );
}

/* ---------- IDE mock (split hero): browser window + floating editor overlay ---------- */
/* Real product photos that render in the browser preview as the <Product> lines type out */
const IDE_PRODUCTS = [
  { name: "Brand Tee", price: "$28", img: "https://images.unsplash.com/photo-1521572163474-6864f9cf17ab?w=360&q=80&auto=format&fit=crop" },
  { name: "Logo Cap",  price: "$18", img: "https://images.unsplash.com/photo-1588850561407-ed78c282e89b?w=360&q=80&auto=format&fit=crop" },
];

const IDE_LINES = [
  { t: [{ c: "cmt", v: "// shop.tsx" }] },
  { t: [{ c: "kw", v: "import" }, { c: "pn", v: " { " }, { c: "fn", v: "Logo" }, { c: "pn", v: ", " }, { c: "fn", v: "Nav" }, { c: "pn", v: ", " }, { c: "fn", v: "Cart" }, { c: "pn", v: ", " }, { c: "fn", v: "Hero" }, { c: "pn", v: ", " }, { c: "fn", v: "Product" }, { c: "pn", v: " } " }, { c: "kw", v: "from" }, { c: "str", v: " './ui'" }] },
  { t: [] },
  { t: [{ c: "kw", v: "export" }, { c: "kw", v: " function" }, { c: "fn", v: " Shop" }, { c: "pn", v: "() {" }] },
  { t: [{ c: "pn", v: "  " }, { c: "kw", v: "const" }, { c: "pn", v: " items " }, { c: "pn", v: "= [" }] },
  { t: [{ c: "pn", v: "    { " }, { c: "pn", v: "name: " }, { c: "str", v: "\"Brand Tee\"" }, { c: "pn", v: ", price: " }, { c: "num", v: "28" }, { c: "pn", v: " }," }] },
  { t: [{ c: "pn", v: "    { " }, { c: "pn", v: "name: " }, { c: "str", v: "\"Logo Cap\"" }, { c: "pn", v: ", price: " }, { c: "num", v: "18" }, { c: "pn", v: " }," }] },
  { t: [{ c: "pn", v: "  ]" }] },
  { t: [] },
  { t: [{ c: "pn", v: "  " }, { c: "kw", v: "return" }, { c: "pn", v: " (" }] },
  { t: [{ c: "pn", v: "    <" }, { c: "tag", v: "main" }, { c: "pn", v: ">" }] },
  { t: [{ c: "pn", v: "      <" }, { c: "tag", v: "header" }, { c: "pn", v: ">" }] },
  { t: [{ c: "pn", v: "        <" }, { c: "tag", v: "Logo" }, { c: "pn", v: ">" }, { c: "str", v: "yourbrand" }, { c: "pn", v: "</" }, { c: "tag", v: "Logo" }, { c: "pn", v: ">" }], logo: true },
  { t: [{ c: "pn", v: "        <" }, { c: "tag", v: "Nav" }, { c: "pn", v: " links=" }, { c: "pn", v: "{[" }, { c: "str", v: "\"Shop\"" }, { c: "pn", v: ", " }, { c: "str", v: "\"About\"" }, { c: "pn", v: ", " }, { c: "str", v: "\"Contact\"" }, { c: "pn", v: "]} />" }], nav: true },
  { t: [{ c: "pn", v: "        <" }, { c: "tag", v: "Cart" }, { c: "pn", v: " count=" }, { c: "pn", v: "{items.length} />" }], cart: true },
  { t: [{ c: "pn", v: "      </" }, { c: "tag", v: "header" }, { c: "pn", v: ">" }] },
  { t: [] },
  { t: [{ c: "pn", v: "      <" }, { c: "tag", v: "Hero" }] },
  { t: [{ c: "pn", v: "        title=" }, { c: "str", v: "\"Summer Drop\"" }], hero: true },
  { t: [{ c: "pn", v: "        sub=" }, { c: "str", v: "\"New season essentials\"" }] },
  { t: [{ c: "pn", v: "        cta=" }, { c: "str", v: "\"Shop now\"" }] },
  { t: [{ c: "pn", v: "      />" }] },
  { t: [] },
  { t: [{ c: "pn", v: "      <" }, { c: "tag", v: "Grid" }, { c: "pn", v: ">" }] },
  { t: [{ c: "pn", v: "        {items.map(p => (" }] },
  { t: [{ c: "pn", v: "          <" }, { c: "tag", v: "Product" }] },
  { t: [{ c: "pn", v: "            key=" }, { c: "pn", v: "{p.name}" }] },
  { t: [{ c: "pn", v: "            image=" }, { c: "str", v: "{`/${p.name}.jpg`}" }], product: true },
  { t: [{ c: "pn", v: "            name=" }, { c: "pn", v: "{p.name}" }] },
  { t: [{ c: "pn", v: "            price=" }, { c: "pn", v: "{`$${p.price}`}" }] },
  { t: [{ c: "pn", v: "          />" }] },
  { t: [{ c: "pn", v: "        ))}" }] },
  { t: [{ c: "pn", v: "      </" }, { c: "tag", v: "Grid" }, { c: "pn", v: ">" }] },
  { t: [{ c: "pn", v: "    </" }, { c: "tag", v: "main" }, { c: "pn", v: ">" }] },
  { t: [{ c: "pn", v: "  )" }] },
  { t: [{ c: "pn", v: "}" }] },
];

/* Lines 0..BOILERPLATE-1 are pre-written when the hero loads (imports, data, scaffold);
   typing — and the live preview build — begins at the first element-producing line. */
const BOILERPLATE = IDE_LINES.findIndex((l) => l.logo || l.nav || l.cart || l.hero || l.product);

/* "Make it yours" gimmick — free-text industry is matched by keyword. A match
   re-skins the preview copy AND product cards (name / price / image). Anything
   unmatched falls back to a templated line + keyword-driven images. */
const UIMG = (id) => `https://images.unsplash.com/photo-${id}?w=360&q=80&auto=format&fit=crop`;
const DEFAULT_PRESET = {
  title: "Summer Drop", sub: "New season essentials, up to 30% off", cta: "Shop now",
  products: IDE_PRODUCTS,
};
const INDUSTRY_PRESETS = [
  { k: ["fashion", "clothing", "apparel", "boutique", "wear", "streetwear"], title: "Summer Drop", sub: "New season essentials, up to 30% off", cta: "Shop now",
    products: [{ name: "Brand Tee", price: "$28", img: UIMG("1521572163474-6864f9cf17ab") }, { name: "Logo Cap", price: "$18", img: UIMG("1588850561407-ed78c282e89b") }] },
  { k: ["coffee", "cafe", "café", "restaurant", "food", "bakery", "kitchen", "dining", "bar"], title: "Freshly made", sub: "Seasonal menu, served daily", cta: "Order now",
    products: [{ name: "House Blend", price: "$14", img: UIMG("1509042239860-f550ce710b93") }, { name: "Fresh Bakes", price: "$6", img: UIMG("1551024601-bec78aea704b") }] },
  { k: ["fitness", "gym", "yoga", "wellness", "sport", "trainer"], title: "Train harder", sub: "New programs for every goal", cta: "Join now",
    products: [{ name: "Pro Weights", price: "$49", img: UIMG("1571019613454-1cb2f99b2d8b") }, { name: "Trainers", price: "$89", img: UIMG("1542291026-7eec264c27ff") }] },
  { k: ["beauty", "cosmetic", "salon", "spa", "skin", "hair"], title: "Glow up", sub: "New arrivals your skin will love", cta: "Shop now",
    products: [{ name: "Lip Set", price: "$24", img: UIMG("1596462502278-27bfdc403348") }, { name: "Skin Serum", price: "$32", img: UIMG("1556228720-195a672e8a03") }] },
  { k: ["tech", "software", "saas", "app", "digital", "startup"], title: "Ship faster", sub: "Tools built for modern teams", cta: "Get started",
    products: [{ name: "Pro License", price: "$29", img: UIMG("1517336714731-489689fd1ca8") }, { name: "Team Plan", price: "$99", img: UIMG("1512941937669-90a1b58e7e9c") }] },
  { k: ["jewel", "jewellery", "jewelry", "accessor", "watch"], title: "New collection", sub: "Handcrafted pieces, made to last", cta: "Discover",
    products: [{ name: "Gold Ring", price: "$240", img: UIMG("1515562141207-7a88fb7ce338") }, { name: "Pendant", price: "$180", img: UIMG("1599643478518-a784e5dc4c8f") }] },
  { k: ["real estate", "property", "realty", "homes", "architect", "interior"], title: "Find your space", sub: "Featured listings, updated weekly", cta: "Browse",
    products: [{ name: "City Loft", price: "$420k", img: UIMG("1568605114967-8130f3a36994") }, { name: "Garden Villa", price: "$680k", img: UIMG("1505691938895-1758d7feb511") }] },
  { k: ["agency", "marketing", "creative", "media", "studio", "brand"], title: "Work that performs", sub: "Campaigns built to convert", cta: "See work",
    products: [{ name: "Brand Sprint", price: "$2k", img: UIMG("1517245386807-bb43f82c33c4") }, { name: "Web Build", price: "$5k", img: UIMG("1561070791-2526d30994b5") }] },
  { k: ["consult", "finance", "account", "legal", "advisory", "insurance"], title: "Grow with confidence", sub: "Expert guidance for your goals", cta: "Get started",
    products: [{ name: "Growth Plan", price: "$199", img: UIMG("1554224155-6726b3ff858f") }, { name: "Advisory", price: "$499", img: UIMG("1460925895917-afdab827c52f") }] },
  { k: ["education", "course", "school", "academy", "learn", "training", "tutor"], title: "Learn anything", sub: "New courses added every week", cta: "Start learning",
    products: [{ name: "Starter Course", price: "$49", img: UIMG("1503676260728-1c00da094a0b") }, { name: "Full Path", price: "$199", img: UIMG("1497633762265-9d179a990aa6") }] },
  { k: ["travel", "tour", "hotel", "hospitality", "resort", "stay"], title: "Your next escape", sub: "Curated stays and experiences", cta: "Explore",
    products: [{ name: "Beach Escape", price: "$899", img: UIMG("1507525428034-b723cf961d3e") }, { name: "Mountain Trek", price: "$1.2k", img: UIMG("1469854523086-cc02fe5d8800") }] },
  { k: ["glass", "mirror", "aluminium", "aluminum", "glazing"], title: "Cut to perfection", sub: "Custom glass & mirrors, made to measure", cta: "Get a quote",
    products: [{ name: "Custom Glass", price: "Quote", img: UIMG("1431576901776-e539bd916ba2") }, { name: "Mirror Sets", price: "Quote", img: UIMG("1487958449943-2429e8be8625") }] },
  { k: ["construction", "building", "builder", "cement", "concrete", "tiles", "steel", "metal", "hardware", "timber", "plywood", "roofing", "materials"], title: "Built to last", sub: "Quality materials, on site on time", cta: "Get a quote",
    products: [{ name: "Materials", price: "Quote", img: UIMG("1504307651254-35680f356dfd") }, { name: "Project Supply", price: "Quote", img: UIMG("1541888946425-d81bb19240f5") }] },
  { k: ["manufactur", "factory", "industrial", "machinery", "fabrication", "production", "distribution", "wholesale", "supplier", "logistics", "packaging", "mill"], title: "Made at scale", sub: "Custom production, shipped nationwide", cta: "Enquire",
    products: [{ name: "Custom Runs", price: "Quote", img: UIMG("1581091226825-a6a2a5aee158") }, { name: "Bulk Orders", price: "Quote", img: UIMG("1565793298595-6a879b1d9492") }] },
  { k: ["furniture", "furnish", "woodwork", "carpentry", "decor", "upholstery"], title: "New collection", sub: "Handcrafted pieces for every space", cta: "Shop now",
    products: [{ name: "Velvet Sofa", price: "$640", img: UIMG("1555041469-a586c61ea9bc") }, { name: "Lounge Set", price: "$980", img: UIMG("1538688525198-9b88f6f53126") }] },
  { k: ["automotive", "automobile", "vehicle", "motor", "garage", "tyre", "tire", "spare parts", "mechanic"], title: "Drive better", sub: "Sales, service and genuine parts", cta: "Book now",
    products: [{ name: "Showroom", price: "View", img: UIMG("1503376780353-7e6692767b70") }, { name: "Full Service", price: "$89", img: UIMG("1486262715619-67b85e0b08d3") }] },
  { k: ["health", "medical", "pharma", "clinic", "dental", "hospital", "care"], title: "Care you can trust", sub: "Book appointments online, anytime", cta: "Book now",
    products: [{ name: "Consultation", price: "$25", img: UIMG("1576091160550-2173dba999ef") }, { name: "Pharmacy", price: "Open", img: UIMG("1587854692152-cbe660dbde88") }] },
  { k: ["electronic", "appliance", "electrical", "gadget", "computer", "mobile", "phone", "device"], title: "Latest tech", sub: "Top brands, unbeatable prices", cta: "Shop now",
    products: [{ name: "Gadgets", price: "New", img: UIMG("1593344484962-796055d4a3a4") }, { name: "Components", price: "In stock", img: UIMG("1518770660439-4636190af475") }] },
  { k: ["retail", "grocery", "supermarket", "store", "shop", "minimart", "convenience"], title: "Fresh today", sub: "Everyday essentials, great prices", cta: "Shop now",
    products: [{ name: "Daily Picks", price: "New", img: UIMG("1542838132-92c53300491e") }, { name: "Best Sellers", price: "Save", img: UIMG("1578916171728-46686eac8d58") }] },
];
function pickPreset(industry) {
  const q = (industry || "").trim().toLowerCase();
  if (!q) return DEFAULT_PRESET;
  for (const p of INDUSTRY_PRESETS) if (p.k.some((k) => q.includes(k))) return p;
  const nice = industry.trim().replace(/\b\w/g, (c) => c.toUpperCase());
  // No reliable photo for the long tail — use clean on-brand monogram tiles
  // (img: null) instead of a random, possibly-irrelevant stock photo.
  return {
    title: "Just launched", sub: `The best of ${nice}, all in one place.`, cta: "Explore",
    products: [
      { name: "Featured", price: "New", img: null },
      { name: "Popular", price: "New", img: null },
    ],
  };
}
function brandSlug(brand) {
  const s = (brand || "").trim().toLowerCase().replace(/&/g, "and").replace(/[^a-z0-9]+/g, "");
  return s || "yourbrand";
}

function IdeMock({ motion }) {
  const all = motion === "subtle";
  const [shown, setShown] = React.useState(all ? IDE_LINES.length : BOILERPLATE);
  const [logoOn, setLogoOn] = React.useState(all);
  const [navOn, setNavOn] = React.useState(all);
  const [cartOn, setCartOn] = React.useState(all);
  const [heroOn, setHeroOn] = React.useState(all);
  const [productOn, setProductOn] = React.useState(all);
  const [lastEvent, setLastEvent] = React.useState(all ? "product" : null);
  // "Make it yours": typing → prompt → building → done
  const [phase, setPhase] = React.useState(all ? "prompt" : "typing");
  const [brand, setBrand] = React.useState("yourbrand");
  const [copy, setCopy] = React.useState(DEFAULT_PRESET);
  const [products, setProducts] = React.useState(DEFAULT_PRESET.products);
  const [biz, setBiz] = React.useState("");
  const [ind, setInd] = React.useState("");
  const codeRef = React.useRef(null);
  const buildTimers = React.useRef([]);
  React.useEffect(() => () => buildTimers.current.forEach(clearTimeout), []);

  React.useEffect(() => {
    if (motion === "subtle") {
      setShown(IDE_LINES.length);
      setLogoOn(true); setNavOn(true); setCartOn(true); setHeroOn(true); setProductOn(true);
      setLastEvent("product"); setPhase("prompt"); return;
    }
    // Boilerplate is already on screen; start typing the elements after a short beat.
    setShown(BOILERPLATE);
    setLogoOn(false); setNavOn(false); setCartOn(false); setHeroOn(false); setProductOn(false);
    setLastEvent(null); setPhase("typing");
    const speed = motion === "maximal" ? 130 : 175;
    let i = BOILERPLATE;
    let id = null;
    let promptId = null;
    const start = setTimeout(() => {
      id = setInterval(() => {
        const line = IDE_LINES[i];
        if (line && line.logo)    setTimeout(() => { setLogoOn(true);    setLastEvent("logo"); }, 200);
        if (line && line.nav)     setTimeout(() => { setNavOn(true);     setLastEvent("nav"); }, 200);
        if (line && line.cart)    setTimeout(() => { setCartOn(true);    setLastEvent("cart"); }, 200);
        if (line && line.hero)    setTimeout(() => { setHeroOn(true);    setLastEvent("hero"); }, 220);
        if (line && line.product) setTimeout(() => { setProductOn(true); setLastEvent("product"); }, 240);
        i += 1;
        setShown(i);
        if (i >= IDE_LINES.length) { clearInterval(id); promptId = setTimeout(() => setPhase("prompt"), 750); }
      }, speed);
    }, 550);
    return () => { clearTimeout(start); if (id) clearInterval(id); if (promptId) clearTimeout(promptId); };
  }, [motion]);

  const reduce = all || (typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
  function shipIt(e) {
    if (e) e.preventDefault();
    const b = biz.trim();
    if (!b) return;
    const preset = pickPreset(ind);
    if (reduce) { setBrand(b); setCopy(preset); setProducts(preset.products); setPhase("done"); return; }
    setPhase("building");
    buildTimers.current.push(setTimeout(() => { setBrand(b); setCopy(preset); setProducts(preset.products); }, 700));
    buildTimers.current.push(setTimeout(() => setPhase("done"), 1150));
  }
  function tryAnother() { setPhase("prompt"); }

  // Auto-scroll the editor as new lines type out
  React.useEffect(() => {
    if (codeRef.current) codeRef.current.scrollTop = codeRef.current.scrollHeight;
  }, [shown]);

  return (
    <div className="ide-stage reveal" style={{ "--d": "160ms" }}>
      {/* Browser window — the larger surface */}
      <div className="ide-browser">
        <div className="ide-bar">
          <div className="dots"><i></i><i></i><i></i></div>
          <div className="url">https://{brandSlug(brand)}.com</div>
        </div>
        <div className="ide-pv">
          <div className="ide-pv-nav">
            <div className={"ide-pv-logo" + (logoOn ? " on" : "")} key={brand}>{brand}</div>
            <div className="ide-pv-links">
              {["Shop", "About", "Contact"].map((l) => (
                <span className={navOn ? "on" : ""} key={l}>{l}</span>
              ))}
            </div>
            <div className={"ide-pv-cart" + (cartOn ? " on" : "")} aria-hidden="true">
              <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M3 4h2l2.4 12.5a1 1 0 0 0 1 .8h8.7a1 1 0 0 0 1-.8L21 8H6"/>
                <circle cx="9" cy="20" r="1.3"/>
                <circle cx="18" cy="20" r="1.3"/>
              </svg>
              <span className="ide-pv-badge">2</span>
            </div>
          </div>
          <div className="ide-pv-body">
            <div className={"ide-pv-banner" + (heroOn ? " on" : "")} key={copy.title + copy.sub}>
              <div className="ide-pv-banner-title">{copy.title}</div>
              <div className="ide-pv-banner-sub">{copy.sub}</div>
              <div className="ide-pv-banner-btn">{copy.cta}</div>
            </div>
            <div className="ide-pv-products">
              {products.map((p, i) => (
                <div className={"ide-pv-product" + (productOn ? (i === 0 ? " on" : " on d2") : "")} key={p.name + i}>
                  <div className="ide-pv-product-img">
                    {p.img ? (
                      <img
                        src={p.img}
                        alt={p.name}
                        loading="lazy"
                        onError={(e) => { e.currentTarget.style.display = "none"; }}
                      />
                    ) : (
                      <span className="ide-pv-product-ph" aria-hidden="true">{(brand || "·").trim().charAt(0).toUpperCase() || "·"}</span>
                    )}
                  </div>
                  <div className="ide-pv-product-meta">
                    <div className="ide-pv-product-name">{p.name}</div>
                    <div className="ide-pv-product-price">{p.price}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
          {phase === "building" ? (
            <div className="ide-pv-toast" key="rebuilding">↻ Rebuilding for {biz.trim() || "your brand"}…</div>
          ) : phase === "done" ? (
            <div className="ide-pv-toast" key="rebuilt">✓ Live at {brandSlug(brand)}.com</div>
          ) : lastEvent && (
            <div className="ide-pv-toast" key={lastEvent}>
              {lastEvent === "logo"    && "+ Logo added · build ✓"}
              {lastEvent === "nav"     && "+ Nav added · build ✓"}
              {lastEvent === "cart"    && "+ Cart added · build ✓"}
              {lastEvent === "hero"    && "+ Hero added · build ✓"}
              {lastEvent === "product" && "+ Products added · build ✓"}
            </div>
          )}
          {phase === "building" && (
            <div className="ide-pv-rebuild" aria-hidden="true"><span className="ide-pv-rebuild-txt">Rebuilding…</span></div>
          )}
        </div>
      </div>

      {/* Floating editor — smaller window overlaid on the browser's left edge */}
      <div className="ide-editor">
        <div className="ide-bar ide-bar-sm">
          <div className="dots"><i></i><i></i><i></i></div>
          <div className="ide-tabs"><span className="ide-tab on">shop.tsx</span><span className="ide-tab">ui.tsx</span></div>
        </div>
        <div className="ide-editor-body">
          <div className="ide-code" ref={codeRef}>
            {IDE_LINES.slice(0, shown).map((ln, i) => (
              <div className="ide-line" key={i}>
                <span className="ide-num">{i + 1}</span>
                <span className="ide-toks">
                  {ln.t.length === 0
                    ? <span>&nbsp;</span>
                    : ln.t.map((tk, j) => <span key={j} className={"tk tk-" + tk.c}>{tk.v}</span>)}
                </span>
              </div>
            ))}
            {shown < IDE_LINES.length && (
              <div className="ide-line">
                <span className="ide-num">{shown + 1}</span>
                <span className="ide-toks"><span className="ide-caret"></span></span>
              </div>
            )}
          </div>
          {phase !== "typing" && (
            <div className="ide-prompt-overlay">
              {phase === "done" ? (
                <div className="ide-prompt ide-prompt-done">
                  <div className="ide-prompt-ok"><Icon name="check" size={15} /> Shipped</div>
                  <div className="ide-prompt-brand">{brand}</div>
                  <div className="ide-prompt-meta">{brandSlug(brand)}.com is live</div>
                  <button type="button" className="ide-prompt-reset" onClick={tryAnother}>↻ Try another</button>
                </div>
              ) : (
                <form className="ide-prompt" onSubmit={shipIt}>
                  <div className="ide-prompt-head">Your turn — make it yours</div>
                  <input
                    className="ide-prompt-input"
                    value={biz}
                    onChange={(e) => setBiz(e.target.value)}
                    placeholder="Business name"
                    aria-label="Business name"
                    maxLength={28}
                    disabled={phase === "building"}
                  />
                  <input
                    className="ide-prompt-input"
                    value={ind}
                    onChange={(e) => setInd(e.target.value)}
                    placeholder="Industry — e.g. Coffee shop"
                    aria-label="Industry"
                    maxLength={28}
                    disabled={phase === "building"}
                  />
                  <button className="ide-prompt-btn" type="submit" disabled={phase === "building" || !biz.trim()}>
                    {phase === "building" ? "Building…" : <>Build it <span className="arr"><Icon name="arrow" size={15} /></span></>}
                  </button>
                </form>
              )}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

/* ---------- terminal panel (terminal hero) ---------- */
const TERM_LINES = [
  { t: "$ devnonames init yourbrand", cls: "pr" },
  { t: "→ scaffolding project…", cls: "dim" },
  { t: "✓ design system ready", cls: "ok" },
  { t: "✓ pages built · 8/8", cls: "ok" },
  { t: "$ deploy --prod", cls: "pr" },
  { t: "→ optimising assets…", cls: "dim" },
  { t: "✓ lighthouse 98 · LCP 1.1s", cls: "ok" },
  { t: "✓ live at yourbrand.com", cls: "ok" },
];

function TerminalPanel({ motion }) {
  const [shown, setShown] = React.useState(motion === "subtle" ? TERM_LINES.length : 0);
  React.useEffect(() => {
    if (motion === "subtle") { setShown(TERM_LINES.length); return; }
    setShown(0);
    let i = 0;
    const speed = motion === "maximal" ? 380 : 520;
    const id = setInterval(() => {
      i += 1;
      setShown(i);
      if (i >= TERM_LINES.length) clearInterval(id);
    }, speed);
    return () => clearInterval(id);
  }, [motion]);
  return (
    <div className="term reveal" style={{ "--d": "200ms" }}>
      <div className="term-bar">
        <div className="dots"><i></i><i></i><i></i></div>
        <div className="ttl">~/dev.nonames · zsh</div>
      </div>
      <div className="term-body">
        {TERM_LINES.slice(0, shown).map((l, i) => (
          <div className="term-line" key={i}><span className={l.cls}>{l.t}</span></div>
        ))}
        {shown < TERM_LINES.length && <div className="term-line"><span className="pr">$ </span><span className="term-cursor"></span></div>}
        {shown >= TERM_LINES.length && <div className="term-line"><span className="pr">$ </span><span className="term-cursor"></span></div>}
      </div>
    </div>
  );
}

function Hero({ heroStyle, motion }) {
  if (heroStyle === "split") {
    return (
      <header className="hero hero-split" id="top">
        <div className="hero-bg"></div><div className="hero-grid"></div>
        <div className="container">
          <div className="hero-row">
            <div className="hero-copy"><HeroCopy /></div>
            <IdeMock motion={motion} />
          </div>
        </div>
      </header>
    );
  }
  if (heroStyle === "terminal") {
    return (
      <header className="hero hero-terminal" id="top">
        <div className="hero-bg"></div><div className="hero-grid"></div>
        <div className="container">
          <div className="hero-row">
            <div><HeroCopy /></div>
            <TerminalPanel motion={motion} />
          </div>
        </div>
      </header>
    );
  }
  // statement (centered)
  return (
    <header className="hero hero-statement" id="top">
      <div className="hero-bg"></div><div className="hero-grid"></div>
      <div className="container">
        <HeroCopy centered />
      </div>
    </header>
  );
}

function Marquee() {
  const items = [...window.MARQUEE, ...window.MARQUEE];
  return (
    <div className="marquee">
      <div className="marquee-track">
        {items.map((m, i) => (
          <span className="marquee-item" key={i}>{m} <span className="s">◆</span></span>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { Icon, Nav, Hero, Marquee });
