/* Shared system: data, hooks, Logo, Nav (with mega menu), Footer, primitives */
const { useState, useEffect, useRef, useMemo } = React;

/* ---------- Palette ---------- */
const PALETTE = {
  red:'#E53A1F', orange:'#F08A2B', yellow:'#F5C53A', lime:'#B6CC3A',
  green:'#4FA53A', teal:'#2BAFA9', blue:'#2C58B3', purple:'#6E3F9E', magenta:'#C03B7A'
};

const LANGS = [
  { code:'EN', label:'English'   },
  { code:'RU', label:'Русский'   },
  { code:'UK', label:'Українська'},
  { code:'DE', label:'Deutsch'   },
  { code:'FR', label:'Français'  },
];

/* ---------- Data ---------- */
const CASES = [
  { slug:'crystal-tax',   name:'Crystal Tax',   industry:'Tax & Accounting · Ottawa',  tags:['Web','Local SEO','Lead funnel'],     line:'New website and local SEO system for an Ottawa tax practice.', color:PALETTE.blue },
  { slug:'apium',         name:'Apium',         industry:'B2B SaaS · EU',              tags:['Brand','Web','Performance'],         line:'Brand and acquisition funnel rebuild for a category challenger.', color:PALETTE.red },
  { slug:'kidsup',        name:'KidsUp Kanata', industry:'Education · Canada',         tags:['Web','SEO','SMM'],                   line:'Local growth program for a children’s activities studio.', color:PALETTE.yellow },
  { slug:'fast-coffee',   name:'Fast Coffee',   industry:'F&B · Ukraine',              tags:['Brand','Web','SMM'],                 line:'Brand system and digital presence for a specialty coffee chain.', color:PALETTE.orange },
  { slug:'mbsoy',         name:'MBSoy',         industry:'Agri export · International',tags:['Web','Content','GEO'],               line:'Bilingual export site and buyer-targeted content system.', color:PALETTE.green },
  { slug:'iceborn',       name:'Iceborn',       industry:'Consumer · DTC',             tags:['Web','PPC','Analytics'],             line:'Performance acquisition and analytics for a DTC brand.', color:PALETTE.teal },
  { slug:'cf-parea',      name:'CF Parea',      industry:'Wellness · Ottawa',          tags:['Web','Local SEO'],                   line:'Studio site and local discovery for a community fitness brand.', color:PALETTE.purple },
];

/* AI practice now has TWO arms: Visibility (LLM SEO/GEO) + AI-Native operations (agents, pipelines) */
const SERVICE_GROUPS = [
  { id:'build',    num:'01', title:'Build', tag:'Engineering', color:PALETTE.blue,
    blurb:'Websites, web apps, CRMs, and product surfaces. Built for measurement, speed, and AI legibility from day one.',
    forWho:'For teams ready to ship a real product surface, not a brochure.',
    items:[
      { slug:'web-development',  name:'Web development',          note:'Marketing sites, multi-language, headless' },
      { slug:'mobile-apps',      name:'Mobile apps',              note:'iOS / Android, hybrid stacks' },
      { slug:'telegram-mini',    name:'Telegram Mini Apps',       note:'In-chat commerce and tooling' },
      { slug:'crm',              name:'CRM & business systems',   note:'HubSpot, Pipedrive, custom' },
      { slug:'web3',             name:'Blockchain / Web3',        note:'Wallet flows, on-chain UX' },
    ]},
  { id:'promote',  num:'02', title:'Promote', tag:'Performance', color:PALETTE.red,
    blurb:'Demand and pipeline. Channels are tools — we engineer the system that compounds across them.',
    forWho:'For founders and CMOs who need measurable revenue, not vanity reach.',
    items:[
      { slug:'seo',          name:'SEO',                     note:'Technical, on-page, content' },
      { slug:'ppc',          name:'PPC',                     note:'Google Ads, Microsoft Ads' },
      { slug:'targeted-ads', name:'Targeted ads',            note:'Meta, LinkedIn, TikTok' },
      { slug:'smm',          name:'SMM',                     note:'Organic + paid social systems' },
      { slug:'performance',  name:'Performance marketing',   note:'Full-funnel acquisition' },
      { slug:'content',      name:'Content marketing',       note:'Editorial, video, programmatic' },
    ]},
  { id:'ai', num:'03', title:'AI Operations', tag:'Differentiator', color:PALETTE.purple, highlight:true,
    blurb:'Two arms. Visibility — being legible, citeable, and recommendable across LLMs. Native — running the marketing department on AI agents and automation pipelines.',
    forWho:'For companies whose buyers research with ChatGPT, Claude, Gemini, Perplexity — and whose marketing teams need to operate like one.',
    items:[
      { slug:'ai-seo',         name:'LLM SEO / GEO / AEO',         note:'Visibility in AI answers' },
      { slug:'ai-readable',    name:'AI-readable website',         note:'Structure, schema, retrieval' },
      { slug:'ai-content',     name:'AI content systems',          note:'Entity-grade content at scale' },
      { slug:'ai-native-team', name:'AI-native marketing team',    note:'Transition departments to AI-first' },
      { slug:'ai-agents',      name:'Autonomous marketing agents', note:'Research, outreach, ops bots' },
      { slug:'ai-pipelines',   name:'Marketing pipelines',         note:'n8n / Make / Zapier orchestration' },
      { slug:'ai-analytics',   name:'AI search analytics',         note:'Track citation across models' },
    ]},
  { id:'strategy', num:'04', title:'Strategy', tag:'Direction', color:PALETTE.green,
    blurb:'Senior marketing thinking before the build. Audit, position, sequence, and pressure-test before spend.',
    forWho:'For boards and CEOs choosing where the next dollar goes.',
    items:[
      { slug:'audit',        name:'Marketing audit',         note:'Funnel, channels, AI readiness' },
      { slug:'gtm',          name:'Go-to-market strategy',   note:'New markets, new products' },
      { slug:'crm-strategy', name:'CRM & funnel strategy',   note:'Lifecycle, scoring, retention' },
      { slug:'automation',   name:'Marketing automation',    note:'Sequences, ops, data' },
      { slug:'analytics',    name:'Analytics & reporting',   note:'GA4, server-side, dashboards' },
      { slug:'growth',       name:'Growth consulting',       note:'Quarterly operator partnership' },
    ]},
];

