/* polish/leren-shared.jsx
   Cross-view Leren-componenten. Wordt door alle 4 Leren-HTMLs geladen,
   na shared.jsx en leren-components.jsx. Bevat:
   - LerenPage (page-shell wrapper: Sidebar + Topbar + main)
   - ChapterHeader (breadcrumb + subject-chip + titel + mastery)
   - FlashcardDeck (vraag/antwoord-flip + grade-knoppen — gebruikt in
     hoofdstuk-flashcards-tab én herhaalsessie)
   - ChatPanel + ChatBubble + ChatComposer (gebruikt in hoofdstuk-pulse-tab
     én bibliotheek-pulse-entry)
   - LerenTabs (kleine tab-strip; gebruikt in hoofdstuk én bibliotheek)
*/

/* ─── LerenPage — page shell ─────────────────────────────── */
function LerenPage({ t, children, subtitle, title = 'Leren',
                    snaps = 1240, streak = 12, level = 7,
                    streakFrozen = false,
                    activeNav = 'leren', url = 'snapsnel.nl/leren',
                    rightExtra }) {
  const user = {
    name: 'sam_bakker', level, xp: 73, xpMax: 272,
    streak, snaps,
  };
  return (
    <div style={{
      display: 'flex',
      width: '100%',
      minHeight: 'calc(100vh - 44px)',
      background: t.bg,
    }}>
      <Sidebar t={t} active={activeNav} user={user} streakFrozen={streakFrozen} />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
        <Topbar t={t} title={title} subtitle={subtitle} rightExtra={rightExtra} />
        <main style={{ flex: 1, overflow: 'auto', padding: '20px 24px 28px', background: t.bg }}>
          {children}
        </main>
      </div>
    </div>
  );
}

/* ─── LerenTabs ──────────────────────────────────────────────
   Smalle horizontale tab-strip. Active = onderlijn in pijler-kleur,
   inactive = fgMute. Counts optioneel rechts in tab.
   ──────────────────────────────────────────────────────────── */
function LerenTabs({ t, tabs = [], active, accent }) {
  const c = accent || t.primary;
  return (
    <div style={{
      display: 'flex', gap: 4,
      borderBottom: `1px solid ${t.border}`,
      marginBottom: 0,
    }}>
      {tabs.map(tab => {
        const isActive = tab.id === active;
        return (
          <div key={tab.id} style={{
            padding: '12px 18px',
            borderBottom: `2px solid ${isActive ? c : 'transparent'}`,
            marginBottom: -1,
            display: 'inline-flex', alignItems: 'center', gap: 8,
            cursor: 'pointer',
          }}>
            {tab.icon && (
              <PI name={tab.icon} size={14}
                color={isActive ? c : t.fgMute} strokeWidth={2.4} />
            )}
            <span style={{
              fontFamily: 'Nunito', fontSize: 13, fontWeight: 800,
              color: isActive ? t.fg : t.fgMute,
              whiteSpace: 'nowrap',
            }}>{tab.label}</span>
            {tab.count != null && (
              <span style={{
                fontSize: 10.5, fontWeight: 800,
                padding: '2px 7px', borderRadius: 999,
                background: isActive
                  ? `color-mix(in srgb, ${c} 14%, transparent)`
                  : t.cardSunken,
                color: isActive ? c : t.fgMute,
                border: `1px solid ${isActive
                  ? `color-mix(in srgb, ${c} 28%, transparent)`
                  : t.border}`,
              }}>{tab.count}</span>
            )}
          </div>
        );
      })}
    </div>
  );
}

/* ─── ChapterHeader ─────────────────────────────────────────
   Breadcrumb + subject-chip + grote Fredoka-titel + MasteryDots
   + planner-handoff-badge. Hergebruikt in hoofdstuk-detail
   en eventueel later in herhaalsessie-context.
   ──────────────────────────────────────────────────────────── */
function ChapterHeader({ t, subject, breadcrumb = [], chapter, source,
                         masteryLevel, fromPlannen, toetsContext, rightExtra }) {
  return (
    <div style={{
      background: t.card, border: `1px solid ${t.border}`,
      borderRadius: 12, padding: 22,
      display: 'flex', flexDirection: 'column', gap: 14,
    }}>
      {/* breadcrumb */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap',
        fontSize: 11.5, color: t.fgMute, fontWeight: 700,
      }}>
        {breadcrumb.map((bc, i) => (
          <React.Fragment key={i}>
            {i > 0 && <PI name="chevron-right" size={12} color={t.fgMute} />}
            <span style={{ color: i === breadcrumb.length - 1 ? t.fgDim : t.fgMute }}>{bc}</span>
          </React.Fragment>
        ))}
      </div>

      {/* main row: subject-chip + title + meta */}
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 16 }}>
        <SubjectChip t={t} subject={subject} size="lg" iconOnly />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6, flexWrap: 'wrap' }}>
            {fromPlannen && (
              <HandoffBadge t={t} pillar="plannen" direction="from" label="uit Plannen" />
            )}
            {toetsContext && (
              <span style={{
                display: 'inline-flex', alignItems: 'center', gap: 5, height: 22, padding: '0 9px',
                borderRadius: 999,
                background: t.mode === 'dark' ? 'rgba(244,114,182,0.14)' : 'rgba(190,24,93,0.10)',
                color: t.mode === 'dark' ? '#F472B6' : '#BE185D',
                border: `1px solid ${t.mode === 'dark' ? 'rgba(244,114,182,0.28)' : 'rgba(190,24,93,0.28)'}`,
                fontSize: 10.5, fontWeight: 800, letterSpacing: 0.3, textTransform: 'uppercase',
              }}>
                <PI name="alert-circle" size={10} strokeWidth={2.6} />{toetsContext}
              </span>
            )}
          </div>
          <h1 style={{
            margin: 0, fontFamily: 'Fredoka One', fontSize: 26,
            color: t.fg, lineHeight: 1.15, letterSpacing: '-0.01em',
          }}>{chapter}</h1>
          {source && (
            <div style={{ fontSize: 12, color: t.fgDim, fontWeight: 600, marginTop: 6 }}>
              {source}
            </div>
          )}
        </div>
        {rightExtra && <div style={{ flexShrink: 0 }}>{rightExtra}</div>}
      </div>

      {/* mastery rail */}
      {masteryLevel != null && (
        <div style={{
          display: 'flex', alignItems: 'center', gap: 10,
          paddingTop: 12, borderTop: `1px solid ${t.border}`,
        }}>
          <span style={{ fontSize: 10.5, color: t.fgMute, fontWeight: 800, letterSpacing: 0.4, textTransform: 'uppercase' }}>
            Beheersing
          </span>
          <MasteryDots t={t} level={masteryLevel} size="md" showLabel />
        </div>
      )}
    </div>
  );
}

