/* LIBRANCY — Child LMS frontend (Phase 2 · Lesson Experience v2 with Libra)
 * Implements the approved prototype against the live PHP API.
 * Flow: family unlock (parent) → profile picker (+ set PIN once) → child PIN
 *       → learner home → course path → lesson (video/task/quiz) → A-card → creations
 * Sessions persist on the device (this is the deployed app, not a sandbox).
 */
const { useState, useEffect, useRef, useCallback } = React;
const API = "";

const T = {
  navy:"#001F3F", navy2:"#0A3055", coral:"#FF6B6B", teal:"#00A88E", tealDeep:"#00715E",
  tealTint:"#E6F7F3", yellow:"#FFC93C", yellowTint:"#FFF6DC", purple:"#6C5CE7",
  ink:"#1B2733", slate:"#5C6B7A", mist:"#8597A6", line:"#E4EAF0", paper:"#FFFFFF",
  cloud:"#F5F8FB", good:"#1B9E6B",
};
const FONT = `"Poppins","Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif`;
const RANK_ICONS = { Explorer:"✦", Builder:"🚀", Creator:"★", Founder:"👑" };
const AVATARS = ["🦁","🐘","🦋","🚀","🌟","🎨","🤖","⚽"];

/* Libra — the Librancy companion. Fixed filenames: swap a file on the server to update a pose. */
function Libra({ pose, size=76, style }) {
  return <img src={`/learn/assets/libra/${pose}.webp`} alt="" aria-hidden="true" width={size}
    style={{ display:"block", flexShrink:0, ...style }} />;
}
const SAFETY_TIPS = [
  "Never share your real name, school or address with any AI tool.",
  "AI makes mistakes too — always check important answers.",
  "Ask a grown-up before sharing any photo online.",
  "If something online feels strange or scary, tell a trusted adult.",
  "Be kind online — real people read what you write.",
  "Don't believe everything you read — verify with a book or a teacher.",
  "Keep your passwords and PIN secret, even from friends.",
  "Keep personal stories private — AI is a helper, not a friend who needs them.",
  "Take breaks! Great builders rest their eyes and stretch.",
  "If AI says something unkind or wrong, stop and ask an adult.",
];
const tipFor = (id) => {
  let h = 0; for (const ch of String(id)) h = (h * 31 + ch.charCodeAt(0)) >>> 0;
  return SAFETY_TIPS[h % SAFETY_TIPS.length];
};

/* session helpers (device persistence is intended here) */
const store = {
  get: (k) => { try { return JSON.parse(localStorage.getItem("lbr_"+k)); } catch { return null; } },
  set: (k,v) => localStorage.setItem("lbr_"+k, JSON.stringify(v)),
  del: (k) => localStorage.removeItem("lbr_"+k),
};

async function api(path, opts = {}) {
  const token = opts.child === false ? store.get("parentToken") : store.get("childToken");
  const res = await fetch(API + "/api" + path, {
    method: opts.method || "GET",
    headers: { "Content-Type":"application/json", ...(token ? { Authorization:"Bearer "+token } : {}) },
    body: opts.body ? JSON.stringify(opts.body) : undefined,
  });
  const j = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(j.error || "Something went wrong");
  return j;
}

/* ── atoms ── */
const btnS = (bg, extra={}) => ({ border:"none", borderRadius:14, padding:"15px 18px", width:"100%",
  cursor:"pointer", background:bg, color:"#fff", fontSize:15.5, fontWeight:600, fontFamily:FONT,
  display:"flex", alignItems:"center", justifyContent:"center", gap:8, ...extra });
const chip = (bg,c) => ({ display:"inline-flex", alignItems:"center", gap:5, background:bg, color:c,
  fontSize:11.5, fontWeight:700, padding:"4px 10px", borderRadius:20 });
function Card({children, style}) {
  return <div style={{ background:T.paper, border:`1px solid ${T.line}`, borderRadius:18, padding:16, ...style }}>{children}</div>;
}
function Logo({ small }) {
  return <img src="/learn/assets/logo.png" alt="Librancy AI" style={{ height: small?26:34, display:"block" }} />;
}
function Spinner() {
  return <div style={{ textAlign:"center", padding:"60px 0", color:T.mist, fontSize:14 }}>Loading…</div>;
}
function Toast({ msg }) {
  if (!msg) return null;
  return <div style={{ position:"fixed", left:"50%", bottom:86, transform:"translateX(-50%)",
    background:T.navy, color:"#fff", padding:"10px 18px", borderRadius:24, fontSize:13.5,
    fontWeight:600, boxShadow:"0 8px 22px rgba(0,0,0,.3)", zIndex:60, whiteSpace:"nowrap" }}>{msg}</div>;
}

