// Science hi-fi — onboarding (5 steps) + report generation
// Uses globals from science-hifi.jsx: SCI, MonoLabel, Pill, SciBtn, Rule, BigFiveBars, EnneaRadar, MBTIStack, Sparkline

// — shared chrome ————————————————————————
function ObProgress({ step, total=5, compact }) {
  return (
    <div style={{ display:'flex', alignItems:'center', gap:compact?10:18 }}>
      <MonoLabel size={10}>Step {String(step).padStart(2,'0')} / {String(total).padStart(2,'0')}</MonoLabel>
      <div style={{ display:'flex', gap:4 }}>
        {Array.from({length:total}).map((_,i)=>(
          <div key={i} style={{
            width: compact?18:28, height:4,
            background: i<step ? SCI.ink : (i===step-1?SCI.orange:SCI.tint),
          }}/>
        ))}
      </div>
    </div>
  );
}

function ObFrameDesktop({ step, title, kicker, lead, children, side, width=1400 }) {
  return (
    <div style={{ width, background:SCI.paper, color:SCI.ink, fontFamily:SCI.body, border:`1px solid ${SCI.ink}` }}>
      {/* top chrome */}
      <div style={{ display:'flex', alignItems:'stretch', height:56, borderBottom:`1px solid ${SCI.ink}` }}>
        <div style={{ padding:'0 28px', display:'flex', alignItems:'center', borderRight:`1px solid ${SCI.ink}`, gap:10 }}>
          <div style={{ width:14, height:14, border:`1.5px solid ${SCI.ink}`, display:'grid', gridTemplateColumns:'1fr 1fr', gridTemplateRows:'1fr 1fr' }}>
            <div style={{background:SCI.ink}}/><div/><div/><div style={{background:SCI.ink}}/>
          </div>
          <div style={{ fontFamily:SCI.display, fontSize:20, fontWeight:500 }}>Persona</div>
        </div>
        <div style={{ flex:1, display:'flex', alignItems:'center', padding:'0 28px', justifyContent:'space-between' }}>
          <MonoLabel>§ Assessment intake · {kicker}</MonoLabel>
          <ObProgress step={step}/>
        </div>
        <div style={{ borderLeft:`1px solid ${SCI.ink}`, padding:'0 20px', display:'flex', alignItems:'center', fontFamily:SCI.mono, fontSize:11, color:SCI.ink3, letterSpacing:0.5 }}>
          SAVE & EXIT
        </div>
      </div>

      {/* body split */}
      <div style={{ display:'grid', gridTemplateColumns:'1.05fr 1fr', minHeight:640 }}>
        <div style={{ padding:'56px 56px 40px', borderRight:`1px solid ${SCI.ink}`, display:'flex', flexDirection:'column', justifyContent:'space-between' }}>
          <div>
            <MonoLabel>Question {step} of 5</MonoLabel>
            <h1 style={{ fontFamily:SCI.display, fontSize:64, lineHeight:0.96, letterSpacing:-1, fontWeight:500, margin:'16px 0 16px' }}>
              {title}
            </h1>
            {lead && <div style={{ maxWidth:440, fontSize:15, lineHeight:1.55, color:SCI.ink2 }}>{lead}</div>}
          </div>
          <div style={{ marginTop:40 }}>{children}</div>
        </div>
        <div style={{ background:SCI.tint2 }}>{side}</div>
      </div>
    </div>
  );
}

// — Step 01 · Name & DOB —————————————————
function ObStep1Desktop() {
  return (
    <ObFrameDesktop
      step={1}
      kicker="Identity"
      title={<>Start with <span style={{fontStyle:'italic'}}>who</span><br/>and <span style={{fontStyle:'italic'}}>when</span>.</>}
      lead="Birth date is the seed value for seven of the ten archetypal instruments. Spelling of name matters for numerology — use what is on your birth certificate."
      side={<ObSideReadout label="Why we ask" figNumber="02" rows={[
        ['Seeds',       '7 archetypal instruments'],
        ['Accuracy',    'Numerology requires name'],
        ['Timezone',    'Not yet — step 03'],
        ['Privacy',     'Deletable anytime'],
      ]}/>}
    >
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:18, maxWidth:560 }}>
        <FieldDesktop label="Given name" value="Jane" hint="as on birth certificate"/>
        <FieldDesktop label="Family name" value="Doe" hint="optional"/>
        <FieldDesktop label="Birth year"  value="1994"/>
        <FieldDesktop label="Month / Day" value="06 / 12" mono/>
      </div>
      <div style={{ marginTop:28, display:'flex', alignItems:'center', gap:16 }}>
        <SciBtn primary size="lg" icon="→">Continue</SciBtn>
        <MonoLabel size={10} style={{color:SCI.ink3}}>↵ ENTER TO CONTINUE</MonoLabel>
      </div>
    </ObFrameDesktop>
  );
}