/* ─── FlashcardDeck ─────────────────────────────────────────
   Eén kaart-in-beeld pattern. Toont:
   - Subject-bron-context bovenaan
   - Voortgang (3 / 12)
   - Front- of back-state (controle via prop `flipped`)
   - 4 grade-knoppen post-flip met tijdsindicaties (wanneer je deze kaart weer ziet)
   Statische compositie — geen click-handling.
   ──────────────────────────────────────────────────────────── */
function FlashcardDeck({ t, card, flipped = true, idx = 1, total = 12,
                         showStackHint = false, flipCtaSub, onGrade }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
      {/* Context-rail */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10,
        fontSize: 11.5, color: t.fgDim, fontWeight: 700,
      }}>
        <SubjectChip t={t} subject={card.subject} size="sm" iconOnly />
        <span>{card.source}</span>
        <span style={{ flex: 1 }} />
        <span style={{ color: t.fgMute, fontWeight: 800, letterSpacing: 0.3 }}>
          Kaart {idx} / {total}
        </span>
      </div>

      {/* Card itself, with optional stack-hint */}
      <div style={{ position: 'relative' }}>
        {showStackHint && (
          <>
            <div style={{
              position: 'absolute', left: 18, right: 18, top: 8,
              height: 24, background: t.card, border: `1px solid ${t.border}`,
              borderRadius: 8, opacity: 0.5, zIndex: 0,
            }} />
            <div style={{
              position: 'absolute', left: 10, right: 10, top: 4,
              height: 24, background: t.card, border: `1px solid ${t.border}`,
              borderRadius: 8, opacity: 0.7, zIndex: 0,
            }} />
          </>
        )}

        <div style={{
          position: 'relative', zIndex: 1,
          background: t.card, border: `1px solid ${t.border}`,
          borderRadius: 12, padding: '28px 28px 24px',
          minHeight: 240, display: 'flex', flexDirection: 'column', gap: 14,
        }}>
          {/* Side label */}
          <div style={{
            display: 'inline-flex', alignSelf: 'flex-start',
            padding: '3px 10px', borderRadius: 999,
            background: flipped ? t.primaryDim : t.cardSunken,
            color: flipped ? t.primary : t.fgMute,
            fontSize: 9.5, fontWeight: 800, letterSpacing: 0.6, textTransform: 'uppercase',
            border: `1px solid ${flipped ? `color-mix(in srgb, ${t.primary} 28%, transparent)` : t.border}`,
          }}>
            {flipped ? 'Antwoord' : 'Vraag'}
          </div>

          {/* Question */}
          <div style={{
            fontFamily: 'Fredoka One', fontSize: 22, color: t.fg,
            lineHeight: 1.3, letterSpacing: '-0.005em',
          }}>{card.front}</div>

          {/* Answer (only when flipped) */}
          {flipped && (
            <div style={{
              paddingTop: 14, borderTop: `1px dashed ${t.border}`,
              display: 'flex', flexDirection: 'column', gap: 10,
            }}>
              <div style={{ fontSize: 14.5, color: t.fg, fontWeight: 600, lineHeight: 1.6 }}>
                {card.back}
              </div>
              {card.note && (
                <div style={{
                  display: 'flex', alignItems: 'flex-start', gap: 8,
                  padding: '10px 12px', borderRadius: 8,
                  background: t.cardSunken, border: `1px solid ${t.border}`,
                }}>
                  <PI name="lightbulb" size={13} color={t.gold} strokeWidth={2.4}
                       fill="currentColor" style={{ marginTop: 2, flexShrink: 0 }} />
                  <span style={{ fontSize: 12, color: t.fgDim, fontWeight: 600, lineHeight: 1.5 }}>
                    {card.note}
                  </span>
                </div>
              )}
            </div>
          )}
        </div>
      </div>

      {/* Grade buttons or flip-CTA */}
      {flipped ? (
        <GradeButtonRow t={t} />
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>
          <BtnPrimary t={t} icon="repeat-2">Toon antwoord</BtnPrimary>
          {flipCtaSub && (
            <span style={{ fontSize: 11.5, color: t.fgMute, fontWeight: 600 }}>
              {flipCtaSub}
            </span>
          )}
        </div>
      )}
    </div>
  );
}

/* Tweeregelige header + 4-koloms grade-grid. Eén consistente eenheid
   die de "hoe goed kende je deze kaart" framing levert. */
function GradeButtonRow({ t }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
        <h3 style={{
          margin: 0, fontFamily: 'Nunito', fontSize: 14.5, fontWeight: 800,
          color: t.fg, letterSpacing: '-0.005em',
        }}>Hoe goed kende je deze kaart?</h3>
        <span style={{ fontSize: 11.5, color: t.fgMute, fontWeight: 600, lineHeight: 1.5 }}>
          Pulse plant op basis hiervan wanneer je 'm weer ziet.
        </span>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
        <GradeButton t={t} grade="opnieuw"   label="Vergeten"  due="zo weer" />
        <GradeButton t={t} grade="moeilijk"  label="Moeilijk"  due="later vandaag" />
        <GradeButton t={t} grade="goed"      label="Goed"      due="morgen" />
        <GradeButton t={t} grade="makkelijk" label="Makkelijk" due="over 4 dagen" />
      </div>
    </div>
  );
}