const INDUSTRIES = [
  { slug:'saas',          name:'B2B SaaS',              color:PALETTE.blue,    lede:'Long sales cycles, technical buyers, AI-research by default.',
    help:'We engineer demand systems for sellers whose buyers research deeply. SEO + LLM visibility + paid + funnel telemetry.',
    services:['LLM SEO','SEO','PPC','Content','Web','Analytics'],
    outcome:'3.4× qualified inbound; multi-model AI citation; CAC down on a 6-month curve.' },
  { slug:'pro-services',  name:'Professional services', color:PALETTE.red,     lede:'Tax, legal, accounting, consulting — referral-grown, now competing in AI search.',
    help:'Trust signals, local SEO, AI-readable practice pages, instrumented funnels. We replace word-of-mouth dependence with a measurable surface.',
    services:['Local SEO','LLM SEO','Web','CRM','Content','Lead funnel'],
    outcome:'Map-pack positions, cited in AI answers, measurable booking pipeline.' },
  { slug:'dtc',           name:'DTC & E-commerce',      color:PALETTE.orange,  lede:'Brand systems, performance, and clean attribution after iOS.',
    help:'Brand build, paid acquisition, post-iOS measurement, retention. AI agents for ops and creative iteration.',
    services:['Brand','Web','PPC','SMM','Analytics','AI agents'],
    outcome:'Lower CAC, higher LTV, post-iOS attribution clarity.' },
  { slug:'agri-export',   name:'Agri & Export',         color:PALETTE.green,   lede:'Buyer-targeted content systems across markets and languages.',
    help:'Bilingual export sites, structured buyer pages, AI visibility for B2B agri queries, document-grade content.',
    services:['Web','Multilingual SEO','Content','GEO','LLM SEO','Lead funnel'],
    outcome:'New geographies online, buyer inbound from EU/MENA/Asia, AI-cited authority.' },
  { slug:'education',     name:'Education',             color:PALETTE.teal,    lede:'Local discovery, parent funnels, retention sequences.',
    help:'Local SEO, parent-targeted content, seasonal campaigns, CRM + automation. AI agents handle inquiries and routing.',
    services:['Local SEO','SMM','PPC','CRM','AI agents','Content'],
    outcome:'Class fill rate up, parent inquiry to booking time down.' },
  { slug:'fintech',       name:'Fintech & Accounting',  color:PALETTE.purple,  lede:'Compliance-friendly content, trust signals, AI-search authority.',
    help:'Authoritative content, compliance-aware copy, trust architecture, AI citation strategy. Conservative voice with sharp execution.',
    services:['Content','LLM SEO','Web','Compliance copy','Analytics','PR'],
    outcome:'Trust signals visible to humans and machines; qualified inbound on technical queries.' },
];

const NAV_ITEMS = [
  { id:'services',   label:'Services',   mega:'services' },
  { id:'ai',         label:'AI',         mega:'ai' },
  { id:'industries', label:'Industries', mega:'industries' },
  { id:'cases',      label:'Cases'      },
  { id:'about',      label:'About'      },
  { id:'insights',   label:'Insights'   },
  { id:'contact',    label:'Contact'    },
];

Object.assign(window, { PALETTE, LANGS, CASES, SERVICE_GROUPS, INDUSTRIES, NAV_ITEMS });

/* ---------- Hooks ---------- */
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const showNow = () => el.classList.add('in');
    const r = el.getBoundingClientRect();
    const vh = window.innerHeight || document.documentElement.clientHeight;
    if (r.top < vh && r.bottom > 0) { requestAnimationFrame(showNow); return; }
    let timer;
    if (typeof IntersectionObserver === 'function') {
      const io = new IntersectionObserver((entries) => {
        entries.forEach(e => { if (e.isIntersecting) { showNow(); io.disconnect(); clearTimeout(timer); } });
      }, { threshold: 0.08, rootMargin: '0px 0px -10% 0px' });
      io.observe(el);
      timer = setTimeout(() => { showNow(); io.disconnect(); }, 1200);
      return () => { io.disconnect(); clearTimeout(timer); };
    } else { showNow(); }
  }, []);
  return ref;
}

function useScrolled(threshold = 8) {
  const [s, setS] = useState(false);
  useEffect(() => {
    const on = () => setS(window.scrollY > threshold);
    on(); window.addEventListener('scroll', on, { passive: true });
    return () => window.removeEventListener('scroll', on);
  }, [threshold]);
  return s;
}

function useClickOutside(ref, onClose, enabled=true) {
  useEffect(() => {
    if (!enabled) return;
    const onDown = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose(); };
    document.addEventListener('mousedown', onDown);
    return () => document.removeEventListener('mousedown', onDown);
  }, [ref, onClose, enabled]);
}

/* ---------- Primitives ---------- */
function Reveal({ as: As = 'div', children, className = '', delay = 0, ...rest }) {
  const ref = useReveal();
  const style = delay ? { transitionDelay: `${delay}ms` } : undefined;
  return <As ref={ref} className={`reveal ${className}`} style={style} {...rest}>{children}</As>;
}

function Container({ children, className='' }) {
  return <div className={`mx-auto w-full max-w-[1360px] px-5 md:px-10 ${className}`}>{children}</div>;
}

function Mono({ children, className='' }) {
  return <span className={`num text-mute ${className}`}>{children}</span>;
}

function Eyebrow({ num, label, color, dark=false }) {
  const dotColor = color || '#E53A1F';
  return (
    <div className="flex items-center gap-3 flex-wrap">
      <span className="w-2 h-2 inline-block shrink-0" style={{ background: dotColor }} />
      {num != null && <span className={`num shrink-0 ${dark?'text-paper/70':'text-mute'}`}>{num}</span>}
      <span className={`h-px w-8 shrink-0 ${dark?'bg-paper/30':'bg-ink/30'}`}></span>
      <span className={`num ${dark?'text-paper':'text-ink'}`}>{label}</span>
    </div>
  );
}