// — Step 02 · Birth time —————————————————
function ObStep2Desktop() {
  return (
    <ObFrameDesktop
      step={2}
      kicker="Temporal anchor"
      title={<>The <span style={{fontStyle:'italic'}}>time</span><br/>you were born.</>}
      lead="Optional, but the birth time sets the house structure for the astrology and Human Design instruments. Without it, we will still generate a report — flagged with the ~40% of signal that is unavailable."
      side={<ObSideAccuracy/>}
    >
      <div style={{ display:'flex', gap:18, alignItems:'end', maxWidth:560 }}>
        <FieldDesktop label="Hour" value="14" mono w={110}/>
        <div style={{ fontFamily:SCI.display, fontSize:40, paddingBottom:10, color:SCI.ink3 }}>:</div>
        <FieldDesktop label="Minute" value="32" mono w={110}/>
        <FieldDesktop label="Period" value="24-hour" w={180}/>
      </div>
      <div style={{ marginTop:18, display:'flex', gap:10 }}>
        {['Exact','±15 min','±1 hour','Unknown'].map((t,i)=>(
          <Pill key={i} dark={i===0}>{t}</Pill>
        ))}
      </div>
      <div style={{ marginTop:32, display:'flex', gap:14, alignItems:'center' }}>
        <SciBtn size="lg">← Back</SciBtn>
        <SciBtn primary size="lg" icon="→">Continue</SciBtn>
        <span style={{ marginLeft:12, fontFamily:SCI.mono, fontSize:11, color:SCI.ink3, textDecoration:'underline' }}>I don't know my birth time →</span>
      </div>
    </ObFrameDesktop>
  );
}

function ObSideAccuracy() {
  return (
    <div style={{ padding:'56px 40px', display:'flex', flexDirection:'column', gap:20 }}>
      <MonoLabel>FIG. 03 · Time precision → signal</MonoLabel>
      <div style={{ fontFamily:SCI.display, fontSize:22, lineHeight:1.2, letterSpacing:-0.2 }}>
        More precise time, more precise houses.
      </div>
      {/* bar chart: precision vs signal */}
      <div style={{ background:SCI.paper, border:`1px solid ${SCI.ink}`, padding:20 }}>
        {[
          ['Exact',      100, true ],
          ['± 15 min',    92, false],
          ['± 1 hour',    78, false],
          ['± 4 hours',   62, false],
          ['Unknown',     58, false],
        ].map(([l,v,active],i)=>(
          <div key={i} style={{ display:'grid', gridTemplateColumns:'80px 1fr 50px', gap:12, alignItems:'center', padding:'7px 0', borderBottom: i<4?`1px solid ${SCI.tint}`:'none' }}>
            <div style={{ fontFamily:SCI.mono, fontSize:11, color: active?SCI.ink:SCI.ink2 }}>{l}</div>
            <div style={{ height:8, background:SCI.tint, position:'relative' }}>
              <div style={{ position:'absolute', inset:0, right:'auto', width:`${v}%`, background: active?SCI.orange:SCI.ink }}/>
            </div>
            <div style={{ fontFamily:SCI.mono, fontSize:11, textAlign:'right' }}>{v}<span style={{color:SCI.ink3}}>%</span></div>
          </div>
        ))}
      </div>
      <div style={{ fontSize:13, lineHeight:1.5, color:SCI.ink2 }}>
        Rounded guesses are fine — the accuracy tag follows your answer through the report. Exactness is never assumed.
      </div>
    </div>
  );
}

// — Step 03 · Location —————————————————
function ObStep3Desktop() {
  const results = [
    ['Brooklyn, New York · United States', '40.68° N · 73.94° W', true],
    ['Brussels · Belgium',                 '50.85° N · 4.35° E',  false],
    ['Buenos Aires · Argentina',           '34.61° S · 58.38° W', false],
    ['Brasília · Brazil',                  '15.79° S · 47.88° W', false],
  ];
  return (
    <ObFrameDesktop
      step={3}
      kicker="Geographic anchor"
      title={<>Where the sky<br/><span style={{fontStyle:'italic'}}>was, then</span>.</>}
      lead="We use place of birth to compute the coordinates for astrocartography and to resolve timezone for step 02. Cities only — street-level precision is not useful here."
      side={<ObSideWorldMap/>}
    >
      <div style={{ maxWidth:520 }}>
        <FieldDesktop label="Birth location" value="Brook" cursor hint="start typing a city"/>
        <div style={{ border:`1px solid ${SCI.ink}`, borderTop:'none' }}>
          {results.map(([n,c,sel],i)=>(
            <div key={i} style={{
              padding:'12px 16px',
              borderBottom: i<3?`1px solid ${SCI.tint}`:'none',
              background: sel?SCI.tint2:SCI.paper,
              display:'flex', justifyContent:'space-between', alignItems:'center',
            }}>
              <span style={{ fontSize:14 }}>{n}</span>
              <MonoLabel size={10}>{c}</MonoLabel>
            </div>
          ))}
        </div>
      </div>
      <div style={{ marginTop:28, display:'flex', gap:14 }}>
        <SciBtn size="lg">← Back</SciBtn>
        <SciBtn primary size="lg" icon="→">Continue</SciBtn>
      </div>
    </ObFrameDesktop>
  );
}