/* ── Screen: family unlock ── */
function Unlock({ onDone }) {
  const [email,setEmail] = useState(""); const [pw,setPw] = useState("");
  const [err,setErr] = useState(""); const [busy,setBusy] = useState(false);
  const go = async () => {
    setBusy(true); setErr("");
    try {
      const r = await api("/learn/family", { method:"POST", body:{ email, password: pw } });
      store.set("parentToken", r.parentToken); store.set("children", r.children);
      onDone();
    } catch(e){ setErr(e.message); } finally { setBusy(false); }
  };
  return (
    <div style={{ padding:"36px 24px", textAlign:"center" }}>
      <div style={{ display:"flex", justifyContent:"center" }}><Logo /></div>
      <h1 style={{ fontSize:22, color:T.navy, margin:"26px 0 6px" }}>Welcome to the learning space</h1>
      <p style={{ fontSize:14, color:T.slate, margin:"0 0 24px", lineHeight:1.55 }}>
        A parent unlocks this device once — then your child signs in with just their PIN.
      </p>
      <input value={email} onChange={e=>setEmail(e.target.value)} placeholder="Parent email" type="email"
        style={{ width:"100%", padding:"15px 16px", borderRadius:14, border:`2px solid ${T.line}`, fontSize:16, fontFamily:FONT, marginBottom:12, boxSizing:"border-box" }} />
      <input value={pw} onChange={e=>setPw(e.target.value)} placeholder="Password" type="password"
        onKeyDown={e=>e.key==="Enter"&&go()}
        style={{ width:"100%", padding:"15px 16px", borderRadius:14, border:`2px solid ${T.line}`, fontSize:16, fontFamily:FONT, marginBottom:14, boxSizing:"border-box" }} />
      {err && <div style={{ color:"#C0392B", fontSize:13, marginBottom:10 }}>{err}</div>}
      <button style={btnS(T.coral)} disabled={busy} onClick={go}>{busy?"Unlocking…":"Unlock family"}</button>
      <p style={{ fontSize:12, color:T.mist, marginTop:16 }}>Use the email and password from your purchase.</p>
    </div>
  );
}

/* ── Screen: profile picker (+ first-time PIN setup) ── */
function Profiles({ onChild, onReset }) {
  const children = store.get("children") || [];
  const [setup,setSetup] = useState(null); // child needing a PIN
  const [pin,setPin] = useState(""); const [err,setErr] = useState(""); const [busy,setBusy] = useState(false);

  const savePin = async () => {
    if (!/^\d{4}$/.test(pin)) { setErr("PIN must be 4 digits"); return; }
    setBusy(true); setErr("");
    try {
      await api(`/children/${setup.id}/pin`, { method:"POST", child:false, body:{ pin } });
      const kids = children.map(c => c.id===setup.id ? { ...c, hasPin:true } : c);
      store.set("children", kids); setSetup(null); setPin("");
    } catch(e){ setErr(e.message); } finally { setBusy(false); }
  };

  if (setup) return (
    <div style={{ padding:"36px 24px", textAlign:"center" }}>
      <div style={{ fontSize:56 }}>{setup.avatar || "🦁"}</div>
      <h2 style={{ fontSize:20, color:T.navy, margin:"10px 0 6px" }}>Set {setup.firstName}’s PIN</h2>
      <p style={{ fontSize:13.5, color:T.slate, margin:"0 0 18px" }}>A parent creates a 4-digit PIN {setup.firstName} will use to sign in.</p>
      <input value={pin} onChange={e=>setPin(e.target.value.replace(/\D/g,"").slice(0,4))} inputMode="numeric"
        placeholder="4-digit PIN" style={{ width:180, textAlign:"center", letterSpacing:8, padding:"15px 16px",
        borderRadius:14, border:`2px solid ${T.line}`, fontSize:22, fontFamily:FONT, marginBottom:14 }} />
      {err && <div style={{ color:"#C0392B", fontSize:13, marginBottom:10 }}>{err}</div>}
      <button style={btnS(T.teal)} disabled={busy} onClick={savePin}>Save PIN</button>
      <button style={{ ...btnS("transparent",{ color:T.slate, marginTop:6 }) }} onClick={()=>{setSetup(null);setPin("");}}>Back</button>
    </div>
  );

  return (
    <div style={{ padding:"36px 24px", textAlign:"center" }}>
      <div style={{ display:"flex", justifyContent:"center" }}><Logo small /></div>
      <h1 style={{ fontSize:22, color:T.navy, margin:"22px 0 4px" }}>Who's learning today?</h1>
      <p style={{ fontSize:13.5, color:T.slate, margin:"0 0 22px" }}>Tap your profile</p>
      <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:12 }}>
        {children.map((c,i)=>(
          <button key={c.id} onClick={()=> c.hasPin ? onChild(c) : setSetup(c)}
            style={{ padding:"22px 10px", borderRadius:18, border:`2px solid ${T.line}`, background:T.paper,
              cursor:"pointer", fontFamily:FONT }}>
            <div style={{ fontSize:44 }}>{c.avatar || AVATARS[i % AVATARS.length]}</div>
            <div style={{ fontWeight:700, color:T.navy, fontSize:15, marginTop:8 }}>{c.firstName}</div>
            <div style={{ fontSize:11, color:c.hasPin?T.mist:T.coral, fontWeight:600, marginTop:3 }}>
              {c.hasPin ? `Ages ${c.ageBand}` : "Set PIN (parent)"}
            </div>
          </button>
        ))}
      </div>
      <button style={{ ...btnS("transparent",{ color:T.mist, marginTop:22, fontSize:13 }) }} onClick={onReset}>
        Switch family
      </button>
    </div>
  );
}