/* ---------- Polygon Decor ---------- */
function PolygonAccent({ className='', size=300, opacity=1 }) {
  return (
    <svg className={`poly ${className}`} width={size} height={size*0.78} viewBox="0 0 300 234" fill="none" aria-hidden="true" style={{ opacity }}>
      <polygon points="0,80 80,0 80,80"     fill={PALETTE.red} />
      <polygon points="80,0 160,0 80,80"    fill={PALETTE.orange} />
      <polygon points="160,0 240,0 160,80"  fill={PALETTE.yellow} />
      <polygon points="240,0 300,0 300,80"  fill={PALETTE.lime} />
      <polygon points="80,80 0,80 0,160"    fill={PALETTE.magenta} />
      <polygon points="80,80 160,80 80,160" fill={PALETTE.green} />
      <polygon points="160,80 240,80 160,160" fill={PALETTE.teal} />
      <polygon points="240,80 300,80 300,160" fill={PALETTE.blue} />
      <polygon points="0,160 80,160 0,234"  fill={PALETTE.purple} />
      <polygon points="80,160 160,160 80,234" fill={PALETTE.red} />
      <polygon points="160,160 240,160 160,234" fill={PALETTE.orange} />
      <polygon points="240,160 300,160 240,234" fill={PALETTE.yellow} />
    </svg>
  );
}

function PolygonScatter({ className='' }) {
  return (
    <svg className={`poly ${className}`} width="640" height="500" viewBox="0 0 640 500" fill="none" aria-hidden="true">
      <polygon points="40,40 160,40 100,160"   fill={PALETTE.red}     opacity="0.95" />
      <polygon points="180,80 300,40 240,180"  fill={PALETTE.orange}  opacity="0.95" />
      <polygon points="340,30 460,60 400,170"  fill={PALETTE.yellow}  opacity="0.95" />
      <polygon points="500,40 620,80 560,200"  fill={PALETTE.green}   opacity="0.95" />
      <polygon points="60,220 200,200 140,340" fill={PALETTE.teal}    opacity="0.95" />
      <polygon points="220,240 360,220 320,380" fill={PALETTE.blue}   opacity="0.95" />
      <polygon points="380,250 500,260 460,380" fill={PALETTE.purple} opacity="0.95" />
      <polygon points="520,260 640,300 600,420" fill={PALETTE.magenta} opacity="0.95" />
      <polygon points="120,380 280,400 200,480" fill={PALETTE.red}    opacity="0.95" />
      <polygon points="320,400 460,400 400,490" fill={PALETTE.orange} opacity="0.95" />
    </svg>
  );
}

