/* maydays — view components (one per page) */
const { useState: _us, useMemo: _um, useEffect: _ue } = React;

/* ---------- Landing ---------- */
function Landing({ onNavigate, data }) {
  const { STEP2, BUGS, DRUGS, RAPIDS_POOLS, TOOLS_LIST } = data;
  const sections = [STEP2, BUGS, DRUGS];
  const totalSubtopics = sections.reduce((a, s) => a + s.subjects.reduce((b, sj) => b + sj.count, 0), 0);
  const totalSubjects = sections.reduce((a, s) => a + s.subjects.length, 0);
  const rapidsPools = Object.values(RAPIDS_POOLS);
  const totalRapids = rapidsPools.reduce((a, p) =>
    a + p.sections.reduce((b, s) => b + s.questions.length, 0), 0);
  const hubs = [
    {
      id: 'library',  go: { name: 'library' },
      eyebrow: 'STEP 2 · BUGS · DRUGS · PROGRESS',
      title: 'Library',
      blurb: 'The whole curriculum tree. Step 2 CK by rotation, the bugs catalog, the drugs catalog, and your overall progress.',
      chips: ['Step 2 CK', 'Bugs', 'Drugs', 'Progress'],
      meta: `${totalSubjects} subjects · ${totalSubtopics} subtopics`,
    },
    {
      id: 'rapids', go: { name: 'rapids' },
      eyebrow: 'QBANK-STYLE SPRINTS',
      title: 'Rapids',
      blurb: 'Quick reps in three pools: Diagnosis, Bugs, and Drugs. Build a session, set difficulty and count, and run it.',
      chips: rapidsPools.map(p => p.title),
      meta: `${rapidsPools.length} pools · ${totalRapids} stems`,
    },
    {
      id: 'tools', go: { name: 'tools' },
      eyebrow: 'THE WORKSHOP',
      title: 'Tools',
      blurb: 'Small programs for med-school logistics. Trackers, planners, templates, cheat sheets. Drop yours here.',
      chips: TOOLS_LIST.slice(0,4).map(t => t.title),
      meta: `${TOOLS_LIST.length} tools · placeholders for now`,
      extra: TOOLS_LIST.length > 4 ? TOOLS_LIST.length - 4 : 0,
    },
  ];
  return (
    <div className="fade">
      <section className="hero">
        <div>
          <div className="eyebrow">{ORN.sprig} maydays · for the wards and the boards</div>
          <h1 style={{ marginTop: 14 }}>
            How medicine<br/>
            <span className="it">should be taught.</span>
          </h1>
          <p className="lede">
            Step 2 CK by rotation, with dedicated browsers for bugs and drugs. Drill down from
            rotation to topic to subtopic and find exactly what you need, explained the way it
            actually clicks. Not dumped on you all at once.
          </p>
          <div className="cta-row">
            <button className="btn" onClick={() => onNavigate({ name: 'library' })}>
              Open the library →
            </button>
            <button className="btn ghost" onClick={() => onNavigate({ name: 'rapids' })}>
              Rapids
            </button>
            <button className="btn ghost" onClick={() => onNavigate({ name: 'tools' })}>
              Tools
            </button>
          </div>
          <div className="stats">
            <div className="stat">
              <div className="n">{totalSubtopics}</div>
              <div className="l mono">SUBTOPICS</div>
            </div>
            <div className="stat">
              <div className="n">{totalRapids}</div>
              <div className="l mono">RAPIDS</div>
            </div>
            <div className="stat">
              <div className="n">{TOOLS_LIST.length}</div>
              <div className="l mono">TOOLS</div>
            </div>
          </div>
        </div>
        <div style={{ position:'relative' }}>
          <div style={{ position:'absolute', top:-14, right:-14, opacity: 0.7, zIndex: 2 }}>
            <CornerOrnament />
          </div>
          <BotanicalFrame label="botanical · anatomy plate (placeholder)" />
        </div>
      </section>

      <BranchDivider />

      <section style={{ marginTop: 16 }}>
        <div className="grid-3">
          {hubs.map(h => (
            <div key={h.id} className="card hov" style={{ padding: 28, cursor: 'pointer', position: 'relative' }}
                 onClick={() => onNavigate(h.go)}>
              <div style={{ position: 'absolute', top: 18, right: 22, opacity: 0.6 }}>
                <BotanicalFern size={32} />
              </div>
              <div className="eyebrow">{h.eyebrow}</div>
              <h2 style={{ marginTop: 10, fontSize: 32 }}>{h.title}</h2>
              <p className="ink-soft" style={{ marginTop: 8, fontSize: 15, maxWidth: 320 }}>{h.blurb}</p>
              <div className="row-wrap" style={{ marginTop: 16, gap: 8 }}>
                {h.chips.map(c => <span key={c} className="chip">{c}</span>)}
                {h.extra > 0 && <span className="muted mono" style={{ fontSize: 11 }}>+{h.extra} more</span>}
              </div>
              <div className="row" style={{ marginTop: 22, justifyContent: 'space-between' }}>
                <span className="muted" style={{ fontSize: 13 }}>{h.meta}</span>
                <span style={{ color: 'var(--clay)', fontWeight: 500 }}>Open →</span>
              </div>
            </div>
          ))}
        </div>
      </section>

      <BranchDivider />

      <section style={{ marginTop: 16 }}>
        <div className="eyebrow" style={{ marginBottom: 18 }}>{ORN.sprig} how maydays teaches</div>
        <div className="grid-3">
          {[
            { t: 'One line picture', d: 'Every subtopic starts with the single sentence you should be able to recite. Build the scaffold first, hang detail on it later.' },
            { t: 'Why, not just what', d: 'Mechanisms first so the presentation makes sense. If you cannot see why warfarin causes more SDHs, the fact will not stick.' },
            { t: 'Your own way to think of it', d: 'Every lesson has a personal note section. Drop in the analogy or mnemonic that finally made it click for you.' },
            { t: 'Comparisons built in', d: 'Every disease is taught next to the one it gets confused with. SDH sits next to EDH and SAH. That is where the exam lives too.' },
            { t: 'Qbank style questions', d: 'Vignettes written in the cadence you will see on test day, with explanations for every option.' },
            { t: 'Send to Anki', d: 'Every subpage exports its key cards into Anki via the AnkiConnect addon. Spaced repetition stays in the app you already use.' },
          ].map((f, i) => (
            <div key={i} className="card" style={{ padding: 22 }}>
              <div style={{ color: 'var(--sage)', marginBottom: 10 }}><BotanicalSprig size={22} /></div>
              <h4>{f.t}</h4>
              <p className="ink-soft" style={{ marginTop: 6, fontSize: 14 }}>{f.d}</p>
            </div>
          ))}
        </div>
      </section>

      <BranchDivider />

      <section style={{ marginTop: 16 }}>
        <div className="eyebrow" style={{ marginBottom: 18 }}>{ORN.sprig} pick up where you left off</div>
        <div className="grid-3">
          {[
            { step:'step2', subj:'neuro', topic:'stroke', sub:'sdh', name:'Subdural Hematoma', path:'Step 2 · Neurology · Stroke', pct: 35 },
            { step:'bugs',  subj:'bact',  topic:'gram-positive-cocci', sub:null, name:'Gram-Positive Cocci', path:'Bugs · Bacteriology', pct: 50 },
            { step:'drugs', subj:'cv-rx', topic:'antihypertensives',   sub:null, name:'Antihypertensives',   path:'Drugs · Cardiovascular', pct: 28 },
          ].map((r,i) => (
            <div key={i} className="card hov" style={{ padding: 20, cursor: 'pointer' }}
                 onClick={() => {
                   if (r.sub) onNavigate({ name: 'lesson', stepId: r.step, subjectId: r.subj, topicId: r.topic, subtopicId: r.sub });
                   else onNavigate({ name: 'topic', stepId: r.step, subjectId: r.subj, topicId: r.topic });
                 }}>
              <div className="eyebrow">CONTINUE</div>
              <div className="serif" style={{ fontSize: 22, marginTop: 6 }}>{r.name}</div>
              <div className="muted" style={{ fontSize: 12.5, marginTop: 4 }}>{r.path}</div>
              <div style={{ marginTop: 14 }}><Progress value={r.pct} /></div>
            </div>
          ))}
        </div>
      </section>
    </div>
  );
}

