// Client Portal shell — login gate + simplified sidebar + topbar.
// Pages register into window.CP_PAGES = { id: { title, render } }.
// Client data lives in window.CP_CLIENT, password in window.CP_CONFIG.

if (typeof document !== 'undefined' && !document.getElementById('hk-shell-css')) {
  const s = document.createElement('style');
  s.id = 'hk-shell-css';
  s.textContent = `
    .hk-shell { display: grid; grid-template-columns: var(--sidebar-w) 1fr; height: 100vh; height: 100dvh; background: var(--paper); }
    .hk-sidebar {
      display: flex; flex-direction: column;
      border-right: 1px solid var(--border);
      background: var(--paper);
      padding: 14px 12px;
      gap: 4px;
      overflow-y: auto;
    }
    .hk-side-section { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em;
      text-transform: uppercase; color: var(--ink-3); padding: 14px 10px 6px; }
    .hk-nav {
      display: flex; align-items: center; gap: 10px;
      padding: 7px 10px; border-radius: var(--r-2);
      font-size: 13.5px; color: var(--ink-2); cursor: pointer;
      transition: background .12s, color .12s;
      position: relative;
    }
    .hk-nav:hover { background: var(--surface-3); color: var(--ink); }
    .hk-nav[aria-current="page"] {
      background: var(--surface);
      color: var(--ink);
      box-shadow: 0 0 0 1px var(--border) inset, var(--shadow-1);
    }
    .hk-nav[aria-current="page"] .hk-nav-icon { color: var(--accent); }
    .hk-nav-icon { color: var(--ink-3); display: flex; align-items: center; }
    .hk-nav-label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

    .hk-account {
      display: flex; align-items: center; gap: 10px;
      padding: 8px 10px; border-radius: var(--r-3);
      background: var(--surface); border: 1px solid var(--border);
      box-shadow: var(--shadow-1);
      margin: 8px 0 2px;
    }

    .hk-topbar {
      height: var(--topbar-h);
      display: flex; align-items: center; gap: 10px;
      padding: 0 24px;
      border-bottom: 1px solid var(--border);
      background: color-mix(in srgb, var(--paper) 88%, transparent);
      backdrop-filter: blur(10px);
      position: sticky; top: 0; z-index: 20;
    }

    .hk-page { display: flex; flex-direction: column; min-width: 0; min-height: 0; height: 100vh; height: 100dvh; }
    .hk-page-body { flex: 1; min-height: 0; overflow: auto; padding: 24px 32px 64px; }
    .hk-page-inner { max-width: var(--content-max); margin: 0 auto; }

    .hk-bread { display: flex; align-items: center; gap: 6px; font-size: 13.5px; color: var(--ink-2); white-space: nowrap; min-width: 0; }
    .hk-bread .sep { color: var(--ink-4); }
    .hk-bread .cur { color: var(--ink); font-weight: 500; overflow: hidden; text-overflow: ellipsis; }

    .hk-side-divider { height: 1px; background: var(--border); margin: 10px 4px 6px; }

    /* ── Collapsible nav group ────────────────────── */
    .hk-nav-grp-hdr {
      display: flex; align-items: center; gap: 9px;
      padding: 6px 10px; border-radius: var(--r-2);
      font-size: 10.5px; font-family: var(--font-mono);
      letter-spacing: 0.08em; text-transform: uppercase;
      color: var(--ink-3); cursor: pointer;
      transition: background .12s, color .12s;
      user-select: none; margin-top: 10px;
    }
    .hk-nav-grp-hdr:hover { background: var(--surface-3); color: var(--ink-2); }
    .hk-nav-grp-lbl { flex: 1; }
    .hk-nav-grp-body {
      padding-left: 8px;
      border-left: 1.5px solid var(--border);
      margin-left: 17px;
      display: flex; flex-direction: column; gap: 1px;
      margin-bottom: 2px;
    }

    /* burger + mobile */
    .hk-burger { display: none; }
    .hk-mobile-scrim { display: none; }

    @media (max-width: 1024px) {
      :root { --topbar-h: 52px; }
      .hk-shell { grid-template-columns: 1fr; }
      .hk-sidebar {
        position: fixed; top: 0; left: 0; bottom: 0;
        width: 280px; max-width: 86vw;
        z-index: 60;
        transform: translateX(-100%);
        transition: transform .25s cubic-bezier(.2, .8, .25, 1);
        box-shadow: var(--shadow-pop);
      }
      .hk-sidebar.open { transform: translateX(0); }
      .hk-mobile-scrim {
        display: block; position: fixed; inset: 0; background: rgba(0,0,0,0.36);
        z-index: 55; opacity: 0; pointer-events: none; transition: opacity .2s;
      }
      .hk-mobile-scrim.open { opacity: 1; pointer-events: auto; }
      .hk-burger {
        display: inline-flex; align-items: center; justify-content: center;
        width: 36px; height: 36px; border-radius: 10px;
        background: transparent; color: var(--ink); cursor: pointer; flex-shrink: 0;
        border: 0;
      }
      .hk-burger:hover { background: var(--surface-3); }
      .hk-topbar { padding: 0 12px; gap: 8px; }
      .hk-page-body { padding: 16px 14px 48px; }
      .hk-bread { font-size: 14px; flex: 1; }
      .hk-page-inner { max-width: 100%; }
    }

    @media (min-width: 1025px) {
      .hk-burger, .hk-mobile-scrim { display: none !important; }
    }

    @media (max-width: 1180px) and (min-width: 1025px) {
      .hk-page-body { padding: 20px 22px 64px; }
      :root { --sidebar-w: 220px; }
    }

    /* ── Login gate — matches hikit.studio/sign-in exactly ─────────────────── */
    .cp-gate {
      min-height: 100dvh; display: flex;
      background: #0A0A0A; overflow: hidden;
    }
    /* Left brand panel */
    .cp-gate-left {
      display: none; flex-direction: column;
      position: relative; overflow: hidden; flex: 0 0 50%;
    }
    @media (min-width: 1024px) { .cp-gate-left { display: flex; } }
    .cp-gate-canvas { position: absolute; inset: 0; z-index: 0; pointer-events: none; width:100%; height:100%; }
    .cp-gate-glow {
      position: absolute; inset: 0; z-index: 1; pointer-events: none;
      background: radial-gradient(ellipse 70% 60% at 50% 40%, rgba(0,255,148,0.08) 0%, transparent 70%);
    }
    .cp-gate-dark {
      position: absolute; inset: 0; z-index: 2; pointer-events: none;
      background: rgba(10,10,10,0.7);
    }
    .cp-gate-left-content {
      position: relative; z-index: 3;
      display: flex; flex-direction: column; height: 100%; padding: 48px;
    }
    /* Right form panel */
    .cp-gate-right {
      flex: 1; display: flex; align-items: center; justify-content: center;
      padding: 80px 24px 40px; position: relative;
    }
    .cp-mobile-logo {
      position: absolute; top: 24px; left: 24px;
      display: flex; align-items: center; gap: 9px;
    }
    @media (min-width: 1024px) { .cp-mobile-logo { display: none !important; } }
    /* Glass card */
    .cp-glass-card {
      width: 100%; max-width: 420px;
      background: rgba(255,255,255,0.03);
      border: 1px solid rgba(255,255,255,0.08);
      border-radius: 16px;
      backdrop-filter: blur(20px);
      -webkit-backdrop-filter: blur(20px);
      padding: 32px;
    }
    /* Field label */
    .cp-field-label {
      display: block; margin-bottom: 8px;
      font-family: var(--font-mono); font-size: 10px;
      text-transform: uppercase; letter-spacing: 0.12em; color: #444444;
    }
    /* Input */
    .cp-field-input {
      width: 100%; box-sizing: border-box; height: 44px;
      padding: 0 16px; font-size: 14px; color: #fff; font-family: inherit;
      outline: none;
      background: rgba(255,255,255,0.04);
      border: 1px solid rgba(255,255,255,0.08);
      border-radius: 8px;
      backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
      transition: border-color .2s, box-shadow .2s;
    }
    .cp-field-input::placeholder { color: #2a2a2a; }
    .cp-field-input:focus {
      border-color: rgba(0,255,148,0.4);
      box-shadow: 0 0 0 3px rgba(0,255,148,0.08);
    }
    .cp-pw-wrap { position: relative; }
    .cp-pw-toggle {
      position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
      background: none; border: none; cursor: pointer; padding: 4px;
      color: #444444; transition: color .2s;
      display: flex; align-items: center; justify-content: center;
    }
    .cp-pw-toggle:hover { color: #fff; }
    /* Submit button */
    .cp-submit-btn {
      width: 100%; height: 44px; box-sizing: border-box;
      display: flex; align-items: center; justify-content: center; gap: 8px;
      background: #fff; color: #000;
      font-size: 14px; font-weight: 600; font-family: inherit;
      border: none; border-radius: 8px; cursor: pointer;
      transition: background .15s, transform .1s; letter-spacing: 0.01em;
    }
    .cp-submit-btn:hover { background: rgba(255,255,255,0.88); }
    .cp-submit-btn:active { transform: scale(0.99); }
    .cp-gate-err {
      font-size: 12px; color: rgba(255,100,100,0.9);
      margin: 0; text-align: center; font-family: var(--font-mono);
    }
    @keyframes cp-shake {
      0%,100% { transform: translateX(0); }
      20%,60%  { transform: translateX(-6px); }
      40%,80%  { transform: translateX(6px); }
    }
    .cp-glass-card.shake { animation: cp-shake .36s ease; }
  `;
  document.head.appendChild(s);
}