/* ---------- Hero Art — thematic polygon compositions per page ---------- */
function HeroArt({ preset='services', className='' }) {
  // Each preset renders a polygon SVG art piece in the logo palette, themed for its page.
  const P = PALETTE;
  let inner = null;
  if (preset === 'services') {
    inner = (
      <g>
        {/* four stacked practice bars */}
        <rect x="40"  y="60"  width="320" height="60" fill={P.blue} />
        <polygon points="360,60 420,90 360,120" fill={P.blue} opacity="0.7" />
        <rect x="40"  y="140" width="320" height="60" fill={P.red} />
        <polygon points="360,140 420,170 360,200" fill={P.red} opacity="0.7" />
        <rect x="40"  y="220" width="320" height="60" fill={P.purple} />
        <polygon points="360,220 420,250 360,280" fill={P.purple} opacity="0.7" />
        <rect x="40"  y="300" width="320" height="60" fill={P.green} />
        <polygon points="360,300 420,330 360,360" fill={P.green} opacity="0.7" />
      </g>
    );
  } else if (preset === 'ai') {
    inner = (
      <g>
        {/* neural-ish cluster */}
        <polygon points="220,40 320,110 240,170 140,110" fill={P.purple} />
        <polygon points="60,180 180,160 130,260" fill={P.red} />
        <polygon points="320,150 420,200 360,290" fill={P.yellow} />
        <polygon points="180,260 260,220 290,330 200,360" fill={P.teal} />
        <polygon points="320,290 410,330 360,400" fill={P.green} />
        <polygon points="60,310 180,330 120,400" fill={P.blue} />
        {/* connecting lines */}
        <line x1="220" y1="110" x2="130" y2="220" stroke={P.ink} strokeWidth="2" />
        <line x1="220" y1="110" x2="370" y2="220" stroke={P.ink} strokeWidth="2" />
        <line x1="230" y1="280" x2="130" y2="350" stroke={P.ink} strokeWidth="2" />
        <line x1="230" y1="280" x2="370" y2="350" stroke={P.ink} strokeWidth="2" />
        <circle cx="220" cy="110" r="6" fill={P.ink} />
        <circle cx="230" cy="280" r="6" fill={P.ink} />
      </g>
    );
  } else if (preset === 'industries') {
    inner = (
      <g>
        {/* sector tiles */}
        <rect x="40"  y="40"  width="120" height="120" fill={P.blue} />
        <rect x="170" y="40"  width="120" height="120" fill={P.red} />
        <rect x="300" y="40"  width="120" height="120" fill={P.orange} />
        <rect x="40"  y="170" width="120" height="120" fill={P.green} />
        <rect x="170" y="170" width="120" height="120" fill={P.teal} />
        <rect x="300" y="170" width="120" height="120" fill={P.purple} />
        <rect x="40"  y="300" width="120" height="60"  fill={P.yellow} />
        <rect x="170" y="300" width="250" height="60"  fill={P.magenta} />
      </g>
    );
  } else if (preset === 'cases') {
    inner = (
      <g>
        {/* stacked frames */}
        <rect x="60"  y="50"  width="320" height="80"  fill={P.red} />
        <rect x="80"  y="150" width="320" height="80"  fill={P.yellow} />
        <rect x="40"  y="250" width="320" height="80"  fill={P.green} />
        <rect x="100" y="350" width="320" height="60"  fill={P.purple} />
        <polygon points="380,50 460,90 380,130"  fill={P.red}    opacity="0.7" />
        <polygon points="400,150 460,190 400,230" fill={P.yellow} opacity="0.7" />
        <polygon points="360,250 460,290 360,330" fill={P.green}  opacity="0.7" />
        <polygon points="420,350 460,380 420,410" fill={P.purple} opacity="0.7" />
      </g>
    );
  } else if (preset === 'about') {
    inner = (
      <g>
        {/* abstract globe / continents */}
        <circle cx="230" cy="220" r="170" fill="none" stroke={P.ink} strokeWidth="2" />
        <polygon points="120,140 200,120 180,200 100,210" fill={P.green} />
        <polygon points="230,110 320,130 290,210 230,200" fill={P.yellow} />
        <polygon points="170,230 260,220 290,310 200,320" fill={P.red} />
        <polygon points="300,230 360,260 330,320" fill={P.blue} />
        <polygon points="100,260 170,260 140,330 90,310" fill={P.purple} />
        {/* city dots */}
        <circle cx="150" cy="170" r="8" fill={P.red} />
        <circle cx="270" cy="160" r="8" fill={P.yellow} />
        <circle cx="240" cy="270" r="8" fill={P.blue} />
        <circle cx="330" cy="280" r="8" fill={P.green} />
      </g>
    );
  } else if (preset === 'contact') {
    inner = (
      <g>
        {/* speech bubble of polygons */}
        <polygon points="80,80 380,80 380,260 240,260 200,320 200,260 80,260" fill={P.yellow} />
        <polygon points="80,80 240,80 160,180" fill={P.red} opacity="0.9" />
        <polygon points="240,80 380,80 320,180" fill={P.orange} opacity="0.9" />
        <polygon points="80,180 240,180 200,260 80,260" fill={P.green} opacity="0.9" />
        <polygon points="240,180 380,180 320,260 240,260" fill={P.blue} opacity="0.9" />
        {/* dot trio */}
        <circle cx="160" cy="220" r="14" fill={P.ink} />
        <circle cx="230" cy="220" r="14" fill={P.ink} />
        <circle cx="300" cy="220" r="14" fill={P.ink} />
      </g>
    );
  } else if (preset === 'insights') {
    inner = (
      <g>
        {/* open book pages */}
        <rect x="60"  y="80"  width="170" height="280" fill={P.yellow} />
        <rect x="240" y="80"  width="170" height="280" fill={P.orange} />
        <line x1="70" y1="130" x2="220" y2="130" stroke={P.ink} strokeWidth="3" />
        <line x1="70" y1="170" x2="200" y2="170" stroke={P.ink} strokeWidth="3" />
        <line x1="70" y1="210" x2="210" y2="210" stroke={P.ink} strokeWidth="3" />
        <line x1="70" y1="250" x2="180" y2="250" stroke={P.ink} strokeWidth="3" />
        <line x1="70" y1="290" x2="210" y2="290" stroke={P.ink} strokeWidth="3" />
        <line x1="250" y1="130" x2="400" y2="130" stroke={P.ink} strokeWidth="3" />
        <line x1="250" y1="170" x2="380" y2="170" stroke={P.ink} strokeWidth="3" />
        <line x1="250" y1="210" x2="390" y2="210" stroke={P.ink} strokeWidth="3" />
        <line x1="250" y1="250" x2="360" y2="250" stroke={P.ink} strokeWidth="3" />
        <polygon points="60,80 230,80 230,360 60,360" fill="none" stroke={P.ink} strokeWidth="2" />
        <polygon points="240,80 410,80 410,360 240,360" fill="none" stroke={P.ink} strokeWidth="2" />
      </g>
    );
  } else {
    inner = <PolygonAccent />;
  }

  return (
    <div className={`relative border-2 border-ink overflow-hidden ${className}`} style={{ background: '#FFFFFF' }} data-asset={`hero-art-${preset}`}>
      <div className="absolute inset-0 pointer-events-none opacity-30 bg-grid-light"></div>
      <svg width="100%" height="100%" viewBox="0 0 460 440" preserveAspectRatio="xMidYMid meet" className="relative block" aria-hidden="true">
        {inner}
      </svg>
      <div className="label">data-asset · hero-art-{preset}</div>
    </div>
  );
}

/* ---------- Logo (horizontal lockup: elephant + wordmark) ---------- */
function Logo({ dark=false, onClick, size=44 }) {
  const word = dark ? 'assets/mmix-wordmark-light.png' : 'assets/mmix-wordmark.png';
  return (
    <button onClick={onClick} className="inline-flex items-center gap-2.5 focus:outline-none" aria-label="Marketing MIX, home">
      <img src="assets/mmix-elephant.png" alt="" style={{ height: size, width: 'auto' }} className="select-none pointer-events-none shrink-0" />
      <img src={word} alt="Marketing MIX" style={{ height: size * 0.55, width: 'auto' }} className="select-none pointer-events-none shrink-0 hidden sm:inline-block" />
    </button>
  );
}

/* ---------- Mega Menu Panels ---------- */
function ServicesMega({ onNavigate, onOpenService, close }) {
  return (
    <div className="grid grid-cols-1 md:grid-cols-4 gap-x-8 gap-y-6 p-7 md:p-10">
      {SERVICE_GROUPS.map(g => (
        <div key={g.id} className="border-t-4 pt-4" style={{ borderColor: g.color }}>
          <div className="flex items-center justify-between">
            <span className="num font-bold" style={{ color: g.color }}>{g.num} · {g.tag.toUpperCase()}</span>
            {g.highlight && <span className="num px-1.5 py-0.5" style={{background: PALETTE.yellow, color: PALETTE.ink, fontWeight:700}}>NEW</span>}
          </div>
          <button onClick={() => { onNavigate('services'); close(); }} className="display text-[28px] md:text-[32px] mt-2 hover:translate-x-1 transition-transform text-left">{g.title.toUpperCase()}</button>
          <ul className="mt-3 space-y-1.5">
            {g.items.map(s => (
              <li key={s.slug}>
                <button onClick={() => { onOpenService(s.slug); close(); }} className="text-[14px] text-ink/85 hover:text-ink font-medium ed-link text-left">
                  {s.name}
                </button>
              </li>
            ))}
          </ul>
        </div>
      ))}
    </div>
  );
}