/* ── Screen: child PIN ── */
function Pin({ child, onDone, onBack }) {
  const [pin,setPin] = useState(""); const [err,setErr] = useState("");
  useEffect(()=>{ if (pin.length===4) (async()=>{
    try {
      const r = await api("/auth/child-login", { method:"POST", body:{ childId: child.id, pin } });
      store.set("childToken", r.token); store.set("childName", child.firstName); onDone();
    } catch(e){ setErr("That PIN isn't right — try again!"); setPin(""); }
  })(); }, [pin]);
  return (
    <div style={{ padding:"36px 24px", textAlign:"center" }}>
      <div style={{ fontSize:56 }}>{child.avatar || "🦁"}</div>
      <h2 style={{ fontSize:21, color:T.navy, margin:"10px 0 4px" }}>Hi {child.firstName}!</h2>
      <p style={{ fontSize:13.5, color:T.slate, margin:"0 0 18px" }}>Enter your secret PIN</p>
      <div style={{ display:"flex", justifyContent:"center", gap:12, marginBottom:20 }}>
        {[0,1,2,3].map(i=><div key={i} style={{ width:16, height:16, borderRadius:"50%",
          background: i<pin.length?T.teal:T.line, transition:"all .15s" }} />)}
      </div>
      {err && <div style={{ color:"#C0392B", fontSize:13, marginBottom:12 }}>{err}</div>}
      <div style={{ display:"grid", gridTemplateColumns:"repeat(3,1fr)", gap:10, maxWidth:260, margin:"0 auto" }}>
        {[1,2,3,4,5,6,7,8,9,"",0,"⌫"].map((k,i)=>(
          <button key={i} disabled={k===""} onClick={()=> k==="⌫" ? setPin(pin.slice(0,-1)) : pin.length<4 && setPin(pin+k)}
            style={{ height:58, borderRadius:16, border:`1px solid ${T.line}`, background:k===""?"transparent":T.paper,
              fontSize:20, fontWeight:600, color:T.navy, cursor:k===""?"default":"pointer", fontFamily:FONT }}>{k}</button>
        ))}
      </div>
      <button style={{ ...btnS("transparent",{ color:T.mist, marginTop:18, fontSize:13 }) }} onClick={onBack}>Not {child.firstName}?</button>
    </div>
  );
}