/* ---------- Step Hub ---------- */
function StepHub({ step, onNavigate, hideCrumbs }) {
  const hasSections = step.sections && step.sections.length > 1;
  const [section, setSection] = _us(hasSections ? step.sections[0].id : 'all');
  const [filter, setFilter] = _us('all');

  const subjects = _um(() => {
    let arr = hasSections ? step.subjects.filter(s => s.section === section) : step.subjects;
    if (filter === 'inprog') arr = arr.filter(s => s.progress > 0 && s.progress < 100);
    if (filter === 'untouched') arr = arr.filter(s => s.progress === 0);
    return arr;
  }, [filter, section, step, hasSections]);

  const overall = Math.round(step.subjects.reduce((a,s) => a + s.progress, 0) / Math.max(1, step.subjects.length));
  const totalSubt = step.subjects.reduce((a,s) => a + s.topics.reduce((b,t) => b + (t.subtopics?.length || 0), 0), 0);
  const currentSection = hasSections ? step.sections.find(s => s.id === section) : null;

  return (
    <div className="fade">
      {!hideCrumbs && (
        <Crumbs items={[
          { label: 'Home', to: { name: 'home' } },
          { label: 'Library', to: { name: 'library' } },
          { label: step.title }
        ]} onNavigate={onNavigate} />
      )}

      <div className="row" style={{ justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 8, gap: 24 }}>
        <div>
          <div className="eyebrow">{
            step.id === 'step2' ? 'CLINICAL · BY ROTATION' :
            step.id === 'bugs'  ? 'MICROBIOLOGY' :
            step.id === 'drugs' ? 'PHARMACOLOGY' : 'OVERVIEW'
          }</div>
          <h1 style={{ marginTop: 8 }}>{step.title}</h1>
          <p className="ink-soft" style={{ fontSize: 17, marginTop: 8, maxWidth: 640 }}>{step.blurb}</p>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div className="mono muted" style={{ fontSize: 11 }}>OVERALL</div>
          <div className="serif" style={{ fontSize: 38 }}>{overall}<span style={{ fontSize: 18, color: 'var(--muted)' }}>%</span></div>
          <div className="muted" style={{ fontSize: 12 }}>{totalSubt} subtopics</div>
        </div>
      </div>

      {hasSections && (
        <div style={{ marginTop: 22 }}>
          <div className="tabs">
            {step.sections.map(sec => {
              const subjCount = step.subjects.filter(s => s.section === sec.id).length;
              return (
                <span key={sec.id} className={`tab ${section === sec.id ? 'active' : ''}`} onClick={() => setSection(sec.id)}>
                  <BotanicalSprig size={14} color={section === sec.id ? 'rgba(255,255,255,0.7)' : 'var(--sage)'} />
                  {sec.title}
                  <span className="count">{subjCount}</span>
                </span>
              );
            })}
          </div>
          {currentSection && currentSection.blurb && (
            <p className="ink-soft" style={{ fontSize: 14, marginTop: 14, maxWidth: 720, fontStyle: 'italic' }}>
              {currentSection.blurb}
            </p>
          )}
        </div>
      )}

      <div className="row" style={{ marginTop: 28, marginBottom: 24, justifyContent: 'space-between' }}>
        <div className="pill-row">
          <span className={`pill ${filter === 'all' ? 'active' : ''}`} onClick={() => setFilter('all')}>All subjects</span>
          <span className={`pill ${filter === 'inprog' ? 'active' : ''}`} onClick={() => setFilter('inprog')}>In progress</span>
          <span className={`pill ${filter === 'untouched' ? 'active' : ''}`} onClick={() => setFilter('untouched')}>Not started</span>
        </div>
        <span className="muted mono" style={{ fontSize: 11 }}>{subjects.length} showing</span>
      </div>

      <div className="grid-3">
        {subjects.map(s => (
          <SubjectCard key={s.id} subject={s}
                       onClick={() => onNavigate({ name: 'subject', stepId: step.id, subjectId: s.id })} />
        ))}
      </div>

      {subjects.length === 0 && (
        <div className="card" style={{ padding: 32, textAlign: 'center', color: 'var(--muted)' }}>
          Nothing here yet. Try another filter or section.
        </div>
      )}
    </div>
  );
}