function ObSideWorldMap() {
  // rough world map with pin on NYC
  return (
    <div style={{ padding:'56px 40px', display:'flex', flexDirection:'column', gap:18 }}>
      <MonoLabel>FIG. 04 · Location preview</MonoLabel>
      <div style={{ background:SCI.paper, border:`1px solid ${SCI.ink}`, padding:20 }}>
        <svg viewBox="0 0 400 220" style={{ width:'100%', height:'auto', display:'block' }}>
          {/* graticule */}
          {Array.from({length:7}).map((_,i)=>(
            <line key={i} x1={40+i*50} y1="20" x2={40+i*50} y2="200" stroke={SCI.tint} strokeWidth="0.5"/>
          ))}
          {Array.from({length:5}).map((_,i)=>(
            <line key={i} x1="20" y1={30+i*40} x2="380" y2={30+i*40} stroke={SCI.tint} strokeWidth="0.5"/>
          ))}
          {/* continents (abstract blocks) */}
          <g fill={SCI.ink} opacity="0.82">
            <path d="M38,70 Q52,56 82,60 L108,72 L110,108 L84,124 L58,118 L42,102 Z"/>
            <path d="M120,160 L138,144 L164,152 L160,196 L138,200 L124,182 Z"/>
            <path d="M180,62 L222,56 L250,72 L244,104 L212,112 L188,98 Z"/>
            <path d="M220,128 L246,124 L258,156 L232,168 L218,148 Z"/>
            <path d="M260,76 L320,62 L354,80 L360,110 L334,128 L294,120 L268,102 Z"/>
            <path d="M306,148 L330,144 L346,162 L322,178 L308,164 Z"/>
          </g>
          {/* pin */}
          <circle cx="88" cy="96" r="14" fill="none" stroke={SCI.orange} strokeWidth="1.5"/>
          <circle cx="88" cy="96" r="5" fill={SCI.orange}/>
          <line x1="88" y1="96" x2="88" y2="20" stroke={SCI.orange} strokeWidth="0.8" strokeDasharray="2 3"/>
          <line x1="88" y1="96" x2="20" y2="96" stroke={SCI.orange} strokeWidth="0.8" strokeDasharray="2 3"/>
          <text x="96" y="92" fontFamily={SCI.mono} fontSize="9" fill={SCI.ink}>BROOKLYN</text>
          <text x="96" y="104" fontFamily={SCI.mono} fontSize="8" fill={SCI.ink3}>40.68° N · 73.94° W</text>
        </svg>
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:10 }}>
        {[['Latitude','40.6782° N'],['Longitude','73.9442° W'],['Timezone','America/New_York'],['UTC offset','−05:00 (DST)']].map(([k,v],i)=>(
          <div key={i} style={{ padding:'10px 12px', background:SCI.paper, border:`1px solid ${SCI.tint}` }}>
            <MonoLabel size={9}>{k}</MonoLabel>
            <div style={{ fontFamily:SCI.mono, fontSize:12, marginTop:4 }}>{v}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// — Step 04 · Psychometric quiz —————————————
function ObStep4Desktop() {
  const answers = ['Strongly disagree','Disagree','Neutral','Agree','Strongly agree'];
  const selected = 3;
  return (
    <ObFrameDesktop
      step={4}
      kicker="Psychometric intake"
      title={<>Agree, or<br/><span style={{fontStyle:'italic'}}>don't</span>.</>}
      lead="Item 24 of 120. Answer on instinct — this is an IRT-scaled instrument and it auto-adjusts to your response pattern. No right answer exists."
      side={<ObSideIRT/>}
    >
      <div style={{ background:SCI.tint2, border:`1px solid ${SCI.ink}`, padding:32, maxWidth:620 }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:14 }}>
          <MonoLabel>Item № 024 · Big Five · Openness</MonoLabel>
          <MonoLabel size={10} style={{color:SCI.ink3}}>Loading: +0.72 O</MonoLabel>
        </div>
        <div style={{ fontFamily:SCI.display, fontSize:30, lineHeight:1.2, letterSpacing:-0.2, marginBottom:28 }}>
          “I find abstract ideas exciting, even when they have no obvious practical use.”
        </div>
        <div style={{ display:'grid', gridTemplateColumns:`repeat(${answers.length}, 1fr)`, gap:8 }}>
          {answers.map((a,i)=>(
            <div key={i} style={{
              padding:'16px 10px 14px',
              border:`1px solid ${SCI.ink}`,
              background: i===selected ? SCI.ink : SCI.paper,
              color:     i===selected ? SCI.paper : SCI.ink,
              textAlign:'center',
            }}>
              <div style={{ fontFamily:SCI.mono, fontSize:10, letterSpacing:1, opacity:0.65, marginBottom:6 }}>{i+1}</div>
              <div style={{ fontSize:12, lineHeight:1.3 }}>{a}</div>
            </div>
          ))}
        </div>
      </div>
      <div style={{ marginTop:28, display:'flex', gap:14, alignItems:'center' }}>
        <SciBtn size="lg">← Previous</SciBtn>
        <SciBtn primary size="lg" icon="→">Continue</SciBtn>
        <MonoLabel size={10} style={{color:SCI.ink3, marginLeft:8}}>KEYS 1–5 · TAB TO SKIP</MonoLabel>
      </div>
    </ObFrameDesktop>
  );
}

function ObSideIRT() {
  return (
    <div style={{ padding:'56px 40px', display:'flex', flexDirection:'column', gap:18 }}>
      <MonoLabel>FIG. 05 · Adaptive progress</MonoLabel>
      <div style={{ fontFamily:SCI.display, fontSize:22, lineHeight:1.2, letterSpacing:-0.2 }}>
        Live calibration of your profile.
      </div>
      <div style={{ background:SCI.paper, border:`1px solid ${SCI.ink}`, padding:20 }}>
        <div style={{ display:'flex', justifyContent:'space-between', marginBottom:6 }}>
          <MonoLabel size={10}>Items answered</MonoLabel>
          <MonoLabel size={10}>24 / 120</MonoLabel>
        </div>
        <div style={{ height:8, background:SCI.tint, position:'relative', marginBottom:14 }}>
          <div style={{ position:'absolute', inset:'0 auto 0 0', width:'20%', background:SCI.orange }}/>
        </div>
        <MonoLabel size={10} style={{marginBottom:6}}>Running Big Five estimate · ±CI</MonoLabel>
        <BigFiveBars values={[78,62,44,58,34]}/>
        <MonoLabel size={10} style={{marginTop:14, display:'block', color:SCI.ink3}}>Confidence band narrows with each item.</MonoLabel>
      </div>
      <div style={{ fontSize:13, lineHeight:1.5, color:SCI.ink2 }}>
        Your profile estimate updates in real time. You can stop anywhere after item 60 — we will flag lower-confidence traits rather than guess.
      </div>
    </div>
  );
}

// — Step 05 · Tier select —————————————————
function ObStep5Desktop() {
  const tiers = [
    { t:'Observation', p:'$0',   per:'forever', selected:false },
    { t:'Blueprint',   p:'$79',  per:'once',    selected:true  },
    { t:'Inner Circle',p:'$199', per:'year',    selected:false },
  ];
  return (
    <ObFrameDesktop
      step={5}
      kicker="Report depth"
      title={<>Choose the<br/><span style={{fontStyle:'italic'}}>depth</span> of report.</>}
      lead="Your assessment is complete. Pick a tier — you can upgrade from any tier at any time. Downgrading just hides content, never deletes it."
      side={<ObSideCheckoutPreview/>}
    >
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:10, maxWidth:620 }}>
        {tiers.map((t,i)=>(
          <div key={i} style={{
            padding:'18px 16px 20px',
            border:`1.5px solid ${t.selected?SCI.ink:SCI.tint}`,
            background: t.selected?SCI.ink:SCI.paper,
            color: t.selected?SCI.paper:SCI.ink,
            position:'relative',
          }}>
            <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:10 }}>
              <MonoLabel size={9} style={{color:t.selected?'rgba(243,239,228,0.6)':SCI.ink3}}>Tier 0{i+1}</MonoLabel>
              <div style={{
                width:14, height:14, borderRadius:8,
                border:`1.5px solid ${t.selected?SCI.paper:SCI.ink3}`,
                background: t.selected?SCI.orange:'transparent',
              }}/>
            </div>
            <div style={{ fontFamily:SCI.display, fontSize:22, lineHeight:1.1 }}>{t.t}</div>
            <div style={{ fontFamily:SCI.display, fontSize:38, lineHeight:1, margin:'10px 0 2px', letterSpacing:-0.5 }}>{t.p}</div>
            <MonoLabel size={10} style={{color:t.selected?'rgba(243,239,228,0.6)':SCI.ink3}}>/ {t.per}</MonoLabel>
          </div>
        ))}
      </div>
      <div style={{ marginTop:22, padding:'14px 18px', background:SCI.tint2, border:`1px solid ${SCI.ink}`, display:'flex', justifyContent:'space-between', alignItems:'center', maxWidth:620 }}>
        <div>
          <MonoLabel>Add-on</MonoLabel>
          <div style={{ fontSize:14, marginTop:4 }}>Relationship pairing — compare with a partner</div>
        </div>
        <div style={{ display:'flex', alignItems:'center', gap:14 }}>
          <div style={{ fontFamily:SCI.display, fontSize:22 }}>+ $29</div>
          <div style={{ width:18, height:18, border:`1.5px solid ${SCI.ink}`, background:SCI.orange, display:'flex', alignItems:'center', justifyContent:'center', fontFamily:SCI.mono, fontSize:12, color:SCI.paper }}>✓</div>
        </div>
      </div>
      <div style={{ marginTop:28, display:'flex', gap:14, alignItems:'center' }}>
        <SciBtn size="lg">← Back</SciBtn>
        <SciBtn primary size="lg" icon="→">Continue to checkout</SciBtn>
        <MonoLabel size={10} style={{color:SCI.ink3, marginLeft:8}}>$108.00 TOTAL</MonoLabel>
      </div>
    </ObFrameDesktop>
  );
}