function GradeButton({ t, grade, label, due }) {
  const dark = t.mode === 'dark';
  const palette = {
    opnieuw:   { c: dark ? '#F87171' : '#DC2626', bg: dark ? 'rgba(248,113,113,0.12)' : 'rgba(220,38,38,0.06)' },
    moeilijk:  { c: dark ? '#FBBF24' : '#B45309', bg: dark ? 'rgba(251,191,36,0.12)' : 'rgba(180,83,9,0.06)' },
    goed:      { c: dark ? '#22C55E' : '#15803D', bg: dark ? 'rgba(34,197,94,0.12)' : 'rgba(21,128,61,0.06)' },
    makkelijk: { c: dark ? '#22D3EE' : '#0369A1', bg: dark ? 'rgba(34,211,238,0.12)' : 'rgba(3,105,161,0.06)' },
  }[grade];
  return (
    <button style={{
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3,
      padding: '11px 8px', borderRadius: 10,
      background: palette.bg,
      border: `1px solid ${palette.c}40`,
      color: palette.c, cursor: 'pointer', fontFamily: 'Nunito',
      whiteSpace: 'nowrap',
    }}>
      <span style={{
        fontSize: 13, fontWeight: 800, color: t.fg,
        whiteSpace: 'nowrap', lineHeight: 1.2,
      }}>{label}</span>
      <span style={{
        fontSize: 11, fontWeight: 700, color: t.fgMute,
        whiteSpace: 'nowrap', lineHeight: 1.2,
      }}>{due}</span>
    </button>
  );
}

/* ─── ChatPanel ──────────────────────────────────────────────
   RAG-chat-paneel. Toont een stack van bubbles + composer onderaan.
   Source-context-badge bovenaan. Voorbeeld-vraag-chips boven composer
   wanneer er nog geen geschiedenis is.
   ──────────────────────────────────────────────────────────── */
function ChatPanel({ t, source, messages = [], suggestions = [],
                     placeholder = 'Stel een vraag…', height = 520 }) {
  const dark = t.mode === 'dark';
  const purple = dark ? '#9D4EDD' : '#7C3AED';
  return (
    <div style={{
      background: t.card, border: `1px solid ${t.border}`,
      borderRadius: 12, padding: 0,
      display: 'flex', flexDirection: 'column', height,
      overflow: 'hidden',
    }}>
      {/* Header */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10,
        padding: '14px 18px', borderBottom: `1px solid ${t.border}`,
        background: t.cardSunken,
      }}>
        <PulseMascot size={28} mood="thinking" />
        <div style={{ flex: 1 }}>
          <div style={{ fontFamily: 'Nunito', fontWeight: 800, fontSize: 13, color: t.fg }}>
            Pulse — vraag iets
          </div>
          {source && (
            <div style={{ fontSize: 10.5, color: t.fgMute, fontWeight: 700, marginTop: 2 }}>
              Antwoorden uit: <span style={{ color: t.fgDim }}>{source}</span>
            </div>
          )}
        </div>
        <span style={{
          display: 'inline-flex', alignItems: 'center', gap: 4,
          padding: '3px 9px', borderRadius: 999,
          background: dark ? 'rgba(157,78,221,0.14)' : 'rgba(124,58,237,0.10)',
          color: purple, border: `1px solid ${dark ? 'rgba(157,78,221,0.28)' : 'rgba(124,58,237,0.28)'}`,
          fontSize: 9.5, fontWeight: 800, letterSpacing: 0.4, textTransform: 'uppercase',
          whiteSpace: 'nowrap',
        }}>
          <PI name="sparkles" size={9} color={purple} strokeWidth={2.4} />RAG
        </span>
      </div>

      {/* Messages */}
      <div style={{
        flex: 1, overflowY: 'auto', padding: '18px',
        display: 'flex', flexDirection: 'column', gap: 14,
      }}>
        {messages.length === 0 ? (
          <div style={{
            margin: 'auto', maxWidth: 360,
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12,
          }}>
            <PulseMascot size={56} mood="curious" />
            <div style={{
              fontFamily: 'Fredoka One', fontSize: 17, color: t.fg, textAlign: 'center',
            }}>Wat zou je willen weten?</div>
            <div style={{
              fontSize: 12, color: t.fgDim, textAlign: 'center', lineHeight: 1.5, fontWeight: 500,
            }}>
              Ik antwoord op basis van je lesmateriaal. Bronnen staan altijd onder het antwoord.
            </div>
          </div>
        ) : (
          messages.map((m, i) => <ChatBubble key={i} t={t} {...m} />)
        )}
      </div>

      {/* Suggestion chips */}
      {suggestions.length > 0 && (
        <div style={{
          display: 'flex', gap: 6, padding: '0 18px 10px', flexWrap: 'wrap',
        }}>
          {suggestions.map((s, i) => (
            <button key={i} style={{
              padding: '6px 10px', borderRadius: 999,
              background: t.cardSunken, border: `1px solid ${t.border}`,
              color: t.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
              fontFamily: 'Nunito', whiteSpace: 'nowrap',
            }}>{s}</button>
          ))}
        </div>
      )}

      {/* Composer */}
      <div style={{
        padding: '12px 14px',
        borderTop: `1px solid ${t.border}`, background: t.bg,
      }}>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8,
          padding: '8px 8px 8px 14px', borderRadius: 999,
          background: t.card, border: `1px solid ${t.borderStrong}`,
        }}>
          <span style={{ fontSize: 13, color: t.fgMute, flex: 1, fontFamily: 'Nunito' }}>
            {placeholder}
          </span>
          <button style={{
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            width: 32, height: 32, borderRadius: 999,
            background: t.primary, border: 'none', cursor: 'pointer',
            color: dark ? '#0A0F1E' : '#FFFFFF',
          }}>
            <PI name="arrow-up" size={16} strokeWidth={2.6} />
          </button>
        </div>
      </div>
    </div>
  );
}