/* ---------- Subject page ---------- */
function SubjectPage({ step, subject, onNavigate }) {
  const libCrumb = { label: 'Library', to: { name: 'library' } };
  const [q, setQ] = _us('');
  const topics = _um(() => {
    if (!q.trim()) return subject.topics;
    const n = q.toLowerCase();
    return subject.topics.filter(t => t.title.toLowerCase().includes(n) || (t.blurb && t.blurb.toLowerCase().includes(n)));
  }, [q, subject]);

  return (
    <div className="fade">
      <Crumbs items={[
        { label: 'Home', to: { name: 'home' } },
        libCrumb,
        { label: step.title, to: { name: 'step', stepId: step.id } },
        { label: subject.title }
      ]} onNavigate={onNavigate} />

      <div className="row" style={{ justifyContent:'space-between', alignItems:'flex-start', marginBottom: 8, gap: 24 }}>
        <div style={{ flex: 1 }}>
          <div className="eyebrow">{step.id === 'step2' ? 'ROTATION' : step.id === 'bugs' ? 'BUG CLASS' : 'DRUG CLASS'} · {step.title}</div>
          <h1 style={{ marginTop: 8 }}>{subject.title}</h1>
          <p className="ink-soft" style={{ fontSize: 17, marginTop: 10, maxWidth: 640 }}>{subject.blurb}</p>
          <div className="row-wrap" style={{ gap: 10, marginTop: 18 }}>
            <span className="chip"><span className="dot" />{subject.topics.length} topics</span>
            <span className="chip"><span className="dot" />{subject.count} subtopics</span>
            <span className="chip"><span className="dot" style={{ background: 'var(--clay)' }} />{subject.progress}% complete</span>
            <AnkiButton label={`Send ${subject.title} deck`} count={subject.count} />
          </div>
        </div>
        <div style={{ width: 220, flexShrink: 0 }}>
          <BotanicalFrame label={`botanical · ${subject.title.toLowerCase()}`} height={180} />
        </div>
      </div>

      <div className="row" style={{ marginTop: 32, marginBottom: 16, justifyContent: 'space-between' }}>
        <div className="search" style={{ minWidth: 320, maxWidth: 380, background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 999, padding: '8px 14px', display:'flex', alignItems:'center', gap: 8 }}>
          <input style={{ flex: 1, border:'none', outline:'none', background:'none', fontSize:14 }}
                 placeholder={`Filter ${subject.title.toLowerCase()} topics`}
                 value={q} onChange={e => setQ(e.target.value)} />
        </div>
        <span className="muted mono" style={{ fontSize: 11 }}>{topics.length} topics</span>
      </div>

      <div>
        {topics.map((t, i) => (
          <div key={t.id} className="topic-row" onClick={() => onNavigate({ name:'topic', stepId: step.id, subjectId: subject.id, topicId: t.id })}>
            <div className="num">{String(i+1).padStart(2,'0')}</div>
            <div className="ttl">
              <b>{t.title}</b>
              {t.blurb && <div className="sub">{t.blurb}</div>}
            </div>
            <div className="right">
              <MasteryDots value={t.mastery} />
              <div style={{ width: 100 }}><Progress value={t.progress} /></div>
              <span className="mono">{(t.subtopics?.length || 0)} subt.</span>
              <span style={{ color: 'var(--muted)' }}>→</span>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Topic page ---------- */
function TopicPage({ step, subject, topic, onNavigate }) {
  return (
    <div className="fade">
      <Crumbs items={[
        { label: 'Home', to: { name: 'home' } },
        { label: 'Library', to: { name: 'library' } },
        { label: step.title, to: { name: 'step', stepId: step.id } },
        { label: subject.title, to: { name: 'subject', stepId: step.id, subjectId: subject.id } },
        { label: topic.title }
      ]} onNavigate={onNavigate} />

      <div className="row" style={{ justifyContent:'space-between', alignItems:'flex-start', gap: 24 }}>
        <div style={{ flex: 1 }}>
          <div className="eyebrow">TOPIC · {subject.title.toUpperCase()}</div>
          <h1 style={{ marginTop: 8 }}>{topic.title}</h1>
          <div className="row-wrap" style={{ gap: 10, marginTop: 18 }}>
            <MasteryDots value={topic.mastery} />
            <span className="muted" style={{ fontSize: 13 }}>
              {topic.subtopics.length} subtopics · {topic.progress}% complete
            </span>
            <AnkiButton label={`Send ${topic.title} deck`} count={topic.subtopics.length} />
          </div>
        </div>
      </div>

      {topic.blurb && (
        <div className="topic-desc">
          <div className="eyebrow">{ORN.sprig} about this topic</div>
          <p>{topic.blurb}</p>
        </div>
      )}

      <BranchDivider />

      <div className="grid-2">
        {topic.subtopics.map((s, i) => {
          const hasLesson = !!s.lesson;
          return (
            <div key={s.id} className="card hov" style={{ padding: 22, cursor:'pointer', position:'relative' }}
                 onClick={() => onNavigate({ name:'lesson', stepId: step.id, subjectId: subject.id, topicId: topic.id, subtopicId: s.id })}>
              <div className="row" style={{ justifyContent:'space-between', alignItems:'flex-start' }}>
                <div>
                  <div className="mono muted">{String(i+1).padStart(2,'0')}</div>
                  <div className="serif" style={{ fontSize: 22, marginTop: 4 }}>{s.title}</div>
                </div>
                <div style={{ textAlign:'right' }}>
                  <MasteryDots value={s.mastery} />
                  {hasLesson && <div className="mono" style={{ fontSize: 10, color:'var(--sage-2)', marginTop: 6 }}>● FULL LESSON</div>}
                </div>
              </div>
              <div style={{ marginTop: 16 }}><Progress value={s.progress} /></div>
              <div className="row" style={{ marginTop: 12, justifyContent:'space-between' }}>
                <span className="muted" style={{ fontSize: 12.5 }}>
                  {s.progress}% · {s.mastery === 'm' ? 'mastered' : s.mastery === 'l' ? 'learning' : 'not started'}
                </span>
                <span style={{ color:'var(--clay)', fontSize: 13, fontWeight: 500 }}>Open →</span>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ---------- Lesson page ---------- */
function LessonPage({ step, subject, topic, subtopic, onNavigate }) {
  const lesson = subtopic.lesson || window.MAYDAY_DATA.stubLesson(subtopic.title);
  const isStub = !subtopic.lesson;
  const [activeId, setActiveId] = _us(lesson.sections[0].id);

  _ue(() => {
    const onScroll = () => {
      const candidates = lesson.sections.map(s => ({ id: s.id, el: document.getElementById('s-'+s.id) }))
        .filter(x => x.el)
        .map(x => ({ id: x.id, top: x.el.getBoundingClientRect().top }));
      const passed = candidates.filter(c => c.top < 120);
      if (passed.length) setActiveId(passed[passed.length-1].id);
      else if (candidates[0]) setActiveId(candidates[0].id);
    };
    window.addEventListener('scroll', onScroll);
    return () => window.removeEventListener('scroll', onScroll);
  }, [lesson]);

  const renderBlock = (b, i) => {
    if (b.kind === 'p')   return <p key={i} dangerouslySetInnerHTML={{ __html: b.text }} />;
    if (b.kind === 'ul')  return <ul key={i}>{b.items.map((it, j) => <li key={j} dangerouslySetInnerHTML={{ __html: it }} />)}</ul>;
    if (b.kind === 'kv')  return (
      <div key={i} style={{ marginTop: 6 }}>
        {b.rows.map(([k, v], j) => (
          <div key={j} className="kv">
            <div className="k">{k}</div>
            <div className="v" dangerouslySetInnerHTML={{ __html: v }} />
          </div>
        ))}
      </div>
    );
    if (b.kind === 'callout') return <div key={i} className={`callout ${b.tone === 'sage' ? 'sage' : ''}`} dangerouslySetInnerHTML={{ __html: b.text }} />;
    if (b.kind === 'note') return (
      <div key={i} className="note">
        <div className="lab"><BotanicalSprig size={14} color="var(--leaf-gold)" /> ways to think of it</div>
        <div className={`body ${b.empty ? 'empty' : ''}`}>{b.text}</div>
        {b.empty && <div className="edit-stub">↳ This is a placeholder. Your personal note will live here.</div>}
      </div>
    );
    if (b.kind === 'pic') return (
      <div key={i} className="pic">
        <div className="pic-frame"><div className="label">{b.label || 'image placeholder'}</div></div>
        {b.caption && <div className="cap">{b.caption}</div>}
      </div>
    );
    if (b.kind === 'refs') return (
      <div key={i} className="see-also">
        <div className="lab">{ORN.sprig} see also</div>
        <ul>
          {b.items.map((r, j) => (
            <li key={j} onClick={() => onNavigate(r.to)}>
              <span className="xref" style={{ borderBottom: 'none' }}>{r.label}</span>
              <span className="path">{r.to.stepId === 'step1' ? 'Step 1' : 'Step 2'} · same topic</span>
            </li>
          ))}
        </ul>
      </div>
    );
    return null;
  };

  // Pull a representative ways-to-think note for the lesson sidebar preview
  const noteSnippet = (() => {
    for (const s of lesson.sections) {
      for (const b of s.body) {
        if (b.kind === 'note') return b.text;
      }
    }
    return null;
  })();

  return (
    <div className="fade">
      <Crumbs items={[
        { label: 'Home', to: { name: 'home' } },
        { label: 'Library', to: { name: 'library' } },
        { label: step.title, to: { name: 'step', stepId: step.id } },
        { label: subject.title, to: { name: 'subject', stepId: step.id, subjectId: subject.id } },
        { label: topic.title, to: { name: 'topic', stepId: step.id, subjectId: subject.id, topicId: topic.id } },
        { label: subtopic.title }
      ]} onNavigate={onNavigate} />

      <div className="lesson" style={{ position:'relative' }}>
        {/* Decorative vine running down the article column on wide screens */}
        <div style={{ position:'absolute', left:-30, top: 80, bottom: 80, width: 22, pointerEvents:'none', display: 'none' }}
             className="vine-decor">
          <VineColumn />
        </div>

        <article>
          <div className="row" style={{ justifyContent:'space-between', alignItems:'flex-start', gap: 16 }}>
            <div style={{ flex: 1 }}>
              <div className="eyebrow">{topic.title.toUpperCase()} · {subject.title}</div>
              <h1>{lesson.title}</h1>
              <p className="deck">{lesson.deck}</p>
            </div>
            <div style={{ flexShrink: 0 }}>
              <AnkiButton label="Send to Anki" />
            </div>
          </div>

          {isStub && (
            <div className="callout" style={{ marginBottom: 22 }}>
              <b>Note.</b> This lesson is part of the prototype scaffold. <b>Subdural Hematoma</b> is the fully fleshed example.&nbsp;
              <a onClick={() => onNavigate({ name: 'lesson', stepId: 'step2', subjectId: 'neuro', topicId: 'stroke', subtopicId: 'sdh' })}
                 className="xref" style={{ marginLeft: 4 }}>open it</a>
            </div>
          )}

          {lesson.sections.map(s => (
            <div key={s.id} id={'s-'+s.id} className="section">
              <h3><span className="num">{s.num}</span> {s.title}</h3>
              {s.body.map(renderBlock)}
            </div>
          ))}

          {lesson.qbank && <Qbank qbank={lesson.qbank} />}

          <CommentsSection lessonId={`${step.id}/${subject.id}/${topic.id}/${subtopic.id}`} lessonTitle={lesson.title} />

          {/* nav footer */}
          <div className="row" style={{ marginTop: 36, justifyContent: 'space-between', flexWrap: 'wrap', gap: 12 }}>
            <button className="btn ghost" onClick={() => onNavigate({ name: 'topic', stepId: step.id, subjectId: subject.id, topicId: topic.id })}>
              ← Back to {topic.title}
            </button>
            <div className="row" style={{ gap: 10 }}>
              <AnkiButton label="Send this lesson" />
              <button className="btn" onClick={() => {
                const idx = topic.subtopics.findIndex(s => s.id === subtopic.id);
                const nxt = topic.subtopics[(idx+1) % topic.subtopics.length];
                onNavigate({ name: 'lesson', stepId: step.id, subjectId: subject.id, topicId: topic.id, subtopicId: nxt.id });
              }}>Next subtopic →</button>
            </div>
          </div>
        </article>

        <aside>
          <nav className="toc">
            <div className="lab">In this lesson</div>
            {lesson.sections.map(s => (
              <a key={s.id} className={s.id === activeId ? 'active' : ''} onClick={(e) => {
                e.preventDefault();
                const el = document.getElementById('s-'+s.id);
                if (el) window.scrollTo({ top: el.offsetTop - 80, behavior: 'smooth' });
              }}>{s.title}</a>
            ))}
            {lesson.qbank && <a onClick={(e) => { e.preventDefault(); window.scrollBy({ top: 9999 }); }}>Qbank check</a>}

            {noteSnippet && (
              <div className="note" style={{ margin: '18px 0 0', padding: '14px 16px 14px 18px' }}>
                <div className="lab"><BotanicalSprig size={12} color="var(--leaf-gold)" /> note preview</div>
                <div className="body" style={{ fontSize: 14, lineHeight: 1.5 }}>
                  {noteSnippet.length > 140 ? noteSnippet.slice(0, 140) + '…' : noteSnippet}
                </div>
              </div>
            )}

            <div className="mini">
              <div className="row" style={{ justifyContent:'space-between', marginBottom: 8 }}>
                <span className="mono muted" style={{ fontSize: 10.5 }}>MASTERY</span>
                <MasteryDots value={subtopic.mastery} />
              </div>
              <div className="row">
                <Progress value={subtopic.progress} />
              </div>
              <div className="row mini" style={{ justifyContent:'space-between', marginTop: 12 }}>
                <span>Reviewed</span><b>3 days ago</b>
              </div>
              <div className="row mini" style={{ justifyContent:'space-between' }}>
                <span>Streak</span><b>4 days 🔥</b>
              </div>
              <div className="row mini" style={{ justifyContent:'space-between' }}>
                <span>Cards in deck</span><b>6</b>
              </div>
            </div>
          </nav>
        </aside>
      </div>
    </div>
  );
}

/* ---------- Progress Dashboard ---------- */
function ProgressDashboard({ onNavigate, data, hideCrumbs }) {
  const overview = _um(() => data.buildOverview(), [data]);
  const { overall, totalSubt, allTopics, strong, weak, untouched } = overview;
  const completed = Math.round((overall / 100) * totalSubt);

  // synthetic last 8 days of activity bars
  const days = ['M','T','W','T','F','S','S','M'];
  const heights = [40, 70, 25, 90, 55, 80, 30, 65];

  const subjStats = _um(() => {
    const map = new Map();
    allTopics.forEach(({ step, subj, progress }) => {
      const k = `${step.id}/${subj.id}`;
      if (!map.has(k)) map.set(k, { step, subj, totals: [], topics: 0 });
      const v = map.get(k);
      v.totals.push(progress); v.topics++;
    });
    return [...map.values()].map(v => ({
      step: v.step, subj: v.subj, topics: v.topics,
      avg: Math.round(v.totals.reduce((a,b) => a + b, 0) / v.totals.length),
    }));
  }, [allTopics]);

  const strongSubj = [...subjStats].sort((a,b) => b.avg - a.avg).slice(0, 4);
  const weakSubj   = [...subjStats].filter(s => s.avg > 0 && s.avg < 50).sort((a,b) => a.avg - b.avg).slice(0, 4);

  return (
    <div className="fade">
      {!hideCrumbs && (
        <Crumbs items={[
          { label: 'Home', to: { name: 'home' } },
          { label: 'Library', to: { name: 'library' } },
          { label: 'Progress' }
        ]} onNavigate={onNavigate} />
      )}

      <div className="row" style={{ justifyContent:'space-between', alignItems:'flex-end', marginBottom: 24, gap: 24 }}>
        <div>
          <div className="eyebrow">{ORN.sprig} your study so far</div>
          <h1 style={{ marginTop: 8 }}>How you are doing</h1>
          <p className="ink-soft" style={{ fontSize: 17, marginTop: 10, maxWidth: 640 }}>
            Overall progress, where you are strong, where to catch up. Built from your subtopic mastery.
          </p>
        </div>
        <div className="row" style={{ gap: 10 }}>
          <AnkiButton label="Sync all decks" />
        </div>
      </div>

      <div className="dash-grid">
        <div className="dash-hero">
          <div className="eyebrow">OVERALL PROGRESS</div>
          <div style={{ display:'flex', alignItems:'flex-end', gap: 18 }}>
            <div className="big">{overall}<span className="pct">%</span></div>
            <div style={{ paddingBottom: 14 }}>
              <div className="muted mono" style={{ fontSize: 11 }}>SUBTOPICS COMPLETE</div>
              <div className="serif" style={{ fontSize: 22 }}>{completed} <span className="muted" style={{ fontSize: 14 }}>/ {totalSubt}</span></div>
            </div>
            <div style={{ paddingBottom: 14 }}>
              <div className="muted mono" style={{ fontSize: 11 }}>CURRENT STREAK</div>
              <div className="serif" style={{ fontSize: 22 }}>4 days 🔥</div>
            </div>
          </div>
          <div>
            <Progress value={overall} />
          </div>
          <div style={{ marginTop: 16 }}>
            <div className="muted mono" style={{ fontSize: 11, marginBottom: 6 }}>LAST 8 DAYS · MINUTES STUDIED</div>
            <div className="bar-row">
              {heights.map((h, i) => (
                <div key={i} className="bar"><i style={{ height: `${h}%` }} /><div className="lab">{days[i]}</div></div>
              ))}
            </div>
          </div>
          <div style={{ position:'absolute', top: 18, right: 22, opacity: 0.5 }}>
            <BotanicalFern size={40} />
          </div>
        </div>

        <div className="dash-card">
          <h4>{ORN.sprig} suggestions</h4>
          <p className="muted" style={{ fontSize: 13, marginBottom: 12 }}>Topics worth catching up on, based on weakness and recency.</p>
          {weak.slice(0, 3).map(({ step, subj, topic }, i) => (
            <div key={i} className="suggest-card" onClick={() => onNavigate({ name:'topic', stepId: step.id, subjectId: subj.id, topicId: topic.id })}>
              <div className="ico"><BotanicalSprig size={20} color="var(--clay)" /></div>
              <div>
                <div className="ttl">{topic.title}</div>
                <div className="desc">{step.title} · {subj.title} · {topic.progress}% so far</div>
              </div>
            </div>
          ))}
          {untouched.length > 0 && (
            <div className="suggest-card" onClick={() => onNavigate({ name:'topic', stepId: untouched[0].step.id, subjectId: untouched[0].subj.id, topicId: untouched[0].topic.id })}>
              <div className="ico"><BotanicalSprig size={20} color="var(--sage)" /></div>
              <div>
                <div className="ttl">Start: {untouched[0].topic.title}</div>
                <div className="desc">{untouched[0].step.title} · {untouched[0].subj.title} · not started yet</div>
              </div>
            </div>
          )}
        </div>
      </div>

      <div className="dash-grid" style={{ marginTop: 22 }}>
        <div className="dash-card">
          <h4>{ORN.sprig} where you are strong</h4>
          <div className="dash-list">
            {strongSubj.map(({ step, subj, avg, topics }, i) => (
              <div key={i} className="row" onClick={() => onNavigate({ name:'subject', stepId: step.id, subjectId: subj.id })} style={{ cursor: 'pointer' }}>
                <div className="name">
                  <b>{subj.title}</b>
                  <div className="meta">{step.title} · {topics} topics</div>
                </div>
                <div style={{ display:'flex', alignItems:'center', gap: 12 }}>
                  <div style={{ width: 100 }}><Progress value={avg} tone="sage" /></div>
                  <span className="mono" style={{ fontSize: 12, color: 'var(--sage-2)', minWidth: 36, textAlign: 'right' }}>{avg}%</span>
                </div>
              </div>
            ))}
          </div>
        </div>

        <div className="dash-card">
          <h4>{ORN.sprig} where to catch up</h4>
          <div className="dash-list">
            {weakSubj.map(({ step, subj, avg, topics }, i) => (
              <div key={i} className="row" onClick={() => onNavigate({ name:'subject', stepId: step.id, subjectId: subj.id })} style={{ cursor: 'pointer' }}>
                <div className="name">
                  <b>{subj.title}</b>
                  <div className="meta">{step.title} · {topics} topics</div>
                </div>
                <div style={{ display:'flex', alignItems:'center', gap: 12 }}>
                  <div style={{ width: 100 }}><Progress value={avg} /></div>
                  <span className="mono" style={{ fontSize: 12, color: 'var(--clay-2)', minWidth: 36, textAlign: 'right' }}>{avg}%</span>
                </div>
              </div>
            ))}
            {weakSubj.length === 0 && (
              <div className="muted" style={{ fontSize: 13, padding: 8 }}>No weak spots yet. Keep going.</div>
            )}
          </div>
        </div>
      </div>

      <BranchDivider />

      <div className="dash-card">
        <h4>{ORN.sprig} recent activity</h4>
        <div className="dash-list">
          {[
            { name: 'Subdural Hematoma', path: 'Step 2 · Neurology · Stroke', when: 'yesterday', ref: { name:'lesson', stepId:'step2', subjectId:'neuro', topicId:'stroke', subtopicId:'sdh' } },
            { name: 'Gram-Positive Cocci', path: 'Bugs · Bacteriology', when: '2 days ago', ref: { name:'subject', stepId:'bugs', subjectId:'bact' } },
            { name: 'Antihypertensives', path: 'Drugs · Cardiovascular', when: '3 days ago', ref: { name:'subject', stepId:'drugs', subjectId:'cv-rx' } },
            { name: 'Beta-lactams', path: 'Drugs · Antimicrobials', when: '5 days ago', ref: { name:'subject', stepId:'drugs', subjectId:'antimicro-rx' } },
          ].map((r, i) => (
            <div key={i} className="row" style={{ cursor: 'pointer' }} onClick={() => onNavigate(r.ref)}>
              <div className="name"><b>{r.name}</b><div className="meta">{r.path}</div></div>
              <div className="meta">{r.when}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Landing, StepHub, SubjectPage, TopicPage, LessonPage, ProgressDashboard });