function ObSideCheckoutPreview() {
  return (
    <div style={{ padding:'56px 40px', display:'flex', flexDirection:'column', gap:18 }}>
      <MonoLabel>FIG. 06 · What you unlock</MonoLabel>
      <div style={{ fontFamily:SCI.display, fontSize:22, lineHeight:1.2, letterSpacing:-0.2 }}>
        Blueprint tier · 10 instruments.
      </div>
      <div style={{ background:SCI.paper, border:`1px solid ${SCI.ink}`, padding:20 }}>
        {[
          ['All 10 instruments computed', true],
          ['Convergence matrix',          true],
          ['~8,000-word editorial report',true],
          ['38-minute narrated audio',    true],
          ['PDF export',                  true],
          ['Relationship pairing',        true],
          ['Quarterly transit update',    false],
          ['Chat with your chart',        false],
        ].map(([l,inc],i)=>(
          <div key={i} style={{ display:'grid', gridTemplateColumns:'20px 1fr', padding:'8px 0', borderBottom: i<7?`1px solid ${SCI.tint}`:'none', fontSize:13, color: inc?SCI.ink:SCI.ink3 }}>
            <span style={{ fontFamily:SCI.mono, fontSize:12, color: inc?SCI.orange:SCI.ink3 }}>{inc?'✓':'·'}</span>
            <span style={{ textDecoration: inc?'none':'line-through' }}>{l}</span>
          </div>
        ))}
      </div>
      <div style={{ padding:'12px 14px', border:`1px dashed ${SCI.ink}`, fontSize:12, color:SCI.ink2, background:'rgba(198,90,42,0.05)' }}>
        Upgrade to Inner Circle post-purchase for the last two — retroactive credit applied.
      </div>
    </div>
  );
}

