/* 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:"#101450", navy2:"#1B2270", coral:"#FF6B6B", blue:"#1C6BF6", teal:"#02B5AA", tealDeep:"#00715E",
  tealTint:"#E6F7F3", yellow:"#FEC323", 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 = ["🦁","🐘","🦋","🚀","🌟","🎨","🤖","⚽"];
/* Same child = same animal on every screen: stored avatar wins, else a stable pick from the id. */
function avatarFor(c) {
  if (!c) return "🦁";
  if (c.avatar) return c.avatar;
  let h = 0; for (const ch of String(c.id || c.firstName || "")) h = (h * 31 + ch.charCodeAt(0)) >>> 0;
  return AVATARS[h % AVATARS.length];
}

/* 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, onClick}) {
  return <div onClick={onClick} style={{ background:T.paper, border:`1px solid ${T.line}`, borderRadius:18, padding:16, ...style }}>{children}</div>;
}
function Logo({ small, white }) {
  return <img src={white ? "/assets/cert/logo-white.png" : "/assets/cert/logo.png"}
    alt="Librancy AI" style={{ height: small?24:32, 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, onCode }) {
  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>
      <button style={{ ...btnS(T.teal,{ marginTop:14 }) }} onClick={onCode}>
        🎟️  My child has a code
      </button>
      <a href="/parent/" style={{ display:"inline-block", marginTop:10, fontSize:13, color:T.blue,
        fontWeight:600, textDecoration:"none" }}>Forgot password? Reset it here →</a>
    </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 }}>{avatarFor(setup)}</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>
      <Libra pose="welcome" size={84} style={{ margin:"18px auto 0" }} />
      <h1 style={{ fontSize:22, color:T.navy, margin:"10px 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 }}>{avatarFor(c)}</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);
      store.set("activeChild", { id: child.id, avatar: child.avatar || null, firstName: child.firstName }); onDone();
    } catch(e){ setErr("That PIN isn't right — try again!"); setPin(""); }
  })(); }, [pin]);
  return (
    <div style={{ padding:"36px 24px", textAlign:"center" }}>
      <Libra pose="welcome" size={64} style={{ margin:"0 auto 4px" }} />
      <div style={{ fontSize:56 }}>{avatarFor(child)}</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: universal code login (any device, no parent needed) ── */
function CodeLogin({ onDone, onBack }) {
  const [code,setCode] = useState("");
  const [pin,setPin]   = useState("");
  const [err,setErr]   = useState(""); const [busy,setBusy] = useState(false);
  const onCode = (v) => {
    let s = v.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 7);
    if (s.length > 3) s = s.slice(0,3) + "-" + s.slice(3);
    setCode(s);
  };
  const go = async () => {
    if (!/^[A-Z]{3}-\d{4}$/.test(code)) { setErr("Enter your code, like UBA-4823"); return; }
    if (!/^\d{4}$/.test(pin)) { setErr("Enter your 4-digit PIN"); return; }
    setBusy(true); setErr("");
    try {
      const r = await api("/auth/code-login", { method:"POST", body:{ code, pin } });
      store.set("childToken", r.token);
      store.set("childName", r.childName || "");
      store.set("activeChild", { id: r.childId, avatar: null, firstName: r.childName || "" });
      onDone();
    } catch(e){ setErr("That code or PIN isn’t right — try again!"); setPin(""); }
    finally { setBusy(false); }
  };
  const inputS = { width:"100%", padding:"15px 16px", borderRadius:14, border:`2px solid ${T.line}`,
    fontSize:18, fontFamily:FONT, marginBottom:12, boxSizing:"border-box", textAlign:"center" };
  return (
    <div style={{ padding:"36px 24px", textAlign:"center" }}>
      <Libra pose="welcome" size={64} style={{ margin:"0 auto 6px" }} />
      <h1 style={{ fontSize:22, color:T.navy, margin:"8px 0 6px" }}>Welcome to Librancy</h1>
      <p style={{ fontSize:14, color:T.slate, margin:"0 0 22px", lineHeight:1.55 }}>
        Enter your code and PIN to start learning — on any device.
      </p>
      <input value={code} onChange={e=>onCode(e.target.value)} placeholder="Your code (e.g. UBA-4823)"
        autoCapitalize="characters" style={{ ...inputS, letterSpacing:2, fontWeight:700 }} />
      <input value={pin} onChange={e=>setPin(e.target.value.replace(/\D/g,"").slice(0,4))}
        placeholder="4-digit PIN" inputMode="numeric" type="password"
        onKeyDown={e=>e.key==="Enter"&&go()}
        style={{ ...inputS, letterSpacing:8 }} />
      {err && <div style={{ color:"#C0392B", fontSize:13, marginBottom:10 }}>{err}</div>}
      <button style={btnS(T.coral)} disabled={busy} onClick={go}>{busy?"Starting…":"Start learning →"}</button>
      <p style={{ fontSize:12, color:T.mist, marginTop:16 }}>
        Your parent has your code. Works on any phone, tablet or computer.
      </p>
      <button style={{ ...btnS("transparent",{ color:T.blue, marginTop:8, fontSize:13, fontWeight:600 }) }}
        onClick={onBack}>← A parent? Unlock this device instead</button>
    </div>
  );
}

