// osb/osb-splash.jsx
// Pre-landing for the OS Builder onboarding.
// Phases: splash → scraping (live SSE feed) → review (high confidence) → form
// OSBOnboardingApp is the root — replaces the direct <OSBuilder/> mount.

/* ─── ROOT WRAPPER ──────────────────────────────────────────────────────── */
function OSBOnboardingApp() {
  const hasProgress = React.useMemo(() => {
    try {
      const ph  = localStorage.getItem('hp-os-builder-phase');
      const st  = localStorage.getItem('hp-os-builder');
      return (!!ph && ph !== '0') || (!!st && st !== '{}');
    } catch { return false; }
  }, []);

  const [phase,   setPhase]   = React.useState(hasProgress ? 'form' : 'splash');
  const [input,   setInput]   = React.useState({});
  const [result,  setResult]  = React.useState(null);

  const goScraping = (splashInput) => { setInput(splashInput); setPhase('scraping'); };

  const onScrapeDone = (res) => {
    setResult(res);
    if (res.confidence === 'high' && res.prefill?.meta?.website_url) {
      setPhase('review');
    } else {
      setPhase('form');
    }
  };

  const onConfirm = (prefill) => { setResult(r => ({ ...r, prefill })); setPhase('form'); };

  if (phase === 'splash')   return <OSBSplash onStart={goScraping}/>;
  if (phase === 'scraping') return <OSBScrapingFeed input={input} onDone={onScrapeDone}/>;
  if (phase === 'review')   return <OSBReview input={input} result={result} onConfirm={onConfirm} onEdit={() => setPhase('form')}/>;

  // form phase — build initial state from prefill and pass to OSBuilder
  return <OSBuilder initialState={buildOSBInitialState(result?.prefill, input)}/>;
}

function buildOSBInitialState(pf, input) {
  if (!pf) {
    // Still pass bizName from splash input so Phase 1 is pre-filled
    if (input?.bizName) return { identity: { bizName: input.bizName, city: input.city || '' } };
    return {};
  }

  const id = pf.identity || {};
  const w  = pf.welcome  || {};
  const v  = pf.voice    || {};
  const m  = pf.meta     || {};

  const identity = {};
  if (input?.bizName)      identity.bizName = input.bizName;
  if (id.trades?.length)   identity.trades  = id.trades;
  if (id.years)            identity.years   = id.years;
  if (id.team)             identity.team    = id.team;
  if (id.city)             identity.city    = id.city;
  if (id.areas)            identity.areas   = id.areas;
  if (id.tools?.length)    identity.tools   = id.tools;
  if (id.dba)              identity.dba     = id.dba;

  const tech = {};
  if (m.website_url)  tech.url   = m.website_url;
  if (w.phone)        tech.phone = w.phone;
  if (w.email)        tech.email = w.email;

  const voice = {};
  if (v.tone != null)    voice.tone  = v.tone;
  if (m.about_snippet)   voice.about = m.about_snippet;
  if (m.brand_voice)     voice.style = m.brand_voice;

  const out = {};
  if (Object.keys(identity).length) out.identity = identity;
  if (Object.keys(tech).length)     out.tech     = tech;
  if (Object.keys(voice).length)    out.voice    = voice;
  return out;
}