// — Field ————————————————————
function FieldDesktop({ label, value, hint, mono, w, cursor }) {
  return (
    <div style={{ width:w }}>
      <MonoLabel size={10} style={{ display:'block', marginBottom:6 }}>{label}</MonoLabel>
      <div style={{ height:48, border:`1px solid ${SCI.ink}`, display:'flex', alignItems:'center', padding:'0 14px', background:SCI.paper }}>
        <span style={{ fontFamily: mono?SCI.mono:SCI.body, fontSize: mono?14:15 }}>{value}</span>
        {cursor && <span style={{ display:'inline-block', width:1.5, height:20, background:SCI.ink, marginLeft:2, animation:'none' }}/>}
      </div>
      {hint && <MonoLabel size={9} style={{ display:'block', marginTop:6, color:SCI.ink3 }}>{hint}</MonoLabel>}
    </div>
  );
}

// —————————————————————————————
// Readout side (shared style)
function ObSideReadout({ label, figNumber, rows, extra }) {
  return (
    <div style={{ padding:'56px 40px', display:'flex', flexDirection:'column', gap:18 }}>
      <MonoLabel>FIG. {figNumber} · {label}</MonoLabel>
      <div style={{ fontFamily:SCI.display, fontSize:26, lineHeight:1.15, letterSpacing:-0.2 }}>
        Every field has a purpose. Here are yours.
      </div>
      <div style={{ background:SCI.paper, border:`1px solid ${SCI.ink}` }}>
        {rows.map(([k,v],i)=>(
          <div key={i} style={{ display:'grid', gridTemplateColumns:'110px 1fr', gap:12, padding:'12px 16px', borderBottom: i<rows.length-1?`1px solid ${SCI.tint}`:'none' }}>
            <MonoLabel size={10}>{k}</MonoLabel>
            <div style={{ fontSize:13, lineHeight:1.4 }}>{v}</div>
          </div>
        ))}
      </div>
      {extra}
      <div style={{ fontSize:13, lineHeight:1.5, color:SCI.ink2 }}>
        The intake instrument adapts to your answers. The fewer guesses, the tighter the confidence band on your final report.
      </div>
    </div>
  );
}