function AIMega({ onNavigate, onOpenService, close }) {
  const visibility = SERVICE_GROUPS.find(g=>g.id==='ai').items.slice(0,3);
  const native     = SERVICE_GROUPS.find(g=>g.id==='ai').items.slice(3);
  return (
    <div className="grid grid-cols-1 md:grid-cols-3 gap-8 p-7 md:p-10">
      <div className="md:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-6">
        <div className="border-t-4 pt-4" style={{borderColor: PALETTE.purple}}>
          <span className="num font-bold" style={{color: PALETTE.purple}}>ARM 01 · VISIBILITY</span>
          <button onClick={() => { onNavigate('ai'); close(); }} className="block display text-[26px] md:text-[28px] mt-2 hover:translate-x-1 transition-transform text-left">AI SEO & LLM VISIBILITY</button>
          <p className="text-[13.5px] text-mute mt-2 leading-[1.5] max-w-[36ch]">Be cited and recommended across ChatGPT, Claude, Gemini, Perplexity.</p>
          <ul className="mt-4 space-y-1.5">
            {visibility.map(s => (
              <li key={s.slug}><button onClick={() => { onOpenService(s.slug); close(); }} className="text-[14px] text-ink/85 ed-link font-medium text-left">{s.name}</button></li>
            ))}
          </ul>
        </div>
        <div className="border-t-4 pt-4" style={{borderColor: PALETTE.magenta}}>
          <span className="num font-bold" style={{color: PALETTE.magenta}}>ARM 02 · NATIVE OPS</span>
          <button onClick={() => { onNavigate('ai'); close(); }} className="block display text-[26px] md:text-[28px] mt-2 hover:translate-x-1 transition-transform text-left">AI-NATIVE MARKETING</button>
          <p className="text-[13.5px] text-mute mt-2 leading-[1.5] max-w-[36ch]">Transition departments to AI-first. Agents, pipelines, automation.</p>
          <ul className="mt-4 space-y-1.5">
            {native.map(s => (
              <li key={s.slug}><button onClick={() => { onOpenService(s.slug); close(); }} className="text-[14px] text-ink/85 ed-link font-medium text-left">{s.name}</button></li>
            ))}
          </ul>
        </div>
      </div>
      <div className="border-2 border-ink p-5 bg-ink text-paper">
        <span className="num font-bold" style={{color: PALETTE.yellow}}>FREE AUDIT</span>
        <p className="display text-[22px] mt-2 text-paper">AI VISIBILITY DIAGNOSTIC.</p>
        <p className="text-[13.5px] text-paper/75 mt-2 leading-[1.5]">Per-model snapshot across ChatGPT, Claude, Gemini, Perplexity. Free, 1 business day.</p>
        <button onClick={() => { onNavigate('contact'); close(); }} className="btn btn-bright btn-sq mt-4 w-full justify-center">Request audit →</button>
      </div>
    </div>
  );
}

function IndustriesMega({ onOpenIndustry, onNavigate, close }) {
  return (
    <div className="p-7 md:p-10">
      <div className="grid grid-cols-1 md:grid-cols-3 gap-x-8 gap-y-6">
        {INDUSTRIES.map(i => (
          <button key={i.slug} onClick={() => { onOpenIndustry(i.slug); close(); }} className="text-left group border-t-4 pt-4 hover:translate-x-1 transition-transform" style={{borderColor: i.color}}>
            <span className="num font-bold" style={{color: i.color}}>{i.name.toUpperCase()}</span>
            <p className="text-[14px] text-ink/85 mt-2 leading-[1.5] max-w-[38ch]">{i.lede}</p>
            <span className="num font-bold mt-2 inline-block" style={{color: i.color}}>Explore →</span>
          </button>
        ))}
      </div>
      <div className="mt-7 pt-6 border-t-2 border-ink flex items-center justify-between">
        <p className="text-[14px] text-mute">Don't see your industry? We work across categories where buyers research deeply.</p>
        <button onClick={() => { onNavigate('contact'); close(); }} className="num font-bold text-ink ed-link">Talk to us →</button>
      </div>
    </div>
  );
}