/* ── Screen: learner home ── */
function ChallengeCert() {
  const [state,setState] = useState("idle");   // idle | loading | done
  const [url,setUrl] = useState("");
  const claim = async () => {
    setState("loading");
    try {
      const r = await api("/learn/challenge/claim", { method:"POST" });
      setUrl(r.url); setState("done");
    } catch(e){ setState("idle"); }
  };
  if (state === "done") {
    return (
      <div style={{ display:"flex", flexDirection:"column", gap:8 }}>
        <a href={url} target="_blank" rel="noreferrer"
          style={{ ...btnS("#fff",{ color:T.tealDeep, padding:"13px", fontSize:14.5, textDecoration:"none", textAlign:"center", display:"block" }) }}>
          🏆 See my certificate</a>
        <div style={{ fontSize:11.5, color:"#DFF7F1" }}>Show a grown-up — they can share it! 💛</div>
      </div>
    );
  }
  return (
    <button onClick={claim} disabled={state==="loading"}
      style={{ ...btnS("#fff",{ color:T.tealDeep, padding:"13px", fontSize:14.5,
        opacity: state==="loading"?.6:1 }) }}>
      {state==="loading" ? "Making your certificate…" : "🏆 Get my certificate"}
    </button>
  );
}

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:"center", marginBottom:12 }}><Logo small /></div>
      <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} {avatarFor(store.get("activeChild") || data.child)}</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.challenge && (
        data.challenge.complete ? (
          <Card style={{ marginTop:14, textAlign:"center",
            background:`linear-gradient(135deg, ${T.tealDeep}, ${T.teal})`, border:"none" }}>
            <div style={{ fontSize:34 }}>🏆</div>
            <div style={{ fontSize:17, fontWeight:800, color:"#fff", marginTop:4 }}>
              30-Day AI Challenge complete!</div>
            <div style={{ fontSize:12.5, color:"#DFF7F1", marginTop:6, lineHeight:1.5, marginBottom:12 }}>
              You finished all 30 days, {data.child.firstName}. You didn't just use AI —
              you learned to build with it. 🎉</div>
            <ChallengeCert />
          </Card>
        ) : (
          <Card style={{ marginTop:14, background:"#fff", border:`2px solid ${T.teal}` }}>
            <div style={{ display:"flex", justifyContent:"space-between", alignItems:"baseline", marginBottom:8 }}>
              <span style={{ fontWeight:800, color:T.tealDeep, fontSize:14 }}>🔥 30-Day AI Challenge</span>
              <span style={{ fontSize:13, fontWeight:800, color:T.navy }}>
                Day {data.challenge.day} <span style={{ color:T.mist, fontWeight:600 }}>of 30</span></span>
            </div>
            <div style={{ height:10, borderRadius:6, background:T.tealTint, overflow:"hidden" }}>
              <div style={{ height:"100%", width:`${data.challenge.percent}%`, borderRadius:6,
                background:`linear-gradient(90deg, ${T.teal}, ${T.yellow})`, transition:"width .6s" }} />
            </div>
            <div style={{ fontSize:11.5, color:T.slate, marginTop:8 }}>
              {data.challenge.day === 0
                ? "Finish your first lesson to start the challenge!"
                : `${30 - data.challenge.day} day${30 - data.challenge.day === 1 ? "" : "s"} to go — one lesson a day keeps your streak alive.`}
            </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>
      )}

      {data.certificates && data.certificates.length > 0 && (
        <>
          <div style={{ margin:"18px 0 8px", fontWeight:700, color:T.navy, fontSize:14.5 }}>My trophy shelf 🏆</div>
          {data.certificates.map(ct=>(
            <Card key={ct.code} style={{ marginBottom:10, display:"flex", alignItems:"center", gap:12, cursor:"pointer" }}
              onClick={()=>window.open(ct.url, "_blank")}>
              <div style={{ fontSize:28 }}>🎓</div>
              <div style={{ flex:1 }}>
                <div style={{ fontWeight:700, color:T.navy, fontSize:14.5 }}>{ct.courseTitle} — Complete!</div>
                <div style={{ fontSize:11.5, color:T.mist, marginTop:2 }}>Certificate {ct.displayId} · {ct.issuedOn}</div>
              </div>
              <div style={{ color:T.blue, fontWeight:700, fontSize:13, whiteSpace:"nowrap" }}>View →</div>
            </Card>
          ))}
          {(() => {
            const nxt = data.courses.find(c => c.percent < 100 &&
              !data.certificates.some(ct => ct.courseId === c.id));
            return nxt ? (
              <Card onClick={()=> nxt.resumeLessonId && openLesson(nxt.resumeLessonId)}
                style={{ marginBottom:10, display:"flex", alignItems:"center", gap:12, cursor:"pointer",
                  background:T.tealTint, border:`1px solid #BFE7DD` }}>
                <div style={{ fontSize:28 }}>{nxt.started ? "📘" : "✨"}</div>
                <div style={{ flex:1 }}>
                  <div style={{ fontWeight:700, color:T.navy, fontSize:14.5 }}>{nxt.title}</div>
                  <div style={{ fontSize:11.5, color:T.tealDeep, marginTop:2 }}>
                    {nxt.started ? "Keep going to earn this certificate" : "Start this course whenever you like"}</div>
                </div>
                <div style={{ color:T.coral, fontWeight:700, fontSize:13, whiteSpace:"nowrap" }}>
                  {nxt.started ? "Continue →" : "Start →"}</div>
              </Card>
            ) : null;
          })()}
        </>
      )}
      <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} onClick={()=> c.resumeLessonId && openLesson(c.resumeLessonId)}
          style={{ marginBottom:10, cursor: c.resumeLessonId ? "pointer" : "default" }}>
          <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, transition:"width .4s" }} />
          </div>
          <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center" }}>
            <span style={{ fontSize:11.5, color:T.mist }}>{c.lessonsDone}/{c.lessonsTotal} lessons</span>
            <span style={{ fontSize:12.5, fontWeight:700, color:T.coral }}>
              {c.percent===100 ? "Review ↺" : c.started ? "Continue →" : "Start →"}
            </span>
          </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) ── */

