// ============================================================
// GUIDED REVIEW, Corporate demo
// A reviewer lands as the FreshNest corporate marketing lead, gets a
// briefing on who they are and what they're walking into, then is guided
// through the product in a deliberate order — corporate surfaces first,
// then stepping into a local operator's view. The tour is a sequence of
// pop-up walkthrough windows; it collects no feedback in place. At the end
// it opens the single "Give Feedback" panel. Not part of the shipping product.
// ============================================================
(function () {
  const { useState, useEffect } = React;

  const F = { orange: '#f28020', orangeDeep: '#b35f18', orange100: '#fdf0e4', orange50: '#fef9f4', navy: '#002857', star: '#d6b84d', teal: '#0d8a8a', green: '#2e9e6b' };
  const G_KEY = 'la_guide_v1';

  // Pull real, internally-consistent FreshNest numbers so the briefing
  // matches what the reviewer will actually see in the app.
  const DATA = (typeof window !== 'undefined' && window.LOCALACT_DATA) || {};
  const PB = DATA.playbookPortfolio || {};
  const PLAYBOOK = DATA.playbook || {};
  const TOTAL_LOC = PB.totalLocations || 700;
  const ENROLLED_LOC = PB.enrolledLocations || 664;
  const ADOPTION = Math.round((ENROLLED_LOC / TOTAL_LOC) * 100); // ~95
  const AT_RISK = (() => {
    const seg = (PB.tierPlaybook || []).find(t => /aggressive/i.test(t.tier || ''));
    return seg ? seg.count : 14;
  })();
  const PB_VERSION = PLAYBOOK.version || 'v3.2';
  const NET = DATA.network || {};
  const ADOPTION_GOAL = NET.enrollmentGoalPct || 75;
  const BASELINE_PER_LOC = NET.baselinePerLoc || 100;

  // ---- The route. Corporate story in order: Command Center → Results →
  // Leads → Locations → Marketing Stack → Billing → Network Playbook →
  // mirror a local operator (density → reviews → strategy → budget) →
  // Support & governance → Corporate settings → Enterprise Reporting.
  // `feature` is a stable id (React key + mirror logic).
  const STEPS = [
    { feature: 'hq',          page: 'hq',         scope: 'corporate', title: 'Local and national performance',
      guide: 'Your corporate and franchisee paid LOCAL programs roll up here to give you high-level spend, performance, and enrollment rates across active services. Explore the Listings & Review analysis and Offer & Label tabs.' },

    { feature: 'results',     page: 'results',    scope: 'corporate', title: 'Results',
      guide: 'Measure what matters here. Spend, leads, ROAS, by channel across the network, with trends. Explore top and bottom performing locations, key insights, and regional breakdowns here. Dive deep into specific channels as needed.' },

    { feature: 'leads',       page: 'leads',      scope: 'corporate', title: 'Leads',
      guide: 'Call tracking analysis and lead details are highlighted here. By default, this report will show if you are using our call tracking provider and/or your locations are active on Local Service Ads. CRM integrations are possible in future phases depending on the CRM you are using and the health of that data.' },

    { feature: 'listings',    page: 'listings',   scope: 'corporate', title: 'Locations',
      guide: 'The source of truth for every location. Try drilling into one to see its listings and presence.' },

    { feature: 'stack',       page: 'services',   scope: 'corporate', title: 'Command Center',
      guide: 'Every active national or local service across your brand. The marketing stack highlights what you are doing with us today.' },

    { feature: 'invoice',     page: 'invoice',    scope: 'corporate', title: 'Billing',
      guide: 'National invoicing and franchisee billing health, consolidated in one place. Here, you will manage your corporate payment method for National or Corporate paid programs.' },

    { feature: 'bench',       page: 'bench',      scope: 'corporate', title: 'Network Playbook',
      guide: 'The decision system your network runs on. The playbook highlights the current channels and strategies available to your locations. Suggestions are discussed and edits are made with your Location3 Strategy Director.' },

    { feature: 'users',       page: 'local-users', scope: 'corporate', title: 'View as a local user',
      guide: 'Corporate can step into any operator’s exact view, from this directory or the “Viewing as” selector in the sidebar. Next will take you into one.' },

    { feature: 'density',     page: 'home',       scope: 'local', mirror: true, title: 'Basic view vs Advanced view',
      guide: 'You are seeing what the local operator sees. They can flip between a calm owner summary and full detail advanced. Try both with the toggle in the top bar.', density: true },

    { feature: 'reviews',     page: 'reviews',    scope: 'local', mirror: true, title: 'Reviews',
      guide: 'The local reputation view. Ratings by platform, response tracking, coaching, and the ability to respond to reviews. Auto-mode with corporate guidelines available in future updates.' },

    { feature: 'initiatives', page: 'services',   scope: 'local', mirror: true, title: 'Strategy',
      guide: 'The operator’s active marketing strategy and channels. This is closely related to the budget tab but provides budget in-line with performance and shows strategic initiatives the local operator is not enrolled in as well.' },

    { feature: 'budget',      page: 'budget',     scope: 'local', mirror: true, title: 'Budget',
      guide: 'Where the local operator manages spend. Set one monthly budget and let LOCALACT split it across channels automatically, or tune each channel by hand, with pacing and spend-versus-performance in view.' },

    { feature: 'support',     page: 'support',    scope: 'corporate', title: 'Support & governance',
      guide: 'Here you will see Location3 Advisor performance, franchisees with high conversation volume, and common themes based on what franchisees are discussing with our advisors.' },

    { feature: 'settings',    page: 'settings',   scope: 'corporate', title: 'Corporate settings',
      guide: 'The governance layer, where corporate sets the rules. Assign roles to your corporate team members, upload your brand standards, review the phases of the playbook, and see the changes corporate users are making across the system.' },

    { feature: 'ent-rep',     page: 'enterprise-reporting', scope: 'corporate', title: 'Enterprise Reporting',
      guide: 'National programs are measured here. Brands without Enterprise/National spend will not see an Enterprise Reporting tab.' },
  ];

  // ---- Persisted guide state ----
  function loadG() {
    try { const raw = localStorage.getItem(G_KEY); if (raw) { return JSON.parse(raw); } } catch (e) {}
    return { reviewer: null, step: 0, started: false, skipped: false, done: false };
  }
  function saveG(g) { try { localStorage.setItem(G_KEY, JSON.stringify(g)); } catch (e) {} }

  function setGuideActive(on) {
    if (window.__LA_GUIDE_ACTIVE !== on) {
      window.__LA_GUIDE_ACTIVE = on;
      window.dispatchEvent(new CustomEvent('guide-active', { detail: on }));
    }
  }

  const ev = (name, detail) => window.dispatchEvent(new CustomEvent(name, { detail }));

  // Put the app in the right state for a step, then navigate to it.
  function applyStep(step, ctx) {
    if (step.mirror && !ctx.mirroredUser) ev('mirror-user');
    if (!step.mirror && ctx.mirroredUser) ev('exit-mirror');
    if (!step.mirror && ctx.persona !== 'hq') ev('set-persona', 'hq');
    ev('go-page', step.page);
  }

  // ============================================================
  // Welcome / briefing gate — you are the FreshNest corporate lead
  // ============================================================
  function Welcome({ onStart, onSkip }) {
    const stats = [
      { v: TOTAL_LOC.toLocaleString(), l: 'Locations supported' },
      { v: ADOPTION + '%', l: 'LOCALACT adoption' },
      { v: ADOPTION_GOAL + '%', l: 'Adoption goal' },
      { v: '$' + BASELINE_PER_LOC + '/mo', l: 'Corporate funding / location' },
    ];
    return (
      <div style={{ position: 'fixed', inset: 0, zIndex: 8600, background: 'rgba(11,36,71,0.86)', backdropFilter: 'blur(4px)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20, overflowY: 'auto', animation: 'gr-in .25s ease' }}>
        <div style={{ width: 620, maxWidth: 'calc(100vw - 40px)', background: 'var(--paper)', borderRadius: 24, overflow: 'hidden', boxShadow: '0 30px 80px rgba(0,0,0,.4)', margin: 'auto' }}>

          {/* Navy briefing header */}
          <div style={{ background: F.navy, padding: '22px 28px 22px', color: '#fff', display: 'flex', alignItems: 'flex-end', gap: 16 }}>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 }}>
                <span style={{ fontFamily: 'var(--ff-display)', fontWeight: 700, letterSpacing: '.04em', fontSize: 17 }}>LOCAL<span style={{ color: F.orange }}>ACT</span></span>
                <span style={{ fontSize: 9, fontWeight: 700, letterSpacing: '.1em', background: F.orange, color: '#fff', padding: '3px 8px', borderRadius: 5 }}>CORPORATE DEMO</span>
              </div>
              <div style={{ fontFamily: 'var(--ff-display)', fontSize: 25, fontWeight: 600, letterSpacing: '-0.01em', lineHeight: 1.15 }}>
                Welcome. You’re FreshNest’s corporate marketing lead.
              </div>
              <div style={{ fontSize: 13, color: 'rgba(255,255,255,.72)', marginTop: 8, lineHeight: 1.55 }}>
                You oversee local marketing for a <strong style={{ color: '#fff' }}>{TOTAL_LOC.toLocaleString()}-location</strong> home-services brand. Right now <strong style={{ color: '#fff' }}>{ADOPTION}%</strong> of your network is live on LOCALACT against a <strong style={{ color: '#fff' }}>{ADOPTION_GOAL}%</strong> adoption goal, with corporate funding <strong style={{ color: '#fff' }}>${BASELINE_PER_LOC}/mo</strong> of local marketing at every location.
              </div>
            </div>
            <img src="assets/lenny-map.png" alt="Lenny" draggable={false} style={{ height: 128, width: 'auto', display: 'block', flexShrink: 0, alignSelf: 'flex-end', marginBottom: -22, filter: 'drop-shadow(0 6px 14px rgba(0,0,0,.28))' }}/>
          </div>

          {/* Stat strip */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', borderBottom: '1px solid var(--line)' }}>
            {stats.map((s, i) => (
              <div key={i} style={{ padding: '14px 12px', textAlign: 'center', borderRight: i < 3 ? '1px solid var(--line)' : 'none' }}>
                <div style={{ fontFamily: 'var(--ff-display)', fontSize: 22, fontWeight: 600, color: F.navy, letterSpacing: '-0.01em' }}>{s.v}</div>
                <div style={{ fontSize: 9.5, fontWeight: 700, letterSpacing: '.06em', textTransform: 'uppercase', color: 'var(--ink-4)', marginTop: 3 }}>{s.l}</div>
              </div>
            ))}
          </div>

          <div style={{ padding: '20px 28px 26px' }}>
            {/* Flow explanation */}
            <div style={{ fontSize: 13.5, color: 'var(--ink-2)', lineHeight: 1.6 }}>
              Over <strong>{STEPS.length} stops</strong>, we’ll walk you through the <strong>corporate experience</strong> first: local and national performance, results, your locations, the Command Center, and the network playbook. Then you’ll step into a single franchisee’s view to see the <strong>local operator experience</strong>. You can wander off the path anytime and pick the tour back up. At the end, take a break and share your feedback.
            </div>

            <button autoFocus onClick={() => onStart({})}
              style={{ width: '100%', marginTop: 20, border: 'none', borderRadius: 12, padding: '13px 16px', cursor: 'pointer',
                background: F.orange, color: '#fff', fontFamily: 'var(--ff-display)', fontWeight: 600, fontSize: 15 }}>
              Start the guided review
            </button>
          </div>
        </div>
        <style>{`@keyframes gr-in { from { opacity: 0; } to { opacity: 1; } }`}</style>
      </div>
    );
  }

  // ============================================================
  // Guide panel — a single centered walkthrough pop-up with a blurred
  // backdrop. Clicking the backdrop (or "Explore") dismisses it so the
  // reviewer can interact with the screen; a small pill brings it back.
  // ============================================================
  function GuidePanel({ g, setG, page, persona, mirroredUser, density }) {
    const [introOpen, setIntroOpen] = useState(true);
    const [listOpen, setListOpen] = useState(false);

    const i = Math.min(g.step, STEPS.length - 1);
    const step = STEPS[i];
    const ctx = { persona, mirroredUser };

    // Reopen the centered pop-up whenever the step changes.
    useEffect(() => { setIntroOpen(true); setListOpen(false); }, [i]);

    function go(n) {
      const clamped = Math.max(0, Math.min(n, STEPS.length - 1));
      setG(prev => ({ ...prev, step: clamped }));
      applyStep(STEPS[clamped], ctx);
      setListOpen(false);
      setIntroOpen(true);
    }
    function next() {
      if (step.feature === 'users' && !mirroredUser) { ev('mirror-user'); }
      if (i >= STEPS.length - 1) {
        setG(prev => ({ ...prev, done: true }));
        if (mirroredUser) ev('exit-mirror');
        ev('open-feedback');
        window.toast && window.toast('That’s the full tour', 'Take a break, then click Give Feedback to share your thoughts.', 'ok');
        return;
      }
      go(i + 1);
    }
    function explore() {
      setIntroOpen(false);
      window.dispatchEvent(new CustomEvent('gr-intro-dismissed', { detail: { feature: step.feature } }));
    }

    // Dismissed → exploring. Bottom-right control: reopen the guide, or
    // advance to the next stop from here.
    if (!introOpen) {
      const nextLabel = i >= STEPS.length - 1 ? 'Finish → give feedback'
        : step.feature === 'users' && !mirroredUser ? 'View as a local user →'
        : 'Next stop →';
      return (
        <div style={{ position: 'fixed', right: 18, bottom: 18, zIndex: 8200, display: 'flex', alignItems: 'center', gap: 8,
          background: F.navy, borderRadius: 999, padding: 6, paddingLeft: 15,
          boxShadow: '0 8px 22px rgba(11,36,71,.4)', border: '2px solid #fff', fontFamily: 'var(--ff-display)' }}>
          <button onClick={() => setIntroOpen(true)} title="Reopen the guide"
            style={{ display: 'flex', alignItems: 'center', gap: 9, background: 'none', border: 'none', color: '#fff', cursor: 'pointer', fontWeight: 600, fontSize: 13, fontFamily: 'var(--ff-display)' }}>
            <span style={{ width: 8, height: 8, borderRadius: '50%', background: F.orange }}/>
            Guided review · step {i + 1}/{STEPS.length}
          </button>
          <button onClick={() => ev('open-feedback')} title="Jump to the rating"
            style={{ border: '1px solid rgba(255,255,255,.35)', background: 'none', color: '#fff', borderRadius: 999, padding: '8px 14px', fontFamily: 'var(--ff-display)', fontWeight: 600, fontSize: 12.5, cursor: 'pointer', whiteSpace: 'nowrap' }}>
            Rate the app
          </button>
          <button onClick={next}
            style={{ border: 'none', background: F.orange, color: '#fff', borderRadius: 999, padding: '9px 18px', fontFamily: 'var(--ff-display)', fontWeight: 700, fontSize: 13.5, cursor: 'pointer', whiteSpace: 'nowrap', boxShadow: '0 4px 14px rgba(242,128,32,.4)' }}>
            {nextLabel}
          </button>
        </div>
      );
    }

    const side = i % 2 === 0 ? 'left' : 'right';
    const pose = ['laptop', 'think', 'map'][i % 3];

    // Centered pop-up over a partial glass-blur backdrop.
    return (
      <div onClick={explore}
        style={{ position: 'fixed', inset: 0, zIndex: 8500, display: 'flex', alignItems: 'center', justifyContent: 'center',
          padding: 20, overflowY: 'auto', background: 'rgba(11,36,71,0.30)', backdropFilter: 'blur(6px)', WebkitBackdropFilter: 'blur(6px)', animation: 'gr-in .22s ease' }}>
        <style>{`@keyframes gr-in{from{opacity:0}to{opacity:1}}@keyframes gr-lenny{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}`}</style>
        <div onClick={e => e.stopPropagation()}
          style={{ width: 540, maxWidth: 'calc(100vw - 40px)', maxHeight: 'calc(100vh - 40px)', overflowY: 'auto', margin: 'auto',
            background: 'var(--paper)', borderRadius: 20, boxShadow: '0 30px 80px rgba(11,36,71,.4)', border: `1px solid ${F.orange100}`, fontFamily: 'var(--ff-ui)' }}>

          {/* Header */}
          <div style={{ background: F.navy, color: '#fff', padding: '12px 20px', display: 'flex', alignItems: 'center', gap: 9 }}>
            <span style={{ fontSize: 8.5, fontWeight: 700, letterSpacing: '.1em', background: F.orange, color: '#fff', padding: '2px 7px', borderRadius: 4 }}>STEP {i + 1} / {STEPS.length}</span>
            <span style={{ fontSize: 12, fontWeight: 600, color: 'rgba(255,255,255,.7)' }}>{step.scope === 'corporate' ? 'Corporate view' : 'Local operator view'}</span>
            <div style={{ flex: 1 }}/>
            <span onClick={() => setListOpen(o => !o)} title="All steps" style={{ cursor: 'pointer', color: 'rgba(255,255,255,.75)', fontSize: 14, padding: '0 4px', userSelect: 'none' }}>☰</span>
          </div>

          {/* Segmented progress */}
          <div style={{ display: 'flex', gap: 3, padding: '12px 22px 0' }}>
            {STEPS.map((s, k) => (
              <div key={s.feature} onClick={() => go(k)} title={`${k + 1}. ${s.title}`}
                style={{ flex: 1, height: 5, borderRadius: 999, cursor: 'pointer',
                  background: k < i ? F.orange : k === i ? F.navy : 'var(--cream-3)',
                  outline: k === i ? `2px solid ${F.orange100}` : 'none' }}/>
            ))}
          </div>

          {listOpen ? (
            <div style={{ maxHeight: 360, overflowY: 'auto', padding: '10px 12px 12px' }}>
              {STEPS.map((s, k) => (
                <div key={s.feature} onClick={() => go(k)}
                  style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '8px 10px', borderRadius: 9, cursor: 'pointer',
                    background: k === i ? F.orange50 : 'transparent' }}>
                  <span style={{ width: 18, height: 18, borderRadius: '50%', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontSize: 9.5, fontWeight: 700, background: k < i ? F.orange : 'var(--cream-2)', color: k < i ? '#fff' : 'var(--ink-3)' }}>
                    {k < i ? '✓' : k + 1}
                  </span>
                  <span style={{ flex: 1, fontSize: 12.5, fontWeight: k === i ? 700 : 500, color: 'var(--ink)' }}>{s.title}</span>
                  {s.scope === 'local' && <span style={{ fontSize: 8.5, fontWeight: 700, letterSpacing: '.06em', color: '#0a6666', background: 'rgba(13,138,138,0.10)', padding: '1px 6px', borderRadius: 999 }}>LOCAL</span>}
                </div>
              ))}
            </div>
          ) : (
            <React.Fragment>
              {/* Two columns: big Lenny on one side (alternating), copy on the other */}
              <div style={{ display: 'flex', flexDirection: side === 'left' ? 'row' : 'row-reverse', alignItems: 'flex-end', gap: 18, padding: '18px 26px 0' }}>
                <img key={side} src={`assets/lenny-${pose}.png`} alt="Lenny" draggable={false}
                  style={{ height: 200, width: 'auto', display: 'block', flexShrink: 0, marginBottom: -2, filter: 'drop-shadow(0 8px 16px rgba(11,36,71,.22))', animation: 'gr-lenny .3s ease' }}/>
                <div style={{ flex: 1, minWidth: 0, textAlign: 'left', paddingBottom: 18 }}>
                  <div style={{ fontFamily: 'var(--ff-display)', fontSize: 21, fontWeight: 600, color: 'var(--ink)', letterSpacing: '-0.01em', marginBottom: 8 }}>{step.title}</div>
                  <div style={{ fontSize: 13.5, color: 'var(--ink-2)', lineHeight: 1.6 }}>{step.guide}</div>
                  {i === 0 && (
                    <div style={{ marginTop: 14, padding: '10px 13px', background: F.orange50, border: `1px solid ${F.orange100}`, borderRadius: 12, fontSize: 12, color: F.orangeDeep, lineHeight: 1.5 }}>
                      <strong>Try this first:</strong> click through the Command Center tabs, Listings &amp; Review analysis and Offer &amp; Label, before you press Next.
                    </div>
                  )}
                  {/* Density stop gets its own try-it controls */}
                  {step.density && (
                    <div style={{ display: 'flex', gap: 6, marginTop: 12 }}>
                      {[{ k: 'simple', l: 'Basic view' }, { k: 'full', l: 'Advanced view' }].map(o => (
                        <button key={o.k} onClick={() => ev('set-density', o.k)}
                          style={{ flex: 1, padding: '8px 8px', borderRadius: 9, fontSize: 11.5, fontWeight: 700, cursor: 'pointer', fontFamily: 'var(--ff-ui)',
                            border: density === o.k ? `1.5px solid ${F.orange}` : '1px solid var(--line)',
                            background: density === o.k ? F.orange50 : 'var(--paper)', color: density === o.k ? F.orangeDeep : 'var(--ink-2)' }}>
                          {o.l}{density === o.k ? ' ✓' : ''}
                        </button>
                      ))}
                    </div>
                  )}
                </div>
              </div>
            </React.Fragment>
          )}

          {/* Footer nav */}
          <div style={{ borderTop: '1px solid var(--line)', padding: '12px 20px', display: 'flex', alignItems: 'center', gap: 8, background: F.orange50 }}>
            <button onClick={() => go(i - 1)} disabled={i === 0}
              style={{ border: '1px solid var(--line)', background: 'var(--paper)', color: i === 0 ? 'var(--ink-5)' : 'var(--ink-2)', borderRadius: 10, padding: '9px 14px', fontSize: 12.5, fontWeight: 600, cursor: i === 0 ? 'not-allowed' : 'pointer', fontFamily: 'var(--ff-ui)' }}>
              ← Back
            </button>
            <div style={{ flex: 1 }}/>
            <button onClick={explore}
              style={{ border: 'none', background: F.orange, color: '#fff', borderRadius: 12, padding: '13px 26px', fontFamily: 'var(--ff-display)', fontWeight: 700, fontSize: 15, cursor: 'pointer', whiteSpace: 'nowrap', display: 'inline-flex', alignItems: 'center', gap: 9, boxShadow: '0 6px 18px rgba(242,128,32,.4)' }}>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
              Explore this screen
            </button>
          </div>
        </div>
      </div>
    );
  }

  // ============================================================
  // Root
  // ============================================================
  function GuidedReview({ page, persona, mirroredUser, density }) {
    const [g, setGState] = useState(loadG);
    const setG = (updater) => setGState(prev => { const nx = typeof updater === 'function' ? updater(prev) : updater; saveG(nx); return nx; });

    const active = !!(g.started && !g.skipped && !g.done);
    useEffect(() => { setGuideActive(active); }, [active]);

    // Logo click → back to the sign-in / welcome gate
    useEffect(() => {
      function resetGuide() {
        setG({ reviewer: null, step: 0, started: false, skipped: false, done: false });
      }
      window.addEventListener('la-reset-demo', resetGuide);
      return () => window.removeEventListener('la-reset-demo', resetGuide);
    }, []);

    if (g.done || g.skipped) {
      // Small re-entry pill so a skipped/finished reviewer can (re)start
      return (
        <button onClick={() => setG(prev => ({ ...prev, skipped: false, done: false, started: !!prev.reviewer, step: prev.done ? 0 : prev.step }))}
          style={{ position: 'fixed', right: 18, bottom: 18, zIndex: 8200, display: 'flex', alignItems: 'center', gap: 8,
            background: 'var(--paper)', color: F.navy, border: `1.5px solid ${F.orange}`, borderRadius: 999, padding: '9px 15px',
            boxShadow: '0 6px 18px rgba(11,36,71,.18)', cursor: 'pointer', fontFamily: 'var(--ff-display)', fontWeight: 600, fontSize: 12.5 }}>
          {g.done ? '✓ Review done · revisit the tour' : '▶ Start guided review'}
        </button>
      );
    }

    if (!g.started) {
      return (
        <Welcome
          onStart={(reviewer) => {
            setG(prev => ({ ...prev, reviewer, started: true, skipped: false, step: 0 }));
            applyStep(STEPS[0], { persona, mirroredUser });
            window.toast && window.toast('Welcome', 'Step 1 of ' + STEPS.length + ': Command Center.', 'info');
          }}
          onSkip={() => setG(prev => ({ ...prev, skipped: true }))}
        />
      );
    }

    return <GuidePanel g={g} setG={setG} page={page} persona={persona} mirroredUser={mirroredUser} density={density}/>;
  }
  window.GuidedReview = GuidedReview;
})();