/* ─── SPLASH (entry screen) ─────────────────────────────────────────────── */
function OSBSplash({ onStart }) {
  const [form, setForm] = React.useState({ bizName:'', city:'', state:'', url:'', phone:'' });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const canGo = form.bizName.trim().length >= 2 && form.city.trim().length >= 2;

  const go = (e) => {
    e.preventDefault();
    if (!canGo) return;
    onStart({ bizName: form.bizName.trim(), city: form.city.trim(), state: form.state.trim(), url: form.url.trim(), phone: form.phone.trim() });
  };

  return (
    <div style={{ minHeight:'100vh', background:'var(--paper-2)', fontFamily:'var(--font-body)', color:'var(--ink)', display:'flex', flexDirection:'column' }}>
      {/* Nav */}
      <nav style={{ padding:'16px 40px', display:'flex', alignItems:'center', gap:10, borderBottom:'1px solid var(--line-2)', background:'rgba(255,255,255,0.9)', backdropFilter:'blur(20px)' }}>
        <Logo size={28}/>
        <Wordmark size={16}/>
        <span style={{ fontFamily:'var(--font-display)', fontWeight:600, fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', padding:'3px 9px', borderRadius:99, background:'var(--ink)', color:'var(--chart-300)', marginLeft:4 }}>OS Builder</span>
      </nav>

      {/* Hero */}
      <div style={{ flex:1, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', padding:'60px 24px' }}>
        <div style={{ width:'100%', maxWidth:520 }}>
          <div style={{ fontFamily:'var(--font-mono)', fontSize:11, fontWeight:700, letterSpacing:'0.18em', color:'var(--lilac-700)', textTransform:'uppercase', marginBottom:18 }}>
            AI-powered setup · OS Builder
          </div>
          <h1 className="display" style={{ fontSize:'clamp(42px, 7vw, 68px)', fontWeight:500, letterSpacing:'-0.045em', lineHeight:1, margin:'0 0 16px', color:'var(--ink)' }}>
            Your business.<br/>
            <span style={{ color:'var(--lilac-700)', fontStyle:'italic' }}>We'll build the OS.</span>
          </h1>
          <p style={{ fontSize:16, color:'var(--mute-1)', lineHeight:1.55, margin:'0 0 40px' }}>
            We scan your website, Google listing, reviews, and social pages — then pre-fill 12 phases of your OS configuration before you answer a single question.
          </p>

          <form onSubmit={go} style={{ display:'flex', flexDirection:'column', gap:14 }}>
            <OSBSplashField
              label="Business name"
              placeholder="Cardinal Roofing LLC"
              value={form.bizName}
              onChange={v => set('bizName', v)}
              required
            />
            <div style={{ display:'grid', gridTemplateColumns:'1fr 80px', gap:12 }}>
              <OSBSplashField label="City" placeholder="Tampa" value={form.city} onChange={v => set('city', v)} required/>
              <OSBSplashField label="State" placeholder="FL" value={form.state} onChange={v => set('state', v)}/>
            </div>
            <OSBSplashField
              label="Website URL"
              sublabel="Recommended — speeds up the search significantly"
              placeholder="https://cardinalroofing.com"
              value={form.url}
              onChange={v => set('url', v)}
              type="url"
            />
            <OSBSplashField
              label="Phone"
              sublabel="Optional"
              placeholder="(813) 555-0198"
              value={form.phone}
              onChange={v => set('phone', v)}
              type="tel"
            />

            <button
              type="submit"
              disabled={!canGo}
              style={{
                marginTop:8,
                padding:'16px 28px',
                background: canGo ? 'var(--ink)' : 'var(--paper-3)',
                color: canGo ? 'var(--chart-300)' : 'var(--mute-3)',
                border:0, borderRadius:99,
                fontFamily:'var(--font-body)', fontWeight:700, fontSize:16,
                cursor: canGo ? 'pointer' : 'default',
                display:'flex', alignItems:'center', justifyContent:'center', gap:10,
                boxShadow: canGo ? '0 12px 32px rgba(12,14,16,0.2)' : 'none',
                transition:'all 0.15s',
              }}
            >
              Find my business
              <IconArrow size={16} stroke="var(--chart-300)"/>
            </button>
          </form>

          <button
            onClick={() => onStart({ bizName: form.bizName || 'My Business', city: form.city || '', url: '', phone: '', skip: true })}
            style={{ marginTop:18, background:'transparent', border:0, fontSize:13, color:'var(--mute-2)', cursor:'pointer', fontFamily:'var(--font-body)', display:'block', width:'100%', textAlign:'center' }}
          >
            Skip and fill manually →
          </button>
        </div>
      </div>
    </div>
  );
}

function OSBSplashField({ label, sublabel, value, onChange, placeholder, required, type = 'text' }) {
  return (
    <label style={{ display:'flex', flexDirection:'column', gap:5 }}>
      <span style={{ fontSize:11, fontWeight:700, letterSpacing:'0.1em', textTransform:'uppercase', color:'var(--mute-1)' }}>
        {label}{required && <span style={{ color:'var(--lilac-700)', marginLeft:4 }}>*</span>}
        {sublabel && <span style={{ fontWeight:400, textTransform:'none', letterSpacing:0, marginLeft:6, color:'var(--mute-3)' }}>{sublabel}</span>}
      </span>
      <input
        type={type}
        value={value || ''}
        onChange={e => onChange(e.target.value)}
        placeholder={placeholder}
        style={{
          padding:'13px 16px',
          background:'#fff',
          border:'1.5px solid var(--line)',
          borderRadius:12,
          fontFamily:'var(--font-body)',
          fontSize:15,
          color:'var(--ink)',
          outline:'none',
          transition:'border-color 0.15s',
          width:'100%',
          boxSizing:'border-box',
        }}
        onFocus={e  => e.target.style.borderColor = 'var(--ink)'}
        onBlur={e   => e.target.style.borderColor = 'var(--line)'}
      />
    </label>
  );
}

/* ─── SCRAPING FEED (live SSE) ───────────────────────────────────────────── */
function OSBScrapingFeed({ input, onDone }) {
  const [events, setEvents] = React.useState([]);
  const [pct,    setPct]    = React.useState(0);
  const listRef = React.useRef(null);

  React.useEffect(() => {
    if (input.skip) { onDone({ prefill: null, confidence: 'low' }); return; }
    let cancelled = false;

    async function stream() {
      let res;
      try {
        res = await fetch('/api/prefill-stream', {
          method:  'POST',
          headers: { 'Content-Type': 'application/json' },
          body:    JSON.stringify({ bizName: input.bizName, city: input.city, url: input.url, phone: input.phone }),
        });
      } catch {
        onDone({ prefill: null, confidence: 'low' });
        return;
      }

      if (!res.ok || !res.body) { onDone({ prefill: null, confidence: 'low' }); return; }

      const reader  = res.body.getReader();
      const decoder = new TextDecoder();
      let buffer = '';
      let count  = 0;

      while (!cancelled) {
        const { done, value } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });
        const parts = buffer.split('\n\n');
        buffer = parts.pop() || '';

        for (const part of parts) {
          const line = part.split('\n').find(l => l.startsWith('data: '));
          if (!line) continue;
          let evt;
          try { evt = JSON.parse(line.slice(6)); } catch { continue; }

          if (evt.type === 'done') {
            setPct(100);
            setTimeout(() => { if (!cancelled) onDone(evt); }, 700);
            return;
          }
          if (evt.type === 'error') {
            onDone({ prefill: null, confidence: 'low' });
            return;
          }

          count++;
          setPct(Math.min(88, count * 7));
          setEvents(prev => [...prev, { ...evt, id: Date.now() + Math.random() }]);
          requestAnimationFrame(() => {
            if (listRef.current) listRef.current.scrollTop = listRef.current.scrollHeight;
          });
        }
      }
    }

    stream();
    return () => { cancelled = true; };
  }, []);

  return (
    <div style={{ minHeight:'100vh', background:'var(--ink)', color:'#fff', fontFamily:'var(--font-body)', display:'flex', flexDirection:'column' }}>
      <nav style={{ padding:'16px 40px', display:'flex', alignItems:'center', gap:10, borderBottom:'1px solid rgba(255,255,255,0.08)' }}>
        <Logo size={28}/>
        <Wordmark size={16}/>
      </nav>

      <div style={{ flex:1, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', padding:'60px 24px' }}>
        <div style={{ width:'100%', maxWidth:500 }}>
          <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:12 }}>
            <span style={{ width:8, height:8, borderRadius:99, background:'var(--chart-300)' }}/>
            <span style={{ fontFamily:'var(--font-mono)', fontSize:11, fontWeight:700, letterSpacing:'0.14em', color:'var(--chart-300)', textTransform:'uppercase' }}>AI · Researching</span>
          </div>
          <h1 className="display" style={{ fontSize:'clamp(32px,6vw,52px)', fontWeight:500, letterSpacing:'-0.04em', lineHeight:1.05, margin:'0 0 32px' }}>
            Building your OS for {input.bizName}…
          </h1>

          <div style={{ height:3, background:'rgba(255,255,255,0.1)', borderRadius:99, overflow:'hidden', marginBottom:28 }}>
            <div style={{ height:'100%', width:`${pct}%`, background:'linear-gradient(90deg, var(--chart-300), var(--lilac-300))', transition:'width 0.6s ease', boxShadow:'0 0 12px rgba(196,240,0,0.5)' }}/>
          </div>

          <div ref={listRef} style={{ maxHeight:300, overflowY:'auto', display:'flex', flexDirection:'column', gap:6 }}>
            {events.map(e => <OSBFeedEvent key={e.id} evt={e}/>)}
            {pct < 95 && events.length > 0 && (
              <div style={{ display:'flex', alignItems:'center', gap:10, padding:'6px 0', color:'rgba(255,255,255,0.4)', fontSize:13 }}>
                <span style={{ display:'inline-block', animation:'spin 1.2s linear infinite', width:14, textAlign:'center' }}>⟳</span>
                <span>Working…</span>
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function OSBFeedEvent({ evt }) {
  const [visible, setVisible] = React.useState(false);
  React.useEffect(() => { requestAnimationFrame(() => setVisible(true)); }, []);

  let icon  = '⟳';
  let label = '';
  let sub   = '';

  if (evt.type === 'start')     { icon = '⟳'; label = `Starting research for ${evt.bizName}`; }
  if (evt.type === 'searching') { icon = '⟳'; label = `Searching · ${osbTruncate(evt.query, 52)}`; }
  if (evt.type === 'fetching')  { icon = '⟳'; label = `Reading ${evt.label || osbTruncate(evt.url, 40)}`; }
  if (evt.type === 'found') {
    icon = '✓';
    if (evt.source === 'profile') {
      label = evt.reviewCount ? `${evt.reviewCount} reviews · ${evt.reviewRating} ★` : 'Profile extracted';
      sub   = `Confidence: ${evt.confidence || '—'}`;
    } else {
      label = `Found · ${evt.source}`;
    }
  }

  const done = evt.type === 'found';

  return (
    <div style={{
      display:'flex', alignItems:'flex-start', gap:10, padding:'5px 0',
      opacity: visible ? 1 : 0,
      transform: visible ? 'translateY(0)' : 'translateY(6px)',
      transition: 'opacity 0.25s, transform 0.25s',
    }}>
      <span style={{
        width:18, flexShrink:0, fontSize:12, textAlign:'center', marginTop:1,
        color: done ? 'var(--chart-300)' : 'rgba(255,255,255,0.4)',
        display:'inline-block',
        animation: done ? 'none' : 'spin 1.4s linear infinite',
      }}>
        {icon}
      </span>
      <div>
        <div style={{ fontSize:13.5, color: done ? '#fff' : 'rgba(255,255,255,0.65)', fontWeight: done ? 500 : 400, lineHeight:1.35 }}>{label}</div>
        {sub && <div style={{ fontSize:11, color:'rgba(255,255,255,0.35)', marginTop:2 }}>{sub}</div>}
      </div>
    </div>
  );
}

/* ─── REVIEW SCREEN (high confidence) ───────────────────────────────────── */
function OSBReview({ input, result, onConfirm, onEdit }) {
  const pf   = result?.prefill || {};
  const meta = pf.meta    || {};
  const w    = pf.welcome  || {};
  const c    = pf.certs    || {};
  const s    = pf.services || {};
  const id   = pf.identity || {};

  const bizName  = meta.legal_name || input.bizName;
  const hasSocials = meta.gmb_url || meta.facebook_url || meta.instagram_url || meta.yelp_url;
  const trades   = id.trades || [];

  return (
    <div style={{ minHeight:'100vh', background:'var(--paper-2)', fontFamily:'var(--font-body)', color:'var(--ink)', display:'flex', flexDirection:'column' }}>
      <nav style={{ padding:'16px 40px', display:'flex', alignItems:'center', gap:10, borderBottom:'1px solid var(--line-2)', background:'rgba(255,255,255,0.9)', backdropFilter:'blur(20px)' }}>
        <Logo size={28}/><Wordmark size={16}/>
        <span style={{ fontFamily:'var(--font-display)', fontWeight:600, fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', padding:'3px 9px', borderRadius:99, background:'var(--ink)', color:'var(--chart-300)', marginLeft:4 }}>OS Builder</span>
      </nav>

      <div style={{ flex:1, display:'flex', flexDirection:'column', alignItems:'center', padding:'60px 24px' }}>
        <div style={{ width:'100%', maxWidth:640 }}>
          <div style={{ fontFamily:'var(--font-mono)', fontSize:11, fontWeight:700, letterSpacing:'0.18em', color:'var(--chart-700)', textTransform:'uppercase', marginBottom:10 }}>
            Found you.
          </div>
          <h1 className="display" style={{ fontSize:'clamp(36px,6vw,60px)', fontWeight:500, letterSpacing:'-0.04em', lineHeight:1, margin:'0 0 6px' }}>
            {bizName}
          </h1>
          <p style={{ fontSize:15, color:'var(--mute-1)', margin:'0 0 36px', display:'flex', alignItems:'center', gap:10, flexWrap:'wrap' }}>
            {meta.website_url && <a href={meta.website_url} target="_blank" rel="noreferrer" style={{ color:'var(--lilac-700)', textDecoration:'none', fontWeight:500 }}>{meta.website_url.replace(/^https?:\/\/(www\.)?/, '')}</a>}
            {(w.city || w.state) && <span style={{ color:'var(--mute-3)' }}>·</span>}
            {w.city && <span>{w.city}{w.state ? `, ${w.state}` : ''}</span>}
          </p>

          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14, marginBottom:28 }}>
            {/* Contact */}
            {(w.phone || w.email) && (
              <OSBReviewCard title="Contact" accent="var(--chart-400)">
                {w.phone && <OSBReviewRow label="Phone" value={w.phone}/>}
                {w.email && <OSBReviewRow label="Email" value={w.email}/>}
                {w.founded && <OSBReviewRow label="Est." value={String(w.founded)}/>}
                {w.crew && <OSBReviewRow label="Crew" value={w.crew}/>}
              </OSBReviewCard>
            )}

            {/* Reputation */}
            {(c.reviewCount || c.reviewRating || c.bbb) && (
              <OSBReviewCard title="Reputation" accent="var(--chart-300)">
                {(c.reviewCount || c.reviewRating) && (
                  <OSBReviewRow label="Google" value={`${c.reviewRating ? `★ ${c.reviewRating}` : ''} ${c.reviewCount ? `· ${c.reviewCount} reviews` : ''}`.trim()}/>
                )}
                {c.bbb && <OSBReviewRow label="BBB" value={c.bbb}/>}
              </OSBReviewCard>
            )}

            {/* Trades detected */}
            {trades.length > 0 && (
              <OSBReviewCard title="Trades detected" accent="var(--lilac-500)">
                <div style={{ display:'flex', flexWrap:'wrap', gap:5, marginTop:2 }}>
                  {trades.map(t => (
                    <span key={t} style={{ background:'var(--lilac-100)', color:'var(--lilac-800)', padding:'4px 10px', borderRadius:99, fontSize:12, fontWeight:600 }}>{t}</span>
                  ))}
                </div>
                {s.subTrades?.length > 0 && (
                  <div style={{ marginTop:8, fontSize:11, color:'var(--lilac-700)', fontWeight:600 }}>{s.subTrades.length} specific services found</div>
                )}
              </OSBReviewCard>
            )}

            {/* Credentials */}
            {(c.certs?.length || c.licenses?.length) && (
              <OSBReviewCard title="Credentials" accent="var(--ink)">
                {c.certs?.slice(0,3).map(cert => <OSBReviewRow key={cert} label="" value={cert}/>)}
                {c.licenses?.slice(0,2).map(lic => <OSBReviewRow key={lic} label="Lic" value={lic}/>)}
              </OSBReviewCard>
            )}
          </div>

          {hasSocials && (
            <div style={{ marginBottom:32, padding:'16px 20px', background:'#fff', borderRadius:16, border:'1px solid var(--line-2)' }}>
              <div style={{ fontSize:11, fontWeight:700, letterSpacing:'0.1em', textTransform:'uppercase', color:'var(--mute-1)', marginBottom:10 }}>Web presence found</div>
              <div style={{ display:'flex', flexWrap:'wrap', gap:8 }}>
                {meta.website_url   && <OSBPresenceChip label="Website"   url={meta.website_url}/>}
                {meta.gmb_url       && <OSBPresenceChip label="Google"    url={meta.gmb_url}/>}
                {meta.facebook_url  && <OSBPresenceChip label="Facebook"  url={meta.facebook_url}/>}
                {meta.instagram_url && <OSBPresenceChip label="Instagram" url={meta.instagram_url}/>}
                {meta.yelp_url      && <OSBPresenceChip label="Yelp"      url={meta.yelp_url}/>}
                {meta.linkedin_url  && <OSBPresenceChip label="LinkedIn"  url={meta.linkedin_url}/>}
              </div>
            </div>
          )}

          <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
            <button
              onClick={() => onConfirm(pf)}
              style={{ padding:'16px 28px', background:'var(--ink)', color:'var(--chart-300)', border:0, borderRadius:99, fontFamily:'var(--font-body)', fontWeight:700, fontSize:16, cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', gap:10, boxShadow:'0 12px 32px rgba(12,14,16,0.2)' }}
            >
              <IconCheck size={16} stroke="var(--chart-300)" sw={3}/>
              That's us — build my OS
            </button>
            <button
              onClick={onEdit}
              style={{ padding:'13px 28px', background:'transparent', border:'1px solid var(--line)', color:'var(--mute-1)', borderRadius:99, fontFamily:'var(--font-body)', fontWeight:500, fontSize:14, cursor:'pointer' }}
            >
              Something's off — let me edit
            </button>
          </div>

          <p style={{ marginTop:16, fontSize:12, color:'var(--mute-3)', textAlign:'center', lineHeight:1.5 }}>
            All data sourced from your public website and business listings. Nothing is stored until you submit.
          </p>
        </div>
      </div>
    </div>
  );
}

function OSBReviewCard({ title, accent, children }) {
  return (
    <div style={{ background:'#fff', borderRadius:16, padding:'18px 20px', border:'1px solid var(--line-2)' }}>
      <div style={{ display:'flex', alignItems:'center', gap:7, marginBottom:12 }}>
        <span style={{ width:7, height:7, borderRadius:99, background: accent || 'var(--chart-300)', flexShrink:0 }}/>
        <span style={{ fontSize:11, fontWeight:700, letterSpacing:'0.1em', textTransform:'uppercase', color:'var(--mute-1)' }}>{title}</span>
      </div>
      {children}
    </div>
  );
}

function OSBReviewRow({ label, value }) {
  if (!value) return null;
  return (
    <div style={{ display:'flex', alignItems:'baseline', gap:8, marginBottom:5 }}>
      {label && <span style={{ fontSize:11, color:'var(--mute-2)', minWidth:36, flexShrink:0 }}>{label}</span>}
      <span style={{ fontSize:13.5, fontWeight:500, color:'var(--ink)' }}>{value}</span>
    </div>
  );
}

function OSBPresenceChip({ label, url }) {
  return (
    <a href={url} target="_blank" rel="noreferrer" style={{ display:'inline-flex', alignItems:'center', gap:5, padding:'6px 12px', background:'var(--paper-3)', border:'1px solid var(--line-2)', borderRadius:99, fontSize:12.5, fontWeight:600, color:'var(--ink)', textDecoration:'none', transition:'all 0.15s' }}
      onMouseEnter={e => { e.currentTarget.style.background = 'var(--ink)'; e.currentTarget.style.color = 'var(--chart-300)'; }}
      onMouseLeave={e => { e.currentTarget.style.background = 'var(--paper-3)'; e.currentTarget.style.color = 'var(--ink)'; }}
    >
      {label}
    </a>
  );
}

/* ─── HELPERS ────────────────────────────────────────────────────────────── */
function osbTruncate(str = '', max = 60) {
  return str.length > max ? str.slice(0, max) + '…' : str;
}

Object.assign(window, { OSBOnboardingApp });

// Mount here — runs after all JSX files are loaded, avoiding race conditions
ReactDOM.createRoot(document.getElementById('root')).render(<OSBOnboardingApp />);