/* ── Screen: learner home ── */
function Home({ data, openLesson, openCreations, refresh }) {
  const r = data.rank;
  const pct = Math.min(100, Math.round(((data.sparks - r.at) / Math.max(1,(r.nextAt - r.at))) * 100));
  return (
    <div style={{ padding:"20px 20px 90px" }}>
      <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:14 }}>
        <div>
          <div style={{ fontSize:13, color:T.slate }}>Welcome back,</div>
          <div style={{ fontSize:22, fontWeight:700, color:T.navy }}>{data.child.firstName} {data.child.avatar||"🦁"}</div>
        </div>
        <div style={{ textAlign:"right" }}>
          <span style={chip(T.yellowTint,"#8A6A00")}>⚡ {data.sparks.toLocaleString()} Sparks</span>
          <div style={{ fontSize:11.5, color:T.coral, fontWeight:700, marginTop:5 }}>🔥 {data.streak}-day streak</div>
        </div>
      </div>

      {data.cheers && data.cheers.length > 0 && (
        <Card style={{ marginBottom:14, background:"#FFF0F0", border:"1.5px solid #FFD3D3", textAlign:"center" }}>
          <div style={{ fontSize:26 }}>💛</div>
          <div style={{ fontWeight:700, color:T.navy, fontSize:14.5, marginTop:4 }}>A message from home!</div>
          {data.cheers.map((m,i)=>(
            <div key={i} style={{ fontSize:13.5, color:T.ink, marginTop:6, fontStyle:"italic" }}>“{m}”</div>
          ))}
        </Card>
      )}

      <Card style={{ background:`linear-gradient(135deg, ${T.navy}, ${T.navy2})`, border:"none" }}>
        <div style={{ display:"flex", justifyContent:"space-between", marginBottom:10 }}>
          {["Explorer","Builder","Creator","Founder"].map((name,i)=>(
            <div key={name} style={{ textAlign:"center", opacity: i<=r.index?1:0.45 }}>
              <div style={{ fontSize:18 }}>{RANK_ICONS[name]}</div>
              <div style={{ fontSize:9.5, color: i===r.index?T.yellow:"#9FB3C8", fontWeight:700,
                letterSpacing:.4, textTransform:"uppercase" }}>{name}</div>
            </div>
          ))}
        </div>
        <div style={{ height:8, borderRadius:6, background:"rgba(255,255,255,.15)" }}>
          <div style={{ height:"100%", width:`${25*r.index + pct/4}%`, borderRadius:6,
            background:`linear-gradient(90deg, ${T.teal}, ${T.yellow})`, transition:"width .6s" }} />
        </div>
        <div style={{ fontSize:11.5, color:"#BFD3E6", marginTop:8 }}>
          {r.index===3 ? <>You made it — <b style={{color:"#fff"}}>Founder</b> rank! 👑</>
            : <>{Math.max(0, r.nextAt - data.sparks)} Sparks to <b style={{color:"#fff"}}>{r.next}</b> — keep building!</>}
        </div>
      </Card>

      {data.continue ? (
        <Card style={{ marginTop:14 }}>
          <div style={{ fontSize:12, color:T.mist, fontWeight:600, marginBottom:4 }}>{data.continue.courseTitle}</div>
          <button style={btnS(T.coral)} onClick={()=>openLesson(data.continue.lessonId)}>
            ▶ Continue · {data.continue.lessonTitle}
          </button>
        </Card>
      ) : data.courses.length > 0 && (
        <Card style={{ marginTop:14, textAlign:"center", background:T.tealTint, border:"none" }}>
          <Libra pose="hero" size={96} style={{ margin:"0 auto 6px" }} />
          <div style={{ fontWeight:700, color:T.tealDeep }}>Everything complete — you're becoming future-ready!</div>
        </Card>
      )}

      <div style={{ margin:"18px 0 8px", fontWeight:700, color:T.navy, fontSize:14.5 }}>My courses</div>
      {data.courses.length===0 && (
        <Card><div style={{ fontSize:13.5, color:T.slate, textAlign:"center" }}>
          No courses unlocked yet — ask a parent to complete enrolment on librancy.com.
        </div></Card>
      )}
      <div className="grid-auto">
      {data.courses.map(c=>(
        <Card key={c.id} style={{ marginBottom:10 }}>
          <div style={{ display:"flex", justifyContent:"space-between", alignItems:"baseline" }}>
            <div style={{ fontWeight:700, color:T.navy, fontSize:15 }}>{c.title}</div>
            <span style={{ fontSize:12, color:T.tealDeep, fontWeight:700 }}>{c.percent}%</span>
          </div>
          <div style={{ height:6, borderRadius:4, background:T.line, margin:"10px 0 6px" }}>
            <div style={{ height:"100%", width:`${c.percent}%`, background:T.teal, borderRadius:4 }} />
          </div>
          <div style={{ fontSize:11.5, color:T.mist }}>{c.lessonsDone}/{c.lessonsTotal} lessons</div>
        </Card>
      ))}
      </div>

      <button style={{ ...btnS(T.paper,{ color:T.navy, border:`1.5px solid ${T.line}`, marginTop:6 }) }} onClick={openCreations}>
        🎨 My creations · {data.creations}
      </button>
    </div>
  );
}