function ChatBubble({ t, role, body, citations = [] }) {
  const dark = t.mode === 'dark';
  const isUser = role === 'user';
  return (
    <div style={{
      display: 'flex', flexDirection: 'column',
      alignItems: isUser ? 'flex-end' : 'flex-start',
      gap: 6,
    }}>
      <div style={{
        maxWidth: '88%',
        background: isUser
          ? t.primary
          : t.cardSunken,
        color: isUser
          ? (dark ? '#0A0F1E' : '#FFFFFF')
          : t.fg,
        border: isUser ? 'none' : `1px solid ${t.border}`,
        padding: '10px 14px', borderRadius: 8,
        borderBottomRightRadius: isUser ? 4 : 14,
        borderBottomLeftRadius: isUser ? 14 : 4,
        fontSize: 13.5, lineHeight: 1.55, fontWeight: isUser ? 700 : 500,
        whiteSpace: 'pre-wrap',
      }}>{body}</div>
      {citations.length > 0 && (
        <div style={{
          display: 'flex', flexWrap: 'wrap', gap: 5,
          maxWidth: '88%',
        }}>
          {citations.map((c, i) => (
            <span key={i} style={{
              display: 'inline-flex', alignItems: 'center', gap: 4,
              padding: '2px 8px', borderRadius: 999,
              background: t.cardSunken, border: `1px solid ${t.border}`,
              color: t.fgMute, fontSize: 10, fontWeight: 700, letterSpacing: 0.2,
            }}>
              <PI name="book-open" size={10} color={t.fgMute} />
              {c}
            </span>
          ))}
        </div>
      )}
    </div>
  );
}

/* ─── TestJezelfTab ──────────────────────────────────────────
   Two-mode Active Recall + Feynman tab rendered inside chapter-detail.
   Quick Recall: 3 questions, score each, overview at end.
   Feynman: topic pick → free-write → AI rubric feedback.
   Feynman is gated behind hasFeature('feynman') (premium-plus only).
   ──────────────────────────────────────────────────────────── */
function TestJezelfTab({ t, hasFeature }) {
  const { useState, useRef } = React;
  const dark = t.mode === 'dark';

  /* shared mode state */
  const [mode, setMode] = useState(null);           // null | 'recall' | 'feynman'
  const [feynmanUnlocked, setFeynmanUnlocked] = useState(false);

  if (!mode) {
    return <TestJezelfModeKeuze t={t} dark={dark} hasFeature={hasFeature}
      feynmanUnlocked={feynmanUnlocked}
      onStart={m => {
        if (m === 'feynman' && !hasFeature('feynman') && !feynmanUnlocked) {
          /* preview trial — unlock once */
          setFeynmanUnlocked(true);
        }
        setMode(m);
      }}
    />;
  }
  if (mode === 'recall') {
    return <QuickRecallFlow t={t} dark={dark} onExit={() => setMode(null)} />;
  }
  if (mode === 'feynman') {
    return <FeynmanFlow t={t} dark={dark} onExit={() => setMode(null)} />;
  }
  return null;
}

