// global-nav.jsx v2, Layer 1 (Mall / Global nav).
// Desktop: gradient bar + glass pill (≥1024px).
// Mobile (≤1023px): compact bar [≡ hamburger · UD logo · 繁]
//                   Hamburger opens full-screen drill-down takeover containing
//                   ONLY Layer 1 items (no shop-specific stuff, that lives in
//                   <ShopNav />'s own mobile row).

const GlobalNav = ({ activeShop = '', logoHref = (typeof window !== 'undefined' && window.UD_HOME) || '/' }) => {
  const [localeOpen, setLocaleOpen] = React.useState(false);
  const [mLocaleOpen, setMLocaleOpen] = React.useState(false);
  const [ddOpen, setDdOpen] = React.useState(null);
  const localeRef = React.useRef(null);
  const mLocaleRef = React.useRef(null);
  const ddRef = React.useRef(null);
  const ddCloseTimer = React.useRef(null);

  // Mobile state
  const [mobileOpen, setMobileOpen] = React.useState(false);
  const [navStack, setNavStack] = React.useState(['root']);
  const [mobileExpanded, setMobileExpanded] = React.useState(() => {
    // On a digital-solutions or company page, open that accordion by default.
    try {
      const norm = (p) => (p || '').replace(/[?#].*$/, '').replace(/\.html$/i, '').replace(/\/+$/, '').split('/').filter(Boolean).pop() || '';
      const cur = norm(typeof location !== 'undefined' ? location.pathname : '');
      if (!cur) return null;
      const inGroup = (arr) => Array.isArray(arr) && arr.some((it) => it && it.href && norm(it.href) === cur);
      if (typeof DIGITAL_DROPDOWN !== 'undefined' && inGroup(DIGITAL_DROPDOWN)) return 'digital';
      if (typeof COMPANY_DROPDOWN !== 'undefined' && inGroup(COMPANY_DROPDOWN)) return 'company';
    } catch (e) {}
    return null;
  });
  const pushPanel = (key) => setNavStack((s) => [...s, key]);
  const popPanel  = () => setNavStack((s) => s.length > 1 ? s.slice(0, -1) : s);
  const closeAll  = () => { setMobileOpen(false); setMobileExpanded(null); setTimeout(() => setNavStack(['root']), 300); };

  // Defer scroll-lock by one frame. On mobile Safari, toggling overflow:hidden
  // on the same tick as the fade triggers a URL-bar reflow that stutters the
  // opening animation.
  React.useEffect(() => {
    let raf;
    if (mobileOpen) {
      raf = requestAnimationFrame(() => { document.body.style.overflow = 'hidden'; });
    } else {
      document.body.style.overflow = '';
    }
    return () => {
      if (raf) cancelAnimationFrame(raf);
      document.body.style.overflow = '';
    };
  }, [mobileOpen]);

  const openDd = (k) => {
    if (ddCloseTimer.current) { clearTimeout(ddCloseTimer.current); ddCloseTimer.current = null; }
    setDdOpen(k);
  };
  const scheduleCloseDd = () => {
    if (ddCloseTimer.current) clearTimeout(ddCloseTimer.current);
    ddCloseTimer.current = setTimeout(() => setDdOpen(null), 220);
  };
  const cancelCloseDd = () => {
    if (ddCloseTimer.current) { clearTimeout(ddCloseTimer.current); ddCloseTimer.current = null; }
  };

  React.useEffect(() => {
    const onDoc = (e) => {
      if (localeRef.current && !localeRef.current.contains(e.target)) setLocaleOpen(false);
      if (mLocaleRef.current && !mLocaleRef.current.contains(e.target)) setMLocaleOpen(false);
      const inDd = e.target.closest && e.target.closest('.ud-l1-shops, .ud-l1-mall');
      if (!inDd) setDdOpen(null);
    };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, []);

  const currentLocale = LOCALES[0];

  // ──────────────── Desktop ────────────────
  // Dropdown payload lookup so NavLink can render its own DropdownSheet
  // anchored to the trigger element (was previously anchored to the whole
  // nav cluster which left the 580px Digital sheet crossing the entire
  // shops cluster). Per-trigger anchoring + an `anchor` direction handles
  // edge alignment when the centred sheet would clip the viewport.
  // Match a dropdown item's href to the current page, works for both flat
  // .html dev paths and clean deploy paths, so the active page is highlighted.
  const __ddActiveHref = (href) => {
    if (!href || href === '#') return false;
    try {
      const norm = (p) => (p || '').replace(/[?#].*$/, '').replace(/\.html$/i, '').replace(/\/+$/, '').split('/').filter(Boolean).pop() || '';
      const cur = norm(typeof location !== 'undefined' ? location.pathname : '');
      const tgt = norm(href);
      return !!tgt && cur === tgt;
    } catch (e) { return false; }
  };

  const DD_PAYLOADS = {
    digital: { eyebrow: '數碼方案 · 行業應用', items: DIGITAL_DROPDOWN, columns: 1 },
    company: { eyebrow: '公司 · 關於 UD',      items: COMPANY_DROPDOWN, columns: 1 },
  };

  // Flat nav style, dot · label · caret，active = 白色下劃線
  const NavLink = ({ item, anchor = 'center' }) => {
    const isActive = item.key.toLowerCase() === (activeShop || '').toLowerCase();
    const hasDD = !!item.dropdown;
    const isOpen = hasDD && ddOpen === item.dropdown;
    const [hover, setHover] = React.useState(false);
    const lit = isActive || hover || isOpen;
    const dd = hasDD ? DD_PAYLOADS[item.dropdown] : null;

    const link = (
      <a
        href={hasDD ? '#' : item.href}
        onMouseEnter={() => { setHover(true); if (hasDD) openDd(item.dropdown); }}
        onMouseLeave={() => setHover(false)}
        onClick={(e) => { if (hasDD) { e.preventDefault(); setDdOpen(isOpen ? null : item.dropdown); } }}
        style={{
          position: 'relative',
          display: 'inline-flex', alignItems: 'center', gap: 6,
          padding: '6px 0',
          fontSize: 13.5, fontWeight: isActive ? 600 : 500,
          color: lit ? '#ffffff' : 'rgba(255,255,255,0.88)',
          textDecoration: 'none', cursor: 'pointer',
          fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
          whiteSpace: 'nowrap', transition: 'color .15s',
        }}
      >
        {item.dot && (
          <span style={{
            width: 6, height: 6, borderRadius: 999, background: item.dot,
            flexShrink: 0,
          }}/>
        )}
        {item.label}
        {hasDD && (
          <svg width="9" height="9" viewBox="0 0 10 10" style={{
            opacity: 0.85,
            transform: isOpen ? 'rotate(180deg)' : 'rotate(0)',
            transition: 'transform .18s', flexShrink: 0,
          }}>
            <path d="M2 4l3 3 3-3" stroke="currentColor" strokeWidth="1.6" fill="none"
              strokeLinecap="round" strokeLinejoin="round" />
          </svg>
        )}
        {isActive && (
          <span style={{
            position: 'absolute', left: 0, right: 0, bottom: 0, height: 2,
            background: '#ffffff', borderRadius: 2,
          }}/>
        )}
      </a>
    );

    if (!hasDD) return link;

    // Wrap trigger + sheet in a position:relative span so the sheet
    // positions against the TRIGGER (not the nav cluster).
    return (
      <span
        style={{ position: 'relative', display: 'inline-flex', alignItems: 'center' }}
        onMouseEnter={() => openDd(item.dropdown)}
        onMouseLeave={scheduleCloseDd}
      >
        {link}
        <DropdownSheet
          kind={item.dropdown}
          eyebrow={dd.eyebrow}
          items={dd.items}
          columns={dd.columns}
          anchor={anchor}
        />
      </span>
    );
  };

  const DropdownSheet = ({ kind, items, eyebrow, columns, anchor = 'center' }) => {
    const open = ddOpen === kind;
    // anchor refers to which EDGE of the dropdown aligns with which edge of
    // the trigger (the parent <span> wrapping the link). center = centred
    // under the trigger; left = left edge under trigger left; right = right
    // edge under trigger right.
    const baseTransform = `translateY(${open ? 0 : -8}px)`;
    const posStyle = anchor === 'right'
      ? { right: 0, transform: baseTransform }
      : anchor === 'left'
        ? { left: 0, transform: baseTransform }
        : { left: '50%', transform: `translateX(-50%) ${baseTransform}` };
    return (
      <div
        onMouseEnter={cancelCloseDd}
        onMouseLeave={scheduleCloseDd}
        style={{
          position: 'absolute', top: 'calc(100% + 6px)',
          ...posStyle,
          paddingTop: 8,
          width: columns === 2 ? 520 : 260,
          opacity: open ? 1 : 0,
          pointerEvents: open ? 'auto' : 'none',
          transition: 'opacity .18s ease, transform .18s ease',
          zIndex: 200,
        }}
      >
        <div style={{
          background: '#1A1F4D',
          border: '1px solid rgba(255,255,255,0.10)',
          borderRadius: 14,
          boxShadow: '0 24px 56px rgba(0,0,0,0.45)',
          padding: 10,
        }}>
          <div style={{
            display: 'grid',
            gridTemplateColumns: columns === 2 ? 'repeat(2, 1fr)' : '1fr',
            gap: 2,
          }}>
            {items.map((it, i) => {
              const isCur = __ddActiveHref(it.href);
              return (
              <a key={i} href={it.href}
                target={it.ext ? '_blank' : undefined}
                rel={it.ext ? 'noopener noreferrer' : undefined}
                aria-current={isCur ? 'page' : undefined}
                style={{
                  display: 'flex', alignItems: 'center', gap: 6,
                  padding: '10px 12px', borderRadius: 8, cursor: 'pointer',
                  textDecoration: 'none', transition: 'background .12s',
                  background: isCur ? 'rgba(124,142,255,0.16)' : 'transparent',
                  boxShadow: isCur ? 'inset 2px 0 0 #A4B6FF' : 'none',
                }}
                onMouseEnter={(e) => { if (!isCur) e.currentTarget.style.background = 'rgba(255,255,255,0.06)'; }}
                onMouseLeave={(e) => { if (!isCur) e.currentTarget.style.background = 'transparent'; }}>
                <span style={{ fontSize: 13.5, fontWeight: isCur ? 700 : 500, color: isCur ? '#A4B6FF' : '#ffffff' }}>{it.title}</span>
                {it.ext && <span style={{ color: 'rgba(255,255,255,0.62)', fontSize: 11 }}>↗</span>}
              </a>
              );
            })}
          </div>
        </div>
      </div>
    );
  };

  // ──────────────── Mobile takeover (Layer 1 only) ────────────────
  const stackDepth = navStack.length - 1;
  const currentPanel = navStack[navStack.length - 1];

  const mobilePanels = {
    root: {
      title: '選單',
      sections: [
        {
          eyebrow: '解決方案',
          items: GLOBAL_SHOPS.map((s) => ({
            key: s.key, label: s.label, href: s.href, dot: s.dot,
            isCurrentShop: s.key.toLowerCase() === activeShop.toLowerCase(),
            drillTo: s.dropdown === 'digital' ? 'digital' : null,
          })),
        },
        {
          eyebrow: '資源與公司',
          items: GLOBAL_MALL.map((m) => ({
            key: m.key, label: m.label, href: m.href,
            drillTo: m.dropdown === 'company' ? 'company' : null,
          })),
        },
      ],
    },
    digital: { title: '數碼方案', eyebrow: '數碼方案 · 行業應用', items: DIGITAL_DROPDOWN },
    company: { title: '公司',     eyebrow: '公司 · 關於 UD',       items: COMPANY_DROPDOWN },
  };

  const RootPanel = () => (
    <div style={{ padding: '20px 24px 32px', display: 'flex', flexDirection: 'column', gap: 28 }}>
      {mobilePanels.root.sections.map((sec, si) => (
        <div key={si}>
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            {sec.items.map((it) => {
              const exp = it.drillTo && mobileExpanded === it.drillTo;
              return (
              <div key={it.key}>
              <button
                onClick={() => {
                  if (it.drillTo) setMobileExpanded(exp ? null : it.drillTo);
                  else window.location.href = it.href;
                }}
                style={{
                  width: '100%', textAlign: 'left',
                  display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                  padding: '18px 0',
                  borderBottom: '1px solid rgba(255,255,255,0.10)',
                  background: 'transparent', border: 'none', cursor: 'pointer',
                  color: it.isCurrentShop ? '#A4B6FF' : '#ffffff',
                  fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
                }}>
                <span style={{
                  display: 'inline-flex', alignItems: 'center', gap: 12,
                  fontSize: 20, fontWeight: it.isCurrentShop ? 700 : 500,
                  letterSpacing: -0.3,
                }}>
                  {it.dot && (
                    <span style={{
                      width: 8, height: 8, borderRadius: '50%', background: it.dot,
                      boxShadow: it.isCurrentShop ? `0 0 0 4px ${it.dot}33` : 'none',
                    }} />
                  )}
                  {it.label}
                  {it.isCurrentShop && (
                    <span style={{
                      fontFamily: "'Chakra Petch',sans-serif",
                      fontSize: 9.5, fontWeight: 700, letterSpacing: 1.4,
                      padding: '3px 7px', borderRadius: 4,
                      background: 'rgba(164,182,255,0.15)', color: '#A4B6FF',
                      marginLeft: 4,
                    }}>當前</span>
                  )}
                </span>
                <span style={{ color: 'rgba(255,255,255,0.45)', fontSize: 18, display: 'inline-block', transform: it.drillTo && exp ? 'rotate(180deg)' : 'none', transition: 'transform .2s ease' }}>
                  {it.drillTo ? '⌄' : '→'}
                </span>
              </button>
              {it.drillTo && exp && mobilePanels[it.drillTo] && (
                <div style={{ display: 'flex', flexDirection: 'column', padding: '2px 0 10px 14px' }}>
                  {mobilePanels[it.drillTo].items.map((sub, i) => {
                    const subCur = __ddActiveHref(sub.href);
                    return (
                    <a key={i} href={sub.href || '#'} target={sub.ext ? '_blank' : undefined} rel={sub.ext ? 'noopener noreferrer' : undefined}
                      aria-current={subCur ? 'page' : undefined}
                      style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '13px 10px', borderRadius: 8, borderBottom: '1px solid rgba(255,255,255,0.08)', textDecoration: 'none', color: subCur ? '#A4B6FF' : 'rgba(255,255,255,0.86)', background: subCur ? 'rgba(124,142,255,0.16)' : 'transparent', boxShadow: subCur ? 'inset 2px 0 0 #A4B6FF' : 'none', fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif", fontSize: 16, fontWeight: subCur ? 700 : 500 }}>
                      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>{sub.title}{sub.ext && <span style={{ color: 'rgba(255,255,255,0.5)', fontSize: 11 }}>↗</span>}</span>
                      <span style={{ color: 'rgba(255,255,255,0.4)', fontSize: 14 }}>→</span>
                    </a>
                    );
                  })}
                </div>
              )}
              </div>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );

  const SubPanel = ({ panel }) => (
    <div style={{ padding: '20px 24px 32px' }}>
      <h2 style={{
        margin: 0, padding: '0 0 16px',
        fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
        fontSize: 28, fontWeight: 700, color: '#ffffff', letterSpacing: -0.5,
      }}>{panel.title}</h2>
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        {panel.items.map((it, i) => {
          const itCur = __ddActiveHref(it.href);
          return (
          <a key={i} href={it.href || '#'}
            target={it.ext ? '_blank' : undefined}
            rel={it.ext ? 'noopener noreferrer' : undefined}
            aria-current={itCur ? 'page' : undefined}
            style={{
            display: 'flex', flexDirection: 'column', gap: 6,
            padding: '16px 10px', borderRadius: 8, borderBottom: '1px solid rgba(255,255,255,0.10)',
            textDecoration: 'none',
            background: itCur ? 'rgba(124,142,255,0.16)' : 'transparent',
            boxShadow: itCur ? 'inset 2px 0 0 #A4B6FF' : 'none',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
              <span style={{
                fontSize: 17, fontWeight: itCur ? 700 : 600, color: itCur ? '#A4B6FF' : '#ffffff',
                fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
                display: 'inline-flex', alignItems: 'center', gap: 6,
              }}>
                {it.title}
                {it.ext && <span style={{ color: 'rgba(255,255,255,0.55)', fontSize: 12 }}>↗</span>}
              </span>
              <span style={{ color: 'rgba(255,255,255,0.45)', fontSize: 16 }}>→</span>
            </div>
          </a>
          );
        })}
      </div>
    </div>
  );

  const subPanelData = currentPanel !== 'root' ? mobilePanels[currentPanel] : null;

  return (
    <React.Fragment>
      {/* ============ Desktop Layer 1 (≥1024px) ============ */}
      <header
        className="ud-l1"
        style={{
          position: 'relative', top: 0, left: 0, right: 0, zIndex: 101,
          background: 'linear-gradient(90deg, #332D79 0%, #2A3795 52%, #427192 100%)',
          borderBottom: '1px solid rgba(255,255,255,0.20)',
          color: '#ffffff',
        }}
      >
        <div className="ud-l1-inner" style={{
          maxWidth: 1280, margin: '0 auto', padding: '0 80px', height: 60,
          display: 'flex', alignItems: 'center', gap: 24,
        }}>
          <a href={logoHref} style={{
            display: 'inline-flex', alignItems: 'center',
            padding: '6px 0', textDecoration: 'none', flexShrink: 0,
          }} aria-label="UD">
            <img src={window.UD_LOGO || '/ud-logo-white.png'} alt="UD"
              style={{ height: 24, width: 'auto', display: 'block' }} />
          </a>

          {/* Shops, left aligned. 數碼方案 trigger sits at the right end of
              the shops cluster; the 580-wide sheet is anchored to its right
              edge so it expands left under the cluster without clipping the
              viewport's right side. */}
          <nav className="ud-l1-shops" style={{
            position: 'relative',
            display: 'inline-flex', alignItems: 'center', gap: 22, lineHeight: 1,
          }} onMouseLeave={scheduleCloseDd}>
            {GLOBAL_SHOPS.map((it) => (
              <NavLink
                key={it.key}
                item={it}
                anchor="center"
              />
            ))}
          </nav>

          {/* spacer */}
          <div style={{ flex: 1 }} />

          {/* Mall, right aligned. 公司 sits in the middle; centred sheet
              tucks neatly under the trigger. */}
          <nav className="ud-l1-mall" style={{
            position: 'relative',
            display: 'inline-flex', alignItems: 'center', gap: 22, lineHeight: 1,
          }} onMouseLeave={scheduleCloseDd}>
            {GLOBAL_MALL.map((it) => <NavLink key={it.key} item={it} anchor="center" />)}
          </nav>

          <div className="ud-l1-right" style={{
            display: 'flex', alignItems: 'center', gap: 14, flexShrink: 0,
          }}>
            <span aria-hidden="true" style={{
              width: 1, height: 14, background: 'rgba(255,255,255,0.28)', flexShrink: 0,
            }} />
            <a href="https://ud.hk/login" style={{
              fontSize: 13.5, fontWeight: 500, color: 'rgba(255,255,255,0.85)',
              textDecoration: 'none',
              fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
            }}>登入</a>
            <span aria-hidden="true" style={{
              width: 1, height: 14, background: 'rgba(255,255,255,0.28)',
            }} />
            <div ref={localeRef} style={{ position: 'relative' }}>
              <button onClick={() => setLocaleOpen((v) => !v)} style={{
                display: 'inline-flex', alignItems: 'center', gap: 4,
                background: 'transparent', border: 'none', padding: 0,
                color: '#ffffff', cursor: 'pointer',
                fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
                fontSize: 13.5, fontWeight: 600,
              }}>
                <span>{currentLocale.short}</span>
                <svg width="9" height="9" viewBox="0 0 10 10" style={{
                  opacity: 0.85,
                  transform: localeOpen ? 'rotate(180deg)' : 'rotate(0)',
                  transition: 'transform .18s',
                }}>
                  <path d="M2 4l3 3 3-3" stroke="currentColor" strokeWidth="1.6" fill="none"
                    strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </button>
              {localeOpen && (
                <ul style={{
                  position: 'absolute', top: 'calc(100% + 10px)', right: 0,
                  minWidth: 160, background: '#ffffff',
                  border: '1px solid rgba(15,23,42,0.08)', borderRadius: 12,
                  boxShadow: '0 20px 48px rgba(15,23,42,0.18)',
                  padding: 6, margin: 0, listStyle: 'none', zIndex: 200,
                }}>
                  {LOCALES.map((l) => (
                    <li key={l.code}>
                      <button onClick={() => { setLocaleOpen(false); if (l.code !== currentLocale.code) (window.__udLocaleHref && (window.location.href = window.__udLocaleHref(l.code))); }} style={{
                        width: '100%', textAlign: 'left', padding: '10px 12px', borderRadius: 8,
                        background: l.code === currentLocale.code ? 'rgba(42,55,149,0.06)' : 'transparent',
                        border: 'none', cursor: 'pointer', color: '#0f172a', fontSize: 13.5,
                        fontWeight: l.code === currentLocale.code ? 600 : 500,
                        fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
                        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                      }}>
                        <span>{l.label}</span>
                      </button>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          </div>
        </div>
      </header>

      {/* ============ Mobile Layer 1 compact bar (≤1023px) ============ */}
      <header
        className="ud-l1-mobile"
        style={{
          display: 'none',
          position: 'relative', top: 0, left: 0, right: 0, zIndex: 101,
          background: 'linear-gradient(90deg, #332D79 0%, #2A3795 52%, #427192 100%)',
          borderBottom: '1px solid rgba(255,255,255,0.10)',
          color: '#ffffff',
        }}
      >
        <div className="ud-l1-mobile-bar" style={{
          padding: '0 32px', height: 56,
          display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
        }}>
          <a href={logoHref} style={{
            display: 'inline-flex', alignItems: 'center', padding: '6px 0',
            textDecoration: 'none', flexShrink: 0,
          }}>
            <img src={window.UD_LOGO || '/ud-logo-white.png'} alt="UD" style={{ height: 24, display: 'block' }} />
          </a>

          <button onClick={() => setMobileOpen(true)} aria-label="開啟選單" style={{
            width: 40, height: 40, borderRadius: 10,
            background: 'rgba(255,255,255,0.08)',
            border: '1px solid rgba(255,255,255,0.18)',
            cursor: 'pointer', color: '#ffffff', padding: 0,
            display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
          }}>
            <svg width="18" height="14" viewBox="0 0 18 14" fill="none">
              <path d="M1 1h16M1 7h16M1 13h16" stroke="currentColor"
                strokeWidth="1.8" strokeLinecap="round" />
            </svg>
          </button>
        </div>
      </header>

      {/* ============ Mobile takeover (Layer 1 drill-down) ============ */}
      {/* GPU-promote the takeover with translate3d + will-change so the radial
         glow and gradient composite on their own layer instead of repainting
         every frame. visibility:hidden when closed stops those layers being
         painted at all until the user opens the menu. */}
      <div
        style={{
          position: 'fixed', top: 0, left: 0, right: 0, bottom: 0,
          zIndex: 300, color: '#ffffff',
          background: 'linear-gradient(180deg, #1A1F4D 0%, #0F0A18 100%)',
          opacity: mobileOpen ? 1 : 0,
          visibility: mobileOpen ? 'visible' : 'hidden',
          pointerEvents: mobileOpen ? 'auto' : 'none',
          transform: 'translate3d(0,0,0)',
          willChange: 'opacity, transform',
          transition: mobileOpen
            ? 'opacity .25s ease, visibility 0s linear 0s'
            : 'opacity .25s ease, visibility 0s linear .25s',
          display: 'flex', flexDirection: 'column',
        }}
        aria-hidden={!mobileOpen}
      >
        {/* Glow */}
        <div style={{
          position: 'absolute', top: 0, left: 0, right: 0, height: 320,
          background: 'radial-gradient(80% 100% at 50% 0%, rgba(124,142,255,0.20), transparent 70%)',
          pointerEvents: 'none',
        }} />

        {/* Top bar, pixel-aligned to the compact bar so opening the menu
            reads as the surrounding chrome filling in, not the logo jumping.
            Matches: 56px height, 32px horiz padding (20px ≤640px), logo 24px,
            right-side 40×40 button in the same position. */}
        <div className="ud-l1-takeover-bar" style={{
          position: 'relative', zIndex: 2,
          padding: '0 32px', height: 56,
          display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
          borderBottom: '1px solid rgba(255,255,255,0.10)',
          flexShrink: 0,
        }}>
          {stackDepth === 0 ? (
            <a href={logoHref} style={{
              display: 'inline-flex', alignItems: 'center', padding: '6px 0',
              textDecoration: 'none', flexShrink: 0,
            }}>
              <img src={window.UD_LOGO || '/ud-logo-white.png'} alt="UD" style={{ height: 24, display: 'block' }} />
            </a>
          ) : (
            <button onClick={popPanel} style={{
              display: 'inline-flex', alignItems: 'center', gap: 8,
              padding: '8px 10px 8px 6px', borderRadius: 8,
              background: 'transparent', border: 'none', cursor: 'pointer',
              color: '#ffffff',
              fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
              fontSize: 14, fontWeight: 500,
            }}>
              <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
                <path d="M12 4l-6 6 6 6" stroke="currentColor" strokeWidth="1.8"
                  fill="none" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
              <span>返回</span>
            </button>
          )}
          <button onClick={closeAll} aria-label="關閉" style={{
            width: 40, height: 40, borderRadius: 10,
            background: 'rgba(255,255,255,0.08)',
            border: '1px solid rgba(255,255,255,0.16)',
            cursor: 'pointer', color: '#ffffff', padding: 0,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
              <path d="M3 3l10 10M13 3l-10 10" stroke="currentColor"
                strokeWidth="1.8" strokeLinecap="round" />
            </svg>
          </button>
        </div>

        {/* Panel carousel, promote to its own GPU layer so the slide between
            root/sub panels doesn't repaint the takeover gradient each frame. */}
        <div style={{ position: 'relative', flex: 1, overflow: 'hidden' }}>
          <div style={{
            display: 'flex', width: '200%', height: '100%',
            transform: `translate3d(${-stackDepth * 50}%, 0, 0)`,
            transition: 'transform .35s cubic-bezier(.4,0,.2,1)',
            willChange: 'transform',
          }}>
            <div style={{ width: '50%', height: '100%', overflowY: 'auto' }}>
              <RootPanel />
            </div>
            <div style={{ width: '50%', height: '100%', overflowY: 'auto' }}>
              {subPanelData && <SubPanel panel={subPanelData} />}
            </div>
          </div>
        </div>

        {/* Bottom utility */}
        <div style={{
          padding: '14px 16px 20px',
          borderTop: '1px solid rgba(255,255,255,0.10)',
          background: 'rgba(0,0,0,0.25)',
          flexShrink: 0,
          display: 'flex', gap: 10,
        }}>
          <a href="https://ud.hk/login" style={{
            flex: 1, textAlign: 'center', padding: '12px 14px', borderRadius: 10,
            background: 'rgba(255,255,255,0.06)',
            border: '1px solid rgba(255,255,255,0.16)',
            fontSize: 13.5, fontWeight: 500, color: '#ffffff', textDecoration: 'none',
            fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
          }}>登入</a>
          <div ref={mLocaleRef} style={{ flex: 1, position: 'relative' }}>
            <button onClick={() => setMLocaleOpen((v) => !v)} aria-haspopup="true" aria-expanded={mLocaleOpen} style={{
              width: '100%', padding: '12px 14px', borderRadius: 10,
              background: 'rgba(255,255,255,0.06)',
              border: '1px solid rgba(255,255,255,0.16)',
              color: '#ffffff', cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
              fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
              fontSize: 13.5, fontWeight: 500,
            }}>
              <svg width="14" height="14" viewBox="0 0 20 20" fill="none">
                <circle cx="10" cy="10" r="8" stroke="currentColor" strokeWidth="1.5" />
                <path d="M2 10 H18 M10 2 C13 5 13 15 10 18 M10 2 C7 5 7 15 10 18"
                  stroke="currentColor" strokeWidth="1.5" fill="none" />
              </svg>
              <span>{currentLocale.label}</span>
              <svg width="9" height="9" viewBox="0 0 10 10" style={{ opacity: 0.85, transform: mLocaleOpen ? 'rotate(180deg)' : 'rotate(0)', transition: 'transform .18s' }}>
                <path d="M2 4l3 3 3-3" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </button>
            {mLocaleOpen && (
              <ul style={{
                position: 'absolute', bottom: 'calc(100% + 8px)', left: 0, right: 0,
                background: '#ffffff',
                border: '1px solid rgba(15,23,42,0.08)', borderRadius: 12,
                boxShadow: '0 -18px 48px rgba(0,0,0,0.4)',
                padding: 6, margin: 0, listStyle: 'none', zIndex: 320,
              }}>
                {LOCALES.map((l) => {
                  const cur = l.code === currentLocale.code;
                  return (
                    <li key={l.code}>
                      <button onClick={() => { setMLocaleOpen(false); if (l.code !== currentLocale.code) (window.__udLocaleHref && (window.location.href = window.__udLocaleHref(l.code))); }}
                        aria-current={cur ? 'true' : undefined} style={{
                          width: '100%', textAlign: 'left', padding: '11px 12px', borderRadius: 8,
                          background: cur ? 'rgba(42,55,149,0.08)' : 'transparent',
                          border: 'none', cursor: 'pointer', color: '#0f172a', fontSize: 13.5,
                          fontWeight: cur ? 600 : 500,
                          fontFamily: "'Noto Sans HK','Noto Sans TC',sans-serif",
                        }}>{l.label}</button>
                    </li>
                  );
                })}
              </ul>
            )}
          </div>
        </div>
      </div>

      <style>{`
        @media (max-width: 1024px) {
          .ud-l1 .ud-l1-inner { padding: 0 56px !important; }
        }
        @media (max-width: 1180px) {
          .ud-l1 .ud-l1-center { gap: 16px !important; }
          .ud-l1 .ud-l1-center a { font-size: 13px !important; }
        }
        @media (max-width: 1023px) {
          .ud-l1 { display: none !important; }
          .ud-l1-mobile { display: block !important; }
          .ud-l1-mobile-bar, .ud-l1-takeover-bar { padding: 0 48px !important; }
        }
        @media (max-width: 980px) {
          .ud-l1-mobile-bar, .ud-l1-takeover-bar { padding: 0 32px !important; }
        }
        @media (max-width: 640px) {
          .ud-l1-mobile-bar { padding: 0 20px !important; }
          .ud-l1-takeover-bar { padding: 0 20px !important; }
        }
      `}</style>
    </React.Fragment>
  );
};

window.GlobalNav = GlobalNav;