// =========================================================
// Report generation — the 120-second compute screen
// =========================================================
function SciReportGen() {
  const insts = [
    { n:'Big Five (OCEAN)',   cat:'Psychometric',   s:'done'    , t:'00:12' },
    { n:'MBTI 16-Type',       cat:'Typological',    s:'done'    , t:'00:18' },
    { n:'Enneagram',          cat:'Typological',    s:'done'    , t:'00:07' },
    { n:'Human Design',       cat:'Synthetic',      s:'active'  , t:'00:09' },
    { n:'Western astrology',  cat:'Archetypal',     s:'pending' , t:'—' },
    { n:'Numerology',         cat:'Archetypal',     s:'pending' , t:'—' },
    { n:'Astrocartography',   cat:'Archetypal',     s:'pending' , t:'—' },
    { n:'I Ching',            cat:'Archetypal',     s:'pending' , t:'—' },
    { n:'Gene Keys',          cat:'Archetypal',     s:'pending' , t:'—' },
    { n:'Chinese astrology',  cat:'Archetypal',     s:'pending' , t:'—' },
  ];
  return (
    <div style={{ width:1400, background:SCI.paper, color:SCI.ink, fontFamily:SCI.body, border:`1px solid ${SCI.ink}` }}>
      <div style={{ display:'flex', alignItems:'stretch', height:56, borderBottom:`1px solid ${SCI.ink}` }}>
        <div style={{ padding:'0 28px', display:'flex', alignItems:'center', gap:10, borderRight:`1px solid ${SCI.ink}` }}>
          <div style={{ width:14, height:14, border:`1.5px solid ${SCI.ink}`, display:'grid', gridTemplateColumns:'1fr 1fr', gridTemplateRows:'1fr 1fr' }}>
            <div style={{background:SCI.ink}}/><div/><div/><div style={{background:SCI.ink}}/>
          </div>
          <div style={{ fontFamily:SCI.display, fontSize:20 }}>Persona</div>
        </div>
        <div style={{ flex:1, padding:'0 28px', display:'flex', alignItems:'center', justifyContent:'space-between' }}>
          <MonoLabel>§ Compute · Blueprint build</MonoLabel>
          <MonoLabel size={10} style={{color:SCI.ink3}}>DO NOT CLOSE TAB · EST 02:12 REMAINING</MonoLabel>
        </div>
      </div>

      <div style={{ display:'grid', gridTemplateColumns:'1.1fr 1fr', minHeight:720 }}>
        {/* Left — running log of instruments */}
        <div style={{ padding:'48px 56px', borderRight:`1px solid ${SCI.ink}` }}>
          <MonoLabel>§ 01 · Instruments</MonoLabel>
          <h1 style={{ fontFamily:SCI.display, fontSize:56, lineHeight:0.95, letterSpacing:-0.8, fontWeight:500, margin:'12px 0 12px' }}>
            Computing your<br/><span style={{fontStyle:'italic'}}>blueprint</span>.
          </h1>
          <div style={{ fontSize:15, lineHeight:1.55, color:SCI.ink2, marginBottom:24, maxWidth:520 }}>
            Each instrument runs in isolation, then we compute their pairwise agreement. This page will auto-advance when the build completes.
          </div>

          <div style={{ border:`1px solid ${SCI.ink}`, marginTop:6 }}>
            <div style={{ display:'grid', gridTemplateColumns:'40px 1.4fr 1fr 80px 70px', padding:'10px 16px', borderBottom:`1px solid ${SCI.ink}`, background:SCI.tint2 }}>
              {['№','Instrument','Category','Time','Status'].map((h,i)=>(<MonoLabel key={i} size={9}>{h}</MonoLabel>))}
            </div>
            {insts.map((it,i)=>(
              <div key={i} style={{
                display:'grid', gridTemplateColumns:'40px 1.4fr 1fr 80px 70px',
                padding:'12px 16px',
                borderBottom: i<insts.length-1?`1px solid ${SCI.tint}`:'none',
                alignItems:'center',
                background: it.s==='active'?'rgba(198,90,42,0.06)':SCI.paper,
              }}>
                <span style={{ fontFamily:SCI.mono, fontSize:11, color:SCI.ink3 }}>{String(i+1).padStart(2,'0')}</span>
                <span style={{ fontSize:14 }}>{it.n}</span>
                <MonoLabel size={10} style={{color:SCI.ink3}}>{it.cat}</MonoLabel>
                <span style={{ fontFamily:SCI.mono, fontSize:11, color:SCI.ink2 }}>{it.t}</span>
                <span style={{ fontFamily:SCI.mono, fontSize:10, letterSpacing:0.5, textTransform:'uppercase',
                  color: it.s==='done'?SCI.ink:(it.s==='active'?SCI.orange:SCI.ink3) }}>
                  {it.s==='done'?'✓ done':(it.s==='active'?'● running':'· pending')}
                </span>
              </div>
            ))}
          </div>
        </div>

        {/* Right — progress + live preview */}
        <div style={{ padding:'48px 56px', background:SCI.tint2, display:'flex', flexDirection:'column', gap:24 }}>
          <div>
            <MonoLabel>§ 02 · Progress</MonoLabel>
            <div style={{ fontFamily:SCI.display, fontSize:88, lineHeight:0.95, letterSpacing:-1.5, fontWeight:500, marginTop:14 }}>
              36<span style={{color:SCI.orange, fontSize:40, verticalAlign:'super'}}>%</span>
            </div>
            <div style={{ marginTop:14, background:SCI.paper, border:`1px solid ${SCI.ink}`, padding:4, height:14 }}>
              <div style={{ width:'36%', height:'100%', background:SCI.ink, position:'relative' }}>
                <div style={{ position:'absolute', right:0, top:-4, bottom:-4, width:2, background:SCI.orange }}/>
              </div>
            </div>
            <div style={{ display:'flex', justifyContent:'space-between', marginTop:8, fontFamily:SCI.mono, fontSize:10, color:SCI.ink3 }}>
              <span>00:00</span><span>ELAPSED 00:48</span><span>EST 02:12</span>
            </div>
          </div>

          {/* Live preview — what's being computed now */}
          <div style={{ background:SCI.paper, border:`1px solid ${SCI.ink}`, padding:22 }}>
            <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:12 }}>
              <MonoLabel>Now computing · Human Design</MonoLabel>
              <Pill dark>Type · Projector</Pill>
            </div>
            <svg viewBox="0 0 220 180" style={{ width:'100%', height:180 }}>
              {/* abstract body graph */}
              {[[110,22,'△'],[110,56,'□'],[110,90,'□'],[110,124,'□'],[110,158,'▽'],[78,78,'◇'],[142,78,'◇'],[78,118,'○'],[142,118,'○']].map(([x,y],i)=>(
                <g key={i}>
                  <polygon points={`${x},${y-10} ${x+10},${y} ${x},${y+10} ${x-10},${y}`} fill={i%3===0?SCI.orange:'none'} stroke={SCI.ink} strokeWidth="1"/>
                </g>
              ))}
              <line x1="110" y1="32" x2="110" y2="46" stroke={SCI.ink}/>
              <line x1="110" y1="66" x2="110" y2="80" stroke={SCI.ink}/>
              <line x1="110" y1="100" x2="110" y2="114" stroke={SCI.ink}/>
              <line x1="110" y1="134" x2="110" y2="148" stroke={SCI.ink}/>
              <line x1="88" y1="78" x2="100" y2="78" stroke={SCI.ink}/>
              <line x1="120" y1="78" x2="132" y2="78" stroke={SCI.ink}/>
              <line x1="88" y1="118" x2="100" y2="118" stroke={SCI.ink}/>
              <line x1="120" y1="118" x2="132" y2="118" stroke={SCI.ink}/>
            </svg>
            <div style={{ fontFamily:SCI.mono, fontSize:10, letterSpacing:0.3, color:SCI.ink3, marginTop:4, lineHeight:1.5 }}>
              &gt; resolving design-position ephemeris · 88d prior to birth<br/>
              &gt; computing gate activations · 64/64 channels<br/>
              &gt; <span style={{color:SCI.orange}}>● projector · emotional authority</span>
            </div>
          </div>

          <div style={{ fontSize:13, lineHeight:1.55, color:SCI.ink2 }}>
            Once all ten are computed, the convergence engine produces the ~2,300 pairwise scores that drive your final editorial report.
          </div>
        </div>
      </div>
    </div>
  );
}

