// App components for 30-Day AI Learning Plan
const { useState, useEffect, useLayoutEffect, useMemo, useRef } = React;

const GROUPS = [
  { label: "Days 1–5", start: 1, end: 5 },
  { label: "Days 6–10", start: 6, end: 10 },
  { label: "Days 11–15", start: 11, end: 15 },
  { label: "Days 16–20", start: 16, end: 20 },
  { label: "Days 21–25", start: 21, end: 25 },
  { label: "Days 26–30", start: 26, end: 30 },
];

// ---------- Icons ----------
const IconCheck = ({ size = 14, strokeWidth = 2.5, className = "" }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
       stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round"
       strokeLinejoin="round" className={className} aria-hidden="true">
    <path d="M20 6L9 17l-5-5" />
  </svg>
);

const IconChevron = ({ size = 18, className = "" }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
       stroke="currentColor" strokeWidth="2" strokeLinecap="round"
       strokeLinejoin="round" className={className} aria-hidden="true">
    <path d="M6 9l6 6 6-6" />
  </svg>
);

const IconClock = ({ size = 14, className = "" }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
       stroke="currentColor" strokeWidth="2" strokeLinecap="round"
       strokeLinejoin="round" className={className} aria-hidden="true">
    <circle cx="12" cy="12" r="9" />
    <path d="M12 7v5l3 2" />
  </svg>
);

const IconPlay = ({ size = 18, className = "" }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor"
       className={className} aria-hidden="true">
    <path d="M8 5.14v13.72a1 1 0 0 0 1.52.86l11-6.86a1 1 0 0 0 0-1.72l-11-6.86A1 1 0 0 0 8 5.14z" />
  </svg>
);

const IconExternal = ({ size = 14, className = "" }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
       stroke="currentColor" strokeWidth="2" strokeLinecap="round"
       strokeLinejoin="round" className={className} aria-hidden="true">
    <path d="M7 17L17 7" />
    <path d="M8 7h9v9" />
  </svg>
);

const IconDoc = ({ size = 16, className = "" }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
       stroke="currentColor" strokeWidth="2" strokeLinecap="round"
       strokeLinejoin="round" className={className} aria-hidden="true">
    <path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z" />
    <path d="M14 3v5h5" />
  </svg>
);

const IconX = ({ size = 18, className = "" }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
       stroke="currentColor" strokeWidth="2" strokeLinecap="round"
       strokeLinejoin="round" className={className} aria-hidden="true">
    <path d="M18 6L6 18" /><path d="M6 6l12 12" />
  </svg>
);

// youtube id extractor
function ytId(url) {
  if (!url) return null;
  const m = url.match(/(?:youtu\.be\/|v=|embed\/)([\w-]{6,})/);
  return m ? m[1] : null;
}