/* ---------- Language Dropdown ---------- */
function LangDropdown({ lang, setLang, dark=false }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useClickOutside(ref, () => setOpen(false), open);
  const current = LANGS.find(l => l.code === lang) || LANGS[0];
  return (
    <div className="relative" ref={ref}>
      <button onClick={() => setOpen(o => !o)} className={`flex items-center gap-2 num font-bold px-2.5 py-1.5 border-2 border-ink ${dark?'border-paper text-paper':'text-ink hover:bg-paper2'}`}>
        {current.code}
        <svg width="10" height="6" viewBox="0 0 10 6" className={`transition-transform ${open?'rotate-180':''}`}><path d="M1 1l4 4 4-4" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
      </button>
      {open && (
        <div className="absolute right-0 top-full mt-2 w-44 border-2 border-ink bg-paper z-50 shadow-[6px_6px_0_0_#0A0A0A]">
          {LANGS.map(l => (
            <button key={l.code} onClick={() => { setLang(l.code); setOpen(false); }} className={`w-full flex items-center justify-between px-3 py-2.5 num text-left transition-colors ${l.code===lang?'bg-ink text-paper':'hover:bg-paper2 text-ink'}`}>
              <span className="font-bold">{l.code}</span>
              <span className="text-[11px]">{l.label}</span>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

/* ---------- Nav ---------- */
function Nav({ activePage, onNavigate, onOpenService, onOpenCase, onOpenIndustry, openMobile, setOpenMobile, lang, setLang }) {
  const scrolled = useScrolled(6);
  const [openMega, setOpenMega] = useState(null);
  const closeTimer = useRef(null);

  function openItem(id) {
    if (closeTimer.current) { clearTimeout(closeTimer.current); closeTimer.current = null; }
    setOpenMega(id);
  }
  function scheduleClose() {
    if (closeTimer.current) clearTimeout(closeTimer.current);
    closeTimer.current = setTimeout(() => setOpenMega(null), 180);
  }
  function close() { setOpenMega(null); }

  return (
    <header className={`fixed top-0 inset-x-0 z-50 transition-all duration-300 ${scrolled || openMega ? 'bg-paper border-b-2 border-ink' : 'bg-transparent border-b-2 border-transparent'}`} onMouseLeave={scheduleClose}>
      <div className="mx-auto w-full max-w-[1360px] px-5 md:px-10">
        <div className="flex items-center justify-between h-[68px] gap-4">
          <Logo onClick={() => { close(); onNavigate('home'); }} />
          <nav className="hidden lg:flex items-center gap-5 xl:gap-7">
            {NAV_ITEMS.map(item => {
              const active = activePage === item.id || (item.id==='services' && activePage==='service-detail') || (item.id==='cases' && activePage==='case-detail') || (item.id==='industries' && activePage==='industry-detail');
              return (
                <button
                  key={item.id}
                  onMouseEnter={() => item.mega ? openItem(item.id) : openItem(null)}
                  onFocus={() => item.mega ? openItem(item.id) : openItem(null)}
                  onClick={() => {
                    if (item.mega) {
                      // toggle on click as well
                      openMega === item.id ? close() : openItem(item.id);
                    } else { close(); onNavigate(item.id); }
                  }}
                  aria-expanded={openMega === item.id}
                  className={`relative text-[13.5px] font-semibold transition-colors flex items-center gap-1`}
                >
                  <span className={active ? 'text-ink' : 'text-ink/65 hover:text-ink'}>{item.label}</span>
                  {item.mega && (
                    <svg width="9" height="6" viewBox="0 0 10 6" className={`shrink-0 transition-transform ${openMega===item.id?'rotate-180':''}`}><path d="M1 1l4 4 4-4" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
                  )}
                  {active && <span className="absolute -bottom-1.5 left-0 right-0 h-[3px]" style={{background: PALETTE.red}}></span>}
                </button>
              );
            })}
          </nav>
          <div className="hidden md:flex items-center gap-3">
            <LangDropdown lang={lang} setLang={setLang} />
            <button onClick={() => { close(); onNavigate('contact'); }} className="btn btn-bright btn-sq !py-2.5 !px-4">
              Free AI audit
              <span aria-hidden="true">→</span>
            </button>
          </div>
          <button className="lg:hidden p-2 -mr-2" aria-label="Menu" onClick={() => setOpenMobile(true)}>
            <div className="flex flex-col gap-1.5">
              <span className="block w-6 h-0.5 bg-ink"></span>
              <span className="block w-6 h-0.5 bg-ink"></span>
              <span className="block w-6 h-0.5 bg-ink"></span>
            </div>
          </button>
        </div>
      </div>

      {/* Mega menu panel */}
      {openMega && (
        <div className="absolute inset-x-0 top-full bg-paper border-b-2 border-ink animate-fadein"
             onMouseEnter={() => openItem(openMega)}>
          <div className="mx-auto w-full max-w-[1360px]">
            {openMega === 'services'  && <ServicesMega   onNavigate={onNavigate} onOpenService={onOpenService} close={close} />}
            {openMega === 'ai'        && <AIMega         onNavigate={onNavigate} onOpenService={onOpenService} close={close} />}
            {openMega === 'industries'&& <IndustriesMega onOpenIndustry={onOpenIndustry} onNavigate={onNavigate} close={close} />}
          </div>
        </div>
      )}

      {/* Mobile drawer */}
      {openMobile && (
        <MobileMenu
          onClose={() => setOpenMobile(false)}
          onNavigate={onNavigate}
          onOpenService={onOpenService}
          onOpenIndustry={onOpenIndustry}
          lang={lang} setLang={setLang}
          activePage={activePage}
        />
      )}
    </header>
  );
}

/* ---------- Mobile Menu ---------- */
function MobileMenu({ onClose, onNavigate, onOpenService, onOpenIndustry, lang, setLang, activePage }) {
  const [expand, setExpand] = useState(null);
  return (
    <div className="lg:hidden fixed inset-0 z-50 flex flex-col bg-paper overflow-y-auto">
      <div className="flex items-center justify-between h-[68px] px-5 border-b-2 border-ink shrink-0 sticky top-0 bg-paper z-10">
        <Logo onClick={() => { onClose(); onNavigate('home'); }} />
        <button onClick={onClose} aria-label="Close menu" className="text-[28px] leading-none">×</button>
      </div>
      <div className="flex-1 px-5 py-4">
        {NAV_ITEMS.map(item => (
          <div key={item.id} className="border-b border-rule">
            {item.mega ? (
              <>
                <button onClick={() => setExpand(expand === item.id ? null : item.id)} className="w-full flex items-center justify-between py-3.5 text-left">
                  <span className="display text-[32px]">{item.label.toUpperCase()}</span>
                  <span className={`display text-[24px] transition-transform ${expand === item.id ? 'rotate-45' : ''}`}>+</span>
                </button>
                {expand === item.id && (
                  <div className="pb-4 pl-2 space-y-3">
                    {item.id === 'services' && SERVICE_GROUPS.map(g => (
                      <div key={g.id} className="border-l-4 pl-3" style={{borderColor: g.color}}>
                        <div className="num font-bold" style={{color: g.color}}>{g.title.toUpperCase()}</div>
                        <ul className="mt-1.5 space-y-1">
                          {g.items.slice(0,4).map(s => (
                            <li key={s.slug}><button onClick={() => { onClose(); onOpenService(s.slug); }} className="text-[14.5px] text-ink/85 ed-link text-left font-medium">{s.name}</button></li>
                          ))}
                        </ul>
                      </div>
                    ))}
                    {item.id === 'ai' && (
                      <>
                        <div className="border-l-4 pl-3" style={{borderColor: PALETTE.purple}}>
                          <div className="num font-bold" style={{color: PALETTE.purple}}>VISIBILITY</div>
                          <ul className="mt-1.5 space-y-1">
                            {SERVICE_GROUPS.find(g=>g.id==='ai').items.slice(0,3).map(s => (
                              <li key={s.slug}><button onClick={() => { onClose(); onOpenService(s.slug); }} className="text-[14.5px] text-ink/85 ed-link text-left font-medium">{s.name}</button></li>
                            ))}
                          </ul>
                        </div>
                        <div className="border-l-4 pl-3" style={{borderColor: PALETTE.magenta}}>
                          <div className="num font-bold" style={{color: PALETTE.magenta}}>NATIVE OPS</div>
                          <ul className="mt-1.5 space-y-1">
                            {SERVICE_GROUPS.find(g=>g.id==='ai').items.slice(3).map(s => (
                              <li key={s.slug}><button onClick={() => { onClose(); onOpenService(s.slug); }} className="text-[14.5px] text-ink/85 ed-link text-left font-medium">{s.name}</button></li>
                            ))}
                          </ul>
                        </div>
                        <button onClick={() => { onClose(); onNavigate('ai'); }} className="num font-bold ed-link mt-2 inline-block">Read AI playbook →</button>
                      </>
                    )}
                    {item.id === 'industries' && INDUSTRIES.map(i => (
                      <button key={i.slug} onClick={() => { onClose(); onOpenIndustry(i.slug); }} className="block border-l-4 pl-3 text-left" style={{borderColor: i.color}}>
                        <span className="num font-bold" style={{color: i.color}}>{i.name.toUpperCase()}</span>
                        <p className="text-[13px] text-mute mt-1 leading-[1.4]">{i.lede}</p>
                      </button>
                    ))}
                  </div>
                )}
              </>
            ) : (
              <button onClick={() => { onClose(); onNavigate(item.id); }} className="w-full flex items-center justify-between py-3.5 text-left">
                <span className="display text-[32px]">{item.label.toUpperCase()}</span>
                <span className="num text-mute">→</span>
              </button>
            )}
          </div>
        ))}
      </div>
      <div className="px-5 py-5 border-t-2 border-ink flex items-center justify-between gap-3 sticky bottom-0 bg-paper">
        <LangDropdown lang={lang} setLang={setLang} />
        <button onClick={() => { onClose(); onNavigate('contact'); }} className="btn btn-bright btn-sq flex-1 justify-center">Free AI audit →</button>
      </div>
    </div>
  );
}

/* ---------- Breadcrumbs ---------- */
function Breadcrumbs({ trail }) {
  if (!trail || trail.length === 0) return null;
  return (
    <nav className="border-b border-rule" aria-label="Breadcrumb">
      <div className="mx-auto w-full max-w-[1360px] px-5 md:px-10 py-3 flex items-center gap-2 flex-wrap overflow-x-auto no-scrollbar">
        {trail.map((t, i) => (
          <React.Fragment key={i}>
            {i > 0 && <span className="num text-mute">/</span>}
            {t.onClick ? (
              <button onClick={t.onClick} className="num text-mute hover:text-ink font-bold whitespace-nowrap">{t.label.toUpperCase()}</button>
            ) : (
              <span className="num text-ink font-bold whitespace-nowrap">{t.label.toUpperCase()}</span>
            )}
          </React.Fragment>
        ))}
      </div>
    </nav>
  );
}

/* ---------- Page Header ---------- */
function PageHeader({ eyebrow, title, lede, num='—', color='#E53A1F', art='services', breadcrumbs }) {
  return (
    <>
      {breadcrumbs && <div className="pt-[68px]"><Breadcrumbs trail={breadcrumbs} /></div>}
      <section className={`${breadcrumbs?'':'pt-[68px]'} pb-12 md:pb-16 border-b-2 border-ink`}>
        <Container>
          <div className="pt-10 md:pt-14">
            <Eyebrow num={num} label={eyebrow} color={color} />
            <div className="grid grid-cols-12 gap-6 md:gap-10 items-end mt-6 md:mt-8">
              <div className="col-span-12 md:col-span-8 min-w-0">
                <h1 className="display display-tight break-words leading-[0.88]" style={{ fontSize: 'clamp(40px, 7.2vw, 128px)', hyphens: 'auto', wordBreak: 'normal', overflowWrap: 'break-word' }}>{title}</h1>
                {lede && (
                  <div className="mt-6 md:mt-8 max-w-[52ch]">
                    <div className="h-1.5 w-12 mb-3" style={{background: color}}></div>
                    <p className="text-[15.5px] md:text-[17px] text-ink/80 leading-[1.55]">{lede}</p>
                  </div>
                )}
              </div>
              <div className="col-span-12 md:col-span-4">
                <div className="aspect-[5/4] md:aspect-[4/3]">
                  <HeroArt preset={art} className="w-full h-full" />
                </div>
              </div>
            </div>
          </div>
        </Container>
      </section>
    </>
  );
}

/* ---------- CTA Band ---------- */
function CTABand({ onNavigate }) {
  return (
    <section className="bg-ink text-paper py-20 md:py-28 relative overflow-hidden">
      <div className="absolute -right-20 -top-20 opacity-50 pointer-events-none">
        <PolygonScatter />
      </div>
      <Container className="relative">
        <div className="grid grid-cols-12 gap-6 md:gap-8">
          <div className="col-span-12 md:col-span-8">
            <Eyebrow num="↘" label="Next move" color={PALETTE.yellow} dark />
            <h2 className="display display-tight text-paper text-[44px] md:text-[96px] mt-6 max-w-[14ch]">
              READY TO BE FOUND BY <span style={{color:PALETTE.yellow}}>HUMANS</span> AND <span style={{color:PALETTE.teal}}>MACHINES?</span>
            </h2>
          </div>
          <div className="col-span-12 md:col-span-4 md:pl-4 flex flex-col justify-end">
            <p className="text-[15.5px] text-paper/75 leading-[1.6] max-w-[46ch] mb-8">
              Two paths in. A 30-minute strategy call to scope the problem, or a free AI visibility audit across ChatGPT, Claude, Gemini, and Perplexity.
            </p>
            <div className="flex flex-wrap gap-3">
              <button onClick={() => onNavigate('contact')} className="btn btn-bright btn-sq">Book 30-min call →</button>
              <button onClick={() => onNavigate('contact')} className="btn btn-dark-on-dark btn-sq">Free AI audit →</button>
            </div>
            <div className="mt-6 num text-paper/55">Avg. response · within 1 business day</div>
          </div>
        </div>
      </Container>
    </section>
  );
}

/* ---------- Footer (utility, on warm paper2 — breaks visual rhythm from the black CTA band) ---------- */
function Footer({ onNavigate }) {
  return (
    <footer className="bg-paper2 text-ink relative overflow-hidden border-t-2 border-ink">
      <div className="grid grid-cols-8 h-3">
        <div style={{ background: PALETTE.red }}></div>
        <div style={{ background: PALETTE.orange }}></div>
        <div style={{ background: PALETTE.yellow }}></div>
        <div style={{ background: PALETTE.lime }}></div>
        <div style={{ background: PALETTE.green }}></div>
        <div style={{ background: PALETTE.teal }}></div>
        <div style={{ background: PALETTE.blue }}></div>
        <div style={{ background: PALETTE.purple }}></div>
      </div>

      <div className="mx-auto w-full max-w-[1360px] px-5 md:px-10 pt-14 md:pt-16 pb-10 relative">
        {/* Compact brand row — utility, no duplicate of hero headline */}
        <div className="grid grid-cols-12 gap-y-8 gap-x-8 items-start">
          <div className="col-span-12 md:col-span-7">
            <img src="assets/mmix-logo.png" alt="Marketing MIX" style={{ height: 56, width: 'auto' }} className="select-none mb-5" />
            <p className="text-[15.5px] text-ink/75 leading-[1.6] max-w-[52ch]">
              International marketing studio. Built since 2014, across markets, crises, and categories. Started in Kyiv, operating from Ottawa, Berlin, and Paris.
            </p>
          </div>
          <div className="col-span-12 md:col-span-5 md:pl-8 md:text-right">
            <div className="num text-mute mb-2">Need a starting point?</div>
            <div className="flex flex-wrap md:justify-end gap-3">
              <button onClick={() => onNavigate('contact')} className="btn btn-bright btn-sq">Free AI audit →</button>
              <button onClick={() => onNavigate('contact')} className="btn btn-secondary btn-sq">Book a 30-min call →</button>
            </div>
          </div>
        </div>

        <div className="grid grid-cols-12 gap-y-10 gap-x-8 mt-14 pt-10 border-t-2 border-ink/15">
          <div className="col-span-6 md:col-span-3">
            <div className="num text-mute mb-5">Navigate</div>
            <ul className="space-y-2.5 text-[14.5px]">
              {['home','services','ai','industries','cases','about','insights','contact'].map(id => (
                <li key={id}><button onClick={() => onNavigate(id)} className="ed-link text-ink/85 hover:text-ink capitalize">{id==='ai'?'AI':id==='home'?'Work':id}</button></li>
              ))}
            </ul>
          </div>

          <div className="col-span-6 md:col-span-3">
            <div className="num text-mute mb-5">Services</div>
            <ul className="space-y-2.5 text-[14.5px]">
              <li><button onClick={() => onNavigate('services')} className="ed-link text-ink/85"><span className="inline-block w-2 h-2 mr-2" style={{background:PALETTE.blue}}></span>Build</button></li>
              <li><button onClick={() => onNavigate('services')} className="ed-link text-ink/85"><span className="inline-block w-2 h-2 mr-2" style={{background:PALETTE.red}}></span>Promote</button></li>
              <li><button onClick={() => onNavigate('ai')} className="ed-link text-ink/85"><span className="inline-block w-2 h-2 mr-2" style={{background:PALETTE.purple}}></span>AI Operations</button></li>
              <li><button onClick={() => onNavigate('services')} className="ed-link text-ink/85"><span className="inline-block w-2 h-2 mr-2" style={{background:PALETTE.green}}></span>Strategy</button></li>
            </ul>
          </div>

          <div className="col-span-6 md:col-span-3">
            <div className="num text-mute mb-5">Locations</div>
            <ul className="space-y-2.5 text-[14.5px] text-ink/85">
              <li>Ottawa<br/><span className="text-mute text-[13px]">208 Booth Street</span></li>
              <li>Kyiv</li>
              <li>Berlin</li>
              <li>Paris</li>
            </ul>
          </div>

          <div className="col-span-6 md:col-span-3">
            <div className="num text-mute mb-5">Trust</div>
            <ul className="space-y-2.5 text-[13px] text-ink/70 num">
              <li>DUNS<br/><span className="text-ink">68-606-2061</span></li>
              <li>NCAGE<br/><span className="text-ink">A3G3J</span></li>
            </ul>
          </div>
        </div>

        <div className="mt-12 pt-6 border-t-2 border-ink/15 flex flex-col md:flex-row md:items-end md:justify-between gap-4">
          <div>
            <div className="num text-mute">Made between</div>
            <div className="display text-[22px] md:text-[28px] mt-2 text-ink">
              <span style={{color:PALETTE.red}}>КИЇВ</span> &nbsp;/&nbsp; OTTAWA &nbsp;/&nbsp; BERLIN &nbsp;/&nbsp; PARIS
            </div>
          </div>
          <div className="num text-mute">© 2026 Marketing MIX · All rights reserved</div>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, {
  Reveal, Container, Mono, Eyebrow,
  Logo, Nav, Footer, PageHeader, CTABand, Breadcrumbs,
  PolygonAccent, PolygonScatter, HeroArt,
  useReveal, useScrolled, useClickOutside,
});