// ———— Mobile variants ————
function ObStepMobile({ step, kicker, title, children, footer }) {
  return (
    <div style={{ width:390, background:SCI.paper, color:SCI.ink, fontFamily:SCI.body, border:`1px solid ${SCI.ink}` }}>
      <div style={{ height:52, borderBottom:`1px solid ${SCI.ink}`, display:'flex', alignItems:'center', padding:'0 18px', justifyContent:'space-between' }}>
        <div style={{ display:'flex', alignItems:'center', gap:8 }}>
          <div style={{ width:14, height:14, border:`1.5px solid ${SCI.ink}`, display:'grid', gridTemplateColumns:'1fr 1fr', gridTemplateRows:'1fr 1fr' }}>
            <div style={{background:SCI.ink}}/><div/><div/><div style={{background:SCI.ink}}/>
          </div>
          <div style={{ fontFamily:SCI.display, fontSize:18 }}>Persona</div>
        </div>
        <MonoLabel size={9} style={{color:SCI.ink3}}>SAVE & EXIT</MonoLabel>
      </div>
      <div style={{ padding:'12px 18px', borderBottom:`1px solid ${SCI.tint}`, display:'flex', justifyContent:'space-between', alignItems:'center' }}>
        <MonoLabel size={10}>{kicker}</MonoLabel>
        <ObProgress step={step} compact/>
      </div>
      <div style={{ padding:'26px 20px 32px' }}>
        <MonoLabel>Question {step} of 5</MonoLabel>
        <h1 style={{ fontFamily:SCI.display, fontSize:42, lineHeight:0.95, letterSpacing:-0.5, fontWeight:500, margin:'10px 0 18px' }}>
          {title}
        </h1>
        {children}
      </div>
      <div style={{ borderTop:`1px solid ${SCI.ink}`, padding:'16px 20px 20px', display:'flex', flexDirection:'column', gap:10 }}>
        {footer}
      </div>
    </div>
  );
}

function ObStep1Mobile() {
  return (
    <ObStepMobile step={1} kicker="§ Identity" title={<>Who and <span style={{fontStyle:'italic'}}>when</span>.</>}
      footer={<><SciBtn primary size="lg" w="100%" icon="→">Continue</SciBtn><MonoLabel size={9} style={{color:SCI.ink3, textAlign:'center'}}>↵ ENTER</MonoLabel></>}>
      <FieldDesktop label="Given name" value="Jane" hint="as on birth certificate"/>
      <div style={{height:14}}/>
      <FieldDesktop label="Family name" value="Doe" hint="optional"/>
      <div style={{height:14}}/>
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:10 }}>
        <FieldDesktop label="Year"    value="1994" mono/>
        <FieldDesktop label="MM / DD" value="06 / 12" mono/>
      </div>
    </ObStepMobile>
  );
}