// ---------- Resource Modal ----------
function ResourceModal({ resource, onClose }) {
  useEffect(() => {
    const onKey = (e) => e.key === "Escape" && onClose();
    document.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [onClose]);

  if (!resource) return null;
  const isVideo = resource.type === "video";
  const yt = isVideo ? ytId(resource.url) : null;

  return (
    <div
      className="fixed inset-0 z-[100] flex items-center justify-center bg-black/50 p-4 backdrop-blur-sm"
      onClick={onClose}
    >
      <div
        className="relative flex w-full max-w-[860px] flex-col overflow-hidden rounded-2xl bg-[var(--surface)] shadow-[0_30px_80px_-20px_rgba(0,0,0,0.4)]"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-start justify-between gap-4 border-b border-[var(--line)] px-5 py-4">
          <div className="min-w-0">
            <div className="text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--muted)]">
              {isVideo ? "Video" : "Article"} · {resource.source}
            </div>
            <h3 className="mt-1 truncate text-[16px] font-semibold text-[var(--ink)]">
              {resource.label}
            </h3>
          </div>
          <button
            onClick={onClose}
            className="-mr-1 shrink-0 rounded-lg p-2 text-[var(--muted)] transition hover:bg-[var(--hover)] hover:text-[var(--ink)]"
            aria-label="Close"
          >
            <IconX />
          </button>
        </div>

        <div className="bg-black" style={{ aspectRatio: "16 / 9" }}>
          {yt ? (
            <iframe
              className="h-full w-full"
              src={`https://www.youtube.com/embed/${yt}`}
              title={resource.label}
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
              allowFullScreen
            />
          ) : (
            <div className="flex h-full w-full flex-col items-center justify-center gap-4 bg-[var(--hover)] text-center">
              <div className="flex h-14 w-14 items-center justify-center rounded-full bg-[var(--surface)] text-[var(--accent)] shadow-sm">
                <IconDoc size={22} />
              </div>
              <div className="px-8 text-[14px] text-[var(--muted)]">
                Article preview isn't available inline.
                <br />Open it in a new tab to read.
              </div>
            </div>
          )}
        </div>

        <div className="flex items-center justify-between gap-3 border-t border-[var(--line)] px-5 py-3">
          <span className="truncate text-xs text-[var(--muted)]">
            {resource.url.replace(/^https?:\/\//, "").split("/")[0]}
          </span>
          <a
            href={resource.url}
            target="_blank"
            rel="noopener noreferrer"
            className="inline-flex items-center gap-1.5 rounded-lg bg-[var(--ink)] px-3 py-1.5 text-xs font-medium text-[var(--surface)] transition hover:bg-[var(--accent)]"
          >
            Open in new tab <IconExternal size={12} />
          </a>
        </div>
      </div>
    </div>
  );
}

// ---------- Header ----------
function Header({ completedCount, total, onReset }) {
  const pct = Math.round((completedCount / total) * 100);
  return (
    <header className="w-full">
      <div className="flex items-start justify-between gap-6">
        <div>
          <div className="flex items-center gap-2 text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--muted)]">
            <span className="inline-block h-1.5 w-1.5 rounded-full bg-[var(--accent)]" />
            A 30-day plan
          </div>
          <h1 className="mt-2 text-[clamp(28px,4.2vw,40px)] font-semibold leading-[1.05] tracking-[-0.02em] text-[var(--ink)]">
            30-Day AI Learning Plan
          </h1>
          <p className="mt-2 text-[15px] text-[var(--muted)]">
            Learn AI in 1 hour a day.
          </p>
        </div>
        <button
          onClick={onReset}
          className="hidden shrink-0 rounded-full border border-[var(--line)] px-3 py-1.5 text-xs font-medium text-[var(--muted)] transition hover:border-[var(--ink)] hover:text-[var(--ink)] sm:inline-flex"
          title="Reset progress"
        >
          Reset
        </button>
      </div>

      <div className="mt-7">
        <div className="flex items-baseline justify-between">
          <div className="flex items-baseline gap-2">
            <span className="text-[32px] font-semibold leading-none tracking-[-0.02em] text-[var(--ink)] tabular-nums">
              {completedCount}
            </span>
            <span className="text-sm text-[var(--muted)]">of {total} days</span>
          </div>
          <span className="text-sm font-medium tabular-nums text-[var(--muted)]">
            {pct}%
          </span>
        </div>
        <div className="mt-3 h-1.5 w-full overflow-hidden rounded-full bg-[var(--line-soft)]">
          <div
            className="h-full rounded-full bg-[var(--accent)] transition-[width] duration-500 ease-out"
            style={{ width: `${pct}%` }}
          />
        </div>
        <div className="mt-2 flex gap-[3px]">
          {Array.from({ length: total }, (_, i) => i + 1).map((d, i) => (
            <div
              key={d}
              className="h-1 flex-1 rounded-full transition-colors"
              style={{
                background:
                  i < completedCount ? "var(--accent)" : "var(--line-soft)",
              }}
            />
          ))}
        </div>
      </div>
    </header>
  );
}

// ---------- Group dropdown ----------
function GroupDropdown({ value, onChange, completedSet }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);

  useEffect(() => {
    if (!open) return;
    const onDoc = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    const onKey = (e) => e.key === "Escape" && setOpen(false);
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  const current = GROUPS[value];
  const groupCompleted = (g) => {
    let n = 0;
    for (let d = g.start; d <= g.end; d++) if (completedSet.has(d)) n++;
    return n;
  };

  return (
    <div className="relative w-full" ref={ref}>
      <button
        type="button"
        onClick={() => setOpen((o) => !o)}
        aria-haspopup="listbox"
        aria-expanded={open}
        className="group flex w-full items-center justify-between gap-3 rounded-xl border border-[var(--line)] bg-[var(--surface)] px-4 py-3 text-left transition hover:border-[var(--ink-soft)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--accent)]"
      >
        <span className="flex items-center gap-3">
          <span className="text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--muted)]">
            Viewing
          </span>
          <span className="text-[15px] font-medium text-[var(--ink)]">
            {current.label}
          </span>
        </span>
        <span className="flex items-center gap-3">
          <span className="text-xs tabular-nums text-[var(--muted)]">
            {groupCompleted(current)}/5 done
          </span>
          <IconChevron
            className={`text-[var(--muted)] transition-transform duration-200 ${
              open ? "rotate-180" : ""
            }`}
          />
        </span>
      </button>

      {open && (
        <ul
          role="listbox"
          className="absolute left-0 right-0 top-full z-20 mt-2 overflow-hidden rounded-xl border border-[var(--line)] bg-[var(--surface)] shadow-[0_12px_32px_-12px_rgba(15,23,42,0.18)]"
        >
          {GROUPS.map((g, i) => {
            const done = groupCompleted(g);
            const active = i === value;
            return (
              <li key={g.label} role="option" aria-selected={active}>
                <button
                  onClick={() => {
                    onChange(i);
                    setOpen(false);
                  }}
                  className={`flex w-full items-center justify-between gap-3 px-4 py-3 text-left text-[15px] transition ${
                    active
                      ? "bg-[var(--accent-soft)] text-[var(--ink)]"
                      : "text-[var(--ink)] hover:bg-[var(--hover)]"
                  }`}
                >
                  <span className="flex items-center gap-3">
                    <span
                      className={`inline-flex h-5 w-5 items-center justify-center rounded-full border text-[10px] font-semibold tabular-nums transition ${
                        done === 5
                          ? "border-transparent bg-[var(--success)] text-white"
                          : done > 0
                          ? "border-[var(--accent)] text-[var(--accent)]"
                          : "border-[var(--line)] text-[var(--muted)]"
                      }`}
                    >
                      {done === 5 ? <IconCheck size={11} /> : done}
                    </span>
                    <span className="font-medium">{g.label}</span>
                  </span>
                  <span className="text-xs tabular-nums text-[var(--muted)]">
                    {done}/5
                  </span>
                </button>
              </li>
            );
          })}
        </ul>
      )}
    </div>
  );
}

// ---------- Day card ----------
function MCQList({ mcqs, dayKey }) {
  const [answers, setAnswers] = useState(() => {
    try { return JSON.parse(localStorage.getItem(dayKey) || "{}"); }
    catch { return {}; }
  });

  const pick = (qi, oi) => {
    setAnswers((prev) => {
      const next = { ...prev, [qi]: oi };
      localStorage.setItem(dayKey, JSON.stringify(next));
      return next;
    });
  };

  return (
    <ol className="mt-3 space-y-4">
      {mcqs.map((m, qi) => {
        const picked = answers[qi];
        const answered = picked != null;
        return (
          <li key={qi} className="rounded-xl border border-[var(--line)] bg-[var(--hover)] p-3.5">
            <div className="flex gap-3">
              <span className="shrink-0 text-[11px] font-semibold tabular-nums text-[var(--accent)] mt-[3px]">
                Q{qi + 1}
              </span>
              <span className="text-[14px] font-medium leading-[1.5] text-[var(--ink)]">
                {m.q}
              </span>
            </div>
            <div className="mt-3 space-y-1.5">
              {m.options.map((opt, oi) => {
                const isPicked = picked === oi;
                const isCorrect = oi === m.correct;
                const state = !answered
                  ? "idle"
                  : isPicked && isCorrect
                  ? "correct"
                  : isPicked && !isCorrect
                  ? "wrong"
                  : isCorrect
                  ? "reveal"
                  : "muted";

                const base =
                  "group flex w-full items-center gap-3 rounded-lg border px-3 py-2 text-left text-[13.5px] leading-[1.45] transition";
                const variants = {
                  idle: "border-[var(--line)] bg-[var(--surface)] text-[var(--ink)] hover:border-[var(--ink-soft)]",
                  correct: "border-[var(--success)] bg-[var(--success-soft)] text-[var(--success-ink)]",
                  wrong: "border-[#e3a3a3] bg-[#fbeaea] text-[#8a2a2a] dark:bg-[#3a1f1f] dark:text-[#f2bcbc] dark:border-[#5b2f2f]",
                  reveal: "border-[var(--success)]/60 bg-[var(--surface)] text-[var(--success-ink)]",
                  muted: "border-[var(--line)] bg-[var(--surface)] text-[var(--muted)]",
                };

                return (
                  <button
                    key={oi}
                    disabled={answered}
                    onClick={(e) => { e.stopPropagation(); pick(qi, oi); }}
                    className={`${base} ${variants[state]}`}
                  >
                    <span
                      className={`flex h-5 w-5 shrink-0 items-center justify-center rounded-full border text-[10px] font-semibold tabular-nums ${
                        state === "correct" || state === "reveal"
                          ? "border-[var(--success)] bg-[var(--success)] text-white"
                          : state === "wrong"
                          ? "border-[#b84a4a] bg-[#b84a4a] text-white"
                          : "border-[var(--line)] text-[var(--muted)]"
                      }`}
                    >
                      {state === "correct" || state === "reveal" ? (
                        <IconCheck size={11} strokeWidth={3} />
                      ) : state === "wrong" ? (
                        "✕"
                      ) : (
                        String.fromCharCode(65 + oi)
                      )}
                    </span>
                    <span className="flex-1">{opt}</span>
                  </button>
                );
              })}
            </div>
            {answered && (
              <div className="mt-2.5 flex items-center justify-between text-[12px]">
                <span className={picked === m.correct ? "text-[var(--success-ink)]" : "text-[var(--muted)]"}>
                  {picked === m.correct ? "Correct." : `Correct answer: ${String.fromCharCode(65 + m.correct)}`}
                </span>
                <button
                  onClick={(e) => {
                    e.stopPropagation();
                    setAnswers((prev) => {
                      const next = { ...prev };
                      delete next[qi];
                      localStorage.setItem(dayKey, JSON.stringify(next));
                      return next;
                    });
                  }}
                  className="rounded px-2 py-0.5 text-[var(--muted)] transition hover:text-[var(--ink)]"
                >
                  Try again
                </button>
              </div>
            )}
          </li>
        );
      })}
    </ol>
  );
}

function DayCard({ lesson, expanded, completed, onToggle, onComplete, onOpenResource }) {
  return (
    <div
      className={`overflow-hidden rounded-2xl border bg-[var(--surface)] transition-[background-color,border-color,box-shadow] duration-300 ${
        expanded
          ? "border-[var(--ink-soft)] shadow-[0_8px_28px_-12px_rgba(15,23,42,0.18)]"
          : "border-[var(--line)]"
      } ${completed ? "bg-[var(--success-soft)]/40" : ""}`}
    >
      <button
        onClick={onToggle}
        className="group flex w-full items-center gap-4 px-4 py-4 text-left sm:px-5 sm:py-5"
        aria-expanded={expanded}
      >
        {/* Day badge */}
        <span
          className={`relative flex h-11 w-11 shrink-0 items-center justify-center rounded-xl text-[15px] font-semibold tabular-nums transition ${
            completed
              ? "bg-[var(--success)] text-white"
              : expanded
              ? "bg-[var(--accent)] text-white"
              : "bg-[var(--accent-soft)] text-[var(--accent)]"
          }`}
        >
          {completed ? <IconCheck size={18} strokeWidth={3} /> : lesson.day}
        </span>

        {/* Title + meta */}
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2">
            <span className="text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--muted)]">
              Day {lesson.day}
            </span>
            {completed && (
              <span className="inline-flex items-center gap-1 rounded-full bg-[var(--success-soft)] px-2 py-0.5 text-[10px] font-medium uppercase tracking-wider text-[var(--success-ink)]">
                <IconCheck size={10} strokeWidth={3} /> Done
              </span>
            )}
          </div>
          <h3 className="mt-0.5 truncate text-[16px] font-semibold text-[var(--ink)] sm:text-[17px]">
            {lesson.title}
          </h3>
        </div>

        {/* Duration + chevron */}
        <div className="flex shrink-0 items-center gap-3">
          <span className="hidden items-center gap-1.5 text-xs text-[var(--muted)] sm:inline-flex">
            <IconClock size={13} />
            {lesson.time}
          </span>
          <IconChevron
            className={`text-[var(--muted)] transition-transform duration-300 ${
              expanded ? "rotate-180 text-[var(--ink)]" : ""
            }`}
          />
        </div>
      </button>

      {/* Expanded body */}
      {expanded && (
      <div aria-hidden={!expanded} style={{ animation: "dayFadeIn 0.25s ease-out" }}>
        <div className="px-4 pb-5 sm:px-5">
          <div className="ml-[60px] border-l border-dashed border-[var(--line)] pl-4 sm:ml-[60px]">
            {/* Mobile time */}
            <div className="mb-4 inline-flex items-center gap-1.5 text-xs text-[var(--muted)] sm:hidden">
              <IconClock size={13} />
              {lesson.time}
            </div>

            {/* Content */}
            <section>
              <div className="flex items-center gap-2">
                <span className="text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--muted)]">
                  What you'll learn
                </span>
                <span className="h-px flex-1 bg-[var(--line-soft)]" />
              </div>
              <ul className="mt-3 space-y-2.5">
                {lesson.content.map((c, i) => (
                  <li key={i} className="flex gap-3 text-[14.5px] leading-[1.55] text-[var(--ink)]">
                    <span className="mt-[9px] h-1 w-1 shrink-0 rounded-full bg-[var(--accent)]" />
                    <span>{c}</span>
                  </li>
                ))}
              </ul>

              {/* Resource preview */}
              {lesson.resource && (
                <button
                  onClick={(e) => { e.stopPropagation(); onOpenResource(lesson.resource); }}
                  className="group mt-4 flex w-full items-center gap-3 overflow-hidden rounded-xl border border-[var(--line)] bg-[var(--hover)] p-2.5 text-left transition hover:border-[var(--ink-soft)] hover:bg-[var(--surface)]"
                >
                  <div className="relative flex h-14 w-24 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-[var(--ink)] text-white">
                    {lesson.resource.type === "video" && ytId(lesson.resource.url) ? (
                      <img
                        src={`https://i.ytimg.com/vi/${ytId(lesson.resource.url)}/mqdefault.jpg`}
                        alt=""
                        className="absolute inset-0 h-full w-full object-cover opacity-80"
                      />
                    ) : (
                      <div className="absolute inset-0" style={{
                        background: "repeating-linear-gradient(45deg, var(--accent-soft), var(--accent-soft) 6px, var(--hover) 6px, var(--hover) 12px)"
                      }} />
                    )}
                    <div className="relative flex h-7 w-7 items-center justify-center rounded-full bg-white/95 text-[var(--ink)] shadow">
                      {lesson.resource.type === "video" ? <IconPlay size={13} /> : <IconDoc size={14} />}
                    </div>
                  </div>
                  <div className="min-w-0 flex-1">
                    <div className="text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--muted)]">
                      {lesson.resource.type === "video" ? "Watch" : "Read"} · {lesson.resource.source}
                    </div>
                    <div className="truncate text-[14px] font-medium text-[var(--ink)]">
                      {lesson.resource.label}
                    </div>
                  </div>
                  <IconExternal className="mr-2 text-[var(--muted)] transition group-hover:text-[var(--ink)]" />
                </button>
              )}
            </section>

            {/* Questions */}
            <section className="mt-6">
              <div className="flex items-center gap-2">
                <span className="text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--muted)]">
                  Check your understanding
                </span>
                <span className="h-px flex-1 bg-[var(--line-soft)]" />
              </div>
              <MCQList mcqs={lesson.mcqs} dayKey={`ai30.mcq.${lesson.day}`} />
            </section>

            {/* Action */}
            <div className="mt-6 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
              <span className="text-xs text-[var(--muted)]">
                {completed ? "Completed — nice work." : "Finish the questions to mark as complete."}
              </span>
              <button
                onClick={(e) => {
                  e.stopPropagation();
                  onComplete();
                }}
                className={`inline-flex items-center justify-center gap-2 rounded-lg px-4 py-2.5 text-sm font-medium transition ${
                  completed
                    ? "border border-[var(--line)] bg-[var(--surface)] text-[var(--muted)] hover:border-[var(--ink-soft)] hover:text-[var(--ink)]"
                    : "bg-[var(--ink)] text-[var(--surface)] hover:bg-[var(--accent)]"
                }`}
              >
                {completed ? (
                  <>Mark incomplete</>
                ) : (
                  <>
                    <IconCheck size={14} strokeWidth={3} />
                    Mark as complete
                  </>
                )}
              </button>
            </div>
          </div>
        </div>
      </div>
      )}
    </div>
  );
}

// ---------- Tweaks panel ----------
const ACCENT_OPTIONS = [
  { id: "indigo", label: "Indigo", hue: 262, sat: 0.17 },
  { id: "blue", label: "Blue", hue: 247, sat: 0.17 },
  { id: "violet", label: "Violet", hue: 290, sat: 0.17 },
  { id: "emerald", label: "Emerald", hue: 160, sat: 0.14 },
  { id: "rose", label: "Rose", hue: 15, sat: 0.17 },
];

function applyAccent(id) {
  const a = ACCENT_OPTIONS.find((o) => o.id === id) || ACCENT_OPTIONS[0];
  const root = document.documentElement;
  root.style.setProperty("--accent", `oklch(0.56 ${a.sat} ${a.hue})`);
  root.style.setProperty("--accent-soft", `oklch(0.96 0.03 ${a.hue})`);
}

function applyDensity(d) {
  const root = document.documentElement;
  root.style.setProperty("--gap", d === "cozy" ? "10px" : "14px");
}

function TweaksPanel({ tweaks, setTweaks, visible }) {
  if (!visible) return null;
  return (
    <div className="fixed bottom-5 right-5 z-50 w-[280px] rounded-2xl border border-[var(--line)] bg-[var(--surface)] p-4 shadow-[0_20px_60px_-20px_rgba(15,23,42,0.35)]">
      <div className="flex items-center justify-between">
        <div className="text-[11px] font-semibold uppercase tracking-[0.14em] text-[var(--muted)]">
          Tweaks
        </div>
        <span className="inline-block h-1.5 w-1.5 rounded-full bg-[var(--accent)]" />
      </div>

      <div className="mt-4">
        <div className="text-xs font-medium text-[var(--ink)]">Accent</div>
        <div className="mt-2 flex gap-2">
          {ACCENT_OPTIONS.map((a) => (
            <button
              key={a.id}
              onClick={() => setTweaks((t) => ({ ...t, accent: a.id }))}
              title={a.label}
              className={`h-7 w-7 rounded-full border-2 transition ${
                tweaks.accent === a.id
                  ? "border-[var(--ink)]"
                  : "border-transparent hover:border-[var(--line)]"
              }`}
              style={{ background: `oklch(0.56 ${a.sat} ${a.hue})` }}
            />
          ))}
        </div>
      </div>

      <div className="mt-4">
        <div className="text-xs font-medium text-[var(--ink)]">Density</div>
        <div className="mt-2 grid grid-cols-2 gap-2">
          {["cozy", "comfortable"].map((d) => (
            <button
              key={d}
              onClick={() => setTweaks((t) => ({ ...t, density: d }))}
              className={`rounded-lg border px-2 py-1.5 text-xs capitalize transition ${
                tweaks.density === d
                  ? "border-[var(--ink)] bg-[var(--ink)] text-[var(--surface)]"
                  : "border-[var(--line)] text-[var(--ink)] hover:border-[var(--ink-soft)]"
              }`}
            >
              {d}
            </button>
          ))}
        </div>
      </div>

      <div className="mt-4">
        <div className="text-xs font-medium text-[var(--ink)]">Layout</div>
        <div className="mt-2 grid grid-cols-2 gap-2">
          {[
            { id: "stack", label: "Stack" },
            { id: "scroll", label: "Horizontal" },
          ].map((l) => (
            <button
              key={l.id}
              onClick={() => setTweaks((s) => ({ ...s, layout: l.id }))}
              className={`rounded-lg border px-2 py-1.5 text-xs transition ${
                tweaks.layout === l.id
                  ? "border-[var(--ink)] bg-[var(--ink)] text-[var(--surface)]"
                  : "border-[var(--line)] text-[var(--ink)] hover:border-[var(--ink-soft)]"
              }`}
            >
              {l.label}
            </button>
          ))}
        </div>
      </div>

      <div className="mt-4">
        <div className="text-xs font-medium text-[var(--ink)]">Theme</div>
        <div className="mt-2 grid grid-cols-2 gap-2">
          {["light", "dark"].map((t) => (
            <button
              key={t}
              onClick={() => setTweaks((s) => ({ ...s, theme: t }))}
              className={`rounded-lg border px-2 py-1.5 text-xs capitalize transition ${
                tweaks.theme === t
                  ? "border-[var(--ink)] bg-[var(--ink)] text-[var(--surface)]"
                  : "border-[var(--line)] text-[var(--ink)] hover:border-[var(--ink-soft)]"
              }`}
            >
              {t}
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}

// ---------- App ----------
function App() {
  const lessons = window.LESSONS;
  const total = lessons.length;

  const [groupIdx, setGroupIdx] = useState(() => {
    const v = localStorage.getItem("ai30.group");
    return v ? Number(v) : 0;
  });
  const [expandedDay, setExpandedDay] = useState(() => {
    const v = localStorage.getItem("ai30.expanded");
    return v ? Number(v) : null;
  });
  const [completed, setCompleted] = useState(() => {
    try {
      return new Set(
        JSON.parse(localStorage.getItem("ai30.completed") || "[]")
      );
    } catch {
      return new Set();
    }
  });

  const tweakDefaults = /*EDITMODE-BEGIN*/ {
    "accent": "indigo",
    "density": "comfortable",
    "theme": "light",
    "layout": "stack"
  } /*EDITMODE-END*/;
  const [tweaks, setTweaks] = useState(tweakDefaults);
  const [tweaksVisible, setTweaksVisible] = useState(false);
  const [openResource, setOpenResource] = useState(null);

  // Persist
  useEffect(() => localStorage.setItem("ai30.group", String(groupIdx)), [groupIdx]);
  useEffect(
    () =>
      localStorage.setItem(
        "ai30.expanded",
        expandedDay == null ? "" : String(expandedDay)
      ),
    [expandedDay]
  );
  useEffect(
    () => localStorage.setItem("ai30.completed", JSON.stringify([...completed])),
    [completed]
  );

  // Apply tweaks
  useEffect(() => {
    applyAccent(tweaks.accent);
    applyDensity(tweaks.density);
    document.documentElement.dataset.theme = tweaks.theme;
    window.parent.postMessage(
      { type: "__edit_mode_set_keys", edits: tweaks },
      "*"
    );
  }, [tweaks]);

  // Edit mode hookup
  useEffect(() => {
    const onMsg = (e) => {
      if (e.data?.type === "__activate_edit_mode") setTweaksVisible(true);
      if (e.data?.type === "__deactivate_edit_mode") setTweaksVisible(false);
    };
    window.addEventListener("message", onMsg);
    window.parent.postMessage({ type: "__edit_mode_available" }, "*");
    return () => window.removeEventListener("message", onMsg);
  }, []);

  const group = GROUPS[groupIdx];
  const visible = lessons.filter((l) => l.day >= group.start && l.day <= group.end);

  const completedCount = completed.size;

  const toggleExpand = (day) =>
    setExpandedDay((cur) => (cur === day ? null : day));
  const toggleComplete = (day) =>
    setCompleted((prev) => {
      const next = new Set(prev);
      if (next.has(day)) next.delete(day);
      else next.add(day);
      return next;
    });

  const reset = () => {
    if (!confirm("Reset all progress?")) return;
    setCompleted(new Set());
    setExpandedDay(null);
    setGroupIdx(0);
  };

  return (
    <div className="mx-auto w-full max-w-[720px] px-5 pb-24 pt-10 sm:px-8 sm:pt-14">
      <Header completedCount={completedCount} total={total} onReset={reset} />

      <div className="mt-9 flex items-stretch gap-2">
        <div className="flex-1">
          <GroupDropdown
            value={groupIdx}
            onChange={(i) => {
              setGroupIdx(i);
              setExpandedDay(null);
            }}
            completedSet={completed}
          />
        </div>
        <div className="flex shrink-0 items-center gap-1 rounded-xl border border-[var(--line)] bg-[var(--surface)] p-1">
          <button
            onClick={() => setTweaks((t) => ({ ...t, layout: "stack" }))}
            title="Stack view"
            aria-label="Stack view"
            aria-pressed={tweaks.layout !== "scroll"}
            className={`flex h-9 w-9 items-center justify-center rounded-lg transition ${
              tweaks.layout !== "scroll"
                ? "bg-[var(--ink)] text-[var(--surface)]"
                : "text-[var(--muted)] hover:text-[var(--ink)]"
            }`}
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="4" y="5" width="16" height="4" rx="1"/><rect x="4" y="13" width="16" height="4" rx="1"/></svg>
          </button>
          <button
            onClick={() => setTweaks((t) => ({ ...t, layout: "scroll" }))}
            title="Horizontal view"
            aria-label="Horizontal view"
            aria-pressed={tweaks.layout === "scroll"}
            className={`flex h-9 w-9 items-center justify-center rounded-lg transition ${
              tweaks.layout === "scroll"
                ? "bg-[var(--ink)] text-[var(--surface)]"
                : "text-[var(--muted)] hover:text-[var(--ink)]"
            }`}
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="6" height="14" rx="1"/><rect x="11" y="5" width="6" height="14" rx="1"/></svg>
          </button>
        </div>
      </div>

      {tweaks.layout === "scroll" ? (
        <div className="mt-5 -mx-5 sm:-mx-8">
          <div
            className="flex snap-x snap-mandatory gap-4 overflow-x-auto scroll-smooth px-5 pb-4 sm:px-8"
            style={{ scrollbarWidth: "thin" }}
          >
            {visible.map((lesson) => (
              <div
                key={lesson.day}
                className="w-[86%] shrink-0 snap-start sm:w-[360px]"
              >
                <DayCard
                  lesson={lesson}
                  expanded={expandedDay === lesson.day}
                  completed={completed.has(lesson.day)}
                  onToggle={() => toggleExpand(lesson.day)}
                  onComplete={() => toggleComplete(lesson.day)}
                  onOpenResource={(r) => setOpenResource(r)}
                />
              </div>
            ))}
          </div>
          <div className="mt-1 flex items-center justify-between px-1 text-[11px] uppercase tracking-[0.14em] text-[var(--muted)]">
            <span>Swipe to explore</span>
            <span className="tabular-nums">{visible.length} cards</span>
          </div>
        </div>
      ) : (
        <div className="mt-5 flex flex-col" style={{ gap: "var(--gap)" }}>
          {visible.map((lesson) => (
            <DayCard
              key={lesson.day}
              lesson={lesson}
              expanded={expandedDay === lesson.day}
              completed={completed.has(lesson.day)}
              onToggle={() => toggleExpand(lesson.day)}
              onComplete={() => toggleComplete(lesson.day)}
              onOpenResource={(r) => setOpenResource(r)}
            />
          ))}
        </div>
      )}

      <footer className="mt-10 border-t border-[var(--line)] pt-6">
        <div className="flex items-center justify-between text-xs text-[var(--muted)]">
          <span>Progress saves automatically.</span>
          <button
            onClick={reset}
            className="rounded px-2 py-1 transition hover:text-[var(--ink)] sm:hidden"
          >
            Reset
          </button>
        </div>

        <div className="mt-6">
          <div className="text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--muted)]">
            References
          </div>
          <p className="mt-2 text-[13px] leading-[1.55] text-[var(--muted)]">
            Content is synthesized from widely-used public learning resources.
            Primary sources include:
          </p>
          <ul className="mt-3 grid grid-cols-1 gap-x-6 gap-y-1.5 sm:grid-cols-2">
            {[
              ["Prompt Engineering Guide", "https://www.promptingguide.ai/"],
              ["Anthropic — Building Effective Agents", "https://www.anthropic.com/research/building-effective-agents"],
              ["OpenAI Documentation", "https://platform.openai.com/docs/"],
              ["3Blue1Brown — Neural Networks", "https://www.3blue1brown.com/topics/neural-networks"],
              ["IBM Think — AI/ML concepts", "https://www.ibm.com/think/topics"],
              ["Nielsen Norman Group — UX research", "https://www.nngroup.com/articles/"],
              ["DeepLearning.AI — Courses", "https://www.deeplearning.ai/courses/"],
              ["Learn Prompting", "https://learnprompting.org/"],
            ].map(([label, href]) => (
              <li key={href}>
                <a
                  href={href}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="inline-flex items-center gap-1.5 text-[13px] text-[var(--ink-soft)] transition hover:text-[var(--accent)]"
                >
                  <span className="truncate">{label}</span>
                  <IconExternal size={11} className="shrink-0 opacity-60" />
                </a>
              </li>
            ))}
          </ul>
        </div>
      </footer>

      <ResourceModal resource={openResource} onClose={() => setOpenResource(null)} />

      <TweaksPanel tweaks={tweaks} setTweaks={setTweaks} visible={tweaksVisible} />
    </div>
  );
}

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