/* ─── AI Build Studio: build endpoint helper (query-string route, child JWT) ─── */
async function buildApi(action, body) {
  const token = store.get("childToken");
  const res = await fetch(API + "/api/build.php?action=" + action, {
    method: body ? "POST" : "GET",
    headers: { "Content-Type":"application/json", ...(token ? { Authorization:"Bearer "+token } : {}) },
    body: body ? JSON.stringify(body) : undefined,
  });
  return res.json();
}

/* ─── The child's AI build loop: prompt → generate (5-gate server) → output →
       refine (up to 3 tries) → keep. A structured build tool, never a chatbot. ─── */
const BUILD_MAX_TRIES = 3;
// Classify a mission: some are "do this now" instructions, some are "reflect on what you made".
// Also redirect any off-platform AI mention to the safe in-app Build box.
function missionKind(text) {
  const t = (text || "").toLowerCase();
  const isInstruction = /\b(open|go to|type this|here is your|use the|paste)\b/.test(t)
    || /\btask\b/.test(t);
  return isInstruction ? "instruction" : "reflect";
}
function sanitizeMission(text) {
  if (!text) return text;
  // Never send a child off-platform: point ChatGPT/other tools at the in-app Build box.
  return text
    .replace(/open chatgpt[.,]?/gi, "Use your Build box below.")
    .replace(/\bchatgpt\b/gi, "your Build box")
    .replace(/\b(open|go to)\s+(gemini|claude|bard|copilot)[.,]?/gi, "use your Build box below")
    .replace(/\b(gemini|bard|copilot)\b/gi, "your Build box");
}