function ObStep2Mobile() {
  return (
    <ObStepMobile step={2} kicker="§ Time" title={<>The <span style={{fontStyle:'italic'}}>time</span>.</>}
      footer={<><SciBtn primary size="lg" w="100%" icon="→">Continue</SciBtn><span style={{ fontFamily:SCI.mono, fontSize:10, color:SCI.ink3, textAlign:'center', textDecoration:'underline' }}>I don't know my birth time →</span></>}>
      <div style={{ fontSize:14, lineHeight:1.5, color:SCI.ink2, marginBottom:16 }}>
        Sets the house structure for astrology + Human Design. Optional, but precision increases report signal.
      </div>
      <div style={{ display:'flex', gap:10, alignItems:'end' }}>
        <FieldDesktop label="Hour" value="14" mono w={100}/>
        <div style={{ fontFamily:SCI.display, fontSize:36, paddingBottom:6, color:SCI.ink3 }}>:</div>
        <FieldDesktop label="Min" value="32" mono w={100}/>
      </div>
      <div style={{ marginTop:14, display:'flex', gap:6, flexWrap:'wrap' }}>
        {['Exact','±15','±1 h','Unknown'].map((t,i)=>(<Pill key={i} dark={i===0}>{t}</Pill>))}
      </div>
    </ObStepMobile>
  );
}

function ObStep3Mobile() {
  return (
    <ObStepMobile step={3} kicker="§ Place" title={<>Where the<br/><span style={{fontStyle:'italic'}}>sky was</span>.</>}
      footer={<SciBtn primary size="lg" w="100%" icon="→">Continue</SciBtn>}>
      <FieldDesktop label="Birth location" value="Brook" cursor hint="cities only"/>
      <div style={{ border:`1px solid ${SCI.ink}`, borderTop:'none' }}>
        {[['Brooklyn, NY · USA',true],['Brussels · BE',false],['Buenos Aires · AR',false]].map(([n,sel],i)=>(
          <div key={i} style={{ padding:'12px 14px', background: sel?SCI.tint2:SCI.paper, borderBottom: i<2?`1px solid ${SCI.tint}`:'none', fontSize:13 }}>
            {n}
          </div>
        ))}
      </div>
    </ObStepMobile>
  );
}

function ObStep4Mobile() {
  return (
    <ObStepMobile step={4} kicker="§ Intake · 24/120" title={<>Agree, or <span style={{fontStyle:'italic'}}>don't</span>.</>}
      footer={<><SciBtn primary size="lg" w="100%" icon="→">Continue</SciBtn><MonoLabel size={9} style={{color:SCI.ink3, textAlign:'center'}}>ITEM 024 · OPENNESS</MonoLabel></>}>
      <div style={{ background:SCI.tint2, border:`1px solid ${SCI.ink}`, padding:20, marginBottom:16 }}>
        <div style={{ fontFamily:SCI.display, fontSize:22, lineHeight:1.2, letterSpacing:-0.2 }}>
          “I find abstract ideas exciting, even when they have no obvious use.”
        </div>
      </div>
      <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
        {['Strongly disagree','Disagree','Neutral','Agree','Strongly agree'].map((a,i)=>(
          <div key={i} style={{
            padding:'12px 14px',
            border:`1px solid ${SCI.ink}`,
            background: i===3?SCI.ink:SCI.paper, color: i===3?SCI.paper:SCI.ink,
            display:'flex', justifyContent:'space-between', alignItems:'center',
          }}>
            <span style={{ fontSize:13 }}>{a}</span>
            <MonoLabel size={10} style={{color: i===3?'rgba(243,239,228,0.6)':SCI.ink3}}>{i+1}</MonoLabel>
          </div>
        ))}
      </div>
    </ObStepMobile>
  );
}

function ObStep5Mobile() {
  return (
    <ObStepMobile step={5} kicker="§ Depth" title={<>Choose <span style={{fontStyle:'italic'}}>depth</span>.</>}
      footer={<><SciBtn primary size="lg" w="100%" icon="→">Continue to checkout</SciBtn><MonoLabel size={9} style={{color:SCI.ink3, textAlign:'center'}}>$108.00 TOTAL</MonoLabel></>}>
      <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
        {[
          {t:'Observation', p:'$0', per:'forever', sel:false},
          {t:'Blueprint', p:'$79', per:'once', sel:true},
          {t:'Inner Circle', p:'$199', per:'year', sel:false},
        ].map((t,i)=>(
          <div key={i} style={{
            padding:'14px 16px',
            border:`1.5px solid ${t.sel?SCI.ink:SCI.tint}`,
            background: t.sel?SCI.ink:SCI.paper,
            color: t.sel?SCI.paper:SCI.ink,
            display:'flex', justifyContent:'space-between', alignItems:'center',
          }}>
            <div>
              <div style={{ fontFamily:SCI.display, fontSize:20, lineHeight:1 }}>{t.t}</div>
              <MonoLabel size={9} style={{color:t.sel?'rgba(243,239,228,0.6)':SCI.ink3, marginTop:4, display:'block'}}>/ {t.per}</MonoLabel>
            </div>
            <div style={{ fontFamily:SCI.display, fontSize:26 }}>{t.p}</div>
          </div>
        ))}
      </div>
      <div style={{ marginTop:14, padding:'12px 14px', background:SCI.tint2, border:`1px solid ${SCI.ink}`, display:'flex', justifyContent:'space-between', alignItems:'center' }}>
        <div>
          <MonoLabel size={10}>Add-on</MonoLabel>
          <div style={{ fontSize:13, marginTop:3 }}>Relationship pairing</div>
        </div>
        <div style={{ display:'flex', alignItems:'center', gap:10 }}>
          <span style={{ fontFamily:SCI.display, fontSize:18 }}>+$29</span>
          <div style={{ width:18, height:18, border:`1.5px solid ${SCI.ink}`, background:SCI.orange, display:'flex', alignItems:'center', justifyContent:'center', fontFamily:SCI.mono, fontSize:11, color:SCI.paper }}>✓</div>
        </div>
      </div>
    </ObStepMobile>
  );
}

function SciReportGenMobile() {
  return (
    <div style={{ width:390, background:SCI.paper, color:SCI.ink, fontFamily:SCI.body, border:`1px solid ${SCI.ink}` }}>
      <div style={{ height:52, borderBottom:`1px solid ${SCI.ink}`, display:'flex', alignItems:'center', padding:'0 18px', justifyContent:'space-between' }}>
        <div style={{fontFamily:SCI.display, fontSize:18}}>Persona</div>
        <MonoLabel size={9} style={{color:SCI.ink3}}>DO NOT CLOSE</MonoLabel>
      </div>
      <div style={{ padding:'32px 20px 24px' }}>
        <MonoLabel>§ Compute</MonoLabel>
        <h1 style={{ fontFamily:SCI.display, fontSize:40, lineHeight:0.95, letterSpacing:-0.5, fontWeight:500, margin:'10px 0 18px' }}>
          Computing your <span style={{fontStyle:'italic'}}>blueprint</span>.
        </h1>
        <div style={{ fontFamily:SCI.display, fontSize:72, lineHeight:0.95, letterSpacing:-1.2, fontWeight:500 }}>
          36<span style={{color:SCI.orange, fontSize:32, verticalAlign:'super'}}>%</span>
        </div>
        <div style={{ height:12, background:SCI.paper, border:`1px solid ${SCI.ink}`, padding:3, marginTop:12 }}>
          <div style={{ width:'36%', height:'100%', background:SCI.ink }}/>
        </div>
        <div style={{ display:'flex', justifyContent:'space-between', fontFamily:SCI.mono, fontSize:10, color:SCI.ink3, marginTop:6 }}>
          <span>ELAPSED 00:48</span><span>EST 02:12</span>
        </div>
      </div>
      <div style={{ borderTop:`1px solid ${SCI.ink}`, padding:'16px 20px' }}>
        <MonoLabel>Instruments · 3 of 10 complete</MonoLabel>
        <div style={{ marginTop:10 }}>
          {[['Big Five','done'],['MBTI','done'],['Enneagram','done'],['Human Design','active'],['Astrology','pending'],['Numerology','pending'],['Astrocartography','pending'],['I Ching','pending'],['Gene Keys','pending'],['Chinese','pending']].map(([n,s],i)=>(
            <div key={i} style={{ display:'flex', justifyContent:'space-between', padding:'9px 0', borderBottom: i<9?`1px solid ${SCI.tint}`:'none', fontSize:13, background: s==='active'?'rgba(198,90,42,0.06)':'transparent' }}>
              <span>{n}</span>
              <span style={{ fontFamily:SCI.mono, fontSize:10, letterSpacing:0.5, textTransform:'uppercase', color: s==='done'?SCI.ink:(s==='active'?SCI.orange:SCI.ink3) }}>
                {s==='done'?'✓':(s==='active'?'●':'·')} {s}
              </span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  ObStep1Desktop, ObStep2Desktop, ObStep3Desktop, ObStep4Desktop, ObStep5Desktop,
  ObStep1Mobile, ObStep2Mobile, ObStep3Mobile, ObStep4Mobile, ObStep5Mobile,
  SciReportGen, SciReportGenMobile,
});
