// H2Learn — supporting screens
// Landing, Onboarding, Dashboard, Explorer, Admin, States

(function() {
  const D = window.H2Data;
  const { useState } = React;

  // ============ LANDING ============
  const LandingScreen = () => (
    <div style={{background:'var(--bg)'}}>
      {/* nav */}
      <header style={{padding:'20px 40px', borderBottom:'1px solid var(--line)'}}>
        <div className="row items-center justify-between" style={{maxWidth: 1400, margin:'0 auto'}}>
          <div className="row items-center gap-2">
            <div style={{width:32,height:32,background:'var(--ink)',borderRadius:'var(--r-2)',display:'flex',alignItems:'center',justifyContent:'center',color:'var(--surface)',fontFamily:'var(--font-display)',fontSize:18}}>H</div>
            <div className="col" style={{lineHeight:1.1}}>
              <span style={{fontWeight:600}}>H2Learn</span>
              <span style={{fontSize:10.5,color:'var(--ink-3)',textTransform:'uppercase',letterSpacing:'0.08em'}}>Knowledge Match Maker</span>
            </div>
          </div>
          <nav className="row items-center gap-1">
            <Btn variant="ghost" size="sm">How it works</Btn>
            <Btn variant="ghost" size="sm">How it works</Btn>
            <Btn variant="ghost" size="sm">For curators</Btn>
            <Btn variant="ghost" size="sm" onClick={() => location.hash='dashboard'}>Sign in</Btn>
            <Btn variant="primary" size="sm" onClick={() => location.hash='onboarding'}>Start profile</Btn>
          </nav>
        </div>
      </header>

      {/* hero */}
      <section style={{padding:'80px 40px 60px', maxWidth:1400, margin:'0 auto'}}>
        <div className="grid cols-12" style={{gap: 48, alignItems:'center'}}>
          <div className="col-span-7 col gap-5">
            <Chip variant="outline"><span style={{width:6,height:6,borderRadius:'50%',background:'var(--moss)'}}/>Open beta · NL hydrogen ecosystem</Chip>
            <h1 style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-hero)', fontWeight:400, margin:0, letterSpacing:'-0.025em', lineHeight:1.0}}>
              The hydrogen learning ecosystem,<br/>
              <span style={{color:'var(--accent)', fontStyle:'italic'}}>finally connected.</span>
            </h1>
            <p style={{fontSize:'var(--t-lg)', color:'var(--ink-2)', lineHeight: 1.5, margin:0, maxWidth: 580, textWrap:'pretty'}}>
              Build a structured profile. Discover relevant peers, projects, methods, and shared challenges. Understand <em>why</em> every match matters.
            </p>
            <div className="row gap-3 items-center" style={{marginTop: 8}}>
              <Btn variant="accent" size="lg" icon="user" onClick={() => location.hash='onboarding'}>Start profile</Btn>
              <Btn variant="ghost" size="lg" icon="eye" onClick={() => location.hash='network'}>Explore demo</Btn>
            </div>
            <div className="row gap-6 items-center" style={{marginTop: 16, fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>
              <span>Built with HvA · TU Delft · TNO</span>
              <span>·</span>
              <span>248 stakeholders · 134 explainable matches</span>
            </div>
          </div>
          <div className="col-span-5">
            <LandingGraphic/>
          </div>
        </div>
      </section>

      {/* how it works */}
      <section style={{padding:'40px 40px 80px', borderTop:'1px solid var(--line)', background:'var(--surface)'}}>
        <div style={{maxWidth:1400, margin:'0 auto'}}>
          <div className="section-head">
            <div className="col">
              <div className="eyebrow">How it works</div>
              <h2>From questionnaire to graph in four moves.</h2>
            </div>
          </div>
          <div className="grid cols-4" style={{gap: 16}}>
            {[
              {n:'01', l:'Profile',   d:'A guided questionnaire captures identity, expertise, projects, needs, offers, bottlenecks, uncertainties.'},
              {n:'02', l:'Normalize', d:'Answers are normalized into structured entities and tagged via a shared taxonomy.'},
              {n:'03', l:'Match',     d:'Nine algorithm families compare profiles and projects, then create explainable relationship edges.'},
              {n:'04', l:'Explore',   d:'Browse the ecosystem as an atlas. Every match shows you the data behind it.'},
            ].map(s => (
              <Card key={s.n} variant="elevated" style={{padding: 24}}>
                <div style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-3xl)', color:'var(--accent)', letterSpacing:'-0.02em', lineHeight:1}}>{s.n}</div>
                <div style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-xl)', marginTop: 16, letterSpacing:'-0.015em', lineHeight: 1.1}}>{s.l}</div>
                <p style={{fontSize:'var(--t-sm)', color:'var(--ink-2)', lineHeight: 1.55, marginTop: 8, marginBottom: 0}}>{s.d}</p>
              </Card>
            ))}
          </div>
        </div>
      </section>

      {/* three pillars */}
      <section style={{padding:'80px 40px', maxWidth: 1400, margin:'0 auto'}}>
        <div className="grid cols-3" style={{gap: 16}}>
          <PillarCard
            eyebrow="Network"
            title="See the ecosystem as an atlas"
            body="Switch between force-directed clusters, ecosystem rings, ego networks, anti-duplication, need-offer flows, and shortest-path views."
            cta="Open the network"
            href="network"/>
          <PillarCard
            eyebrow="Match detail"
            title="Trust every recommendation"
            body="Each match shows a side-by-side, narrative, and signal-dashboard view — and links every signal back to questionnaire data."
            cta="See a match"
            href="match"
            highlight/>
          <PillarCard
            eyebrow="Algorithms"
            title="No black box"
            body="Nine algorithm families with plain-English names, formulas, and worked examples. Curators can review and approve any edge."
            cta="How matching works"
            href="algorithms"/>
        </div>
      </section>

      {/* footer */}
      <footer style={{padding:'40px', borderTop:'1px solid var(--line)', background:'var(--surface)', fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>
        <div className="row justify-between" style={{maxWidth: 1400, margin:'0 auto'}}>
          <div>© H2Learn · A research-tech prototype</div>
          <div className="row gap-4">
            <a href="#admin" style={{color:'inherit'}}>For curators</a>
            <a href="#algorithms" style={{color:'inherit'}}>Algorithms</a>
            <a href="#" style={{color:'inherit'}}>Privacy</a>
          </div>
        </div>
      </footer>
    </div>
  );

  const PillarCard = ({eyebrow, title, body, cta, href, highlight}) => (
    <Card variant={highlight?'elevated':''} style={{padding: 28, background: highlight?'var(--ink)':'var(--surface)', color: highlight?'var(--surface)':'var(--ink)', border: highlight?'none':'1px solid var(--line)'}}>
      <div className="eyebrow" style={{color: highlight?'var(--warm)':'var(--ink-3)'}}>{eyebrow}</div>
      <h3 style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-2xl)', fontWeight:400, margin: '8px 0 16px', letterSpacing:'-0.015em', lineHeight: 1.1}}>{title}</h3>
      <p style={{fontSize:'var(--t-md)', lineHeight: 1.55, color: highlight?'var(--surface-3)':'var(--ink-2)', marginBottom: 24}}>{body}</p>
      <Btn variant={highlight?'warm':'ghost'} icon="arrowRight" onClick={() => location.hash=href}>{cta}</Btn>
    </Card>
  );

  // mini graph for landing
  const LandingGraphic = () => (
    <div style={{position:'relative', aspectRatio:'1', background:'var(--surface-2)', border:'1px solid var(--line)', borderRadius:'var(--r-5)', overflow:'hidden'}}>
      <div className="canvas-bg" style={{position:'absolute', inset: 0}}/>
      <svg viewBox="0 0 480 480" style={{position:'relative', width:'100%', height:'100%'}}>
        <ellipse cx="200" cy="200" rx="140" ry="120" fill="var(--c-person)" opacity="0.08"/>
        <ellipse cx="320" cy="300" rx="120" ry="100" fill="var(--c-project)" opacity="0.08"/>

        {/* edges */}
        <path d="M 160 180 Q 240 100, 320 180" stroke="var(--e-similar)" strokeWidth="2" fill="none" opacity="0.5"/>
        <path d="M 200 240 Q 280 280, 340 320" stroke="var(--e-comp)" strokeWidth="3.5" fill="none"/>
        <path d="M 200 240 L 130 280" stroke="var(--e-similar)" strokeWidth="1.8" fill="none" opacity="0.5"/>
        <path d="M 130 280 Q 200 360, 320 320" stroke="var(--e-bridge)" strokeWidth="2" fill="none" opacity="0.6"/>
        <path d="M 160 180 L 130 280" stroke="var(--e-similar)" strokeWidth="1.5" fill="none" opacity="0.4"/>
        <path d="M 200 240 Q 260 220, 320 180" stroke="var(--e-similar)" strokeWidth="2" fill="none" opacity="0.5"/>
        <path d="M 320 180 Q 360 240, 340 320" stroke="var(--e-similar)" strokeWidth="1.5" fill="none" opacity="0.4"/>
        <path d="M 130 280 Q 240 380, 380 380" stroke="var(--e-antidup)" strokeWidth="1.6" fill="none" strokeDasharray="5 4" opacity="0.5"/>

        {/* nodes */}
        {[
          {x:160, y:180, l:'SA', c:'var(--c-person)', r:22, focal: true},
          {x:320, y:180, l:'LK', c:'var(--c-person)', r:18},
          {x:200, y:240, l:'P', c:'var(--c-domain)', r:12},
          {x:130, y:280, l:'BJ', c:'var(--c-person)', r:16},
          {x:340, y:320, l:'HN', c:'var(--c-project)', r:24, hex:true, recommended: true},
          {x:380, y:380, l:'IH', c:'var(--c-person)', r:18},
          {x:260, y:380, l:'EL', c:'var(--c-project)', r:14, hex: true},
        ].map((n,i) => (
          <g key={i}>
            {n.recommended && <circle cx={n.x} cy={n.y} r={n.r+8} fill="none" stroke={n.c} strokeWidth="1.5" className="pulse-glow"/>}
            {n.focal && <circle cx={n.x} cy={n.y} r={n.r+6} fill="none" stroke={n.c} strokeWidth="2" opacity="0.5"/>}
            {n.hex
              ? <polygon points={hexPoints(n.x, n.y, n.r)} fill="#fff" stroke={n.c} strokeWidth="2"/>
              : <circle cx={n.x} cy={n.y} r={n.r} fill="#fff" stroke={n.c} strokeWidth="2"/>}
            <text x={n.x} y={n.y+4} textAnchor="middle" fontFamily="Inter Tight" fontSize={n.r > 18 ? 12 : 10} fontWeight="600" fill={n.c}>{n.l}</text>
          </g>
        ))}
      </svg>
      <div style={{position:'absolute', top: 16, left: 16, padding: '6px 10px', background:'var(--surface-2)', border:'1px solid var(--line)', borderRadius:'var(--r-2)', fontSize: 10.5, color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'0.08em'}}>Atlas · live preview</div>
      <div style={{position:'absolute', bottom: 16, right: 16, padding: '8px 12px', background:'var(--surface-2)', border:'1px solid var(--line)', borderRadius:'var(--r-2)', boxShadow:'var(--shadow-1)', maxWidth: 200}}>
        <div style={{fontSize: 10.5, color:'var(--accent)', fontWeight:600, textTransform:'uppercase', letterSpacing:'0.08em'}}>★ Top match</div>
        <div style={{fontSize:'var(--t-sm)', fontWeight:600, marginTop: 2}}>Sara × HYDRO-NL</div>
        <div style={{fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>Complementarity · 88%</div>
      </div>
    </div>
  );

  function hexPoints(x, y, r) {
    return Array.from({length:6}).map((_,i) => {
      const a = -Math.PI/2 + i * Math.PI/3;
      return [x + r*Math.cos(a), y + r*Math.sin(a)].join(',');
    }).join(' ');
  }

  // ============ ONBOARDING ============
  const ONBOARDING_STEPS = [
    { id:'identity',     l:'Identity',         icon:'user',     d:'Who you are' },
    { id:'knowledge',    l:'Knowledge',        icon:'book',     d:'Your expertise weighting' },
    { id:'project',      l:'Project',          icon:'flask',    d:'Active research/practice context' },
    { id:'challenges',   l:'Challenges',       icon:'target',   d:'Open problems you face' },
    { id:'bottlenecks',  l:'Bottlenecks',      icon:'alert',    d:'Where progress is blocked' },
    { id:'uncertainties',l:'Uncertainties',    icon:'compass',  d:'What you don\'t know yet' },
    { id:'evidence',     l:'Evidence',         icon:'sparkles', d:'Optional anchors · papers, datasets' },
    { id:'review',       l:'Review',           icon:'check',    d:'Submit & generate matches' },
  ];

  const OnboardingScreen = () => {
    const [step, setStep] = useState('knowledge');
    const stepIdx = ONBOARDING_STEPS.findIndex(s => s.id === step);
    const progress = ((stepIdx) / (ONBOARDING_STEPS.length - 1)) * 100;
    return (
      <div style={{display:'grid', gridTemplateColumns:'280px 1fr 320px', minHeight:'100vh', background:'var(--bg)'}}>
        {/* left rail */}
        <div className="col" style={{borderRight:'1px solid var(--line)', background:'var(--surface)', padding: '32px 24px', gap: 20, position:'sticky', top:0, height:'100vh', overflowY:'auto'}}>
          <div className="col gap-1">
            <div className="eyebrow">Build your profile</div>
            <div style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-2xl)', letterSpacing:'-0.015em', lineHeight:1.1}}>Guided profiling</div>
          </div>
          <div className="col gap-1">
            <div className="row justify-between" style={{fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>
              <span>Step {stepIdx+1} of {ONBOARDING_STEPS.length}</span>
              <span className="tnum">{Math.round(progress)}%</span>
            </div>
            <div className="bar"><div className="fill" style={{width: progress + '%'}}/></div>
          </div>
          <div className="col gap-1">
            {ONBOARDING_STEPS.map((s, i) => (
              <button key={s.id} onClick={() => setStep(s.id)}
                className="row items-center gap-3" style={{
                  padding:'10px 12px', borderRadius:'var(--r-2)', textAlign:'left',
                  background: step === s.id ? 'var(--ink)' : (i < stepIdx ? 'var(--surface-3)' : 'transparent'),
                  color: step === s.id ? 'var(--surface)' : (i < stepIdx ? 'var(--ink-2)' : 'var(--ink-3)'),
                }}>
                <span style={{
                  width: 22, height: 22, borderRadius: '50%',
                  border: '1.5px solid currentColor', display:'flex', alignItems:'center', justifyContent:'center',
                  fontSize: 10.5, fontWeight: 600,
                  background: i < stepIdx ? 'currentColor' : 'transparent',
                  color: i < stepIdx ? (step === s.id ? 'var(--ink)' : 'var(--surface)') : 'currentColor',
                }}>
                  {i < stepIdx ? '✓' : i+1}
                </span>
                <div className="col" style={{flex:1, lineHeight:1.2}}>
                  <span style={{fontSize:'var(--t-sm)', fontWeight: 500}}>{s.l}</span>
                  <span style={{fontSize: 10.5, opacity: 0.7}}>{s.d}</span>
                </div>
              </button>
            ))}
          </div>
          <div className="row items-center gap-2" style={{marginTop: 'auto', padding: 12, background:'var(--surface-3)', borderRadius:'var(--r-2)', fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>
            <Icon name="check" size={12} color="var(--moss)"/>
            Autosaved · 14 sec ago
          </div>
        </div>

        {/* main */}
        <div className="col" style={{padding: '40px 56px', maxWidth: 880, width:'100%', gap: 24}}>
          {step === 'knowledge' && <KnowledgeStep onNext={() => setStep('project')} onBack={() => setStep('identity')}/>}
          {step === 'identity' && <IdentityStep onNext={() => setStep('knowledge')}/>}
          {step === 'project' && <ProjectStep onNext={() => setStep('challenges')} onBack={() => setStep('knowledge')}/>}
          {step === 'challenges' && <SimpleStep title="Challenges" desc="What are the open research/practice problems you're working on?" onNext={() => setStep('bottlenecks')} onBack={() => setStep('project')}/>}
          {step === 'bottlenecks' && <BottlenecksStep onNext={() => setStep('uncertainties')} onBack={() => setStep('challenges')}/>}
          {step === 'uncertainties' && <SimpleStep title="Uncertainties" desc="What unknowns shape your work? Areas where you'd benefit from co-learning." onNext={() => setStep('evidence')} onBack={() => setStep('bottlenecks')}/>}
          {step === 'evidence' && <SimpleStep title="Evidence anchors" desc="Optional. Add papers, datasets, talks, or reports that back up your expertise." onNext={() => setStep('review')} onBack={() => setStep('uncertainties')}/>}
          {step === 'review' && <ReviewStep/>}
        </div>

        {/* right rail — signal preview */}
        <div className="col" style={{borderLeft:'1px solid var(--line)', background:'var(--surface)', padding: '32px 24px', gap: 16, position:'sticky', top:0, height:'100vh', overflowY:'auto'}}>
          <div className="eyebrow">Signal this section produces</div>
          <Card style={{padding: 16}}>
            <div className="card-title">Expertise fingerprint</div>
            <div className="card-sub">100-point allocation across subdomains</div>
            <div style={{marginTop: 14}}>
              <Fingerprint data={D.PEOPLE[0].fingerprint.slice(0,4)} compact/>
            </div>
          </Card>
          <Card style={{padding: 16}}>
            <div className="card-title">What it powers</div>
            <div className="col gap-2" style={{marginTop: 12}}>
              <div className="row gap-2 items-center"><Icon name="sparkles" size={12} color="var(--accent)"/><span style={{fontSize:'var(--t-sm)'}}>Weighted similarity matches</span></div>
              <div className="row gap-2 items-center"><Icon name="git" size={12} color="var(--c-offer)"/><span style={{fontSize:'var(--t-sm)'}}>Need ↔ Offer detection</span></div>
              <div className="row gap-2 items-center"><Icon name="bridge" size={12} color="var(--e-bridge)"/><span style={{fontSize:'var(--t-sm)'}}>Bridge-actor scoring</span></div>
            </div>
          </Card>
          <div style={{padding: 12, background:'var(--accent-soft)', color:'var(--accent)', borderRadius:'var(--r-2)', fontSize:'var(--t-xs)', lineHeight:1.5}}>
            <Icon name="info" size={12} style={{marginRight: 4, verticalAlign:'middle'}}/>
            Your weight allocation creates the cosine vector used in similarity matching.
          </div>
        </div>
      </div>
    );
  };

  const StepHead = ({n, total, title, desc, micro}) => (
    <div className="col gap-2">
      <div className="row items-center gap-2" style={{fontSize:'var(--t-xs)', color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'0.1em'}}>
        <span>Step {n} of {total}</span>
        {micro && <><span>·</span><span>{micro}</span></>}
      </div>
      <h1 style={{fontFamily:'var(--font-display)', fontSize:'var(--t-3xl)', fontWeight:400, margin:0, letterSpacing:'-0.015em', lineHeight:1.1}}>{title}</h1>
      <p style={{fontSize:'var(--t-md)', color:'var(--ink-2)', margin:'4px 0 0', lineHeight: 1.5, maxWidth: 640}}>{desc}</p>
    </div>
  );

  const StepFooter = ({onBack, onNext, nextLabel='Continue', nextIcon='arrowRight'}) => (
    <div className="row items-center justify-between" style={{paddingTop: 20, borderTop:'1px solid var(--line)'}}>
      {onBack ? <Btn variant="ghost" icon="arrowLeft" onClick={onBack}>Back</Btn> : <span/>}
      <Btn variant="primary" iconRight={nextIcon} onClick={onNext}>{nextLabel}</Btn>
    </div>
  );

  const IdentityStep = ({onNext}) => (
    <>
      <StepHead n={1} total={8} title="Tell us who you are" desc="Identity, role, and institutional context. This grounds every match in real ecosystem positioning." micro="Identity"/>
      <div className="grid cols-2" style={{gap: 16}}>
        <div className="field"><label>Full name</label><input className="input" defaultValue="Sara Arif"/></div>
        <div className="field"><label>Email</label><input className="input" defaultValue="s.arif@tudelft.nl"/></div>
        <div className="field"><label>Role</label><input className="input" defaultValue="Postdoctoral researcher"/></div>
        <div className="field"><label>Organization</label><input className="input" defaultValue="TU Delft"/></div>
        <div className="field"><label>Sector</label>
          <div className="row gap-2 flex-wrap">{['Research','Education','Industry','Public sector','NGO'].map((s,i) => <Chip key={s} variant={i===0?'accent':'outline'} size="lg">{s}</Chip>)}</div>
        </div>
        <div className="field"><label>Region</label><input className="input" defaultValue="Delft, NL"/></div>
      </div>
      <div className="field"><label>Short bio</label><textarea className="textarea" rows="3" defaultValue={D.PEOPLE[0].bio}/></div>
      <StepFooter onNext={onNext}/>
    </>
  );

  const KnowledgeStep = ({onBack, onNext}) => {
    const [points, setPoints] = useState({
      'PEM electrolysis': 35, 'Membrane durability': 28, 'Catalyst design': 17,
      'Materials char.': 12, 'LCA': 8,
    });
    const total = Object.values(points).reduce((a,b)=>a+b,0);
    return (
      <>
        <StepHead n={2} total={8} title="Allocate 100 points across subdomains" desc="This becomes your weighted expertise fingerprint — the cosine vector at the heart of similarity matching." micro="Knowledge"/>

        <div className="card" style={{padding: 16, background:'var(--surface-2)'}}>
          <div className="row items-center justify-between" style={{marginBottom: 12}}>
            <span style={{fontSize:'var(--t-sm)', fontWeight: 600}}>Allocated</span>
            <div className="row items-center gap-2">
              <span className="tnum" style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-xl)', color: total === 100 ? 'var(--moss)' : 'var(--accent)'}}>{total}</span>
              <span style={{color:'var(--ink-3)'}}>/ 100</span>
              {total === 100 && <Icon name="check" size={16} color="var(--moss)"/>}
            </div>
          </div>
          <div className="bar"><div className="fill" style={{width: Math.min(100, total) + '%', background: total > 100 ? 'var(--e-antidup)' : 'var(--moss)'}}/></div>
        </div>

        <div className="col gap-3">
          {Object.entries(points).map(([k, v]) => (
            <div key={k} className="grid" style={{gridTemplateColumns: '160px 1fr 80px 70px', alignItems:'center', gap: 12}}>
              <span style={{fontSize:'var(--t-sm)', fontWeight:500}}>{k}</span>
              <input type="range" min="0" max="50" value={v}
                     onChange={e => setPoints({...points, [k]: +e.target.value})}
                     style={{accentColor:'var(--accent)'}}/>
              <div className="bar"><div className="fill" style={{width: (v/50*100) + '%'}}/></div>
              <input type="number" className="input" value={v} onChange={e => setPoints({...points, [k]: +e.target.value || 0})}/>
            </div>
          ))}
        </div>

        <div className="row gap-2 flex-wrap">
          <span style={{fontSize:'var(--t-xs)', color:'var(--ink-3)', alignSelf:'center'}}>Add subdomain:</span>
          {['SOEC','TEA','Digital twins','Hydrogen safety'].map(s => <Chip key={s} variant="outline" onClick={() => {}}>+ {s}</Chip>)}
        </div>

        <StepFooter onBack={onBack} onNext={onNext}/>
      </>
    );
  };

  const ProjectStep = ({onBack, onNext}) => (
    <>
      <StepHead n={3} total={8} title="Active project context" desc="The system uses stage, TRL, and scale to detect project compatibility — projects that are ready to talk to each other." micro="Project"/>
      <div className="card">
        <div className="card-title">HYDRO-NL Pilot</div>
        <div className="card-sub">Industrial pilot · GreenLab + TNO</div>
        <div className="grid cols-2" style={{gap: 16, marginTop:16}}>
          <div className="field"><label>Stage</label>
            <div className="segmented" style={{flexWrap:'wrap'}}>
              {['Concept','Lab','Lab-to-pilot','Pilot','Industrial'].map((s,i) => <button key={s} className={i===3?'on':''}>{s}</button>)}
            </div>
          </div>
          <div className="field"><label>TRL</label>
            <div className="row gap-1">{[1,2,3,4,5,6,7,8,9].map(n => (
              <span key={n} style={{width: 32, height: 32, display:'flex', alignItems:'center', justifyContent:'center', fontSize:'var(--t-sm)', fontWeight:500, background: n<=5?'var(--accent)':'var(--surface-3)', color: n<=5?'#fff':'var(--ink-3)', borderRadius:'var(--r-1)'}}>{n}</span>
            ))}</div>
          </div>
          <div className="field"><label>Scale</label>
            <div className="row gap-2">{['Lab','0.1 MW','0.5 MW','5 MW','&gt;10 MW'].map((s,i) => <Chip key={s} variant={i===3?'accent':'outline'} size="lg">{s}</Chip>)}</div>
          </div>
          <div className="field"><label>Application</label><input className="input" defaultValue="Wind-coupled green H₂ for industrial offtake"/></div>
        </div>
      </div>
      <Btn variant="ghost" icon="plus">Add another project</Btn>
      <StepFooter onBack={onBack} onNext={onNext}/>
    </>
  );

  const BottlenecksStep = ({onBack, onNext}) => (
    <>
      <StepHead n={5} total={8} title="Bottlenecks" desc="Where is progress blocked? Severity 1–5. The system uses overlap of bottlenecks to spot anti-duplication risks." micro="Bottlenecks"/>
      <div className="col gap-3">
        {[
          {label:'Pilot data sharing — partners reluctant', sev: 4, type:'External'},
          {label:'Limited access to industrial test bench',  sev: 3, type:'External'},
          {label:'Internal coordination across PIs',         sev: 2, type:'Internal'},
        ].map((b,i) => (
          <Card key={i} variant="tight">
            <div className="row items-center gap-3">
              <Icon name="alert" color="var(--e-antidup)"/>
              <div className="col flex-1">
                <div style={{fontSize:'var(--t-md)', fontWeight: 500}}>{b.label}</div>
                <div className="row items-center gap-2" style={{marginTop:4, fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>
                  <Chip variant="outline" size="xs">{b.type}</Chip>
                  <span>·</span>
                  <span>severity</span>
                  <div className="row gap-0.5">
                    {[1,2,3,4,5].map(n => <span key={n} style={{width: 10, height: 10, borderRadius:2, background: n <= b.sev ? 'var(--e-antidup)' : 'var(--line)'}}/>)}
                  </div>
                </div>
              </div>
              <Btn variant="ghost" icon="x" className="icon"/>
            </div>
          </Card>
        ))}
        <Btn variant="ghost" icon="plus" style={{justifyContent:'center'}}>Add bottleneck</Btn>
      </div>
      <StepFooter onBack={onBack} onNext={onNext}/>
    </>
  );

  const SimpleStep = ({title, desc, onBack, onNext}) => (
    <>
      <StepHead n={4} total={8} title={title} desc={desc} micro={title}/>
      <div className="card" style={{padding: 32, textAlign:'center', borderStyle:'dashed'}}>
        <Icon name="plus" size={24} color="var(--ink-3)"/>
        <p style={{color:'var(--ink-3)', fontSize:'var(--t-sm)', marginTop: 8}}>Add as many entries as you like. Each entry becomes a tagged signal.</p>
      </div>
      <div className="row gap-2 flex-wrap">
        {(title === 'Challenges' ? ['Membrane durability under variable load','Catalyst stability'] :
          title === 'Uncertainties' ? ['Long-term durability','Future safety regulation','Market adoption'] :
          ['arXiv:2402.xxxx · paper','HYDRO-NL Q3 dataset','Webinar talk · 2025']
        ).map(t => <Chip key={t} variant="accent" size="lg">{t} <Icon name="x" size={10}/></Chip>)}
      </div>
      <StepFooter onBack={onBack} onNext={onNext}/>
    </>
  );

  const ReviewStep = () => (
    <>
      <StepHead n={8} total={8} title="Review & submit" desc="On submit, your answers are normalized into entities, signals are computed, and the matching engine runs against the rest of the ecosystem."/>
      <Card variant="elevated" style={{padding: 24}}>
        <div className="row items-center justify-between flex-wrap gap-3" style={{marginBottom: 16}}>
          <h3 className="card-title">What happens next</h3>
          <Chip variant="accent">~ 12 seconds</Chip>
        </div>
        <div className="col gap-3">
          {[
            ['Normalize answers into 26 entities + 47 tags', 'normalize'],
            ['Compute weighted fingerprint vector', 'fingerprint'],
            ['Compare against 248 stakeholders & 11 projects', 'compare'],
            ['Generate 14 candidate relationship edges', 'edges'],
            ['Draft "Why this match" explanations for each edge', 'explain'],
          ].map(([t, k], i) => (
            <div key={k} className="row items-center gap-3" style={{padding:'8px 0', borderBottom: i < 4 ? '1px dashed var(--line)' : 'none'}}>
              <span style={{width: 24, height: 24, borderRadius:'50%', background:'var(--surface-3)', color:'var(--ink-3)', display:'flex', alignItems:'center', justifyContent:'center', fontSize: 11, fontWeight: 600}}>{i+1}</span>
              <span style={{flex:1, fontSize:'var(--t-sm)'}}>{t}</span>
              <Icon name="check" size={13} color="var(--ink-3)" style={{opacity: 0.4}}/>
            </div>
          ))}
        </div>
      </Card>

      <div className="grid cols-3" style={{gap: 12}}>
        <KPI v="26" l="Entities"/>
        <KPI v="47" l="Tags"/>
        <KPI v="100/100" l="Fingerprint points"/>
      </div>

      <div className="row gap-3 items-center" style={{paddingTop: 16}}>
        <Btn variant="ghost" icon="arrowLeft">Back</Btn>
        <div className="flex-1"/>
        <Btn variant="ghost" icon="eye">Preview as JSON</Btn>
        <Btn variant="accent" size="lg" iconRight="arrowRight" onClick={() => location.hash='dashboard'}>Submit & generate matches</Btn>
      </div>
    </>
  );

  const KPI = ({v, l, delta}) => (
    <Card variant="tight">
      <div className="kpi"><div className="l">{l}</div><div className="v">{v}</div>{delta && <div className="delta">{delta}</div>}</div>
    </Card>
  );

  // ============ DASHBOARD ============
  const DashboardScreen = () => (
    <div className="col" style={{padding:'32px 40px', gap: 24, maxWidth: 1400, margin:'0 auto'}}>
      <div className="row items-end justify-between flex-wrap gap-3">
        <div className="col gap-1">
          <div className="eyebrow">Welcome back, Sara</div>
          <h1 style={{fontFamily:'var(--font-display)', fontSize:'var(--t-3xl)', fontWeight:400, margin:0, letterSpacing:'-0.015em'}}>Your ecosystem this week</h1>
        </div>
        <div className="row gap-2">
          <Btn variant="ghost" icon="bell">3 signals</Btn>
          <Btn variant="ghost" icon="settings"/>
          <Btn variant="primary" icon="user" onClick={() => location.hash='onboarding'}>Edit profile</Btn>
        </div>
      </div>

      {/* KPIs */}
      <div className="grid cols-4" style={{gap: 12}}>
        <KPI v="92%" l="Profile strength" delta="+8% this week"/>
        <KPI v="14" l="Recommended matches" delta="3 new"/>
        <KPI v="3" l="Anti-dup risks" delta="review"/>
        <KPI v="0.42" l="Bridge score" delta="connector"/>
      </div>

      <div className="grid cols-12" style={{gap: 16}}>
        {/* fingerprint + matches */}
        <div className="col-span-8 col gap-4">
          <Card variant="elevated">
            <div className="row items-center justify-between flex-wrap gap-3" style={{marginBottom: 16}}>
              <div className="col">
                <h3 className="card-title">Top recommended matches</h3>
                <div className="card-sub">Ranked by score × confidence × recency</div>
              </div>
              <Btn variant="ghost" size="sm" icon="arrowRight" onClick={() => location.hash='explorer'}>Open explorer</Btn>
            </div>
            <div className="col gap-2">
              {D.MATCHES.slice(0, 4).map(m => {
                const a = D.byId(m.a), b = D.byId(m.b);
                const meta = window.RelMeta[m.type];
                return (
                  <button key={m.id} onClick={() => location.hash='match'} className="card lift" style={{padding: 14, textAlign:'left'}}>
                    <div className="row items-center gap-3">
                      <Avatar initials={a.initials} kind={D.kindOf(m.a)}/>
                      <Icon name="git" size={12} color="var(--ink-3)"/>
                      <Avatar initials={b.initials} kind={D.kindOf(m.b)}/>
                      <div className="col" style={{flex:1, minWidth:0}}>
                        <div className="row items-center gap-2 flex-wrap">
                          <span style={{fontWeight: 600}}>{a.name}</span>
                          <span style={{color:'var(--ink-3)'}}>×</span>
                          <span style={{fontWeight: 600}}>{b.name}</span>
                          <RelChip type={m.type} size="xs"/>
                        </div>
                        <div style={{fontSize:'var(--t-xs)', color:'var(--ink-3)', marginTop: 2, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis'}}>{m.summary.slice(0, 120)}…</div>
                      </div>
                      <div className="col items-end" style={{flexShrink:0}}>
                        <div className="tnum" style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-2xl)', lineHeight: 1, color: meta.color}}>{m.score}<span style={{fontSize:11, color:'var(--ink-3)'}}>%</span></div>
                        <div style={{fontSize: 10, color:'var(--ink-3)'}}>conf {Math.round(m.confidence*100)}%</div>
                      </div>
                      <Icon name="chevronRight" size={14} color="var(--ink-3)"/>
                    </div>
                  </button>
                );
              })}
            </div>
          </Card>

          {/* Anti-duplication alerts */}
          <Card>
            <div className="row items-center justify-between" style={{marginBottom: 12}}>
              <div>
                <h3 className="card-title row items-center gap-2"><Icon name="alert" color="var(--e-antidup)"/>Anti-duplication alerts</h3>
                <div className="card-sub">Possible parallel work — coordinate to reduce duplication</div>
              </div>
              <Btn variant="ghost" size="sm" onClick={() => location.hash='network'}>Open in network</Btn>
            </div>
            <div className="col gap-2">
              <div className="card tight" style={{background:'rgba(176,58,46,0.05)', border:'1px solid rgba(176,58,46,0.2)'}}>
                <div className="row items-center gap-3">
                  <Icon name="alert" color="var(--e-antidup)"/>
                  <div className="col flex-1"><div style={{fontWeight: 600}}>Membrane durability protocols ×3 teams</div><div style={{fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>Sara · Liesbeth · Bram</div></div>
                  <Btn size="xs" variant="ghost">Review cluster</Btn>
                </div>
              </div>
              <div className="card tight" style={{background:'rgba(176,58,46,0.05)', border:'1px solid rgba(176,58,46,0.2)'}}>
                <div className="row items-center gap-3">
                  <Icon name="alert" color="var(--e-antidup)"/>
                  <div className="col flex-1"><div style={{fontWeight: 600}}>Pilot data sharing pattern ×2 projects</div><div style={{fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>HYDRO-NL · GreenH2-PEM</div></div>
                  <Btn size="xs" variant="ghost">Review cluster</Btn>
                </div>
              </div>
            </div>
          </Card>
        </div>

        {/* sidebar */}
        <div className="col-span-4 col gap-4">
          <Card>
            <h3 className="card-title">Your fingerprint</h3>
            <div className="card-sub">100 expertise points, normalized</div>
            <div style={{marginTop: 14}}>
              <Fingerprint data={D.PEOPLE[0].fingerprint} compact/>
            </div>
          </Card>
          <Card style={{padding: 0, overflow:'hidden'}}>
            <div style={{padding: 18}}>
              <h3 className="card-title">Network preview</h3>
              <div className="card-sub">Your local ecosystem</div>
            </div>
            <div style={{aspectRatio:'4/3', position:'relative', background:'var(--surface-3)'}}>
              <LandingGraphic/>
            </div>
            <div style={{padding: 14}}><Btn variant="primary" iconRight="arrowRight" onClick={() => location.hash='network'} style={{justifyContent:'center', width:'100%'}}>Open network</Btn></div>
          </Card>
          <Card>
            <h3 className="card-title">Open opportunities</h3>
            <div className="col gap-2" style={{marginTop: 12}}>
              {[
                {l:'Sara × HYDRO-NL · pilot validation', t:'Action requested'},
                {l:'Iteke proposed a co-learning circle', t:'Invitation'},
                {l:'Lori shared governance dataset', t:'New evidence'},
              ].map((o,i) => (
                <div key={i} className="row items-center gap-2" style={{padding: '8px 0', borderBottom: i<2?'1px dashed var(--line)':'none'}}>
                  <span style={{width:6, height:6, borderRadius:'50%', background:'var(--accent)'}}/>
                  <div className="col flex-1"><span style={{fontSize:'var(--t-sm)', fontWeight:500}}>{o.l}</span><span style={{fontSize: 10.5, color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'0.06em'}}>{o.t}</span></div>
                </div>
              ))}
            </div>
          </Card>
        </div>
      </div>
    </div>
  );

  // ============ EXPLORER ============
  const ExplorerScreen = () => {
    const [tab, setTab] = useState('people');
    const tabs = [
      {k:'people', l:'People', n: D.PEOPLE.length},
      {k:'projects', l:'Projects', n: D.PROJECTS.length},
      {k:'orgs', l:'Organizations', n: D.ORGS.length},
      {k:'domains', l:'Domains', n: D.DOMAINS.length},
      {k:'methods', l:'Methods', n: D.METHODS.length},
      {k:'challenges', l:'Challenges', n: 6},
    ];
    const items = tab === 'people' ? D.PEOPLE : tab === 'projects' ? D.PROJECTS : tab === 'orgs' ? D.ORGS : [];
    return (
      <div className="col" style={{padding:'24px 32px', gap: 16, maxWidth: 1400, margin:'0 auto'}}>
        <div className="row items-end justify-between flex-wrap gap-3">
          <div className="col gap-1">
            <div className="eyebrow">Discovery explorer</div>
            <h1 style={{fontFamily:'var(--font-display)', fontSize:'var(--t-3xl)', fontWeight:400, margin:0, letterSpacing:'-0.015em'}}>Browse the ecosystem</h1>
          </div>
          <div className="row items-center gap-2">
            <input className="input search" placeholder="Search people, projects, methods, domains…" style={{width: 360}}/>
            <Btn variant="ghost" icon="sliders">Filters</Btn>
          </div>
        </div>

        <div className="tabs">
          {tabs.map(t => (
            <button key={t.k} onClick={() => setTab(t.k)} className={tab === t.k ? 'on' : ''}>
              {t.l} <span style={{color:'var(--ink-3)', marginLeft: 6}} className="tnum">{t.n}</span>
            </button>
          ))}
        </div>

        {/* facets row */}
        <div className="row gap-3 items-center flex-wrap" style={{padding: '12px 16px', background:'var(--surface)', borderRadius:'var(--r-3)', border:'1px solid var(--line)'}}>
          <span style={{fontSize:'var(--t-xs)', color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'0.08em'}}>Refine</span>
          <Chip variant="accent">PEM electrolysis ×</Chip>
          <Chip variant="outline">Sector: Research</Chip>
          <Chip variant="outline">Region: NL</Chip>
          <Chip variant="outline">+ Has offer</Chip>
          <Chip variant="outline">+ Curator-reviewed</Chip>
          <span className="flex-1"/>
          <span style={{fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>Sort:</span>
          <select className="select" style={{padding:'4px 22px 4px 8px', fontSize:'var(--t-xs)', width:'auto'}}>
            <option>Match relevance to me</option><option>Recent activity</option><option>Bridge score</option>
          </select>
        </div>

        <div className="grid cols-2" style={{gap: 12}}>
          {items.map(it => (
            <Card key={it.id} className="lift" style={{cursor:'pointer'}} onClick={() => location.hash='match'}>
              <div className="row items-start gap-3">
                <Avatar initials={it.initials} kind={tab === 'people' ? 'person' : tab === 'projects' ? 'project' : 'org'} size="lg"/>
                <div className="col flex-1" style={{minWidth: 0}}>
                  <div className="row items-center justify-between gap-2 flex-wrap">
                    <div className="col">
                      <div style={{fontWeight: 600, fontSize:'var(--t-md)'}}>{it.name}</div>
                      <div style={{fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>{it.role || it.type || it.sector} · {it.org || it.region}</div>
                    </div>
                    {it.bridgeScore != null && (
                      <Chip variant="outline" size="xs">bridge {it.bridgeScore.toFixed(2)}</Chip>
                    )}
                  </div>
                  {it.bio && <p style={{fontSize:'var(--t-sm)', color:'var(--ink-2)', lineHeight: 1.5, margin: '8px 0 0', display:'-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient:'vertical', overflow:'hidden'}}>{it.bio}</p>}
                  {it.domains && (
                    <div className="row gap-1 flex-wrap" style={{marginTop: 10}}>
                      {it.domains.slice(0, 4).map(d => <Chip key={d} variant="outline" size="xs">{d}</Chip>)}
                      {it.domains.length > 4 && <Chip variant="outline" size="xs">+{it.domains.length - 4}</Chip>}
                    </div>
                  )}
                  <div className="row items-center justify-between" style={{marginTop: 14, paddingTop: 12, borderTop: '1px dashed var(--line)'}}>
                    <div className="row gap-1">
                      <Chip variant="rel-similar" size="xs">3 similar</Chip>
                      <Chip variant="rel-comp" size="xs">2 complement</Chip>
                    </div>
                    <Btn variant="ghost" size="xs" icon="network" onClick={(e) => { e.stopPropagation(); location.hash='network'; }}>Open in network</Btn>
                  </div>
                </div>
              </div>
            </Card>
          ))}
        </div>
      </div>
    );
  };

  // ============ ADMIN / CURATOR ============
  const AdminScreen = () => (
    <div className="col" style={{padding:'24px 32px', gap: 24, maxWidth: 1400, margin:'0 auto'}}>
      <div className="row items-end justify-between flex-wrap gap-3">
        <div className="col gap-1">
          <div className="eyebrow">Curator workspace</div>
          <h1 style={{fontFamily:'var(--font-display)', fontSize:'var(--t-3xl)', fontWeight:400, margin:0, letterSpacing:'-0.015em'}}>Trust & quality layer</h1>
        </div>
        <div className="row gap-2">
          <Btn variant="ghost" icon="download">Export curation log</Btn>
          <Btn variant="primary" icon="check">Mark queue as reviewed</Btn>
        </div>
      </div>

      <div className="grid cols-4" style={{gap: 12}}>
        <KPI v="14" l="Profiles in queue" delta="3 new"/>
        <KPI v="42" l="Edges to review" delta="8 high-confidence"/>
        <KPI v="6" l="Anti-dup clusters" delta="2 new"/>
        <KPI v="92%" l="Avg confidence" delta=""/>
      </div>

      <div className="grid cols-12" style={{gap: 16}}>
        <div className="col-span-7 col gap-4">
          <Card>
            <div className="row items-center justify-between" style={{marginBottom: 12}}>
              <div className="col"><h3 className="card-title">Generated edges · review queue</h3><div className="card-sub">Approve · hide · request more evidence</div></div>
              <div className="row gap-2">
                <Chip variant="outline">All</Chip>
                <Chip variant="accent">High conf</Chip>
                <Chip variant="outline">Low conf</Chip>
              </div>
            </div>
            <div className="col gap-2">
              {D.MATCHES.map(m => {
                const a = D.byId(m.a), b = D.byId(m.b);
                return (
                  <div key={m.id} className="card tight" style={{display:'flex', gap: 12, alignItems:'center'}}>
                    <div className="col flex-1">
                      <div className="row items-center gap-2 flex-wrap">
                        <span style={{fontWeight:600}}>{a.name} × {b.name}</span>
                        <RelChip type={m.type} size="xs"/>
                        <Badge level={m.confidence > 0.9 ? 'high' : m.confidence > 0.75 ? 'med' : 'low'}>conf {Math.round(m.confidence*100)}%</Badge>
                      </div>
                      <div style={{fontSize:'var(--t-xs)', color:'var(--ink-3)', marginTop: 4, display:'-webkit-box', WebkitLineClamp:1, WebkitBoxOrient:'vertical', overflow:'hidden'}}>{m.summary}</div>
                    </div>
                    <div className="row gap-1">
                      <Btn variant="ghost" size="xs" icon="eye">Inspect</Btn>
                      <Btn variant="ghost" size="xs" icon="check">Approve</Btn>
                      <Btn variant="ghost" size="xs" icon="x">Hide</Btn>
                    </div>
                  </div>
                );
              })}
            </div>
          </Card>
        </div>

        <div className="col-span-5 col gap-4">
          <Card>
            <h3 className="card-title">Profile review queue</h3>
            <div className="col gap-2" style={{marginTop: 14}}>
              {D.PEOPLE.slice(0, 5).map(p => (
                <div key={p.id} className="row items-center gap-3" style={{padding:'8px 0', borderBottom:'1px dashed var(--line)'}}>
                  <Avatar initials={p.initials} kind="person" size="sm"/>
                  <div className="col flex-1"><span style={{fontSize:'var(--t-sm)', fontWeight:500}}>{p.name}</span><span style={{fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>completeness {Math.round((p.completeness||0.8)*100)}%</span></div>
                  <Btn variant="ghost" size="xs">Review</Btn>
                </div>
              ))}
            </div>
          </Card>
          <Card>
            <h3 className="card-title">Network health</h3>
            <div className="col gap-3" style={{marginTop: 14}}>
              <Bar value={92} variant="moss" label="Profile completeness avg"/>
              <Bar value={78} label="Edges with curator-approved status"/>
              <Bar value={64} variant="warm" label="Domains with ≥5 stakeholders"/>
              <Bar value={46} variant="alert" label="Anti-dup clusters resolved"/>
            </div>
          </Card>
          <Card>
            <h3 className="card-title">Taxonomy</h3>
            <div className="card-sub">14 domains · 47 subdomains · 12 methods</div>
            <div className="row gap-1 flex-wrap" style={{marginTop: 12}}>
              {D.DOMAINS.slice(0, 8).map(d => <Chip key={d} variant="outline" size="xs">{d}</Chip>)}
              <Chip variant="accent" size="xs">+ Add</Chip>
            </div>
          </Card>
        </div>
      </div>
    </div>
  );

  Object.assign(window, { LandingScreen, OnboardingScreen, DashboardScreen, ExplorerScreen, AdminScreen });
})();