/* ── Screen: lesson player (Lesson Experience v2) ── */
function Lesson({ id, back, toast, onACard, openLesson }) {
  const [l,setL] = useState(null); const [ov,setOv] = useState(null); const [err,setErr] = useState("");
  const [taskText,setTaskText] = useState(""); const [busy,setBusy] = useState(false);
  const [canComplete,setCanComplete] = useState(false);
  const [celebrate,setCelebrate] = useState(null); // "lesson" | "mission" | null
  const load = useCallback(()=> api(`/learn/lesson/${id}`).then(setL).catch(e=>setErr(e.message)), [id]);
  useEffect(()=>{ setL(null); setCelebrate(null); setTaskText(""); load();
    api("/learn/overview").then(setOv).catch(()=>{}); }, [load]);

  /* the complete button appears after a short focus period when a video exists */
  useEffect(()=>{
    setCanComplete(false);
    const t = setTimeout(()=>setCanComplete(true), 45000);
    return ()=>clearTimeout(t);
  }, [id]);
  useEffect(()=>{ if (l && !l.videoUrl) setCanComplete(true); }, [l]);

  if (err) return <div style={{ padding:24 }}><Card>{err}</Card>
    <button style={btnS(T.navy,{marginTop:12})} onClick={back}>Back</button></div>;
  if (!l) return <Spinner />;

  const task = l.blocks.find(b=>b.type==="build_task");
  const quiz = l.blocks.find(b=>b.type==="quiz");
  const brief = l.blocks.find(b=>b.type==="brief");
  const videoDone = l.progress.videoDone;
  const course = ov && ov.courses ? ov.courses.find(c=>c.title===l.courseTitle) : null;
  const upNext = ov && ov.continue && ov.continue.lessonId !== id ? ov.continue : null;

  const markWatched = async () => {
    const r = await api(`/learn/lesson/${id}/video`, { method:"POST" });
    if (r.sparksAwarded) { toast(`+${r.sparksAwarded} ⚡ Sparks!`); setCelebrate("lesson"); }
    load(); api("/learn/overview").then(setOv).catch(()=>{});
  };
  const sendTask = async () => {
    if (!taskText.trim()) return;
    setBusy(true);
    try {
      const r = await api(`/learn/lesson/${id}/task`, { method:"POST", body:{ text: taskText.trim() } });
      if (r.sparksAwarded) { toast(`+${r.sparksAwarded} ⚡ Great building!`); setCelebrate("mission"); }
      setTaskText(""); load();
    } catch(e){ toast(e.message); } finally { setBusy(false); }
  };

  const lockedCard = (icon, title, sub) => (
    <Card style={{ marginTop:12, opacity:.55 }}>
      <div style={{ fontWeight:700, color:T.slate, fontSize:13.5 }}>{icon} {title}</div>
      <div style={{ fontSize:12, color:T.mist, marginTop:3 }}>{sub}</div>
    </Card>
  );

  return (
    <div style={{ padding:"18px 20px 90px" }}>
      {/* header: orientation + ambient progress */}
      <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:10 }}>
        <button onClick={back} style={{ background:"none", border:"none", color:T.slate, fontSize:13.5,
          cursor:"pointer", fontFamily:FONT, padding:0 }}>← My path</button>
        {ov && (
          <div style={{ display:"flex", gap:6 }}>
            <span style={chip(T.yellowTint,"#8A6A00")}>⚡ {ov.sparks.toLocaleString()}</span>
            <span style={chip("#FFF0F0","#B84040")}>🔥 Day {ov.streak}</span>
          </div>
        )}
      </div>
      <div style={{ fontSize:11.5, color:T.mist, fontWeight:600 }}>{l.courseTitle} · {l.moduleTitle}</div>
      <h2 style={{ fontSize:18, color:T.navy, margin:"4px 0 8px" }}>{l.title}</h2>
      {course && (
        <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:12 }}>
          <div style={{ flex:1, height:6, borderRadius:4, background:T.line }}>
            <div style={{ height:"100%", width:`${course.percent}%`, background:T.teal, borderRadius:4, transition:"width .5s" }} />
          </div>
          <span style={{ fontSize:11.5, color:T.slate, fontWeight:600 }}>Course {course.percent}% · {course.lessonsDone}/{course.lessonsTotal}</span>
        </div>
      )}

      {/* Stage 1 — Libra greets with the mission brief */}
      <div style={{ display:"flex", gap:10, alignItems:"flex-end", marginBottom:12 }}>
        <Libra pose="welcome" size={78} />
        <div style={{ flex:1, background:"#E9F2FC", borderRadius:"16px 16px 16px 4px", padding:"12px 14px" }}>
          <div style={{ fontWeight:700, color:T.navy, fontSize:13 }}>
            {videoDone ? "Great to see you again, builder!" : "Hi builder! Today you'll discover"}
          </div>
          {!videoDone && brief && brief.payload.bullets && (
            <div style={{ fontSize:12.5, color:"#2B5C8A", lineHeight:1.65, marginTop:5 }}>
              {brief.payload.bullets.map((b,i)=><div key={i}>✓ {b}</div>)}
            </div>
          )}
          {!videoDone && !brief && (
            <div style={{ fontSize:12.5, color:"#2B5C8A", marginTop:5 }}>Watch, build, then earn your A!</div>
          )}
          <div style={{ fontSize:11.5, color:"#2B5C8A", marginTop:6 }}>⚡ up to 45 Sparks in this lesson</div>
        </div>
      </div>

      {/* Stage 2 — learn (video) */}
      <div style={{ borderRadius:18, overflow:"hidden", aspectRatio:"16/9", position:"relative", background:T.navy }}>
        {l.videoUrl ? (
          <iframe src={l.videoUrl} loading="lazy" title={l.title} allow="accelerometer;gyroscope;autoplay;encrypted-media;picture-in-picture"
            allowFullScreen style={{ border:0, position:"absolute", inset:0, width:"100%", height:"100%" }} />
        ) : (
          <div style={{ position:"absolute", inset:0, display:"grid", placeItems:"center",
            background:`linear-gradient(135deg, ${T.navy}, ${T.navy2})`, color:"#BFD3E6",
            fontSize:13, textAlign:"center", padding:"0 24px", lineHeight:1.6 }}>
            🎬 This lesson's video arrives here once it's attached in the admin.<br/>Carry on with your mission and quiz below!
          </div>
        )}
        <div style={{ position:"absolute", top:10, left:10 }}>
          <span style={chip("rgba(0,0,0,.45)","#9FE8D6")}>🔒 Protected stream</span>
        </div>
      </div>

      {!videoDone && (
        canComplete
          ? <button style={btnS(T.teal,{ marginTop:12, padding:"12px" })} onClick={markWatched}>Complete lesson ✓</button>
          : <div style={{ textAlign:"center", fontSize:12, color:T.mist, marginTop:12 }}>
              ▶ Watch with Libra — your complete button is on its way…
            </div>
      )}
      {videoDone && <div style={{ ...chip(T.tealTint,T.tealDeep), marginTop:12 }}>✓ Lesson complete</div>}

      {/* pre-completion: locked anticipation cards */}
      {!videoDone && lockedCard("🔒", "Today's mission", "Unlocks when the video ends")}
      {!videoDone && quiz && lockedCard("🔒", "Mastery A-card", "Complete the lesson to take the quiz")}

      {/* Stage 3 — celebrate, build, master */}
      {videoDone && celebrate === "lesson" && (
        <div style={{ display:"flex", gap:12, alignItems:"center", background:T.tealTint,
          border:"1px solid #BFE7DD", borderRadius:16, padding:"12px 14px", marginTop:12 }}>
          <Libra pose="celebration" size={72} />
          <div>
            <div style={{ fontWeight:700, color:T.tealDeep, fontSize:14 }}>Nice work, builder! 🎉</div>
            <div style={{ fontSize:12.5, color:T.tealDeep, marginTop:2 }}>Libra awarded you <b>+10 Sparks ⚡</b></div>
            <div style={{ fontSize:11.5, color:T.tealDeep, marginTop:4 }}>Your mission is unlocked ↓</div>
          </div>
        </div>
      )}

      {videoDone && task && (
        <Card style={{ marginTop:14, background:T.tealTint, border:"1px solid #BFE7DD" }}>
          <div style={{ display:"flex", gap:12 }}>
            <Libra pose="thinking" size={66} />
            <div style={{ flex:1 }}>
              <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:5 }}>
                <span style={{ fontWeight:700, color:T.tealDeep, fontSize:13.5 }}>🚀 Today's mission {l.progress.taskDone && "· done ✓"}</span>
                {!l.progress.taskDone && <span style={chip("#D3F0E7",T.tealDeep)}>+10 ⚡</span>}
              </div>
              <div style={{ fontSize:13.5, color:T.ink, lineHeight:1.55 }}>{task.payload.prompt}</div>
            </div>
          </div>
          {!l.progress.taskDone && (
            <>
              <textarea value={taskText} onChange={e=>setTaskText(e.target.value)} maxLength={500}
                placeholder="Tell Libra what you made…" rows={2}
                style={{ width:"100%", boxSizing:"border-box", marginTop:10, padding:"12px",
                  borderRadius:12, border:`1.5px solid #BFE7DD`, fontFamily:FONT, fontSize:14 }} />
              <button style={btnS(T.teal,{ marginTop:10, padding:"12px" })} disabled={busy} onClick={sendTask}>
                Complete mission (+10 ⚡)
              </button>
            </>
          )}
          {l.progress.taskDone && celebrate === "mission" && (
            <div style={{ fontSize:12.5, color:T.tealDeep, marginTop:8, fontWeight:600 }}>
              ✨ Libra loved that — you built something real today!
            </div>
          )}
        </Card>
      )}

      {videoDone && quiz && (
        l.progress.grade
          ? <Card style={{ marginTop:14, textAlign:"center" }}>
              <div style={{ fontSize:13, color:T.slate }}>Quiz result</div>
              <div style={{ fontSize:34, fontWeight:800, color:l.progress.grade==="A"?T.teal:T.navy }}>{l.progress.grade}</div>
              <button style={btnS(T.navy,{ marginTop:8, padding:"11px", fontSize:13.5 })} onClick={()=>onACard(id, quiz)}>
                {l.progress.grade==="A" ? "See my A-card 🎉" : "Try the quiz again"}
              </button>
            </Card>
          : <button style={btnS(T.navy,{ marginTop:14 })} onClick={()=>onACard(id, quiz)}>
              🏆 Earn your mastery A-card · up to +25 ⚡
            </button>
      )}

      {videoDone && upNext && (l.progress.grade || l.progress.taskDone) && (
        <Card style={{ marginTop:14 }}>
          <div style={{ fontSize:11.5, color:T.mist, fontWeight:600 }}>Up next · {upNext.courseTitle}</div>
          <button style={btnS(T.coral,{ marginTop:8, padding:"12px" })} onClick={()=>openLesson(upNext.lessonId)}>
            ▶ {upNext.lessonTitle}
          </button>
        </Card>
      )}

      {/* Libra's rotating safety tip */}
      <div style={{ display:"flex", gap:10, alignItems:"center", marginTop:14, padding:"10px 14px",
        borderRadius:14, background:T.yellowTint, border:`1px solid ${T.yellow}` }}>
        <Libra pose="teaching" size={46} />
        <div style={{ fontSize:12.5, color:T.ink, lineHeight:1.5 }}>
          <b>Libra's safety tip:</b> {tipFor(id)}
        </div>
      </div>
    </div>
  );
}