const CP_PAGES = window.CP_PAGES = window.CP_PAGES || {};

function useHashRoute(initial) {
  const [hash, setHash] = React.useState(() => location.hash.slice(1) || initial);
  React.useEffect(() => {
    const onHash = () => setHash(location.hash.slice(1) || initial);
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, [initial]);
  const go = React.useCallback((to) => { location.hash = '#' + to; }, []);
  return [hash, go];
}

// ── Login Gate ───────────────────────────────────────────────────────────────

function HiKitMark({ size = 26 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 32 32" style={{ flexShrink:0 }}>
      <rect x="1.5" y="1.5" width="29" height="29" rx="7" fill="#0B121A"/>
      <path d="M9 8.5 V 23.5 M 9 16 H 17.5 M 17.5 8.5 V 23.5" stroke="#fff" strokeWidth="2.4" strokeLinecap="round" fill="none"/>
      <circle cx="23.5" cy="9" r="2.4" fill="#0FBDB0"/>
    </svg>
  );
}

function EyeIcon({ off }) {
  return off
    ? <svg width={16} height={16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
    : <svg width={16} height={16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>;
}

function LockIcon() {
  return (
    <svg width={14} height={14} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
      <path d="M7 11V7a5 5 0 0 1 10 0v4"/>
    </svg>
  );
}

function LoginGate({ onAuth }) {
  const [email, setEmail]     = React.useState('');
  const [pw, setPw]           = React.useState('');
  const [showPw, setShowPw]   = React.useState(false);
  const [err, setErr]         = React.useState(false);
  const [shaking, setShaking] = React.useState(false);
  const canvasRef             = React.useRef(null);

  // Colored dot canvas — mirrors CanvasRevealEffect (mint + blue)
  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const GRID = 28, DOT = 2;
    const COLORS = ['0,255,148', '0,102,255'];
    let w, h, dots, startTime, frame;

    function init() {
      const rect = canvas.parentElement.getBoundingClientRect();
      w = canvas.width  = rect.width  || window.innerWidth / 2;
      h = canvas.height = rect.height || window.innerHeight;
      startTime = performance.now();
      const cols = Math.ceil(w / GRID) + 1;
      const rows = Math.ceil(h / GRID) + 1;
      const cx = cols / 2, cy = rows / 2;
      dots = [];
      for (let r = 0; r < rows; r++) {
        for (let c = 0; c < cols; c++) {
          const dist = Math.hypot(c - cx, r - cy);
          dots.push({
            x: c * GRID, y: r * GRID,
            delay:    dist * 0.04 + Math.random() * 0.2,
            maxAlpha: 0.05 + Math.random() * 0.12,
            color:    COLORS[Math.floor(Math.random() * 2)],
          });
        }
      }
    }

    function animate(now) {
      ctx.clearRect(0, 0, w, h);
      const t = (now - startTime) / 1000 * 0.5;
      for (const d of dots) {
        const progress = Math.max(0, t - d.delay);
        const alpha = Math.min(d.maxAlpha, progress * d.maxAlpha * 8);
        if (alpha < 0.005) continue;
        ctx.fillStyle = `rgba(${d.color},${alpha})`;
        ctx.beginPath();
        ctx.arc(d.x, d.y, DOT, 0, Math.PI * 2);
        ctx.fill();
      }
      frame = requestAnimationFrame(animate);
    }

    init();
    frame = requestAnimationFrame(animate);
    const onResize = () => { cancelAnimationFrame(frame); init(); frame = requestAnimationFrame(animate); };
    window.addEventListener('resize', onResize);
    return () => { cancelAnimationFrame(frame); window.removeEventListener('resize', onResize); };
  }, []);

  const submit = (e) => {
    e.preventDefault();
    const correct = window.CP_CONFIG?.password || 'hikit2026';
    if (pw === correct) {
      document.cookie = `hk_cp=1; max-age=${7 * 86400}; path=/; SameSite=Strict`;
      onAuth();
    } else {
      setErr(true);
      setShaking(true);
      setTimeout(() => setShaking(false), 400);
    }
  };

  return (
    <div className="cp-gate">

      {/* ── Left brand panel ── */}
      <div className="cp-gate-left">
        <canvas ref={canvasRef} className="cp-gate-canvas"/>
        <div className="cp-gate-glow"/>
        <div className="cp-gate-dark"/>
        <div className="cp-gate-left-content">
          <a href="https://hikit.studio" style={{ display:'inline-flex', alignItems:'center', gap:9, textDecoration:'none', flexShrink:0 }}>
            <HiKitMark size={28}/>
            <span style={{ color:'#fff', fontWeight:600, fontSize:17, letterSpacing:-0.3 }}>HiKit</span>
          </a>
          <div style={{ flex:1, display:'flex', flexDirection:'column', justifyContent:'center', marginTop:64 }}>
            <h1 style={{ fontFamily:'var(--font-display)', fontSize:'clamp(42px,4.5vw,60px)', fontWeight:700, letterSpacing:'-0.03em', textTransform:'uppercase', color:'#fff', margin:'0 0 16px', lineHeight:1.05 }}>
              Welcome back.
            </h1>
            <p style={{ color:'#999999', fontSize:18, lineHeight:1.6, maxWidth:320, margin:0, fontWeight:300 }}>
              Sign in to your HiKit Studio client portal to access your projects, reports, and automations.
            </p>
          </div>
          <p style={{ fontFamily:'var(--font-mono)', fontSize:11, color:'#444444', margin:0 }}>
            © 2026 HiKit Studio. Client portal.
          </p>
        </div>
      </div>

      {/* ── Right form panel ── */}
      <div className="cp-gate-right">
        <div className="cp-mobile-logo">
          <HiKitMark size={24}/>
          <span style={{ color:'#fff', fontWeight:600, fontSize:15, letterSpacing:-0.3 }}>HiKit</span>
        </div>

        <div className={`cp-glass-card${shaking ? ' shake' : ''}`}>
          <div style={{ marginBottom:24 }}>
            <h2 style={{ fontFamily:'var(--font-display)', fontSize:20, fontWeight:700, textTransform:'uppercase', color:'#fff', margin:'0 0 4px', letterSpacing:'-0.01em' }}>Sign In</h2>
            <p style={{ color:'#444444', fontSize:13, margin:0, fontFamily:'var(--font-mono)' }}>Access your client portal</p>
          </div>

          <form onSubmit={submit} style={{ display:'flex', flexDirection:'column', gap:16 }}>
            <div>
              <label className="cp-field-label">Email</label>
              <input
                className="cp-field-input"
                type="email"
                placeholder="you@company.com"
                value={email}
                onChange={e => setEmail(e.target.value)}
                autoComplete="email"
              />
            </div>

            <div>
              <label className="cp-field-label">Password</label>
              <div className="cp-pw-wrap">
                <input
                  className="cp-field-input"
                  type={showPw ? 'text' : 'password'}
                  placeholder="••••••••"
                  value={pw}
                  onChange={e => { setPw(e.target.value); setErr(false); }}
                  autoFocus
                  autoComplete="current-password"
                  style={{ paddingRight:42 }}
                />
                <button type="button" className="cp-pw-toggle" onClick={() => setShowPw(v => !v)} aria-label={showPw ? 'Hide password' : 'Show password'}>
                  <EyeIcon off={showPw}/>
                </button>
              </div>
            </div>

            <div style={{ display:'flex', justifyContent:'flex-end', marginTop:-4 }}>
              <a href="https://hikit.studio/#contact"
                style={{ fontFamily:'var(--font-mono)', fontSize:11, color:'#444444', textDecoration:'none', transition:'color .2s' }}
                onMouseEnter={e => e.currentTarget.style.color='#999'}
                onMouseLeave={e => e.currentTarget.style.color='#444444'}>
                Forgot password?
              </a>
            </div>

            {err && <p className="cp-gate-err">Incorrect password — try again</p>}

            <button className="cp-submit-btn" type="submit">
              <LockIcon/>
              Sign In
            </button>
          </form>

          <p style={{ marginTop:24, textAlign:'center', fontFamily:'var(--font-mono)', fontSize:11, color:'#444444', margin:'24px 0 0' }}>
            Don't have an account?{' '}
            <a href="https://hikit.studio/#contact"
              style={{ color:'#999999', textDecoration:'none', transition:'color .2s' }}
              onMouseEnter={e => e.currentTarget.style.color='#00FF94'}
              onMouseLeave={e => e.currentTarget.style.color='#999999'}>
              Contact us
            </a>
          </p>
          <p style={{ marginTop:8, textAlign:'center', fontFamily:'var(--font-mono)', fontSize:10, color:'#2A2A2A' }}>
            This portal is for existing HiKit Studio clients only.
          </p>
        </div>
      </div>
    </div>
  );
}

// ── Sidebar ──────────────────────────────────────────────────────────────────

function NavItem({ id, icon, label, currentId, onGo }) {
  return (
    <div className="hk-nav" aria-current={currentId === id ? 'page' : undefined} onClick={() => onGo(id)}>
      <span className="hk-nav-icon"><Icon name={icon} size={17} /></span>
      <span className="hk-nav-label">{label}</span>
    </div>
  );
}

function NavGroup({ icon, label, currentId, children, defaultOpen = true }) {
  const childIds = React.Children.toArray(children).map(c => c?.props?.id).filter(Boolean);
  const hasActive = childIds.includes(currentId);
  const [open, setOpen] = React.useState(defaultOpen || hasActive);
  React.useEffect(() => { if (hasActive) setOpen(true); }, [currentId]);
  return (
    <div>
      <div className="hk-nav-grp-hdr" onClick={() => setOpen(o => !o)}>
        <span className="hk-nav-icon"><Icon name={icon} size={15}/></span>
        <span className="hk-nav-grp-lbl">{label}</span>
        <Icon name="chev" size={11} style={{ color:'var(--ink-4)', transform:open?'rotate(180deg)':'none', transition:'transform .2s', flexShrink:0 }}/>
      </div>
      {open && <div className="hk-nav-grp-body">{children}</div>}
    </div>
  );
}

function Sidebar({ currentId, onGo, onTheme, theme, mobileOpen, onCloseMobile }) {
  const client = window.CP_CLIENT || {};
  const goAndClose = (id) => { onGo(id); onCloseMobile && onCloseMobile(); };

  return (
    <aside className={`hk-sidebar${mobileOpen ? ' open' : ''}`}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '4px 6px' }}>
        <Wordmark size={18} />
        <div style={{ display: 'flex', gap: 2 }}>
          <Btn iconOnly variant="ghost" size="sm" icon={theme === 'dark' ? 'sun' : 'moon'}
            title={theme === 'dark' ? 'Switch to light' : 'Switch to dark'} onClick={onTheme}/>
          {mobileOpen && (
            <Btn iconOnly variant="ghost" size="sm" icon="close" title="Close menu" onClick={onCloseMobile}/>
          )}
        </div>
      </div>

      <div className="hk-account">
        <Avatar name={client.name || 'Client'} size={26}/>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="hk-h4" style={{ fontSize: 13 }}>{client.name || 'Client'}</div>
          <div className="hk-tiny" style={{ marginTop: 1 }}>{client.plan || 'HiKit Portal'}</div>
        </div>
      </div>

      <NavGroup icon="seo" label="SEO" currentId={currentId}>
        <NavItem id="overview"   icon="dashboard" label="Dashboard"        currentId={currentId} onGo={goAndClose}/>
        <NavItem id="authority"  icon="star"      label="Domain Authority" currentId={currentId} onGo={goAndClose}/>
        <NavItem id="keywords"   icon="hash"      label="Keywords"         currentId={currentId} onGo={goAndClose}/>
        <NavItem id="backlinks"  icon="link"      label="Backlink Profile" currentId={currentId} onGo={goAndClose}/>
        <NavItem id="local"      icon="pin"       label="Local SEO"        currentId={currentId} onGo={goAndClose}/>
        <NavItem id="audit"      icon="report"    label="Full Report"      currentId={currentId} onGo={goAndClose}/>
        <NavItem id="blog"       icon="trending"  label="Blog Analytics"   currentId={currentId} onGo={goAndClose}/>
        <NavItem id="ai-content" icon="ai"        label="AI Content"       currentId={currentId} onGo={goAndClose}/>
        <NavItem id="links"      icon="globe"     label="Site Links"       currentId={currentId} onGo={goAndClose}/>
      </NavGroup>

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

      <div className="hk-side-divider"/>
      <a className="hk-nav" href="https://hikit.studio" target="_blank" rel="noopener">
        <span className="hk-nav-icon"><Icon name="external" size={17}/></span>
        <span className="hk-nav-label">Back to hikit.studio</span>
      </a>
      <div className="hk-nav" onClick={() => {
        document.cookie = 'hk_cp=; max-age=0; path=/';
        location.reload();
      }}>
        <span className="hk-nav-icon"><Icon name="logout" size={17}/></span>
        <span className="hk-nav-label">Sign out</span>
      </div>
      <NavItem id="settings"  icon="sliders"   label="Settings"         currentId={currentId} onGo={goAndClose}/>
    </aside>
  );
}