function BuildMission({ lessonId, task, onKept, stepLabel }) {
  const [enabled,setEnabled] = useState(null);   // null=checking, false=off, true=on
  const [prompt,setPrompt] = useState("");
  const [output,setOutput] = useState(null);     // { text, eventId }
  const [tries,setTries] = useState(0);
  const [busy,setBusy] = useState(false);
  const [libra,setLibra] = useState("");
  const [kept,setKept] = useState(false);
  const [sparks,setSparks] = useState(0);

  useEffect(()=>{
    let alive = true;
    buildApi("status").then(r=>{ if (alive) setEnabled(!!(r && r.enabled && r.remainingToday > 0)); })
      .catch(()=>{ if (alive) setEnabled(false); });
    return ()=>{ alive = false; };
  }, [lessonId]);

  if (enabled === null || enabled === false) return null;  // silently absent when off/capped

  const triesLeft = BUILD_MAX_TRIES - tries;
  const canGenerate = prompt.trim().length >= 3 && !busy && triesLeft > 0 && !output && !kept;

  const generate = async () => {
    if (!canGenerate) return;
    setBusy(true); setLibra("");
    try {
      const r = await buildApi("generate", { lessonId, prompt, triesUsed: tries });
      if (r.ok && r.kind === "clean") { setOutput({ text:r.output, eventId:r.eventId }); setTries(r.triesUsed); }
      else if (r.kind === "redirected") { setLibra(r.childMsg); if (typeof r.triesUsed === "number") setTries(r.triesUsed); }
      else { setLibra(r.childMsg || "Let's try again in a moment! 🎈"); if (typeof r.triesUsed === "number") setTries(r.triesUsed); }
    } catch(e) { setLibra("The AI got a bit shy — tap generate again! 🎈"); }
    setBusy(false);
  };
  const keep = async () => {
    if (!output) return;
    setBusy(true);
    try {
      const r = await buildApi("keep", { eventId: output.eventId });
      if (r.ok) { setKept(true); setSparks(r.sparksAwarded || 0); if (onKept) onKept(); }
    } catch(e) {}
    setBusy(false);
  };
  const tryAgain = () => { setOutput(null); setLibra(""); };

  return (
    <Card style={{ marginTop:14, background:"#fff", border:`1px solid ${T.line}` }}>
      <div style={{ display:"flex", gap:12, marginBottom:12 }}>
        <Libra pose="teaching" size={60} />
        <div style={{ flex:1 }}>
          {stepLabel && <div style={{ fontSize:11, fontWeight:800, color:T.blue, letterSpacing:.5, marginBottom:4 }}>{stepLabel}</div>}
          <div style={{ fontWeight:700, color:T.blue, fontSize:13.5, marginBottom:3 }}>✨ Build it with AI</div>
          <div style={{ fontSize:13, color:T.ink, lineHeight:1.5 }}>
            Now try it for real — write your prompt and see what the AI makes!</div>
        </div>
      </div>

      {kept ? (
        <div style={{ textAlign:"center", padding:"8px 0" }}>
          <div style={{ fontSize:30 }}>🎉</div>
          <div style={{ fontWeight:800, color:T.navy, fontSize:15, margin:"6px 0" }}>Saved to your creations!</div>
          {sparks > 0 && <span style={{ ...chip("#D3F0E7",T.tealDeep), padding:"7px 14px", fontSize:14, fontWeight:700 }}>+{sparks} ⚡</span>}
        </div>
      ) : (
        <>
          <textarea value={prompt} onChange={e=>{ if(!output) setPrompt(e.target.value); }} disabled={!!output||busy}
            maxLength={500} rows={2} placeholder="Write your prompt here…"
            style={{ width:"100%", boxSizing:"border-box", padding:"12px", borderRadius:12,
              border:`1.5px solid ${T.line}`, fontFamily:FONT, fontSize:14,
              background: output ? T.cloud : "#fff", color: output ? T.slate : T.ink }} />
          <div style={{ display:"flex", justifyContent:"space-between", marginTop:6, fontSize:11, color:T.mist }}>
            <span>Libra reads every prompt to keep things safe 👋</span><span>{prompt.length} / 500</span>
          </div>

          {libra && (
            <div style={{ background:T.yellowTint, border:"1px solid #F0DCA0", borderRadius:12,
              padding:"11px 14px", fontSize:13, color:"#7a5c00", lineHeight:1.5, marginTop:10 }}>{libra}</div>
          )}

          {output && (
            <div style={{ marginTop:12 }}>
              <div style={{ fontSize:11, fontWeight:700, color:T.tealDeep, marginBottom:6 }}>✨ AI output · checked ✓</div>
              <div style={{ background:"#fff", border:`1px solid ${T.line}`, borderLeft:`4px solid ${T.teal}`,
                borderRadius:10, padding:"13px 15px", fontSize:13.5, color:T.ink, lineHeight:1.6, whiteSpace:"pre-wrap" }}>
                {output.text}</div>
            </div>
          )}

          {output ? (
            <>
              <button style={btnS(T.teal,{ marginTop:12, padding:"13px" })} disabled={busy} onClick={keep}>
                Keep this &amp; finish ✓</button>
              {triesLeft > 0
                ? <button style={btnS("#fff",{ marginTop:8, padding:"13px", color:T.navy, border:`1.5px solid ${T.line}` })}
                    disabled={busy} onClick={tryAgain}>Tweak &amp; try again ({triesLeft} left)</button>
                : <div style={{ textAlign:"center", fontSize:12, color:T.mist, marginTop:10 }}>
                    That was your last try — keep this great work! 🌟</div>}
            </>
          ) : (
            <button style={btnS(T.coral,{ marginTop:12, padding:"13px", opacity: canGenerate ? 1 : .5 })}
              disabled={!canGenerate} onClick={generate}>{busy ? "✨ Creating…" : "✨ Generate with AI"}</button>
          )}

          <div style={{ display:"flex", gap:5, alignItems:"center", justifyContent:"center", marginTop:12, fontSize:11, color:T.mist }}>
            {[0,1,2].map(i => <span key={i} style={{ width:7, height:7, borderRadius:"50%",
              background: i < tries ? T.coral : T.line }} />)}
            <span style={{ marginLeft:6 }}>{tries} of {BUILD_MAX_TRIES} tries used</span>
          </div>
        </>
      )}
    </Card>
  );
}

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;
    if (taskText.trim().length < 10) {
      toast("Libra says: ooh, tell me more! What did you make? ✨");
      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" }}>
      <div style={{ display:"flex", justifyContent:"center", marginBottom:12 }}><Logo small /></div>
      {/* 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>
      {l.progress.completed && (
        <div style={{ display:"flex", alignItems:"center", gap:8, background:T.tealTint,
          border:`1px solid #BFE7DD`, borderRadius:12, padding:"8px 12px", margin:"0 0 10px" }}>
          <span style={{ fontSize:15 }}>✓</span>
          <span style={{ fontSize:12.5, color:T.tealDeep, fontWeight:600 }}>
            You've completed this lesson — you're reviewing it. Your Sparks and grade are safe.</span>
        </div>
      )}
      {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 }}>Now take your quiz, build with AI, then reflect ↓</div>
          </div>
        </div>
      )}

      {videoDone && quiz && (
        l.progress.grade
          ? <Card style={{ marginTop:14, textAlign:"center" }}>
              <div style={{ fontSize:11, fontWeight:800, color:T.mist, letterSpacing:.5 }}>STEP 2 · QUIZ</div>
              <div style={{ fontSize:13, color:T.slate, marginTop:4 }}>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" ? "Review your A-card 🎉" : "Try the quiz again"}
              </button>
            </Card>
          : <button style={btnS(T.navy,{ marginTop:14 })} onClick={()=>onACard(id, quiz)}>
              🏆 Step 2 · Earn your mastery A-card · up to +25 ⚡
            </button>
      )}

      {/* Instruction-type missions render as a numbered "do this now" card BEFORE the Build box. */}
      {videoDone && task && missionKind(task.payload.prompt) === "instruction" && (
        <Card style={{ marginTop:14, background:T.blueTint, border:"1px solid #CFE0FF" }}>
          <div style={{ fontSize:11, fontWeight:800, color:T.blue, letterSpacing:.5, marginBottom:6 }}>STEP 3 · YOUR MISSION</div>
          <div style={{ display:"flex", gap:12 }}>
            <Libra pose="teaching" size={60} />
            <div style={{ fontSize:13.5, color:T.ink, lineHeight:1.6 }}>{sanitizeMission(task.payload.prompt)}</div>
          </div>
          <div style={{ fontSize:12, color:T.blue, marginTop:10, fontWeight:600 }}>👇 Do it right here in your Build box — safe, and Libra checks every prompt.</div>
        </Card>
      )}

      {videoDone && task && (
        <BuildMission lessonId={id} task={sanitizeMission(task.payload.prompt)}
          stepLabel={missionKind(task.payload.prompt)==="instruction" ? "STEP 3 · BUILD IT" : "STEP 3 · BUILD WITH AI"}
          onKept={load} />
      )}

      {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={{ fontSize:11, fontWeight:800, color:T.tealDeep, letterSpacing:.5, marginBottom:4 }}>STEP 4 · REFLECT</div>
              <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:5 }}>
                <span style={{ fontWeight:700, color:T.tealDeep, fontSize:13.5 }}>🚀 What did you make? {l.progress.taskDone && "· done ✓"}</span>
                {!l.progress.taskDone && <span style={chip("#D3F0E7",T.tealDeep)}>+10 ⚡</span>}
              </div>
              <div style={{ fontSize:12.5, color:T.slate, lineHeight:1.5 }}>Tell Libra what you built and what you learned.</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 && 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>
      )}

      {/* Prev / Next lesson navigation (within this course) */}
      {(l.prev || l.next) && (
        <div style={{ display:"flex", gap:10, marginTop:16 }}>
          <button onClick={()=> l.prev && openLesson(l.prev.lessonId)} disabled={!l.prev}
            style={{ flex:1, background:l.prev?T.paper:"#F2F5F8", border:`1.5px solid ${T.line}`,
              borderRadius:12, padding:"11px 12px", cursor:l.prev?"pointer":"default", fontFamily:FONT,
              textAlign:"left", opacity:l.prev?1:.5 }}>
            <div style={{ fontSize:11, color:T.mist, fontWeight:700 }}>← Previous</div>
            <div style={{ fontSize:12.5, color:T.navy, fontWeight:600, whiteSpace:"nowrap",
              overflow:"hidden", textOverflow:"ellipsis" }}>{l.prev ? l.prev.title : "Start of course"}</div>
          </button>
          <button onClick={()=> l.next && l.next.unlocked && openLesson(l.next.lessonId)}
            disabled={!l.next || !l.next.unlocked}
            style={{ flex:1, background:(l.next&&l.next.unlocked)?T.paper:"#F2F5F8", border:`1.5px solid ${T.line}`,
              borderRadius:12, padding:"11px 12px", cursor:(l.next&&l.next.unlocked)?"pointer":"default",
              fontFamily:FONT, textAlign:"right", opacity:(l.next&&l.next.unlocked)?1:.5 }}>
            <div style={{ fontSize:11, color:T.mist, fontWeight:700 }}>
              {l.next && !l.next.unlocked ? "🔒 Next" : "Next →"}</div>
            <div style={{ fontSize:12.5, color:T.navy, fontWeight:600, whiteSpace:"nowrap",
              overflow:"hidden", textOverflow:"ellipsis" }}>
              {!l.next ? "End of course" : l.next.unlocked ? l.next.title : "Finish this lesson first"}</div>
          </button>
        </div>
      )}

      {/* 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, goHome }) {
  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 && result.certificate) {
    return <CertCelebration cert={result.certificate} childName={childName} goHome={goHome} />;
  }
  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%, #232B7A 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/cert/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" }}>You're learning to build the future 🚀 · Librancy AI</div>
          </div>
        )}
        {isA && (
          <div style={{ marginTop:16, background:T.tealTint, border:"1px solid #BFE7DD",
            borderRadius:14, padding:"12px 14px", display:"flex", gap:10, alignItems:"center" }}>
            <span style={{ fontSize:22 }}>💌</span>
            <div style={{ fontSize:12.5, color:T.tealDeep, lineHeight:1.5 }}>
              <b>Your grown-up will see this!</b> Your A goes to their dashboard so they can celebrate you
              and show your family. 🎉
            </div>
          </div>
        )}
        {!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:"center", marginBottom:12 }}><Logo small /></div>
      <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>
  );
}

/* ── Course-complete certificate celebration (Wave 1) ── */
function CertCelebration({ cert, childName, goHome }) {
  const share = async () => {
    const text = `${childName} just completed ${cert.courseTitle} at Librancy! 🎓 See the verified certificate:`;
    if (navigator.share) {
      try { await navigator.share({ title: "Librancy", text, url: cert.url }); return; } catch (e) { /* cancelled */ }
    }
    window.open("https://wa.me/?text=" + encodeURIComponent(text + " " + cert.url), "_blank");
  };
  return (
    <div style={{ padding:"22px 20px 90px", position:"relative", overflow:"hidden" }}>
      <Confetti />
      <div style={{ textAlign:"center" }}>
        <Libra pose="hero" size={120} style={{ margin:"0 auto" }} />
        <div style={{ fontSize:12, letterSpacing:".28em", color:T.tealDeep, fontWeight:700, marginTop:8 }}>COURSE COMPLETE</div>
        <h1 style={{ fontSize:25, fontWeight:800, color:T.navy, margin:"4px 0 2px" }}>{childName}, you did it! 🎉</h1>
        <div style={{ fontSize:14, color:T.slate }}>You finished every lesson of <b>{cert.courseTitle}</b></div>
        <div style={{ display:"flex", justifyContent:"center", marginTop:10 }}>
          <span style={chip(T.yellowTint,"#8A6A00")}>⚡ Libra awarded you +200 Sparks</span>
        </div>
      </div>
      <div style={{ margin:"18px -4px 0", transform:"rotate(-1.6deg)" }}>
        <img src={cert.imageUrl} alt="Your certificate" style={{ width:"100%", borderRadius:10, display:"block",
          border:`1px solid ${T.line}`, boxShadow:"0 18px 40px rgba(16,20,80,.35)" }} />
      </div>
      <div style={{ display:"flex", justifyContent:"center", marginTop:12 }}>
        <span style={chip(T.tealTint,T.tealDeep)}>✓ Real verified certificate · yours forever</span>
      </div>
      <button style={btnS("#25D366",{ marginTop:14 })} onClick={share}>Share my certificate 📲</button>
      <button style={btnS(T.paper,{ color:T.navy, border:`1.5px solid ${T.line}`, marginTop:10 })}
        onClick={()=>window.open(cert.url, "_blank")}>See it full size</button>
      <button style={btnS(T.navy,{ marginTop:10 })} onClick={goHome}>Keep building →</button>
      <div style={{ textAlign:"center", fontSize:12.5, color:T.mist, marginTop:14, lineHeight:1.6 }}>
        It's on your trophy shelf now 🏆<br/>Mum &amp; Dad can see and share it from their dashboard too.
      </div>
    </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,T.blue][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" }}>
      <div style={{ display:"flex", justifyContent:"center", marginBottom:12 }}><Logo small /></div>
      <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")} onCode={()=>setScreen("code")} />}
        {screen==="code" && <CodeLogin onDone={loadHome} onBack={()=>setScreen("unlock")} />}
        {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"}
          goHome={loadHome} />}
        {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 />);