/* ── Screen: quiz + A-card ── */
function Quiz({ lessonId, quizBlock, back, toast, childName }) {
  const items = quizBlock.payload.items || [];
  const [i,setI] = useState(0); const [answers,setAnswers] = useState({});
  const [picked,setPicked] = useState(null); const [result,setResult] = useState(null);
  const q = items[i];

  const pick = (idx) => {
    if (picked!==null) return;
    setPicked(idx);
    const next = { ...answers, [q.id]: idx };
    setAnswers(next);
    setTimeout(async ()=>{
      if (i+1 < items.length) { setI(i+1); setPicked(null); }
      else {
        try {
          const r = await api(`/learn/lesson/${lessonId}/quiz`, { method:"POST", body:{ answers: next } });
          setResult(r);
          if (r.sparksAwarded) toast(`+${r.sparksAwarded} ⚡ Sparks!`);
        } catch(e){ toast(e.message); back(); }
      }
    }, 650);
  };

  if (result) {
    const isA = result.grade === "A";
    return (
      <div style={{ padding:"22px 20px 90px", position:"relative" }}>
        {isA && <Confetti />}
        <div style={{ textAlign:"center" }}>
          {isA && <Libra pose="celebration" size={104} style={{ margin:"0 auto 4px" }} />}
          <div style={{ fontSize:15, color:T.slate, fontWeight:600 }}>Quiz complete</div>
          <div style={{ fontSize:56, fontWeight:800, color:isA?T.teal:T.navy, margin:"4px 0" }}>{result.grade}</div>
          <div style={{ fontSize:13.5, color:T.slate }}>{result.score}/{result.total} mastered</div>
        </div>
        {isA && (
          <div style={{ margin:"20px 0 0", borderRadius:20, overflow:"hidden",
            background:`linear-gradient(140deg, ${T.navy} 0%, ${T.navy2} 55%, #113B63 100%)`, padding:20, color:"#fff",
            boxShadow:"0 14px 34px rgba(0,31,63,.35)" }}>
            <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center" }}>
              <img src="assets/logo_white.png" alt="Librancy AI" style={{ height:22 }} />
              <span style={chip("rgba(255,255,255,.14)",T.yellow)}>★ Achievement</span>
            </div>
            <div style={{ fontSize:20, fontWeight:800, marginTop:16 }}>{childName} scored an A!</div>
            <div style={{ fontSize:13, color:"#BFD3E6", marginTop:4 }}>Mastery quiz · Librancy AI Academy</div>
            <div style={{ marginTop:14, paddingTop:12, borderTop:"1px solid rgba(255,255,255,.15)",
              fontSize:11.5, color:"#9FB3C8" }}>Your child can build the future too → librancy.com</div>
          </div>
        )}
        {isA && navigator.share && (
          <button style={btnS("#25D366",{ marginTop:16 })} onClick={async ()=>{
            try {
              const card = await api(`/learn/share`, { method:"POST", body:{ type:"a_card", lessonId } });
              await navigator.share({ title:"Librancy AI",
                text:`${childName} just scored an A on Librancy AI! 🚀 Your child can build the future too:`,
                url: card.url });
            } catch(e){ /* user cancelled or share unsupported */ }
          }}>Share the win 📲</button>
        )}
        {!isA && <p style={{ textAlign:"center", fontSize:13.5, color:T.slate, marginTop:16 }}>
          So close — rewatch the lesson and try again. You've got this!</p>}
        <button style={btnS(T.navy,{ marginTop:10 })} onClick={back}>Back to the lesson</button>
      </div>
    );
  }

  if (!q) return <Spinner />;
  return (
    <div style={{ padding:"18px 20px 90px" }}>
      <div style={{ display:"flex", justifyContent:"space-between", marginBottom:6 }}>
        <span style={{ fontSize:12.5, color:T.slate, fontWeight:600 }}>Mastery quiz · {i+1} of {items.length}</span>
        <span style={chip(T.yellowTint,"#8A6A00")}>⚡ +25 for an A</span>
      </div>
      <div style={{ height:6, borderRadius:4, background:T.line, marginBottom:18 }}>
        <div style={{ height:"100%", width:`${(i/items.length)*100}%`, background:T.teal, borderRadius:4, transition:"width .3s" }} />
      </div>
      <h2 style={{ fontSize:18.5, color:T.navy, lineHeight:1.35, margin:"0 0 16px" }}>{q.prompt}</h2>
      {q.options.map((o,idx)=>(
        <button key={idx} onClick={()=>pick(idx)} style={{ width:"100%", textAlign:"left", padding:"15px 16px",
          borderRadius:14, border:`2px solid ${picked===idx?T.teal:T.line}`,
          background:picked===idx?T.tealTint:T.paper, marginBottom:10, cursor:"pointer",
          fontFamily:FONT, fontSize:14.5, fontWeight:600, color:T.ink }}>{o}</button>
      ))}
      <p style={{ fontSize:12, color:T.mist, textAlign:"center" }}>Pick the answer you believe — there's no penalty for trying.</p>
    </div>
  );
}

function Confetti() {
  return (
    <div style={{ position:"absolute", inset:0, overflow:"hidden", pointerEvents:"none" }} aria-hidden>
      {Array.from({length:26}).map((_,i)=>(
        <span key={i} style={{ position:"absolute", top:-12, left:`${(i*37)%100}%`, width:8, height:12,
          background:[T.coral,T.teal,T.yellow,T.purple,"#0066FF"][i%5], borderRadius:2,
          animation:`fall 2.6s ${i*0.09}s ease-in forwards`, transform:`rotate(${(i*47)%360}deg)` }} />
      ))}
    </div>
  );
}

/* ── Screen: creations ── */
function Creations({ back }) {
  const [rows,setRows] = useState(null);
  useEffect(()=>{ api("/learn/creations").then(setRows).catch(()=>setRows([])); },[]);
  return (
    <div style={{ padding:"20px 20px 90px" }}>
      <button onClick={back} style={{ background:"none", border:"none", color:T.slate, fontSize:13.5,
        cursor:"pointer", fontFamily:FONT, padding:0, marginBottom:12 }}>← Home</button>
      <h2 style={{ fontSize:20, color:T.navy, margin:"0 0 14px" }}>My creations 🎨</h2>
      {!rows ? <Spinner /> : rows.length===0
        ? <Card><div style={{ fontSize:13.5, color:T.slate, textAlign:"center" }}>
            Nothing here yet — finish a Builder task and it appears on your pride wall!</div></Card>
        : rows.map(r=>(
            <Card key={r.id} style={{ marginBottom:10 }}>
              <div style={{ fontSize:11.5, color:T.mist, fontWeight:600 }}>{r.lessonTitle}</div>
              <div style={{ fontSize:14, color:T.ink, marginTop:4, lineHeight:1.5 }}>“{r.content}”</div>
            </Card>
          ))}
    </div>
  );
}

/* ── App shell ── */
function App() {
  const [screen,setScreen] = useState("boot"); // boot|unlock|profiles|pin|home|lesson|quiz|creations
  const [child,setChild] = useState(null);
  const [home,setHome] = useState(null);
  const [lessonId,setLessonId] = useState(null);
  const [quizCtx,setQuizCtx] = useState(null);
  const [toastMsg,setToastMsg] = useState("");
  const toastTimer = useRef(null);
  const toast = (m)=>{ setToastMsg(m); clearTimeout(toastTimer.current);
    toastTimer.current = setTimeout(()=>setToastMsg(""), 2200); };

  const loadHome = () => api("/learn/overview").then(d=>{ setHome(d); setScreen("home"); })
    .catch(()=>{ store.del("childToken"); setScreen(store.get("children") ? "profiles" : "unlock"); });

  useEffect(()=>{
    if (store.get("childToken")) loadHome();
    else if (store.get("children")) setScreen("profiles");
    else setScreen("unlock");
  },[]);

  const openLesson = (id)=>{ setLessonId(id); setScreen("lesson"); };

  return (
    <div style={{ minHeight:"100vh", background:T.cloud, fontFamily:FONT }}>
      <style>{`@keyframes fall { to { transform: translateY(560px) rotate(300deg); opacity:0; } }
        *{box-sizing:border-box} button:active{transform:scale(.985)}`}</style>
      <div className="lbr-shell">
        {screen==="boot" && <Spinner />}
        {screen==="unlock" && <Unlock onDone={()=>setScreen("profiles")} />}
        {screen==="profiles" && <Profiles onChild={(c)=>{setChild(c);setScreen("pin");}}
          onReset={()=>{["parentToken","children","childToken","childName"].forEach(store.del);setScreen("unlock");}} />}
        {screen==="pin" && <Pin child={child} onDone={loadHome} onBack={()=>setScreen("profiles")} />}
        {screen==="home" && (home ? <Home data={home} openLesson={openLesson}
          openCreations={()=>setScreen("creations")} refresh={loadHome} /> : <Spinner />)}
        {screen==="lesson" && <Lesson id={lessonId} back={loadHome} toast={toast} openLesson={openLesson}
          onACard={(id,qb)=>{ setQuizCtx({ id, qb }); setScreen("quiz"); }} />}
        {screen==="quiz" && <Quiz lessonId={quizCtx.id} quizBlock={quizCtx.qb}
          back={()=>setScreen("lesson")} toast={toast} childName={store.get("childName")||"Champion"} />}
        {screen==="creations" && <Creations back={loadHome} />}

        {/* Bottom nav (child session only) */}
        {["home","lesson","quiz","creations"].includes(screen) && (
          <div className="lbr-nav" style={{ position:"fixed", bottom:0, left:"50%", transform:"translateX(-50%)",
            display:"flex", background:T.navy, padding:"10px 8px", gap:4, zIndex:50 }}>
            {[["home","🏠 Home",loadHome],["creations","🎨 Creations",()=>setScreen("creations")],
              ["switch","👤 Switch",()=>{store.del("childToken");setScreen("profiles");}]].map(([k,l,fn])=>(
              <button key={k} onClick={fn} style={{ flex:1, background:screen===k?"rgba(255,255,255,.14)":"none",
                border:"none", color:screen===k?"#fff":"#7E93A8", fontSize:12, fontWeight:700,
                padding:"9px 2px", borderRadius:10, cursor:"pointer", fontFamily:FONT }}>{l}</button>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