// ── Topbar ───────────────────────────────────────────────────────────────────

function Topbar({ currentId, onTheme, theme, onBurger }) {
  const page = CP_PAGES[currentId] || { title: 'Overview' };
  const client = window.CP_CLIENT || {};

  return (
    <header className="hk-topbar">
      <button className="hk-burger" onClick={onBurger} aria-label="Open menu">
        <Icon name="menu" size={20}/>
      </button>

      <div className="hk-bread">
        <span style={{ color: 'var(--ink-3)', fontSize: 13 }}>{client.domain || ''}</span>
        <span className="sep"><Icon name="chevR" size={14}/></span>
        <span className="cur">{page.title}</span>
      </div>

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

      <Btn iconOnly variant="ghost" icon={theme === 'dark' ? 'sun' : 'moon'}
        title={theme === 'dark' ? 'Light theme' : 'Dark theme'} onClick={onTheme}/>
      <Avatar name={client.name || 'C'} size={28}/>
    </header>
  );
}

// ── Root Portal App ──────────────────────────────────────────────────────────

function CPApp() {
  const [route, go] = useHashRoute('overview');
  const [theme, setTheme] = React.useState(() => HKTheme.current);
  const [mobileOpen, setMobileOpen] = React.useState(false);
  const page = CP_PAGES[route] || CP_PAGES.overview;

  React.useEffect(() => {
    document.title = `HiKit · ${page?.title || 'Client Portal'}`;
  }, [page]);

  React.useEffect(() => { setMobileOpen(false); }, [route]);

  React.useEffect(() => {
    const onT = (e) => setTheme(e.detail);
    window.addEventListener('hk:theme', onT);
    return () => window.removeEventListener('hk:theme', onT);
  }, []);

  const toggleTheme = () => HKTheme.toggle();

  return (
    <div className="hk-shell">
      <div className={`hk-mobile-scrim${mobileOpen ? ' open' : ''}`} onClick={() => setMobileOpen(false)}/>
      <Sidebar
        currentId={route} onGo={go}
        onTheme={toggleTheme} theme={theme}
        mobileOpen={mobileOpen} onCloseMobile={() => setMobileOpen(false)}
      />
      <div className="hk-page">
        <Topbar currentId={route} onTheme={toggleTheme} theme={theme} onBurger={() => setMobileOpen(true)}/>
        <div className="hk-page-body">
          <div className="hk-page-inner">
            {(() => {
              const Comp = page?.component;
              return Comp ? <Comp go={go} /> : (
                <div style={{ padding: 40, textAlign: 'center', color: 'var(--ink-3)' }}>
                  <div className="hk-h2" style={{ color: 'var(--ink)' }}>Coming soon</div>
                </div>
              );
            })()}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Entry: check cookie, show gate or app ────────────────────────────────────

function CPPortal() {
  const redirectOnAuth = window.CP_CONFIG?.redirectOnAuth;
  const [authed, setAuthed] = React.useState(() => {
    return document.cookie.split(';').some(c => c.trim().startsWith('hk_cp=1'));
  });

  React.useEffect(() => {
    if (authed && redirectOnAuth) {
      window.location.replace(redirectOnAuth);
    }
  }, [authed]);

  if (!authed) return <LoginGate onAuth={() => setAuthed(true)} />;
  if (redirectOnAuth) return null; // redirect in flight
  return <CPApp />;
}

window.CPPortal = CPPortal;
window.CPApp    = CPApp;
window.CP_PAGES  = CP_PAGES;