/* ─── TestJezelf: mode keuze ───────────────────────────────── */
function TestJezelfModeKeuze({ t, dark, hasFeature, feynmanUnlocked, onStart }) {
  const amber = dark ? '#FBBF24' : '#B45309';
  const violet = dark ? '#A78BFA' : '#7C3AED';
  const feynmanLocked = !hasFeature('feynman') && !feynmanUnlocked;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 2 }}>
        <PulseMascot size={36} mood="encouraging" />
        <div>
          <div style={{ fontFamily: 'Fredoka One', fontSize: 18, color: t.fg, lineHeight: 1.2 }}>
            Test jezelf
          </div>
          <div style={{ fontSize: 12, color: t.fgDim, fontWeight: 600, marginTop: 2 }}>
            Kies hoe je wilt oefenen
          </div>
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
        {/* Quick Recall card */}
        <div style={{
          padding: '18px 16px', borderRadius: 10,
          background: dark ? 'rgba(251,191,36,0.07)' : 'rgba(180,83,9,0.04)',
          border: `1px solid ${dark ? 'rgba(251,191,36,0.28)' : 'rgba(180,83,9,0.20)'}`,
          display: 'flex', flexDirection: 'column', gap: 10,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <PI name="zap" size={18} color={amber} strokeWidth={2.4} />
            <span style={{ fontFamily: 'Fredoka One', fontSize: 16, color: t.fg }}>
              Quick recall
            </span>
          </div>
          <p style={{ margin: 0, fontSize: 12.5, color: t.fgDim, fontWeight: 600, lineHeight: 1.55 }}>
            Korte vraag, kort antwoord. Pulse scoort je direct.
          </p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
            <span style={{ fontSize: 11, color: t.fgMute, fontWeight: 700 }}>
              3 vragen · ~ 30 sec per vraag · 1 credit per 3 vragen
            </span>
          </div>
          <BtnPrimary t={t} icon="play" onClick={() => onStart('recall')}>
            Start
          </BtnPrimary>
        </div>

        {/* Feynman card */}
        <div style={{
          padding: '18px 16px', borderRadius: 10,
          background: dark ? 'rgba(167,139,250,0.07)' : 'rgba(124,58,237,0.04)',
          border: `1px solid ${dark ? 'rgba(167,139,250,0.28)' : 'rgba(124,58,237,0.20)'}`,
          display: 'flex', flexDirection: 'column', gap: 10,
          position: 'relative', overflow: 'hidden',
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <PI name="brain" size={18} color={violet} strokeWidth={2.4} />
            <span style={{ fontFamily: 'Fredoka One', fontSize: 16, color: t.fg }}>
              Leg het uit (Feynman)
            </span>
            {feynmanLocked && (
              <span style={{
                display: 'inline-flex', alignItems: 'center', gap: 4,
                padding: '2px 7px', borderRadius: 999,
                background: dark ? 'rgba(167,139,250,0.14)' : 'rgba(124,58,237,0.10)',
                color: violet, border: `1px solid ${dark ? 'rgba(167,139,250,0.28)' : 'rgba(124,58,237,0.24)'}`,
                fontSize: 9.5, fontWeight: 800, letterSpacing: 0.3,
              }}>
                <PI name="lock" size={9} color={violet} strokeWidth={2.6} />Premium+
              </span>
            )}
          </div>
          <p style={{ margin: 0, fontSize: 12.5, color: t.fgDim, fontWeight: 600, lineHeight: 1.55 }}>
            Leg een onderwerp uit alsof je het aan een onderbouwer vertelt. Pulse geeft pedagogische feedback.
          </p>
          <div style={{ fontSize: 11, color: t.fgMute, fontWeight: 700 }}>
            ~ 2 min · diepgaande analyse
          </div>
          {feynmanLocked ? (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
              <BtnPrimary t={t} icon="sparkles" onClick={() => onStart('feynman')}>
                1 gratis preview-trial
              </BtnPrimary>
              <BtnGhost t={t} icon="chevron-right"
                onClick={() => console.log('[chapter] → premium plus upgrade')}>
                Bekijk Premium+
              </BtnGhost>
            </div>
          ) : (
            <BtnPrimary t={t} icon="play" onClick={() => onStart('feynman')}>
              Start
            </BtnPrimary>
          )}
        </div>
      </div>
    </div>
  );
}

/* ─── Quick Recall flow ────────────────────────────────────── */
function QuickRecallFlow({ t, dark, onExit }) {
  const { useState } = React;
  const [phase, setPhase] = useState('question');   // question | score | overview
  const [qIdx, setQIdx] = useState(0);
  const [answer, setAnswer] = useState('');
  const [results, setResults] = useState([]);
  const [thinking, setThinking] = useState(false);
  const [expanded, setExpanded] = useState(false);
  const [checked, setChecked] = useState({});

  const RECALL_QUESTIONS = [
    { q: 'Wat is mitose?', sample: 'Een soort celdeling waarbij twee identieke cellen ontstaan', score: 8, klopt: 'Celdeling — correct', mist: "'identieke dochtercellen' detail" },
    { q: 'Wat is osmose?', sample: 'Water beweegt door een membraan van lage naar hoge concentratie', score: 7, klopt: 'Bewegingsrichting van water — correct', mist: "'semipermeabel membraan' expliciet noemen" },
    { q: 'Wat is meiose?', sample: 'Celdeling voor geslachtscellen, waarbij het DNA gehalveerd wordt', score: 9, klopt: 'Halvering chromosomen + geslachtscellen — goed', mist: 'tweede deling zonder DNA-verdubbeling niet benoemd' },
  ];

  const total = RECALL_QUESTIONS.length;
  const current = RECALL_QUESTIONS[qIdx % total];

  function handleSubmit() {
    if (!answer.trim()) return;
    setThinking(true);
    setTimeout(() => {
      setResults(rs => [...rs, { q: current.q, answer, score: current.score, klopt: current.klopt, mist: current.mist }]);
      setThinking(false);
      setPhase('score');
    }, 600);
  }

  function handleNextQuestion() {
    if (qIdx + 1 >= total) {
      setPhase('overview');
    } else {
      setQIdx(i => i + 1);
      setAnswer('');
      setPhase('question');
    }
  }

  function handleDoMore() {
    setResults([]);
    setQIdx(0);
    setAnswer('');
    setPhase('question');
  }

  const scoreColor = s => s >= 8 ? (dark ? '#22C55E' : '#15803D') : s >= 5 ? (dark ? '#FBBF24' : '#B45309') : (dark ? '#F87171' : '#DC2626');

  if (phase === 'question') {
    const charLeft = 200 - answer.length;
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        {/* Context rail */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 11.5, color: t.fgDim, fontWeight: 700 }}>
          <SubjectChip t={t} subject="biologie" size="sm" iconOnly />
          <span>Biologie voor jou · H3</span>
          <span style={{ flex: 1 }} />
          <span style={{ color: t.fgMute, fontWeight: 800 }}>Vraag {qIdx + 1} / {total}</span>
        </div>

        <div style={{
          padding: '20px 20px 18px', borderRadius: 10,
          background: t.card, border: `1px solid ${t.border}`,
          display: 'flex', flexDirection: 'column', gap: 14,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <PulseMascot size={28} mood={thinking ? 'thinking' : 'encouraging'} />
            <div style={{ fontFamily: 'Fredoka One', fontSize: 20, color: t.fg, lineHeight: 1.2 }}>
              {current.q}
            </div>
          </div>

          <div style={{ position: 'relative' }}>
            <textarea
              value={answer}
              onChange={e => setAnswer(e.target.value.slice(0, 200))}
              placeholder="Schrijf alsof je het aan een vriend uitlegt — geen volledige zin nodig"
              rows={4}
              style={{
                width: '100%', resize: 'none', boxSizing: 'border-box',
                padding: '10px 12px', borderRadius: 8,
                background: t.cardSunken, border: `1px solid ${t.borderStrong}`,
                color: t.fg, fontSize: 13.5, fontFamily: 'Nunito', fontWeight: 600,
                lineHeight: 1.6, outline: 'none',
              }}
            />
            <span style={{
              position: 'absolute', bottom: 8, right: 10,
              fontSize: 10.5, color: charLeft < 20 ? (dark ? '#F87171' : '#DC2626') : t.fgMute, fontWeight: 700,
            }}>{charLeft}</span>
          </div>
        </div>

        <BtnPrimary t={t} icon="send"
          onClick={handleSubmit}
          disabled={!answer.trim() || thinking}
          style={{ alignSelf: 'flex-end', opacity: (!answer.trim() || thinking) ? 0.45 : 1 }}>
          {thinking ? 'Pulse checkt…' : 'Submit antwoord'}
        </BtnPrimary>
      </div>
    );
  }

  if (phase === 'score') {
    const latest = results[results.length - 1];
    const s = latest.score;
    const c = scoreColor(s);
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        {/* Big score */}
        <div style={{ textAlign: 'center', padding: '20px 0 10px' }}>
          <div style={{ fontFamily: 'Fredoka One', fontSize: 52, color: c, lineHeight: 1 }}>
            {s} / 10
          </div>
          <div style={{ fontSize: 12, color: t.fgMute, fontWeight: 700, marginTop: 4 }}>
            {s >= 8 ? 'Uitstekend!' : s >= 5 ? 'Goed bezig' : 'Nog even oefenen'}
          </div>
        </div>

        {/* Sub-stats */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          <div style={{
            padding: '12px 14px', borderRadius: 8,
            background: dark ? 'rgba(34,197,94,0.08)' : 'rgba(21,128,61,0.05)',
            border: `1px solid ${dark ? 'rgba(34,197,94,0.24)' : 'rgba(21,128,61,0.18)'}`,
          }}>
            <div style={{ fontSize: 11, color: dark ? '#22C55E' : '#15803D', fontWeight: 800, marginBottom: 4 }}>
              Wat klopte ✓
            </div>
            <div style={{ fontSize: 12.5, color: t.fgDim, fontWeight: 600 }}>• {latest.klopt}</div>
          </div>
          <div style={{
            padding: '12px 14px', borderRadius: 8,
            background: dark ? 'rgba(251,191,36,0.08)' : 'rgba(180,83,9,0.05)',
            border: `1px solid ${dark ? 'rgba(251,191,36,0.24)' : 'rgba(180,83,9,0.18)'}`,
          }}>
            <div style={{ fontSize: 11, color: dark ? '#FBBF24' : '#B45309', fontWeight: 800, marginBottom: 4 }}>
              Wat ontbrak ⚠
            </div>
            <div style={{ fontSize: 12.5, color: t.fgDim, fontWeight: 600 }}>• Je miste {latest.mist}</div>
          </div>
        </div>

        {/* Expandable source */}
        <div>
          <button onClick={() => setExpanded(prev => !prev)} style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '6px 10px', borderRadius: 8,
            background: t.cardSunken, border: `1px solid ${t.border}`,
            color: t.fgDim, fontSize: 11.5, fontWeight: 700, cursor: 'pointer', fontFamily: 'Nunito',
          }}>
            <PI name={expanded ? 'chevron-up' : 'chevron-down'} size={12} color={t.fgDim} />
            Bekijk bron-tekst
          </button>
          {expanded && (
            <div style={{
              marginTop: 8, padding: '12px 14px', borderRadius: 8,
              background: t.cardSunken, border: `1px solid ${t.border}`,
              fontSize: 12.5, color: t.fgDim, fontStyle: 'italic', lineHeight: 1.6, fontWeight: 500,
            }}>
              "{latest.q.includes('mitose') || latest.q.includes('Mitose')
                ? 'Bij mitose ontstaan uit één moedercel twee identieke dochtercellen — dit gebruikt je lichaam voor groei en herstel.'
                : latest.q.includes('osmose') || latest.q.includes('Osmose')
                  ? 'Osmose is de diffusie van water door een semipermeabel membraan, van lage naar hoge opgeloste-stof-concentratie.'
                  : 'Bij meiose ontstaan vier verschillende geslachtscellen (eicel of zaadcel) met elk de helft van het DNA.'}"
              <div style={{ marginTop: 6, fontSize: 10.5, color: t.fgMute, fontStyle: 'normal', fontWeight: 700 }}>
                — Biologie voor jou · H3
              </div>
            </div>
          )}
        </div>

        <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
          <BtnGhost t={t} onClick={onExit}>Stop sessie</BtnGhost>
          <BtnPrimary t={t} icon="chevron-right" onClick={handleNextQuestion}>
            {qIdx + 1 >= RECALL_QUESTIONS.length ? 'Bekijk overzicht' : 'Volgende vraag'}
          </BtnPrimary>
        </div>
      </div>
    );
  }

  if (phase === 'overview') {
    const avg = Math.round(results.reduce((s, r) => s + r.score, 0) / results.length);
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div style={{ textAlign: 'center' }}>
          <div style={{ fontFamily: 'Fredoka One', fontSize: 22, color: t.fg }}>
            {total} / {total} gedaan
          </div>
          <div style={{ fontSize: 13, color: t.fgDim, fontWeight: 700, marginTop: 4 }}>
            Gemiddelde score: <span style={{ color: scoreColor(avg), fontFamily: 'Fredoka One', fontSize: 16 }}>{avg} / 10</span>
          </div>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {results.map((r, i) => (
            <div key={i} style={{
              padding: '12px 14px', borderRadius: 8,
              background: t.cardSunken, border: `1px solid ${t.border}`,
              display: 'flex', alignItems: 'flex-start', gap: 12,
            }}>
              <input type="checkbox"
                checked={!!checked[i]}
                onChange={e => setChecked(c => ({ ...c, [i]: e.target.checked }))}
                style={{ marginTop: 3, flexShrink: 0, cursor: 'pointer' }}
              />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, color: t.fg, fontWeight: 800 }}>{r.q}</div>
                <div style={{ fontSize: 11.5, color: t.fgDim, fontWeight: 600, marginTop: 2 }}>
                  Je miste: {r.mist}
                </div>
              </div>
              <span style={{ fontFamily: 'Fredoka One', fontSize: 18, color: scoreColor(r.score), flexShrink: 0 }}>
                {r.score}/10
              </span>
            </div>
          ))}
        </div>

        {Object.values(checked).some(Boolean) && (
          <BtnGhost t={t} icon="repeat"
            onClick={() => console.log('[chapter] recall: maak nieuwe set', Object.keys(checked).filter(k => checked[k]).map(k => results[k].q))}>
            Maak nieuwe set van geselecteerde vragen
          </BtnGhost>
        )}

        <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
          <BtnGhost t={t} icon="rotate-ccw" onClick={handleDoMore}>Doe er nog 3</BtnGhost>
          <BtnPrimary t={t} icon="check" onClick={onExit}>Terug naar hoofdstuk</BtnPrimary>
        </div>
      </div>
    );
  }

  return null;
}

/* ─── Feynman flow ─────────────────────────────────────────── */
function FeynmanFlow({ t, dark, onExit }) {
  const { useState } = React;
  const [phase, setPhase] = useState('topic');      // topic | explain | feedback
  const [selectedTopic, setSelectedTopic] = useState(null);
  const [essay, setEssay] = useState('');
  const [thinking, setThinking] = useState(false);

  const FEYNMAN_TOPICS = [
    {
      id: 'mitose', label: 'Mitose',
      feedback: { volledigheid: 4, helderheid: 5, eigenWoorden: 5, voorbeelden: 2,
        gaps: ['Je noemde de kerndeling (karyokinese) niet apart', 'De fases (profase, metafase, anafase) zijn niet besproken'],
        tips: ['Voeg een concreet voorbeeld toe, bijv. wondheling of groei', 'Noem kort dat het DNA verdubbelt vóór de splitsing', 'Vergelijk met meiose om het contrast te benadrukken'],
        strong: 'celdeling die twee identieke cellen oplevert',
        gaps_inline: 'het doel (groei en herstel) ontbreekt',
      },
    },
    {
      id: 'meiose', label: 'Meiose',
      feedback: { volledigheid: 4, helderheid: 4, eigenWoorden: 5, voorbeelden: 3,
        gaps: ['Crossing-over niet genoemd', 'Tweede deling zonder DNA-verdubbeling niet uitgelegd'],
        tips: ['Leg uit waarom de tweede deling geen DNA-verdubbeling heeft', 'Geef een voorbeeld: eicel of zaadcel'],
        strong: 'halvering van chromosomen is goed uitgelegd',
        gaps_inline: 'het getal vier (vier eindcellen) mist',
      },
    },
    {
      id: 'plant-dier', label: 'Plant- vs dierlijke cel',
      feedback: { volledigheid: 3, helderheid: 5, eigenWoorden: 4, voorbeelden: 3,
        gaps: ['De grote centrale vacuole niet vermeld', 'Centriool van dierlijke cellen vaag'],
        tips: ['Noem de vacuole als waterreservoir', 'Geef een aanschouwelijk voorbeeld: boomstam vs spiercel'],
        strong: 'celwand en chloroplasten correct benoemd',
        gaps_inline: 'de vacuole ontbreekt',
      },
    },
    {
      id: 'stofwisseling', label: 'Stofwisseling',
      feedback: { volledigheid: 3, helderheid: 4, eigenWoorden: 4, voorbeelden: 2,
        gaps: ['Fotosynthese als onderdeel niet vermeld', 'Aerobe vs anaerobe ademhaling niet onderscheiden'],
        tips: ['Onderscheid anabool (opbouwen) en katabool (afbreken)', 'Noem de rol van mitochondriën'],
        strong: 'ATP als energiedrager goed uitgelegd',
        gaps_inline: 'het onderscheid aerob/anaeroob ontbreekt',
      },
    },
  ];

  const violet = dark ? '#A78BFA' : '#7C3AED';

  function stars(n, max = 5) {
    return Array.from({ length: max }, (_, i) => (
      <PI key={i} name={i < n ? 'star' : 'star'}
        size={13}
        color={i < n ? (dark ? '#FBBF24' : '#B45309') : t.fgMute}
        strokeWidth={2}
        fill={i < n ? 'currentColor' : 'none'}
      />
    ));
  }

  if (phase === 'topic') {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <PulseMascot size={36} mood="encouraging" />
          <div style={{ fontFamily: 'Fredoka One', fontSize: 18, color: t.fg }}>
            Welk onderwerp uit dit hoofdstuk wil je uitleggen?
          </div>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {FEYNMAN_TOPICS.map(tp => (
            <button key={tp.id} onClick={() => { setSelectedTopic(tp); setPhase('explain'); }} style={{
              display: 'flex', alignItems: 'center', gap: 12,
              padding: '13px 16px', borderRadius: 10,
              background: t.card, border: `1px solid ${t.border}`,
              color: t.fg, cursor: 'pointer', fontFamily: 'Nunito',
              textAlign: 'left',
            }}>
              <PI name="brain" size={15} color={violet} strokeWidth={2.2} />
              <span style={{ fontSize: 14, fontWeight: 800 }}>{tp.label}</span>
              <PI name="chevron-right" size={14} color={t.fgMute} style={{ marginLeft: 'auto' }} />
            </button>
          ))}
        </div>
        <BtnGhost t={t} onClick={onExit}>Terug</BtnGhost>
      </div>
    );
  }

  if (phase === 'explain') {
    const wordCount = essay.trim().split(/\s+/).filter(Boolean).length;
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div style={{
          padding: '16px 18px', borderRadius: 10,
          background: dark ? 'rgba(167,139,250,0.08)' : 'rgba(124,58,237,0.04)',
          border: `1px solid ${dark ? 'rgba(167,139,250,0.28)' : 'rgba(124,58,237,0.18)'}`,
        }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
            <PulseMascot size={32} mood={thinking ? 'thinking' : 'encouraging'} />
            <div>
              <div style={{ fontFamily: 'Fredoka One', fontSize: 17, color: t.fg, lineHeight: 1.25 }}>
                Leg <span style={{ color: violet }}>{selectedTopic.label}</span> uit alsof je het aan een onderbouw-leerling vertelt.
              </div>
              <div style={{ fontSize: 12, color: t.fgDim, fontWeight: 600, marginTop: 4 }}>
                Gebruik geen vakjargon.
              </div>
            </div>
          </div>
        </div>

        <div>
          <textarea
            value={essay}
            onChange={e => setEssay(e.target.value)}
            placeholder="Schrijf hier je uitleg…"
            rows={7}
            style={{
              width: '100%', resize: 'none', boxSizing: 'border-box',
              padding: '12px 14px', borderRadius: 8,
              background: t.cardSunken, border: `1px solid ${t.borderStrong}`,
              color: t.fg, fontSize: 13.5, fontFamily: 'Nunito', fontWeight: 600,
              lineHeight: 1.65, outline: 'none',
            }}
          />
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 6 }}>
            <span style={{
              fontSize: 11, color: wordCount >= 4 && wordCount <= 7 ? (dark ? '#22C55E' : '#15803D') : t.fgMute,
              fontWeight: 700,
            }}>{wordCount} woorden · doel: 4-7 zinnen</span>
          </div>
        </div>

        <div style={{
          padding: '10px 12px', borderRadius: 8,
          background: t.cardSunken, border: `1px solid ${t.border}`,
          display: 'flex', flexWrap: 'wrap', gap: 10,
        }}>
          {['Beschrijf het proces', 'Noem het doel', 'Geef een voorbeeld'].map((hint, i) => (
            <span key={i} style={{ fontSize: 11.5, color: t.fgDim, fontWeight: 700 }}>
              <PI name="lightbulb" size={11} color={dark ? '#FBBF24' : '#B45309'} strokeWidth={2.4} />
              {' '}{hint}
            </span>
          ))}
        </div>

        <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
          <BtnGhost t={t} onClick={() => setPhase('topic')}>Terug</BtnGhost>
          <BtnPrimary t={t} icon="send"
            onClick={() => {
              if (!essay.trim()) return;
              setThinking(true);
              setTimeout(() => { setThinking(false); setPhase('feedback'); }, 1500);
            }}
            disabled={!essay.trim() || thinking}
            style={{ opacity: (!essay.trim() || thinking) ? 0.45 : 1 }}>
            {thinking ? 'Pulse leest…' : 'Geef feedback'}
          </BtnPrimary>
        </div>
      </div>
    );
  }

  if (phase === 'feedback') {
    const fb = selectedTopic.feedback;
    const metrics = [
      { label: 'Volledigheid', score: fb.volledigheid, note: 'Je noemde de meeste kernpunten' },
      { label: 'Helderheid', score: fb.helderheid, note: 'Een 6e klasser zou dit begrijpen' },
      { label: 'Eigen woorden', score: fb.eigenWoorden, note: 'Bijna geen jargon' },
      { label: 'Voorbeeldgebruik', score: fb.voorbeelden, note: 'Een concreet voorbeeld zou helpen' },
    ];
    const violet = dark ? '#A78BFA' : '#7C3AED';

    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <PulseMascot size={32} mood="celebrating" />
          <div style={{ fontFamily: 'Fredoka One', fontSize: 18, color: t.fg }}>
            Feedback op jouw uitleg van {selectedTopic.label}
          </div>
        </div>

        {/* 2x2 metrics grid */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          {metrics.map(m => (
            <div key={m.label} style={{
              padding: '12px 14px', borderRadius: 8,
              background: t.cardSunken, border: `1px solid ${t.border}`,
              display: 'flex', flexDirection: 'column', gap: 6,
            }}>
              <div style={{ fontSize: 11, color: t.fgMute, fontWeight: 800, textTransform: 'uppercase', letterSpacing: 0.4 }}>
                {m.label}
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                <span style={{ fontFamily: 'Fredoka One', fontSize: 18, color: m.score >= 4 ? (dark ? '#22C55E' : '#15803D') : m.score >= 3 ? (dark ? '#FBBF24' : '#B45309') : (dark ? '#F87171' : '#DC2626') }}>
                  {m.score}/5
                </span>
                <div style={{ display: 'flex', gap: 1 }}>{stars(m.score)}</div>
              </div>
              <div style={{ fontSize: 11.5, color: t.fgDim, fontWeight: 600, lineHeight: 1.4 }}>{m.note}</div>
            </div>
          ))}
        </div>

        {/* Gaps */}
        <div style={{
          padding: '14px 16px', borderRadius: 8,
          background: dark ? 'rgba(251,191,36,0.07)' : 'rgba(180,83,9,0.04)',
          border: `1px solid ${dark ? 'rgba(251,191,36,0.24)' : 'rgba(180,83,9,0.16)'}`,
        }}>
          <div style={{ fontSize: 11, color: dark ? '#FBBF24' : '#B45309', fontWeight: 800, marginBottom: 8 }}>
            Wat ontbrak
          </div>
          {fb.gaps.map((g, i) => (
            <div key={i} style={{ fontSize: 12.5, color: t.fgDim, fontWeight: 600, marginBottom: 4 }}>• {g}</div>
          ))}
        </div>

        {/* Tips */}
        <div style={{
          padding: '14px 16px', borderRadius: 8,
          background: dark ? 'rgba(167,139,250,0.07)' : 'rgba(124,58,237,0.04)',
          border: `1px solid ${dark ? 'rgba(167,139,250,0.24)' : 'rgba(124,58,237,0.16)'}`,
        }}>
          <div style={{ fontSize: 11, color: violet, fontWeight: 800, marginBottom: 8 }}>
            Tips voor de volgende keer
          </div>
          {fb.tips.map((tip, i) => (
            <div key={i} style={{ fontSize: 12.5, color: t.fgDim, fontWeight: 600, marginBottom: 4 }}>• {tip}</div>
          ))}
        </div>

        {/* Jouw uitleg */}
        <div style={{
          padding: '14px 16px', borderRadius: 8,
          background: t.cardSunken, border: `1px solid ${t.border}`,
        }}>
          <div style={{ fontSize: 11, color: t.fgMute, fontWeight: 800, textTransform: 'uppercase', letterSpacing: 0.4, marginBottom: 8 }}>
            Jouw uitleg
          </div>
          <div style={{ fontSize: 13.5, lineHeight: 1.65, fontWeight: 500 }}>
            {essay.split(fb.strong || '___NOMATCH___').map((part, i, arr) => (
              <React.Fragment key={i}>
                <span style={{ color: t.fgDim }}>{part}</span>
                {i < arr.length - 1 && (
                  <span style={{ color: dark ? '#22C55E' : '#15803D', fontWeight: 700, background: dark ? 'rgba(34,197,94,0.10)' : 'rgba(21,128,61,0.08)', borderRadius: 3, padding: '0 2px' }}>
                    {fb.strong}
                  </span>
                )}
              </React.Fragment>
            ))}
          </div>
          {fb.gaps_inline && (
            <div style={{ marginTop: 8, fontSize: 11.5, color: t.fgMute, fontStyle: 'italic', fontWeight: 600 }}>
              Gemist: <span style={{ color: dark ? '#94A3B8' : '#475569' }}>{fb.gaps_inline}</span>
            </div>
          )}
        </div>

        <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
          <BtnGhost t={t} onClick={() => console.log('[chapter] feynman → samenvatting tab')}>Bekijk samenvatting</BtnGhost>
          <BtnGhost t={t} icon="chevron-right" onClick={() => { setPhase('topic'); setEssay(''); }}>Volgend onderwerp</BtnGhost>
          <BtnPrimary t={t} icon="rotate-ccw" onClick={() => { setPhase('explain'); setEssay(''); }}>Probeer opnieuw</BtnPrimary>
        </div>
      </div>
    );
  }

  return null;
}

/* ─── Expose ─────────────────────────────────────────────── */
Object.assign(window, {
  LerenPage, LerenTabs, ChapterHeader,
  FlashcardDeck, GradeButton, GradeButtonRow,
  ChatPanel, ChatBubble,
  TestJezelfTab,
});
