import { useMemo, useState } from "react";
import { X, Plus, Trash2 } from "lucide-react";
import { Input } from "@/components/ui/input";
import { grades as defaultGrades } from "@/data/portraitData";
import { ParentCourseOverviewForm } from "../components/ParentCourseOverviewForm";
import { HowEachCourseSeesForm, normalizeHowEachCourseSeesContent } from "../components/HowEachCourseSeesForm";
import { DynamicContentForm } from "../components/DynamicContentForm";
import { ApiQueryFiltersEditor } from "../components/ApiQueryFiltersEditor";
import { HeroContentForm } from "../components/HeroContentForm";
import {
  GradeHeroForm,
  type EnsurePageComponentResult,
  type EnsurePageComponentTarget,
} from "../components/GradeHeroForm";
import { CardEditGroup, CardEditPanel, CardEditSplit } from "../components/CardEditLayout";
import { EmojiPickerField } from "../components/EmojiPickerField";
import { CompetitionPanelForm } from "../components/CompetitionPanelForm";
import { CompetitionTabsForm } from "../components/CompetitionTabsForm";
import { SteeringCommitteesGridForm } from "../components/SteeringCommitteesGridForm";
import { SwotAnalysisGridForm } from "../components/SwotAnalysisGridForm";
import { RootCauseFishboneForm } from "../components/RootCauseFishboneForm";
import { PortraitGoalsGridForm } from "../components/PortraitGoalsGridForm";
import { GrowthRadarChartForm } from "../components/GrowthRadarChartForm";
import { ProgressHowItWorksForm } from "../components/ProgressHowItWorksForm";
import { ProgressSampleReportForm } from "../components/ProgressSampleReportForm";
import { normalizeParentCourseOverviewContent } from "@/components/page-blocks/parent-course-overview/parseContent";
import { normalizeHeroContent } from "@/components/page-blocks/hero/normalizeContent";
import { normalizeGradeHeroContent } from "@/components/page-blocks/GradeHeroBlock";
import { normalizeCourseCoreSkillsContent } from "@/components/page-blocks/CourseCoreSkillsBlock";
import { COURSE_HERO_WEEKLY_TIME_OPTIONS } from "@/components/page-blocks/course-hero/defaultContent";
import { normalizeCourseHeroContent } from "@/components/page-blocks/course-hero/normalizeContent";
import { validateRequiredContent } from "@/lib/contentFormUtils";
import { CONTENT_PLACEHOLDER_HINT, type ContentPlaceholderVars } from "@/lib/contentPlaceholders";
import { prepareBlockContentForEditor, resolveEditorBlockContent } from "@/lib/mergeBlockContent";
import { getBlockComponent } from "@/components/page-blocks";
import { SiteChromeFrame } from "@/components/SiteChromeFrame";
import { orionExternalApiUrl } from "@/lib/apiUrl";
import { normalizeApiQueryFilters } from "@/lib/apiQueryFilters";

export type BlockContent = Record<string, unknown>;

type GradeItem = { id: string; label: string; shortLabel: string; route: string; available: boolean };
type KaleidoscopeSliceItem = { label: string; emoji: string; color: string; route: string; description: string };
const KALEIDOSCOPE_COLORS = ["deep-sea", "valencia", "moss", "sunflower", "mist", "salmon"] as const;

const nameToSlug: Record<string, string> = {
  Hero: "hero",
  "Dimension Detail": "dimension-detail",
  "Grade Family Guides": "grade-family-guides",
  "Grade Family Guides with API": "grade-family-guides-api",
  "Grade Hero": "grade-hero",
  "Grade Kaleidoscope": "grade-kaleidoscope",
  "Curriculum Hero": "curriculum-hero",
  "Essential Question": "essential-question",
  "Core Courses": "core-courses",
  "DNA Strands": "dna-strands",
  "Year at a Glance": "year-at-glance",
  "Year-Long Story": "year-long-story",
  "Developing the Whole Child": "developing-the-whole-child",
  "Portrait of the Learner": "developing-the-whole-child",
  "Portrait of the Learner — Dimension Grid": "developing-the-whole-child",
  "Fink's Taxonomy of Significant Learning": "finks-taxonomy",
  "Finks Taxonomy": "finks-taxonomy",
  "One Project, Not 13 Tests": "one-project-not-13-tests",
  "Curriculum Architecture": "curriculum-architecture",
  "Problem-Based Experiential Learning": "pbel",
  "Course Hero": "course-hero",
  Science: "course-hero",
  "Why This Course Matters": "why-this-course-matters",
  "How Science Connects to All Learning": "how-connects",
  "How Connects to All Learning": "how-connects",
  "Smarter Assessment = Less Stress": "smarter-assessment",
  "What Your Child Will Gain": "what-your-child-will-gain",
  "Developing the Whole Child (Course)": "course-portrait",
  "Portrait of the Learner (Course)": "course-portrait",
  "Course Portrait — Progress Bars": "course-portrait",
  "Core Skills Your Child Will Master": "course-core-skills",
  "Your Child's Year-Long Journey": "course-journey",
  "What Your Child Will Create": "course-what-they-create",
  "Deep Inquiry Questions to Ask Your Child": "course-inquiry-questions",
  "Simple Ways to Support at Home": "course-support-at-home",
  "Quarter-End Celebration": "course-quarter-celebration",
  "The Nature Investigator": "quarter-hero",
  "Quarter Hero": "quarter-hero",
  "Big Idea": "big-idea",
  "How Each Course Sees This Quarter": "how-each-course-sees",
  "Quarter Learning Tabs": "quarter-learning-tabs",
  "Assessment, Evidence & Inquiry, Growth": "quarter-learning-tabs",
  "Courses (13)": "quarter-courses",
  "Quarter Courses": "quarter-courses",
  "Courses (13) – Assessment, Evidence & Growth": "quarter-courses-and-learning",
  "Quarter Courses & Learning": "quarter-courses-and-learning",
  "Orion STEM Schools": "orion-school-header",
  "What is PBEL?": "what-is-pbel",
  "Why Water? Why Now?": "why-water-why-now",
  "How It Works — The PBEL Cycle": "pbel-cycle",
  "What Your Child Might Do": "what-your-child-might-do",
  "What Families Can Expect — and How You Can Help": "families-expect-help",
  "Benefits for Your Child": "benefits-for-your-child",
  "Our Service Learning Plan (IPARDE)": "service-learning-ipard",
  "Year Timeline at a Glance": "year-timeline-at-glance",
  "How Families Can Help": "how-families-can-help",
  "Deep Inquiry Questions": "deep-inquiry-questions",
  "Stay in the Loop": "stay-in-the-loop",
  "Parent Course Overview": "parent-course-overview",
  "Parent-Facing Course Overview": "parent-course-overview",
  "Design to Impact Hero": "grade-hero",
  "Impact Kaleidoscope": "impact-kaleidoscope",
  "Three Journey Phases": "three-journey-phases",
  "Cross-Cutting Mirrors": "cross-cutting-mirrors",
  "Annual Flow Quarters": "annual-flow-quarters",
  "Diverge Converge Viz": "diverge-converge-viz",
  "Squad Roles": "squad-roles",
  "Grade Band Entrepreneurship": "grade-band-entrepreneurship",
  "Deliverables Evidence": "deliverables-evidence",
  "Design Impact Summit": "design-impact-summit",
  "Closing Vision": "closing-vision",
  "Club Category Grid": "club-category-grid",
  "Steering Committees Grid": "steering-committees-grid",
  "Steering Committees": "steering-committees-grid",
  "Orion Competitions": "orion-competitions",
  "Public Competitions": "public-competitions",
  "Competition Tabs": "competition-tabs",
  "Competitions Timeline": "competition-tabs",
  "SWOT Analysis Grid": "swot-analysis-grid",
  "Root Cause Fishbone": "root-cause-fishbone",
  "Portrait Goals Grid": "portrait-goals-grid",
  "Growth Radar Chart": "growth-radar-chart",
  "Progress How It Works": "progress-how-it-works",
  "Progress Sample Report": "progress-sample-report",
  "PBEL Guide Footer": "pbel-guide-footer",
  Footer: "footer",
};

function getSlug(componentName: string): string {
  return nameToSlug[componentName] ?? "hero";
}

const formRow = "mb-4";
const labelCls = "block text-sm font-medium text-slate-700 mb-1.5";
const HSL_CSS_VAR_OPTIONS = ["--primary", "--accent", "--sunflower", "--deep-sea", "--valencia", "--moss", "--mist", "--salmon"] as const;

function HslCssVarField({
  value,
  onChange,
  label = "Color (CSS var)",
}: {
  value: string;
  onChange: (v: string) => void;
  label?: string;
}) {
  const known = (HSL_CSS_VAR_OPTIONS as readonly string[]).includes(value);
  return (
    <div>
      <label className={labelCls}>{label}</label>
      <div className="flex gap-2">
        <select
          value={known ? value : ""}
          onChange={(e) => {
            if (e.target.value) onChange(e.target.value);
          }}
          className="w-36 rounded-md border border-input bg-background px-3 py-2 text-sm shrink-0"
        >
          <option value="">Custom…</option>
          {HSL_CSS_VAR_OPTIONS.map((c) => (
            <option key={c} value={c}>{c}</option>
          ))}
        </select>
        <Input value={value} onChange={(e) => onChange(e.target.value)} placeholder="--deep-sea" className="flex-1 font-mono text-sm" />
      </div>
    </div>
  );
}

function linesToList(text: string): string[] {
  return text.split(/\r?\n/).map((x) => x.trim()).filter(Boolean);
}

function FooterForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const text = (content?.text as string) ?? "";
  const useSiteFooter = content?.useSiteFooter !== false;
  return (
    <>
      <div className={formRow}>
        <label className="flex items-center gap-2 text-sm text-slate-700 cursor-pointer">
          <input
            type="checkbox"
            checked={useSiteFooter}
            onChange={(e) => onChange({ ...content, useSiteFooter: e.target.checked })}
          />
          Use global footer from Site Settings
        </label>
        <p className="text-[10px] text-slate-500 mt-1">
          When enabled, the footer layout from Site Settings is used instead of custom text below.
        </p>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Custom footer text (optional override)</label>
        <textarea
          value={text}
          onChange={(e) => onChange({ ...content, text: e.target.value, useSiteFooter: false })}
          placeholder="Leave empty to use Site Settings footer layout"
          rows={2}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]"
          disabled={useSiteFooter}
        />
      </div>
    </>
  );
}

function PbelGuideFooterForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const leftTitle = (content?.leftTitle as string) ?? "";
  const middleTitle = (content?.middleTitle as string) ?? "";
  const rightText = (content?.rightText as string) ?? "";
  const currentPageLabel = (content?.currentPageLabel as string) ?? "";
  const totalPageLabel = (content?.totalPageLabel as string) ?? "";
  const dot1Color = (content?.dot1Color as string) ?? "--primary";
  const dot2Color = (content?.dot2Color as string) ?? "--accent";
  const dot3Color = (content?.dot3Color as string) ?? "--sunflower";

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Left Title</label>
        <Input
          value={leftTitle}
          onChange={(e) => onChange({ ...content, leftTitle: e.target.value })}
          placeholder="Orion STEM Schools"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Middle Title</label>
        <Input
          value={middleTitle}
          onChange={(e) => onChange({ ...content, middleTitle: e.target.value })}
          placeholder="PBEL Family Flyer (Water)"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Right Text</label>
        <Input
          value={rightText}
          onChange={(e) => onChange({ ...content, rightText: e.target.value })}
          placeholder="Print double‑sided"
        />
        <p className="text-[10px] text-slate-500 mt-1">Joined with middle dots (·). Leave empty to omit.</p>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Current Page Label</label>
        <Input
          value={currentPageLabel}
          onChange={(e) => onChange({ ...content, currentPageLabel: e.target.value })}
          placeholder="Page 1"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Total Page Label</label>
        <Input
          value={totalPageLabel}
          onChange={(e) => onChange({ ...content, totalPageLabel: e.target.value })}
          placeholder="Page 2"
        />
        <p className="text-[10px] text-slate-500 mt-1">When set, shown as “Current / Total” on the right.</p>
      </div>
      <div className={formRow}>
        <HslCssVarField
          label="Dot 1 color (CSS var)"
          value={dot1Color}
          onChange={(v) => onChange({ ...content, dot1Color: v })}
        />
      </div>
      <div className={formRow}>
        <HslCssVarField
          label="Dot 2 color (CSS var)"
          value={dot2Color}
          onChange={(v) => onChange({ ...content, dot2Color: v })}
        />
      </div>
      <div className={formRow}>
        <HslCssVarField
          label="Dot 3 color (CSS var)"
          value={dot3Color}
          onChange={(v) => onChange({ ...content, dot3Color: v })}
        />
      </div>
    </>
  );
}

function DimensionDetailForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const sectionTitle = (content?.sectionTitle as string) ?? "";
  const sectionSubtitle = (content?.sectionSubtitle as string) ?? "";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Section title</label>
        <Input value={sectionTitle} onChange={(e) => onChange({ ...content, sectionTitle: e.target.value })} placeholder="e.g. Character Traits & Mindsets" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Section subtitle</label>
        <Input value={sectionSubtitle} onChange={(e) => onChange({ ...content, sectionSubtitle: e.target.value })} placeholder="e.g. Courses at Orion" />
      </div>
    </>
  );
}

function KaleidoscopeForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const title = (content?.title as string) ?? "";
  const subtitle = (content?.subtitle as string) ?? "";
  const rawItems = content?.items;
  const items: KaleidoscopeSliceItem[] = Array.isArray(rawItems)
    ? rawItems.map((x: unknown) => {
        const o = x as Record<string, unknown>;
        return {
          label: typeof o?.label === "string" ? o.label : "",
          emoji: typeof o?.emoji === "string" ? o.emoji : "•",
          color: typeof o?.color === "string" ? o.color : "deep-sea",
          route: typeof o?.route === "string" ? o.route : "",
          description: typeof o?.description === "string" ? o.description : "",
        };
      })
    : [];

  const setItems = (next: KaleidoscopeSliceItem[]) => onChange({ ...content, items: next });
  const addItem = () => setItems([...items, { label: "New", emoji: "•", color: "deep-sea", route: "#", description: "" }]);
  const removeItem = (index: number) => setItems(items.filter((_, i) => i !== index));
  const updateItem = (index: number, field: keyof KaleidoscopeSliceItem, value: string) => {
    const next = items.map((item, i) =>
      i === index ? { ...item, [field]: value } : item
    );
    setItems(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (uppercase line)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. The Orion Kaleidoscope" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="e.g. Six Dimensions of the Student Experience" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <Input value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} placeholder="e.g. Click any slice to explore that dimension." />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Wheel slices"
          layout="grid-3"
          onAdd={addItem}
          addLabel="Add slice"
          hint="Each slice becomes a clickable wedge of the kaleidoscope wheel. The wheel redistributes evenly for any number of slices."
          isEmpty={items.length === 0}
          emptyMessage="No slices yet. Click “Add slice” to add PBL, Clubs, etc."
        >
          {items.map((item, index) => (
            <CardEditPanel
              key={index}
              index={index}
              total={items.length}
              layout="grid-3"
              positionLabel={`Slice ${index + 1}`}
              label={item.label}
              accent={item.color}
              preview={{ emoji: item.emoji, title: item.label, subtitle: item.description }}
              onRemove={() => removeItem(index)}
            >
              <div className="flex gap-2 flex-wrap items-end">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={item.emoji} onChange={(v) => updateItem(index, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1 min-w-[120px]">
                  <label className={labelCls}>Label</label>
                  <Input value={item.label} onChange={(e) => updateItem(index, "label", e.target.value)} placeholder="Label" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Color</label>
                <select value={item.color} onChange={(e) => updateItem(index, "color", e.target.value)} className="flex w-full rounded-md border border-input bg-background px-2 py-1.5 text-sm h-10">
                  {KALEIDOSCOPE_COLORS.map((c) => (
                    <option key={c} value={c}>{c}</option>
                  ))}
                </select>
              </div>
              <div>
                <label className={labelCls}>Route</label>
                <Input value={item.route} onChange={(e) => updateItem(index, "route", e.target.value)} placeholder="e.g. /grade/kg/clubs" className="w-full" />
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={item.description} onChange={(e) => updateItem(index, "description", e.target.value)} placeholder="Description" rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

function ensureGradeItem(raw: unknown): GradeItem {
  const o = raw as Record<string, unknown> | null | undefined;
  return {
    id: typeof o?.id === "string" ? o.id : "",
    label: typeof o?.label === "string" ? o.label : "",
    shortLabel: typeof o?.shortLabel === "string" ? o.shortLabel : "",
    route: typeof o?.route === "string" ? o.route : "",
    available: o?.available === true,
  };
}

type CurriculumHeroStatItem = { label: string; value: string };

function CurriculumHeroForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const backLabel = (content?.backLabel as string) ?? "";
  const backHref = (content?.backHref as string) ?? "";
  const label = (content?.label as string) ?? "";
  const title = (content?.title as string) ?? "";
  const subtitle = (content?.subtitle as string) ?? "";
  const bigIdea = (content?.bigIdea as string) ?? "";
  const imageSrc = (content?.imageSrc as string) ?? "";
  const imageAlt = (content?.imageAlt as string) ?? "";
  const rawStats = content?.stats;
  const stats: CurriculumHeroStatItem[] = Array.isArray(rawStats)
    ? rawStats.map((x: unknown) => {
        const o = x as Record<string, unknown>;
        return {
          label: typeof o?.label === "string" ? o.label : "",
          value: typeof o?.value === "string" ? o.value : "",
        };
      })
    : [];

  const setStats = (next: CurriculumHeroStatItem[]) => onChange({ ...content, stats: next });
  const addStat = () => setStats([...stats, { label: "", value: "" }]);
  const removeStat = (index: number) => setStats(stats.filter((_, i) => i !== index));
  const updateStat = (index: number, field: "label" | "value", value: string) => {
    const next = stats.map((item, i) => (i === index ? { ...item, [field]: value } : item));
    setStats(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Back link label</label>
        <Input value={backLabel} onChange={(e) => onChange({ ...content, backLabel: e.target.value })} placeholder="e.g. Back to Kaleidoscope" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Back link URL (Kaleidoscope Dashboard)</label>
        <Input
          value={backHref}
          onChange={(e) => onChange({ ...content, backHref: e.target.value })}
          placeholder="e.g. /grade/kg"
        />
        <p className="text-[10px] text-slate-500 mt-1">
          Must point to the Kaleidoscope Dashboard (e.g. /grade/kg), not Spark (/). Leave empty to derive /grade/:id from the current page path.
        </p>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Label (e.g. school · year)</label>
        <Input value={label} onChange={(e) => onChange({ ...content, label: e.target.value })} placeholder="e.g. Orion STEM Schools · 2026–2027" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title (main headline)</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="e.g. Healthy Habitats & Sun-Safe Spaces" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <Input value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} placeholder="e.g. Comprehensive Family Guide · Kindergarten" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Big idea (paragraph)</label>
        <textarea
          value={bigIdea}
          onChange={(e) => onChange({ ...content, bigIdea: e.target.value })}
          placeholder="Living things have needs that are met by their environment..."
          rows={3}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Background image URL (optional)</label>
        <Input value={imageSrc} onChange={(e) => onChange({ ...content, imageSrc: e.target.value })} placeholder="Leave empty for default hero image" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Background image alt text</label>
        <Input value={imageAlt} onChange={(e) => onChange({ ...content, imageAlt: e.target.value })} placeholder="e.g. Schoolyard habitat illustration" />
      </div>
      <div className={formRow}>
        <div className="flex items-center justify-between mb-2">
          <label className={labelCls}>Stats (value + label pills)</label>
          <button type="button" onClick={addStat} className="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-sm font-medium rounded-md border border-slate-300 bg-white hover:bg-slate-50">
            <Plus size={14} /> Add stat
          </button>
        </div>
        <div className="space-y-3 border border-slate-200 rounded-lg p-3 bg-slate-50/50 max-h-48 overflow-y-auto">
          {stats.length === 0 ? (
            <p className="text-sm text-slate-500">No stats yet. Click “Add stat” or leave empty to use defaults.</p>
          ) : (
            stats.map((item, index) => (
              <div key={index} className="flex flex-wrap items-center gap-2 p-2 bg-white rounded border border-slate-200">
                <Input value={item.value} onChange={(e) => updateStat(index, "value", e.target.value)} placeholder="Value" className="w-20 shrink-0" />
                <Input value={item.label} onChange={(e) => updateStat(index, "label", e.target.value)} placeholder="Label" className="flex-1 min-w-[100px]" />
                <button type="button" onClick={() => removeStat(index)} className="p-1.5 text-red-600 hover:bg-red-50 rounded" title="Remove">
                  <Trash2 size={16} />
                </button>
              </div>
            ))
          )}
        </div>
      </div>
    </>
  );
}

function EssentialQuestionForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const question = (content?.question as string) ?? "";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (uppercase label)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. Essential Question" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Question (main text, shown in quotes)</label>
        <textarea
          value={question}
          onChange={(e) => onChange({ ...content, question: e.target.value })}
          placeholder="e.g. How can we design spaces that help living things (including us) stay healthy and comfortable?"
          rows={3}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]"
        />
      </div>
    </>
  );
}

type CoreCourseItem = { name: string; emoji: string; tagline: string; slug: string; linkText: string; linkHref: string };

function CoreCoursesForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const title = (content?.title as string) ?? "";
  const subtitle = (content?.subtitle as string) ?? "";
  const rawCourses = content?.courses;
  const courses: CoreCourseItem[] = Array.isArray(rawCourses)
    ? rawCourses.map((x: unknown) => {
        const o = x as Record<string, unknown>;
        return {
          name: typeof o?.name === "string" ? o.name : "",
          emoji: typeof o?.emoji === "string" ? o.emoji : "•",
          tagline: typeof o?.tagline === "string" ? o.tagline : "",
          slug: typeof o?.slug === "string" ? o.slug : "",
          linkText: typeof o?.linkText === "string" ? o.linkText : "Learn More →",
          linkHref: typeof o?.linkHref === "string" ? o.linkHref : "",
        };
      })
    : [];

  const setCourses = (next: CoreCourseItem[]) => onChange({ ...content, courses: next });
  const addCourse = () => setCourses([...courses, { name: "New Course", emoji: "•", tagline: "", slug: "new-course", linkText: "Learn More →", linkHref: "" }]);
  const removeCourse = (index: number) => setCourses(courses.filter((_, i) => i !== index));
  const updateCourse = (index: number, field: keyof CoreCourseItem, value: string) => {
    const next = courses.map((c, i) => (i === index ? { ...c, [field]: value } : c));
    setCourses(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (uppercase line)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. The 9 Core Courses" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="e.g. Integrated Learning Across Every Subject" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <textarea
          value={subtitle}
          onChange={(e) => onChange({ ...content, subtitle: e.target.value })}
          placeholder="e.g. Click any course to see how it develops your child across all grade levels."
          rows={2}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]"
        />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Course cards"
          layout="grid-3"
          onAdd={addCourse}
          addLabel="Add course"
          hint="Courses appear in a 3-column grid on the page (2 columns on mobile). Click a card to learn more."
          isEmpty={courses.length === 0}
          emptyMessage="No courses yet. Click “Add course” or paste the Core Courses component to get the default 9."
        >
          {courses.map((item, index) => (
            <CardEditPanel
              key={index}
              index={index}
              total={courses.length}
              layout="grid-3"
              label={item.name}
              preview={{ emoji: item.emoji, title: item.name, subtitle: item.tagline }}
              onRemove={() => removeCourse(index)}
            >
              <div className="flex gap-2 flex-wrap items-end">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={item.emoji} onChange={(v) => updateCourse(index, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1 min-w-[120px]">
                  <label className={labelCls}>Name</label>
                  <Input value={item.name} onChange={(e) => updateCourse(index, "name", e.target.value)} placeholder="Name (e.g. Science)" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Tagline / description</label>
                <textarea value={item.tagline} onChange={(e) => updateCourse(index, "tagline", e.target.value)} placeholder="Tagline / description (shown in the box)" rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
                <div>
                  <label className={labelCls}>Slug</label>
                  <Input value={item.slug} onChange={(e) => updateCourse(index, "slug", e.target.value)} placeholder="science → /course/[slug]" />
                </div>
                <div>
                  <label className={labelCls}>Link text</label>
                  <Input value={item.linkText} onChange={(e) => updateCourse(index, "linkText", e.target.value)} placeholder="e.g. Learn More →" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Link URL (optional)</label>
                <Input value={item.linkHref} onChange={(e) => updateCourse(index, "linkHref", e.target.value)} placeholder="Leave empty to use /course/[slug]; full URL for external" className="w-full" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type DnaCourseFormItem = { name: string; emoji: string; duration: string; slug: string; linkText: string; linkHref: string };
type DnaStrandFormItem = { name: string; courses: DnaCourseFormItem[] };

function DnaStrandsForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const title = (content?.title as string) ?? "";
  const subtitle = (content?.subtitle as string) ?? "";
  const rawStrands = content?.strands;
  const strands: DnaStrandFormItem[] = Array.isArray(rawStrands)
    ? rawStrands.map((s: unknown) => {
        const o = s as Record<string, unknown>;
        const rawC = o.courses;
        const courses: DnaCourseFormItem[] = Array.isArray(rawC)
          ? rawC.map((x: unknown) => {
              const co = x as Record<string, unknown>;
              return {
                name: typeof co?.name === "string" ? co.name : "",
                emoji: typeof co?.emoji === "string" ? co.emoji : "•",
                duration: typeof co?.duration === "string" ? co.duration : "",
                slug: typeof co?.slug === "string" ? co.slug : "",
                linkText: typeof co?.linkText === "string" ? co.linkText : "Learn More →",
                linkHref: typeof co?.linkHref === "string" ? co.linkHref : "",
              };
            })
          : [];
        return { name: typeof o?.name === "string" ? o.name : "", courses };
      })
    : [];

  const setStrands = (next: DnaStrandFormItem[]) => onChange({ ...content, strands: next });
  const addStrand = () => setStrands([...strands, { name: "New Strand", courses: [] }]);
  const removeStrand = (si: number) => setStrands(strands.filter((_, i) => i !== si));
  const updateStrandName = (si: number, name: string) => {
    const next = strands.map((s, i) => (i === si ? { ...s, name } : s));
    setStrands(next);
  };
  const setStrandCourses = (si: number, courses: DnaCourseFormItem[]) => {
    const next = strands.map((s, i) => (i === si ? { ...s, courses } : s));
    setStrands(next);
  };
  const addCourse = (si: number) => {
    const strand = strands[si];
    if (!strand) return;
    setStrandCourses(si, [...strand.courses, { name: "New Course", emoji: "•", duration: "", slug: "", linkText: "Learn More →", linkHref: "" }]);
  };
  const removeCourse = (si: number, ci: number) => setStrandCourses(si, strands[si].courses.filter((_, i) => i !== ci));
  const updateCourse = (si: number, ci: number, field: keyof DnaCourseFormItem, value: string) => {
    const next = strands[si].courses.map((c, i) => (i === ci ? { ...c, [field]: value } : c));
    setStrandCourses(si, next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (uppercase line)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. 4 DNA Strands · 16 Rotating Courses" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="e.g. Specialty Skills That Rotate Every Quarter" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <textarea value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} placeholder="e.g. Each strand delivers a progressive 4-course sequence across the year." rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Strands & courses"
          layout="vertical"
          onAdd={addStrand}
          addLabel="Add strand"
          hint="Each strand is shown as a row on the page, with its courses laid out in a 4-column grid (2 columns on mobile)."
          isEmpty={strands.length === 0}
          emptyMessage="No strands yet. Click “Add strand” or paste the DNA Strands component to get the default 4 strands."
        >
          {strands.map((strand, si) => (
            <CardEditPanel
              key={si}
              index={si}
              total={strands.length}
              layout="vertical"
              positionLabel={`Strand ${si + 1}`}
              label={strand.name}
              onRemove={() => removeStrand(si)}
            >
              <div>
                <label className={labelCls}>Strand name</label>
                <Input value={strand.name} onChange={(e) => updateStrandName(si, e.target.value)} placeholder="Strand name (e.g. Human Skills)" />
              </div>
              <CardEditGroup
                label="Courses in this strand"
                layout="grid-2"
                onAdd={() => addCourse(si)}
                addLabel="Add course"
                isEmpty={strand.courses.length === 0}
                emptyMessage="No courses in this strand yet."
              >
                {strand.courses.map((course, ci) => (
                  <CardEditPanel
                    key={ci}
                    index={ci}
                    total={strand.courses.length}
                    layout="grid-2"
                    positionLabel={`Course ${ci + 1}`}
                    label={course.name}
                    preview={{ emoji: course.emoji, title: course.name, subtitle: course.duration }}
                    onRemove={() => removeCourse(si, ci)}
                  >
                    <div className="flex gap-2 flex-wrap items-end">
                      <div>
                        <label className={labelCls}>Emoji</label>
                        <EmojiPickerField compact value={course.emoji} onChange={(v) => updateCourse(si, ci, "emoji", v)} placeholder="Emoji" />
                      </div>
                      <div className="flex-1 min-w-[100px]">
                        <label className={labelCls}>Course name</label>
                        <Input value={course.name} onChange={(e) => updateCourse(si, ci, "name", e.target.value)} placeholder="Course name" />
                      </div>
                    </div>
                    <div>
                      <label className={labelCls}>Duration</label>
                      <Input value={course.duration} onChange={(e) => updateCourse(si, ci, "duration", e.target.value)} placeholder="e.g. 9 Weeks (Q1)" />
                    </div>
                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
                      <div>
                        <label className={labelCls}>Slug</label>
                        <Input value={course.slug} onChange={(e) => updateCourse(si, ci, "slug", e.target.value)} placeholder="Slug" />
                      </div>
                      <div>
                        <label className={labelCls}>Link text</label>
                        <Input value={course.linkText} onChange={(e) => updateCourse(si, ci, "linkText", e.target.value)} placeholder="Link text" />
                      </div>
                    </div>
                    <div>
                      <label className={labelCls}>Link URL (optional)</label>
                      <Input value={course.linkHref} onChange={(e) => updateCourse(si, ci, "linkHref", e.target.value)} placeholder="Link URL (optional)" className="w-full" />
                    </div>
                  </CardEditPanel>
                ))}
              </CardEditGroup>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

const QUARTER_COLORS = ["moss", "deep-sea", "valencia", "sunflower"] as const;
type YearAtGlanceQuarterFormItem = { id: number; color: string; emoji: string; role: string; subtitle: string; title: string; essentialQuestion: string; theme: string; linkText: string; linkHref: string };

function YearAtGlanceForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const title = (content?.title as string) ?? "";
  const rawQuarters = content?.quarters;
  const quarters: YearAtGlanceQuarterFormItem[] = Array.isArray(rawQuarters)
    ? rawQuarters.map((q: unknown) => {
        const o = q as Record<string, unknown>;
        return {
          id: typeof o?.id === "number" ? o.id : Number(o?.id) || 1,
          color: typeof o?.color === "string" ? o.color : "moss",
          emoji: typeof o?.emoji === "string" ? o.emoji : "•",
          role: typeof o?.role === "string" ? o.role : "",
          subtitle: typeof o?.subtitle === "string" ? o.subtitle : "",
          title: typeof o?.title === "string" ? o.title : "",
          essentialQuestion: typeof o?.essentialQuestion === "string" ? o.essentialQuestion : "",
          theme: typeof o?.theme === "string" ? o.theme : "",
          linkText: typeof o?.linkText === "string" ? o.linkText : "Explore →",
          linkHref: typeof o?.linkHref === "string" ? o.linkHref : "",
        };
      })
    : [];

  const setQuarters = (next: YearAtGlanceQuarterFormItem[]) => onChange({ ...content, quarters: next });
  const addQuarter = () => setQuarters([...quarters, { id: quarters.length + 1, color: "moss", emoji: "•", role: "", subtitle: "", title: "", essentialQuestion: "", theme: "", linkText: "Explore →", linkHref: "" }]);
  const removeQuarter = (i: number) => setQuarters(quarters.filter((_, idx) => idx !== i));
  const updateQuarter = (i: number, field: keyof YearAtGlanceQuarterFormItem, value: string | number) => {
    const next = quarters.map((q, idx) => (idx === i ? { ...q, [field]: value } : q));
    setQuarters(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (uppercase line)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. The Year at a Glance" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="e.g. One Project. Four Roles. Infinite Growth." />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Quarter cards"
          layout="grid-4"
          onAdd={addQuarter}
          addLabel="Add quarter"
          isEmpty={quarters.length === 0}
          emptyMessage='No quarters yet. Click "Add quarter" or paste the Year at a Glance component to get the default 4.'
          hint="Four quarter cards appear in a row on the page."
          className="max-h-[520px] overflow-y-auto pr-1"
        >
          {quarters.map((q, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={quarters.length}
              layout="grid-4"
              label={q.title || q.role || `Quarter ${q.id}`}
              preview={{ emoji: q.emoji, title: q.title || q.role, subtitle: q.subtitle }}
              onRemove={() => removeQuarter(i)}
            >
              <div className="flex flex-wrap items-end gap-2">
                <div>
                  <label className={labelCls}>ID</label>
                  <Input type="number" value={q.id} onChange={(e) => updateQuarter(i, "id", Number((e.target as HTMLInputElement).value) || 1)} placeholder="ID" className="w-14 shrink-0" />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={q.emoji} onChange={(v) => updateQuarter(i, "emoji", v)} placeholder="Emoji" />
                </div>
                <div>
                  <label className={labelCls}>Color</label>
                  <select value={q.color} onChange={(e) => updateQuarter(i, "color", e.target.value)} className="rounded-md border border-input px-2 py-1.5 text-sm w-28">
                    {QUARTER_COLORS.map((c) => (
                      <option key={c} value={c}>{c}</option>
                    ))}
                  </select>
                </div>
              </div>
              <div>
                <label className={labelCls}>Role</label>
                <Input value={q.role} onChange={(e) => updateQuarter(i, "role", e.target.value)} placeholder="Role (e.g. The Nature Investigator)" />
              </div>
              <div className="flex flex-wrap gap-2">
                <div className="flex-1 min-w-[100px]">
                  <label className={labelCls}>Subtitle</label>
                  <Input value={q.subtitle} onChange={(e) => updateQuarter(i, "subtitle", e.target.value)} placeholder="Subtitle" />
                </div>
                <div className="flex-1 min-w-[100px]">
                  <label className={labelCls}>Title</label>
                  <Input value={q.title} onChange={(e) => updateQuarter(i, "title", e.target.value)} placeholder="Title" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Essential question</label>
                <textarea value={q.essentialQuestion} onChange={(e) => updateQuarter(i, "essentialQuestion", e.target.value)} placeholder="Essential question" rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
              <div>
                <label className={labelCls}>Theme</label>
                <Input value={q.theme} onChange={(e) => updateQuarter(i, "theme", e.target.value)} placeholder="Theme" />
              </div>
              <div className="flex flex-wrap gap-2">
                <div className="flex-1 min-w-[100px]">
                  <label className={labelCls}>Link text</label>
                  <Input value={q.linkText} onChange={(e) => updateQuarter(i, "linkText", e.target.value)} placeholder="Explore →" />
                </div>
                <div className="flex-1 min-w-[100px]">
                  <label className={labelCls}>Link URL</label>
                  <Input value={q.linkHref} onChange={(e) => updateQuarter(i, "linkHref", e.target.value)} placeholder="Link URL (optional)" />
                </div>
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

function YearLongStoryForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const story = (content?.story as string) ?? "";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (uppercase label)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. The Year-Long Story" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Story (main paragraph)</label>
        <textarea
          value={story}
          onChange={(e) => onChange({ ...content, story: e.target.value })}
          placeholder="The year-long narrative describing how students spend the year..."
          rows={6}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[120px]"
        />
      </div>
    </>
  );
}

type WholeChildDimensionItem = { emoji: string; title: string; desc: string };
function ensureWholeChildDimension(raw: unknown): WholeChildDimensionItem {
  if (raw && typeof raw === "object" && "title" in raw) {
    const o = raw as Record<string, unknown>;
    return {
      emoji: typeof o.emoji === "string" ? o.emoji : "✨",
      title: typeof o.title === "string" ? o.title : "",
      desc: typeof o.desc === "string" ? o.desc : "",
    };
  }
  return { emoji: "✨", title: "", desc: "" };
}

function DevelopingWholeChildForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const title = (content?.title as string) ?? "";
  const subtitle = (content?.subtitle as string) ?? "";
  const rawDimensions = content?.dimensions;
  const dimensions: WholeChildDimensionItem[] = Array.isArray(rawDimensions) ? rawDimensions.map(ensureWholeChildDimension) : [];

  const setDimensions = (next: WholeChildDimensionItem[]) => onChange({ ...content, dimensions: next });
  const addDimension = () => setDimensions([...dimensions, { emoji: "✨", title: "", desc: "" }]);
  const removeDimension = (index: number) => setDimensions(dimensions.filter((_, i) => i !== index));
  const updateDimension = (index: number, field: keyof WholeChildDimensionItem, value: string) => {
    const next = [...dimensions];
    next[index] = { ...next[index], [field]: value };
    setDimensions(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (uppercase label)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. Developing the Whole Child" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="e.g. Portrait of the Learner" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <Input value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} placeholder="e.g. Every Orion experience..." />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Portrait dimension cards"
          layout="grid-3"
          onAdd={addDimension}
          addLabel="Add dimension"
          isEmpty={dimensions.length === 0}
          emptyMessage='No dimensions yet. Click "Add dimension" to add emoji, title, and description.'
          hint="Dimensions appear as cards in a grid on the page."
        >
          {dimensions.map((dim, index) => (
            <CardEditPanel
              key={index}
              index={index}
              total={dimensions.length}
              layout="grid-3"
              label={dim.title}
              preview={{ emoji: dim.emoji, title: dim.title, subtitle: dim.desc }}
              onRemove={() => removeDimension(index)}
            >
              <div className="flex gap-2 items-end">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={dim.emoji} onChange={(v) => updateDimension(index, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1">
                  <label className={labelCls}>Title</label>
                  <Input value={dim.title} onChange={(e) => updateDimension(index, "title", e.target.value)} placeholder="Title" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <Input value={dim.desc} onChange={(e) => updateDimension(index, "desc", e.target.value)} placeholder="Description" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type FinksTaxonomyItem = { category: string; emoji: string; description: string };
function ensureFinksTaxonomyItem(raw: unknown): FinksTaxonomyItem {
  if (raw && typeof raw === "object" && "category" in raw) {
    const o = raw as Record<string, unknown>;
    return {
      category: typeof o.category === "string" ? o.category : "",
      emoji: typeof o.emoji === "string" ? o.emoji : "📚",
      description: typeof o.description === "string" ? o.description : "",
    };
  }
  return { category: "", emoji: "📚", description: "" };
}

function FinksTaxonomyForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const rawItems = content?.items;
  const items: FinksTaxonomyItem[] = Array.isArray(rawItems) ? rawItems.map(ensureFinksTaxonomyItem) : [];

  const setItems = (next: FinksTaxonomyItem[]) => onChange({ ...content, items: next });
  const addItem = () => setItems([...items, { category: "", emoji: "📚", description: "" }]);
  const removeItem = (index: number) => setItems(items.filter((_, i) => i !== index));
  const updateItem = (index: number, field: keyof FinksTaxonomyItem, value: string) => {
    const next = [...items];
    next[index] = { ...next[index], [field]: value };
    setItems(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (title)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. Fink's Taxonomy of Significant Learning" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Taxonomy category cards"
          layout="grid-2"
          onAdd={addItem}
          addLabel="Add category"
          isEmpty={items.length === 0}
          emptyMessage='No categories yet. Click "Add category" to add category, emoji, and description.'
          hint="Categories appear as cards on the page."
        >
          {items.map((item, index) => (
            <CardEditPanel
              key={index}
              index={index}
              total={items.length}
              layout="grid-2"
              label={item.category}
              preview={{ emoji: item.emoji, title: item.category, subtitle: item.description }}
              onRemove={() => removeItem(index)}
            >
              <div className="flex gap-2 items-end">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={item.emoji} onChange={(v) => updateItem(index, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1">
                  <label className={labelCls}>Category name</label>
                  <Input value={item.category} onChange={(e) => updateItem(index, "category", e.target.value)} placeholder="Category name" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <Input value={item.description} onChange={(e) => updateItem(index, "description", e.target.value)} placeholder="Description" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type OneProjectStatItem = { val: string; label: string; color: string };
function ensureOneProjectStat(raw: unknown): OneProjectStatItem {
  if (raw && typeof raw === "object" && "label" in raw) {
    const o = raw as Record<string, unknown>;
    return {
      val: typeof o.val === "string" ? o.val : "",
      label: typeof o.label === "string" ? o.label : "",
      color: typeof o.color === "string" ? o.color : "text-foreground",
    };
  }
  return { val: "", label: "", color: "text-foreground" };
}

function OneProjectNot13TestsForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "";
  const body = (content?.body as string) ?? "";
  const rawStats = content?.stats;
  const stats: OneProjectStatItem[] = Array.isArray(rawStats) ? rawStats.map(ensureOneProjectStat) : [];

  const setStats = (next: OneProjectStatItem[]) => onChange({ ...content, stats: next });
  const addStat = () => setStats([...stats, { val: "", label: "", color: "text-foreground" }]);
  const removeStat = (index: number) => setStats(stats.filter((_, i) => i !== index));
  const updateStat = (index: number, field: keyof OneProjectStatItem, value: string) => {
    const next = [...stats];
    next[index] = { ...next[index], [field]: value };
    setStats(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="e.g. One Project, Not 13 Tests" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Body (paragraph)</label>
        <textarea
          value={body}
          onChange={(e) => onChange({ ...content, body: e.target.value })}
          placeholder="All 13 teachers assess the same quarter project..."
          rows={5}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]"
        />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Stat cards"
          layout="grid-3"
          onAdd={addStat}
          addLabel="Add stat"
          isEmpty={stats.length === 0}
          emptyMessage='No stats yet. Click "Add stat" (e.g. 13 / Courses / text-valencia).'
          hint="Stats appear as highlight cards below the body text."
        >
          {stats.map((stat, index) => (
            <CardEditPanel
              key={index}
              index={index}
              total={stats.length}
              layout="grid-3"
              label={stat.label}
              preview={{ title: stat.val, subtitle: stat.label }}
              onRemove={() => removeStat(index)}
            >
              <div>
                <label className={labelCls}>Value</label>
                <Input value={stat.val} onChange={(e) => updateStat(index, "val", e.target.value)} placeholder="Value" />
              </div>
              <div>
                <label className={labelCls}>Label</label>
                <Input value={stat.label} onChange={(e) => updateStat(index, "label", e.target.value)} placeholder="Label" />
              </div>
              <div>
                <label className={labelCls}>Color class</label>
                <Input value={stat.color} onChange={(e) => updateStat(index, "color", e.target.value)} placeholder="e.g. text-valencia" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type CurriculumArchitectureRow = { strand: string; courses: string[] };
function ensureCurriculumArchitectureRow(raw: unknown): CurriculumArchitectureRow {
  if (raw && typeof raw === "object" && "strand" in raw) {
    const o = raw as Record<string, unknown>;
    const strand = typeof o.strand === "string" ? o.strand : "";
    const rawCourses = o.courses;
    const courses = Array.isArray(rawCourses) ? rawCourses.map((c) => (typeof c === "string" ? c : "")) : [];
    return { strand, courses };
  }
  return { strand: "", courses: [] };
}

function CurriculumArchitectureForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const title = (content?.title as string) ?? "";
  const subtitle = (content?.subtitle as string) ?? "";
  const rawRows = content?.rows;
  const rows: CurriculumArchitectureRow[] = Array.isArray(rawRows) ? rawRows.map(ensureCurriculumArchitectureRow) : [];

  const setRows = (next: CurriculumArchitectureRow[]) => onChange({ ...content, rows: next });
  const addRow = () => setRows([...rows, { strand: "", courses: ["", "", "", ""] }]);
  const removeRow = (index: number) => setRows(rows.filter((_, i) => i !== index));
  const updateRowStrand = (index: number, value: string) => {
    const next = [...rows];
    next[index] = { ...next[index], strand: value };
    setRows(next);
  };
  const updateRowCourse = (rowIndex: number, courseIndex: number, value: string) => {
    const next = [...rows];
    const courses = [...(next[rowIndex].courses || [])];
    while (courses.length <= courseIndex) courses.push("");
    courses[courseIndex] = value;
    next[rowIndex] = { ...next[rowIndex], courses };
    setRows(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (uppercase label)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. Curriculum Architecture" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="e.g. 9 Core + 4 DNA Strands = 1 Integrated Project" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <Input value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} placeholder="Core Courses run all year..." />
      </div>
      <div className={formRow}>
        <div className="flex items-center justify-between mb-2">
          <label className={labelCls}>Table rows (Strand + Q1–Q4 courses)</label>
          <button type="button" onClick={addRow} className="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-sm font-medium rounded-md border border-slate-300 bg-white hover:bg-slate-50">
            <Plus size={14} /> Add row
          </button>
        </div>
        <div className="space-y-3 border border-slate-200 rounded-lg p-3 bg-slate-50/50">
          {rows.length === 0 ? (
            <p className="text-sm text-slate-500">No rows yet. Click “Add row” to add a strand and its courses per quarter.</p>
          ) : (
            rows.map((row, rowIndex) => (
              <div key={rowIndex} className="p-2 bg-white rounded border border-slate-200 space-y-2">
                <div className="flex items-center gap-2">
                  <Input value={row.strand} onChange={(e) => updateRowStrand(rowIndex, e.target.value)} placeholder="Strand (e.g. 🗣️ Human Skills)" className="flex-1" />
                  <button type="button" onClick={() => removeRow(rowIndex)} className="p-1.5 text-red-600 hover:bg-red-50 rounded" title="Remove row">
                    <Trash2 size={16} />
                  </button>
                </div>
                <div className="grid grid-cols-4 gap-1">
                  {[0, 1, 2, 3].map((ci) => (
                    <Input key={ci} value={row.courses[ci] ?? ""} onChange={(e) => updateRowCourse(rowIndex, ci, e.target.value)} placeholder={`Q${ci + 1}`} className="text-sm" />
                  ))}
                </div>
              </div>
            ))
          )}
        </div>
      </div>
    </>
  );
}

type PbelCycleStep = { step: string; title: string; desc: string };
type PbelTimelinePhase = { period: string; title: string; emoji: string; items: string[] };
function ensurePbelCycleStep(raw: unknown): PbelCycleStep {
  if (raw && typeof raw === "object" && "title" in raw) {
    const o = raw as Record<string, unknown>;
    return { step: typeof o.step === "string" ? o.step : "", title: typeof o.title === "string" ? o.title : "", desc: typeof o.desc === "string" ? o.desc : "" };
  }
  return { step: "", title: "", desc: "" };
}
function ensurePbelTimelinePhase(raw: unknown): PbelTimelinePhase {
  if (raw && typeof raw === "object" && "title" in raw) {
    const o = raw as Record<string, unknown>;
    const items = Array.isArray(o.items) ? o.items.map((i) => (typeof i === "string" ? i : "")) : [];
    return { period: typeof o.period === "string" ? o.period : "", title: typeof o.title === "string" ? o.title : "", emoji: typeof o.emoji === "string" ? o.emoji : "📌", items };
  }
  return { period: "", title: "", emoji: "📌", items: [] };
}

function PbelForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const title = (content?.title as string) ?? "";
  const subtitle = (content?.subtitle as string) ?? "";
  const cycleTitle = (content?.cycleTitle as string) ?? "";
  const rawSteps = content?.cycleSteps;
  const cycleSteps: PbelCycleStep[] = Array.isArray(rawSteps) ? rawSteps.map(ensurePbelCycleStep) : [];
  const timelineTitle = (content?.timelineTitle as string) ?? "";
  const rawPhases = content?.timelinePhases;
  const timelinePhases: PbelTimelinePhase[] = Array.isArray(rawPhases) ? rawPhases.map(ensurePbelTimelinePhase) : [];
  const linkText = (content?.linkText as string) ?? "";
  const linkHref = (content?.linkHref as string) ?? "";

  const setCycleSteps = (next: PbelCycleStep[]) => onChange({ ...content, cycleSteps: next });
  const addCycleStep = () => setCycleSteps([...cycleSteps, { step: String(cycleSteps.length + 1), title: "", desc: "" }]);
  const removeCycleStep = (i: number) => setCycleSteps(cycleSteps.filter((_, idx) => idx !== i));
  const updateCycleStep = (i: number, field: keyof PbelCycleStep, value: string) => {
    const next = [...cycleSteps];
    next[i] = { ...next[i], [field]: value };
    setCycleSteps(next);
  };

  const setTimelinePhases = (next: PbelTimelinePhase[]) => onChange({ ...content, timelinePhases: next });
  const addTimelinePhase = () => setTimelinePhases([...timelinePhases, { period: "", title: "", emoji: "📌", items: [] }]);
  const removeTimelinePhase = (i: number) => setTimelinePhases(timelinePhases.filter((_, idx) => idx !== i));
  const updateTimelinePhase = (i: number, field: keyof PbelTimelinePhase, value: string | string[]) => {
    const next = [...timelinePhases];
    next[i] = { ...next[i], [field]: value };
    setTimelinePhases(next);
  };
  const setPhaseItems = (phaseIndex: number, text: string) => updateTimelinePhase(phaseIndex, "items", text.split("\n").map((s) => s.trim()).filter(Boolean));

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading (uppercase label)</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. Problem-Based Experiential Learning" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="e.g. 💧 PBEL: Water — Every Drop Counts" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <textarea value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} placeholder="Students learn by tackling..." rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Cycle card title</label>
        <Input value={cycleTitle} onChange={(e) => onChange({ ...content, cycleTitle: e.target.value })} placeholder="e.g. 🔄 The PBEL Cycle" />
      </div>
      <div className={formRow}>
        <div className="flex items-center justify-between mb-2">
          <label className={labelCls}>Cycle steps</label>
          <button type="button" onClick={addCycleStep} className="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-sm font-medium rounded-md border border-slate-300 bg-white hover:bg-slate-50">
            <Plus size={14} /> Add
          </button>
        </div>
        <div className="space-y-2 border border-slate-200 rounded-lg p-3 bg-slate-50/50">
          {cycleSteps.map((step, i) => (
            <div key={i} className="p-2 bg-white rounded border border-slate-200 space-y-2">
              <div className="flex gap-2 items-center">
                <Input value={step.step} onChange={(e) => updateCycleStep(i, "step", e.target.value)} placeholder="Step #" className="w-12 shrink-0" />
                <Input value={step.title} onChange={(e) => updateCycleStep(i, "title", e.target.value)} placeholder="Title" className="flex-1" />
                <button type="button" onClick={() => removeCycleStep(i)} className="p-1.5 text-red-600 hover:bg-red-50 rounded shrink-0"><Trash2 size={16} /></button>
              </div>
              <Input value={step.desc} onChange={(e) => updateCycleStep(i, "desc", e.target.value)} placeholder="Description" className="w-full text-sm" />
            </div>
          ))}
        </div>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Timeline card title</label>
        <Input value={timelineTitle} onChange={(e) => onChange({ ...content, timelineTitle: e.target.value })} placeholder="e.g. 📅 Year Timeline" />
      </div>
      <div className={formRow}>
        <div className="flex items-center justify-between mb-2">
          <label className={labelCls}>Timeline phases</label>
          <button type="button" onClick={addTimelinePhase} className="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-sm font-medium rounded-md border border-slate-300 bg-white hover:bg-slate-50">
            <Plus size={14} /> Add
          </button>
        </div>
        <div className="space-y-2 border border-slate-200 rounded-lg p-3 bg-slate-50/50">
          {timelinePhases.map((phase, i) => (
            <div key={i} className="p-2 bg-white rounded border border-slate-200 space-y-2">
              <div className="flex gap-2 items-center">
                <EmojiPickerField compact value={phase.emoji} onChange={(v) => updateTimelinePhase(i, "emoji", v)} placeholder="Emoji" />
                <Input value={phase.period} onChange={(e) => updateTimelinePhase(i, "period", e.target.value)} placeholder="Period (e.g. Sep–Oct)" className="w-24 shrink-0" />
                <Input value={phase.title} onChange={(e) => updateTimelinePhase(i, "title", e.target.value)} placeholder="Title" className="flex-1" />
                <button type="button" onClick={() => removeTimelinePhase(i)} className="p-1.5 text-red-600 hover:bg-red-50 rounded shrink-0"><Trash2 size={16} /></button>
              </div>
              <textarea value={phase.items.join("\n")} onChange={(e) => setPhaseItems(i, e.target.value)} placeholder="Items (one per line)" rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
            </div>
          ))}
        </div>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Link text</label>
        <Input value={linkText} onChange={(e) => onChange({ ...content, linkText: e.target.value })} placeholder="e.g. 💧 Explore the Full PBEL Guide →" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Link URL</label>
        <Input value={linkHref} onChange={(e) => onChange({ ...content, linkHref: e.target.value })} placeholder="e.g. /course/pbel-water" />
      </div>
    </>
  );
}

function CourseHeroForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const backLabel = (content?.backLabel as string) ?? "";
  const backHref = (content?.backHref as string) ?? "";
  const emoji = (content?.emoji as string) ?? "";
  const name = (content?.name as string) ?? "";
  const tagline = (content?.tagline as string) ?? "";
  const courseType = (content?.courseType as string) ?? "";
  const duration = (content?.duration as string) ?? "";
  const weeklyTimeK5 = (content?.weeklyTimeK5 as string) ?? "";
  const weeklyTime612 = (content?.weeklyTime612 as string) ?? "";

  const weeklyTimeOptions = (currentValue: string) => {
    if (!currentValue || COURSE_HERO_WEEKLY_TIME_OPTIONS.some((option) => option.value === currentValue)) {
      return COURSE_HERO_WEEKLY_TIME_OPTIONS;
    }
    return [...COURSE_HERO_WEEKLY_TIME_OPTIONS, { value: currentValue, label: `${currentValue} (legacy)` }];
  };

  const selectCls = "flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm";

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Back link label</label>
        <Input value={backLabel} onChange={(e) => onChange({ ...content, backLabel: e.target.value })} placeholder="e.g. SPARK Dashboard" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Back link URL</label>
        <Input value={backHref} onChange={(e) => onChange({ ...content, backHref: e.target.value })} placeholder="e.g. /" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Emoji</label>
        <EmojiPickerField value={emoji} onChange={(v) => onChange({ ...content, emoji: v })} placeholder="e.g. 📚" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Course name (title)</label>
        <Input
          value={name}
          onChange={(e) => onChange({ ...content, name: e.target.value })}
          placeholder="Enter course name or use {subject}"
        />
        <p className="text-[10px] text-slate-500 mt-1">
          Use {"{subject}"} to automatically show the current course name when the page is rendered.
        </p>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Tagline</label>
        <textarea value={tagline} onChange={(e) => onChange({ ...content, tagline: e.target.value })} placeholder="Empowering your child to learn, grow, and thrive..." rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Course Type (meta bar)</label>
        <Input value={courseType} onChange={(e) => onChange({ ...content, courseType: e.target.value })} placeholder="e.g. Core Course, DNA Strand" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Duration</label>
        <Input value={duration} onChange={(e) => onChange({ ...content, duration: e.target.value })} placeholder="e.g. Full Year, 9 Weeks (Q1)" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>K-5 Weekly time</label>
        <select
          value={weeklyTimeK5}
          onChange={(e) => onChange({ ...content, weeklyTimeK5: e.target.value })}
          className={selectCls}
        >
          {weeklyTimeOptions(weeklyTimeK5).map((option) => (
            <option key={`k5-${option.value || "empty"}`} value={option.value}>
              {option.label}
            </option>
          ))}
        </select>
      </div>
      <div className={formRow}>
        <label className={labelCls}>6-12 Weekly time</label>
        <select
          value={weeklyTime612}
          onChange={(e) => onChange({ ...content, weeklyTime612: e.target.value })}
          className={selectCls}
        >
          {weeklyTimeOptions(weeklyTime612).map((option) => (
            <option key={`612-${option.value || "empty"}`} value={option.value}>
              {option.label}
            </option>
          ))}
        </select>
      </div>
    </>
  );
}

function WhyThisCourseMattersForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const body = (content?.body as string) ?? "";

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 💡" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading text</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="e.g. Why This Course Matters" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Body (main paragraph)</label>
        <textarea value={body} onChange={(e) => onChange({ ...content, body: e.target.value })} placeholder="{subject} is the foundation of curiosity..." rows={6} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[120px]" />
      </div>
    </>
  );
}

function HowConnectsForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const subject = (content?.subject as string) ?? "";
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const body = (content?.body as string) ?? "";
  const otherSubjectsTitle = (content?.otherSubjectsTitle as string) ?? "";
  const otherSubjectsIcon = (content?.otherSubjectsIcon as string) ?? "";
  const otherSubjectsText = (content?.otherSubjectsText as string) ?? "";
  const thisAddsTitle = (content?.thisAddsTitle as string) ?? "";
  const thisAddsIcon = (content?.thisAddsIcon as string) ?? "";
  const thisAddsText = (content?.thisAddsText as string) ?? "";

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Course subject</label>
        <Input
          value={subject}
          onChange={(e) => onChange({ ...content, subject: e.target.value })}
          placeholder="e.g. Science, Math, Language Arts (auto-filled from Course Hero if empty)"
        />
        <p className="text-[10px] text-slate-500 mt-1">
          Optional override. When empty, {"{subject}"} is filled from the Course Hero block on this page.
        </p>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Grade (optional, for {"{grade}"} placeholder)</label>
        <Input
          value={(content?.grade as string) ?? ""}
          onChange={(e) => onChange({ ...content, grade: e.target.value })}
          placeholder="e.g. Kindergarten, K-5"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Teacher (optional, for {"{teacher}"} placeholder)</label>
        <Input
          value={(content?.teacher as string) ?? ""}
          onChange={(e) => onChange({ ...content, teacher: e.target.value })}
          placeholder="e.g. Ms. Rivera"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 🎭" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading template (optional)</label>
        <Input
          value={heading}
          onChange={(e) => onChange({ ...content, heading: e.target.value })}
          placeholder="How {subject} Connects to All Learning"
        />
        <p className="text-[10px] text-slate-500 mt-1">
          Use placeholders like {"{subject}"} — replaced when the page is rendered, not when saved.
        </p>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Main paragraph (how it connects)</label>
        <textarea value={body} onChange={(e) => onChange({ ...content, body: e.target.value })} placeholder="{subject} provides the CONTENT KNOWLEDGE..." rows={4} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
      </div>
      <div className={formRow}>
        <label className={`${labelCls} mb-2`}>Comparison cards</label>
        <CardEditSplit
          left={{
            label: otherSubjectsTitle || "What Other Subjects Teach",
            preview: { emoji: otherSubjectsIcon, title: otherSubjectsTitle, subtitle: otherSubjectsText },
            children: (
              <>
                <div>
                  <label className={labelCls}>Title</label>
                  <Input value={otherSubjectsTitle} onChange={(e) => onChange({ ...content, otherSubjectsTitle: e.target.value })} placeholder="What Other Subjects Teach" />
                </div>
                <div>
                  <label className={labelCls}>Icon (emoji)</label>
                  <EmojiPickerField value={otherSubjectsIcon} onChange={(v) => onChange({ ...content, otherSubjectsIcon: v })} placeholder="e.g. 📚" />
                </div>
                <div>
                  <label className={labelCls}>Text</label>
                  <textarea value={otherSubjectsText} onChange={(e) => onChange({ ...content, otherSubjectsText: e.target.value })} placeholder="Math: Count and measure..." rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
                </div>
              </>
            ),
          }}
          right={{
            label: thisAddsTitle || `What {subject} Adds`,
            preview: { emoji: thisAddsIcon, title: thisAddsTitle, subtitle: thisAddsText },
            children: (
              <>
                <div>
                  <label className={labelCls}>Title</label>
                  <Input value={thisAddsTitle} onChange={(e) => onChange({ ...content, thisAddsTitle: e.target.value })} placeholder="What {subject} Adds" />
                </div>
                <div>
                  <label className={labelCls}>Icon (emoji)</label>
                  <EmojiPickerField value={thisAddsIcon} onChange={(v) => onChange({ ...content, thisAddsIcon: v })} placeholder="e.g. 🔬" />
                </div>
                <div>
                  <label className={labelCls}>Text</label>
                  <textarea value={thisAddsText} onChange={(e) => onChange({ ...content, thisAddsText: e.target.value })} placeholder="{subject} provides the WHY..." rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
                </div>
              </>
            ),
          }}
        />
      </div>
    </>
  );
}

type AssessmentItem = { icon: string; title: string; desc: string; color: string };
function ensureAssessmentItem(o: unknown): AssessmentItem {
  const x = o && typeof o === "object" ? (o as Record<string, unknown>) : {};
  const color = ["deep-sea", "valencia", "moss"].includes(String(x.color).trim()) ? String(x.color).trim() : "deep-sea";
  return {
    icon: (x.icon as string) ?? "",
    title: (x.title as string) ?? "",
    desc: (x.desc as string) ?? "",
    color,
  };
}

function SmarterAssessmentForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const rawItems = content?.items;
  const items: AssessmentItem[] = Array.isArray(rawItems)
    ? rawItems.slice(0, 6).map(ensureAssessmentItem)
    : [
        { icon: "1️⃣", title: "ONE Diagnostic", desc: "All teachers observe the same opening task", color: "deep-sea" },
        { icon: "📊", title: "Daily Check-ins", desc: "Each teacher tracks subject-specific growth", color: "valencia" },
        { icon: "1️⃣", title: "ONE Final Project", desc: "All teachers assess from their expert lens", color: "moss" },
      ];
  const benefitLabel = (content?.benefitLabel as string) ?? "";
  const benefitText = (content?.benefitText as string) ?? "";

  const setItems = (next: AssessmentItem[]) => onChange({ ...content, items: next });
  const updateItem = (index: number, field: keyof AssessmentItem, value: string) => {
    const next = [...items];
    (next[index] as Record<string, string>)[field] = value;
    setItems(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. ✅" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="Smarter Assessment = Less Stress" />
      </div>
      <div className={formRow}>
        <CardEditGroup label="Assessment cards (up to 6)" layout="grid-3" hint="Cards appear in a row on the page.">
          {items.map((item, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={items.length}
              layout="grid-3"
              label={item.title}
              preview={{ emoji: item.icon, title: item.title, subtitle: item.desc }}
              accent={item.color === "valencia" ? "valencia" : item.color === "moss" ? "moss" : "deep-sea"}
            >
              <div>
                <label className={labelCls}>Icon (emoji)</label>
                <EmojiPickerField compact value={item.icon} onChange={(v) => updateItem(i, "icon", v)} placeholder="Icon (emoji)" />
              </div>
              <div>
                <label className={labelCls}>Title</label>
                <Input value={item.title} onChange={(e) => updateItem(i, "title", e.target.value)} placeholder="Title" />
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={item.desc} onChange={(e) => updateItem(i, "desc", e.target.value)} placeholder="Description" rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
              <div>
                <label className={labelCls}>Color</label>
                <select value={item.color} onChange={(e) => updateItem(i, "color", e.target.value)} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm">
                  <option value="deep-sea">Deep Sea</option>
                  <option value="valencia">Valencia</option>
                  <option value="moss">Moss</option>
                </select>
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Benefit label (e.g. 💡 The Benefit:)</label>
        <Input value={benefitLabel} onChange={(e) => onChange({ ...content, benefitLabel: e.target.value })} placeholder="💡 The Benefit:" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Benefit text</label>
        <textarea value={benefitText} onChange={(e) => onChange({ ...content, benefitText: e.target.value })} placeholder="One meaningful project instead of 5-6 separate tests..." rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
      </div>
    </>
  );
}

function WhatYourChildWillGainForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const rawItems = content?.items;
  const items: string[] = Array.isArray(rawItems)
    ? rawItems.map((x) => (typeof x === "string" ? x : String(x)))
    : [
        "Scientific thinking and evidence-based reasoning",
        "Observation skills that transfer to all subjects",
        "Understanding of living systems and environments",
        "Confidence in asking questions and seeking answers",
      ];

  const setItems = (next: string[]) => onChange({ ...content, items: next });
  const addItem = () => setItems([...items, "New gain"]);
  const removeItem = (index: number) => setItems(items.filter((_, i) => i !== index));
  const updateItem = (index: number, value: string) => {
    const next = [...items];
    next[index] = value;
    setItems(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 🌟" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="What Your Child Will Gain" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Gain cards (one item per card)"
          layout={items.length <= 2 ? "horizontal" : items.length === 3 ? "grid-3" : "grid-2"}
          onAdd={addItem}
          addLabel="Add card"
          hint="Each card shows one gain on the page."
        >
          {items.map((item, index) => (
            <CardEditPanel
              key={index}
              index={index}
              total={items.length}
              layout={items.length <= 2 ? "horizontal" : items.length === 3 ? "grid-3" : "grid-2"}
              preview={{ title: item }}
              onRemove={() => removeItem(index)}
            >
              <div>
                <label className={labelCls}>Gain text</label>
                <Input value={item} onChange={(e) => updateItem(index, e.target.value)} placeholder="e.g. Scientific thinking and evidence-based reasoning" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type PortraitDimensionItem = { name: string; emoji: string; pct: number };
function ensurePortraitDimension(o: unknown): PortraitDimensionItem {
  const x = o && typeof o === "object" ? (o as Record<string, unknown>) : {};
  const pct = typeof x.pct === "number" ? x.pct : parseInt(String(x.pct ?? 0), 10) || 0;
  return {
    name: (x.name as string) ?? "",
    emoji: (x.emoji as string) ?? "✨",
    pct: Math.min(100, Math.max(0, Number.isNaN(pct) ? 0 : pct)),
  };
}

function CoursePortraitForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const subtitle = (content?.subtitle as string) ?? "";
  const rawDimensions = content?.dimensions;
  const dimensions: PortraitDimensionItem[] = Array.isArray(rawDimensions)
    ? rawDimensions.map(ensurePortraitDimension)
    : [
        { name: "Inspiring Communicator", emoji: "💬", pct: 85 },
        { name: "Balanced Person", emoji: "⚖️", pct: 60 },
        { name: "Caring Citizen", emoji: "🌍", pct: 80 },
        { name: "Respectful Relationship Builder", emoji: "🤝", pct: 65 },
        { name: "Bold Visionary Leader", emoji: "🚀", pct: 55 },
        { name: "Resilient Problem Solver", emoji: "💪", pct: 75 },
      ];

  const setDimensions = (next: PortraitDimensionItem[]) => onChange({ ...content, dimensions: next });
  const addDimension = () => setDimensions([...dimensions, { name: "New dimension", emoji: "✨", pct: 50 }]);
  const removeDimension = (index: number) => setDimensions(dimensions.filter((_, i) => i !== index));
  const updateDimension = (index: number, field: keyof PortraitDimensionItem, value: string | number) => {
    const next = [...dimensions];
    (next[index] as Record<string, unknown>)[field] = value;
    setDimensions(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 🎨" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="Developing the Whole Child" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <textarea value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} placeholder="This course intentionally develops all six Portrait of the Learner dimensions:" rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Dimension cards"
          layout="grid-3"
          onAdd={addDimension}
          addLabel="Add dimension"
          hint="Portrait dimensions appear as cards in a grid on the page."
        >
          {dimensions.map((dim, index) => (
            <CardEditPanel
              key={index}
              index={index}
              total={dimensions.length}
              layout="grid-3"
              label={dim.name}
              preview={{ emoji: dim.emoji, title: dim.name, subtitle: `${dim.pct}%` }}
              onRemove={() => removeDimension(index)}
            >
              <div className="flex gap-2 flex-wrap">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={dim.emoji} onChange={(v) => updateDimension(index, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1 min-w-[120px]">
                  <label className={labelCls}>Name</label>
                  <Input value={dim.name} onChange={(e) => updateDimension(index, "name", e.target.value)} placeholder="Dimension name" />
                </div>
                <div>
                  <label className={labelCls}>Progress %</label>
                  <Input type="number" min={0} max={100} value={dim.pct} onChange={(e) => updateDimension(index, "pct", parseInt(e.target.value, 10) || 0)} placeholder="%" className="w-16" />
                </div>
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type CoreSkillItem = { title: string; emoji: string; items: string[] };
function ensureCoreSkill(o: unknown): CoreSkillItem {
  const x = o && typeof o === "object" ? (o as Record<string, unknown>) : {};
  const rawItems = x.items;
  const items = Array.isArray(rawItems) ? rawItems.map((i) => (typeof i === "string" ? i : String(i))) : [];
  return {
    title: (x.title as string) ?? "",
    emoji: (x.emoji as string) ?? "•",
    items: items.length ? items : [""],
  };
}

function CourseCoreSkillsForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const rawSkills = content?.skills;
  const skills: CoreSkillItem[] = Array.isArray(rawSkills)
    ? rawSkills.map(ensureCoreSkill)
    : [
        { title: "Observation & Inquiry", emoji: "🔍", items: ["Making detailed observations", "Asking testable questions"] },
        { title: "Investigation & Evidence", emoji: "🧪", items: ["Designing investigations", "Using evidence to support claims"] },
      ];

  const setSkills = (next: CoreSkillItem[]) => onChange({ ...content, skills: next });
  const addSkill = () => setSkills([...skills, { title: "New skill", emoji: "•", items: [""] }]);
  const removeSkill = (index: number) => setSkills(skills.filter((_, i) => i !== index));
  const updateSkill = (index: number, field: keyof CoreSkillItem, value: string | string[]) => {
    const next = [...skills];
    (next[index] as Record<string, unknown>)[field] = value;
    setSkills(next);
  };
  const updateSkillItem = (skillIndex: number, itemIndex: number, value: string) => {
    const next = [...skills];
    const list = [...(next[skillIndex].items || [])];
    list[itemIndex] = value;
    next[skillIndex] = { ...next[skillIndex], items: list };
    setSkills(next);
  };
  const addSkillItem = (skillIndex: number) => {
    const next = [...skills];
    next[skillIndex] = { ...next[skillIndex], items: [...(next[skillIndex].items || []), ""] };
    setSkills(next);
  };
  const removeSkillItem = (skillIndex: number, itemIndex: number) => {
    const next = [...skills];
    const list = (next[skillIndex].items || []).filter((_, i) => i !== itemIndex);
    next[skillIndex] = { ...next[skillIndex], items: list.length ? list : [""] };
    setSkills(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 🎯" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="Core Skills Your Child Will Master" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Skill cards"
          layout="grid-2"
          onAdd={addSkill}
          addLabel="Add skill"
          hint="Each skill appears as its own card — typically shown side by side."
        >
          {skills.map((skill, si) => (
            <CardEditPanel
              key={si}
              index={si}
              total={skills.length}
              layout="grid-2"
              label={skill.title}
              preview={{ emoji: skill.emoji, title: skill.title, subtitle: (skill.items || [])[0] }}
              onRemove={() => removeSkill(si)}
            >
              <div className="flex gap-2 flex-wrap items-end">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={skill.emoji} onChange={(v) => updateSkill(si, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1 min-w-[140px]">
                  <label className={labelCls}>Title</label>
                  <Input value={skill.title} onChange={(e) => updateSkill(si, "title", e.target.value)} placeholder="Skill title" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Bullet items</label>
                <div className="space-y-1">
                  {(skill.items || []).map((item, ii) => (
                    <div key={ii} className="flex gap-2">
                      <Input value={item} onChange={(e) => updateSkillItem(si, ii, e.target.value)} placeholder="Bullet point" className="flex-1 text-sm" />
                      <button type="button" onClick={() => removeSkillItem(si, ii)} className="p-1.5 text-red-600 hover:bg-red-50 rounded shrink-0" title="Remove">
                        <Trash2 size={14} />
                      </button>
                    </div>
                  ))}
                  <button type="button" onClick={() => addSkillItem(si)} className="text-xs text-slate-600 hover:text-slate-800">+ Add bullet</button>
                </div>
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type JourneyPhaseItem = { weeks: string; title: string; emoji: string; desc: string };
function ensureJourneyPhase(o: unknown): JourneyPhaseItem {
  const x = o && typeof o === "object" ? (o as Record<string, unknown>) : {};
  return {
    weeks: (x.weeks as string) ?? "",
    title: (x.title as string) ?? "",
    emoji: (x.emoji as string) ?? "•",
    desc: (x.desc as string) ?? "",
  };
}

function CourseJourneyForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const rawPhases = content?.phases;
  const phases: JourneyPhaseItem[] = Array.isArray(rawPhases)
    ? rawPhases.map(ensureJourneyPhase)
    : [
        { weeks: "Q1", title: "Observe & Discover", emoji: "🌱", desc: "Explore the schoolyard, identify organisms..." },
        { weeks: "Q2", title: "Measure & Analyze", emoji: "📊", desc: "Track sun, shade, temperature..." },
        { weeks: "Q3", title: "Design & Test", emoji: "🔧", desc: "Apply scientific understanding to design..." },
        { weeks: "Q4", title: "Build & Sustain", emoji: "🏗️", desc: "Create a living habitat, monitor its health..." },
      ];

  const setPhases = (next: JourneyPhaseItem[]) => onChange({ ...content, phases: next });
  const addPhase = () => setPhases([...phases, { weeks: "Q?", title: "New phase", emoji: "•", desc: "" }]);
  const removePhase = (index: number) => setPhases(phases.filter((_, i) => i !== index));
  const updatePhase = (index: number, field: keyof JourneyPhaseItem, value: string) => {
    const next = [...phases];
    (next[index] as Record<string, string>)[field] = value;
    setPhases(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 🗓️" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="Your Child's Year-Long Journey" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Journey phase cards"
          layout="grid-4"
          onAdd={addPhase}
          addLabel="Add phase"
          hint="Phases appear left-to-right across the year timeline."
        >
          {phases.map((phase, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={phases.length}
              layout="grid-4"
              label={phase.title}
              preview={{ emoji: phase.emoji, title: `${phase.weeks} — ${phase.title}`, subtitle: phase.desc }}
              onRemove={() => removePhase(i)}
            >
              <div className="flex gap-2 flex-wrap items-end">
                <div>
                  <label className={labelCls}>Weeks / quarter</label>
                  <Input value={phase.weeks} onChange={(e) => updatePhase(i, "weeks", e.target.value)} placeholder="e.g. Q1" className="w-16" />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={phase.emoji} onChange={(v) => updatePhase(i, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1 min-w-[120px]">
                  <label className={labelCls}>Title</label>
                  <Input value={phase.title} onChange={(e) => updatePhase(i, "title", e.target.value)} placeholder="Phase title" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={phase.desc} onChange={(e) => updatePhase(i, "desc", e.target.value)} placeholder="Description" rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type WhatTheyCreateItem = { emoji: string; title: string; desc: string };
function ensureWhatTheyCreateItem(o: unknown): WhatTheyCreateItem {
  const x = o && typeof o === "object" ? (o as Record<string, unknown>) : {};
  return {
    emoji: (x.emoji as string) ?? "",
    title: (x.title as string) ?? "",
    desc: (x.desc as string) ?? "",
  };
}

function CourseWhatTheyCreateForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const rawItems = content?.items;
  const items: WhatTheyCreateItem[] = Array.isArray(rawItems)
    ? rawItems.map(ensureWhatTheyCreateItem)
    : [
        { emoji: "📓", title: "Observation Journals", desc: "Detailed records of scientific findings" },
        { emoji: "📊", title: "Data Charts & Graphs", desc: "Visual representations of collected data" },
        { emoji: "🗺️", title: "System Models", desc: "Maps and models showing ecosystem connections" },
      ];

  const setItems = (next: WhatTheyCreateItem[]) => onChange({ ...content, items: next });
  const addItem = () => setItems([...items, { emoji: "•", title: "New item", desc: "" }]);
  const removeItem = (index: number) => setItems(items.filter((_, i) => i !== index));
  const updateItem = (index: number, field: keyof WhatTheyCreateItem, value: string) => {
    const next = [...items];
    (next[index] as Record<string, string>)[field] = value;
    setItems(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 🎨" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="What Your Child Will Create" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Create items"
          layout="grid-3"
          onAdd={addItem}
          addLabel="Add card"
          hint="Cards appear in a 3-column grid on the page (2 columns on tablet, 1 on mobile)."
        >
          {items.map((item, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={items.length}
              layout="grid-3"
              label={item.title}
              preview={{ emoji: item.emoji, title: item.title, subtitle: item.desc }}
              onRemove={() => removeItem(i)}
            >
              <div className="flex gap-2 flex-wrap items-end">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={item.emoji} onChange={(v) => updateItem(i, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1 min-w-[120px]">
                  <label className={labelCls}>Title</label>
                  <Input value={item.title} onChange={(e) => updateItem(i, "title", e.target.value)} placeholder="Title" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={item.desc} onChange={(e) => updateItem(i, "desc", e.target.value)} placeholder="Description" rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type InquiryCategoryItem = { title: string; emoji: string; questions: string[] };
function ensureInquiryCategory(o: unknown): InquiryCategoryItem {
  const x = o && typeof o === "object" ? (o as Record<string, unknown>) : {};
  const rawQ = x.questions;
  const questions = Array.isArray(rawQ) ? rawQ.map((i) => (typeof i === "string" ? i : String(i))) : [];
  return {
    title: (x.title as string) ?? "",
    emoji: (x.emoji as string) ?? "💭",
    questions: questions.length ? questions : [""],
  };
}

function CourseInquiryQuestionsForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const introTitle = (content?.introTitle as string) ?? "";
  const introIcon = (content?.introIcon as string) ?? "";
  const introText = (content?.introText as string) ?? "";
  const rawCategories = content?.categories;
  const categories: InquiryCategoryItem[] = Array.isArray(rawCategories)
    ? rawCategories.map(ensureInquiryCategory)
    : [
        { title: "About Their Observations", emoji: "🔍", questions: ["What surprised you most?", "How do you know that's a living thing?"] },
        { title: "About Evidence & Reasoning", emoji: "🧠", questions: ["How do you know? What's your evidence?"] },
      ];

  const setCategories = (next: InquiryCategoryItem[]) => onChange({ ...content, categories: next });
  const addCategory = () => setCategories([...categories, { title: "New category", emoji: "💭", questions: [""] }]);
  const removeCategory = (index: number) => setCategories(categories.filter((_, i) => i !== index));
  const updateCategory = (index: number, field: keyof InquiryCategoryItem, value: string | string[]) => {
    const next = [...categories];
    (next[index] as Record<string, unknown>)[field] = value;
    setCategories(next);
  };
  const updateQuestion = (catIndex: number, qIndex: number, value: string) => {
    const next = [...categories];
    const list = [...(next[catIndex].questions || [])];
    list[qIndex] = value;
    next[catIndex] = { ...next[catIndex], questions: list };
    setCategories(next);
  };
  const addQuestion = (catIndex: number) => {
    const next = [...categories];
    next[catIndex] = { ...next[catIndex], questions: [...(next[catIndex].questions || []), ""] };
    setCategories(next);
  };
  const removeQuestion = (catIndex: number, qIndex: number) => {
    const next = [...categories];
    const list = (next[catIndex].questions || []).filter((_, i) => i !== qIndex);
    next[catIndex] = { ...next[catIndex], questions: list.length ? list : [""] };
    setCategories(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 💭" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="Deep Inquiry Questions to Ask Your Child" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Intro block title</label>
        <Input value={introTitle} onChange={(e) => onChange({ ...content, introTitle: e.target.value })} placeholder="Ask About Learning, Not Just Activities" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Intro block icon (emoji)</label>
        <EmojiPickerField value={introIcon} onChange={(v) => onChange({ ...content, introIcon: v })} placeholder="e.g. 🧠" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Intro paragraph</label>
        <textarea value={introText} onChange={(e) => onChange({ ...content, introText: e.target.value })} placeholder='Instead of "What did you do today?"...' rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Question category cards"
          layout="grid-2"
          onAdd={addCategory}
          addLabel="Add category"
          hint="Each category is shown as its own card on the page."
        >
          {categories.map((cat, ci) => (
            <CardEditPanel
              key={ci}
              index={ci}
              total={categories.length}
              layout="grid-2"
              label={cat.title}
              preview={{ emoji: cat.emoji, title: cat.title, subtitle: (cat.questions || [])[0] }}
              onRemove={() => removeCategory(ci)}
            >
              <div className="flex gap-2 flex-wrap items-end">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={cat.emoji} onChange={(v) => updateCategory(ci, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1 min-w-[120px]">
                  <label className={labelCls}>Category title</label>
                  <Input value={cat.title} onChange={(e) => updateCategory(ci, "title", e.target.value)} placeholder="Category title" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Questions</label>
                <div className="space-y-1">
                  {(cat.questions || []).map((q, qi) => (
                    <div key={qi} className="flex gap-2">
                      <Input value={q} onChange={(e) => updateQuestion(ci, qi, e.target.value)} placeholder="Question" className="flex-1 text-sm" />
                      <button type="button" onClick={() => removeQuestion(ci, qi)} className="p-1.5 text-red-600 hover:bg-red-50 rounded shrink-0" title="Remove">
                        <Trash2 size={14} />
                      </button>
                    </div>
                  ))}
                  <button type="button" onClick={() => addQuestion(ci)} className="text-xs text-slate-600 hover:text-slate-800">+ Add question</button>
                </div>
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type SupportAtHomeTipItem = { title: string; emoji: string; items: string[] };
function ensureSupportTip(o: unknown): SupportAtHomeTipItem {
  const x = o && typeof o === "object" ? (o as Record<string, unknown>) : {};
  const rawItems = x.items;
  const items = Array.isArray(rawItems) ? rawItems.map((i) => (typeof i === "string" ? i : String(i))) : [];
  return {
    title: (x.title as string) ?? "",
    emoji: (x.emoji as string) ?? "•",
    items: items.length ? items : [""],
  };
}

function CourseSupportAtHomeForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const rawTips = content?.tips;
  const tips: SupportAtHomeTipItem[] = Array.isArray(rawTips)
    ? rawTips.map(ensureSupportTip)
    : [
        { title: "Explore Together", emoji: "🌿", items: ["Go on nature walks", "Keep a family nature journal"] },
        { title: "Ask Great Questions", emoji: "❓", items: ["'Why do you think that is?' instead of giving answers", "Encourage wondering and hypothesizing"] },
      ];

  const setTips = (next: SupportAtHomeTipItem[]) => onChange({ ...content, tips: next });
  const addTip = () => setTips([...tips, { title: "New tip", emoji: "•", items: [""] }]);
  const removeTip = (index: number) => setTips(tips.filter((_, i) => i !== index));
  const updateTip = (index: number, field: keyof SupportAtHomeTipItem, value: string | string[]) => {
    const next = [...tips];
    (next[index] as Record<string, unknown>)[field] = value;
    setTips(next);
  };
  const updateTipItem = (tipIndex: number, itemIndex: number, value: string) => {
    const next = [...tips];
    const list = [...(next[tipIndex].items || [])];
    list[itemIndex] = value;
    next[tipIndex] = { ...next[tipIndex], items: list };
    setTips(next);
  };
  const addTipItem = (tipIndex: number) => {
    const next = [...tips];
    next[tipIndex] = { ...next[tipIndex], items: [...(next[tipIndex].items || []), ""] };
    setTips(next);
  };
  const removeTipItem = (tipIndex: number, itemIndex: number) => {
    const next = [...tips];
    const list = (next[tipIndex].items || []).filter((_, i) => i !== itemIndex);
    next[tipIndex] = { ...next[tipIndex], items: list.length ? list : [""] };
    setTips(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 🏠" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="Simple Ways to Support at Home" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Support tip cards"
          layout="grid-2"
          onAdd={addTip}
          addLabel="Add tip"
          hint="Tips appear as side-by-side cards on the page."
        >
          {tips.map((tip, ti) => (
            <CardEditPanel
              key={ti}
              index={ti}
              total={tips.length}
              layout="grid-2"
              label={tip.title}
              preview={{ emoji: tip.emoji, title: tip.title, subtitle: (tip.items || [])[0] }}
              onRemove={() => removeTip(ti)}
            >
              <div className="flex gap-2 flex-wrap items-end">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={tip.emoji} onChange={(v) => updateTip(ti, "emoji", v)} placeholder="Emoji" />
                </div>
                <div className="flex-1 min-w-[120px]">
                  <label className={labelCls}>Title</label>
                  <Input value={tip.title} onChange={(e) => updateTip(ti, "title", e.target.value)} placeholder="Tip title" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Bullet items</label>
                <div className="space-y-1">
                  {(tip.items || []).map((item, ii) => (
                    <div key={ii} className="flex gap-2">
                      <Input value={item} onChange={(e) => updateTipItem(ti, ii, e.target.value)} placeholder="Bullet point" className="flex-1 text-sm" />
                      <button type="button" onClick={() => removeTipItem(ti, ii)} className="p-1.5 text-red-600 hover:bg-red-50 rounded shrink-0" title="Remove">
                        <Trash2 size={14} />
                      </button>
                    </div>
                  ))}
                  <button type="button" onClick={() => addTipItem(ti)} className="text-xs text-slate-600 hover:text-slate-800">+ Add bullet</button>
                </div>
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

function CourseQuarterCelebrationForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const headingIcon = (content?.headingIcon as string) ?? "";
  const body = (content?.body as string) ?? "";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading icon (emoji)</label>
        <EmojiPickerField value={headingIcon} onChange={(v) => onChange({ ...content, headingIcon: v })} placeholder="e.g. 🎊" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => onChange({ ...content, heading: e.target.value })} placeholder="Quarter-End Celebration" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Body paragraph</label>
        <textarea value={body} onChange={(e) => onChange({ ...content, body: e.target.value })} placeholder="At the end of each quarter, your child presents..." rows={6} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[120px]" />
      </div>
    </>
  );
}

function QuarterHeroForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const backLabel = (content?.backLabel as string) ?? "";
  const backHref = (content?.backHref as string) ?? "";
  const quarterLabel = (content?.quarterLabel as string) ?? "";
  const role = (content?.role as string) ?? "";
  const subtitle = (content?.subtitle as string) ?? "";
  const title = (content?.title as string) ?? "";
  const emoji = (content?.emoji as string) ?? "";
  const color = (content?.color as string) ?? "moss";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Back link label</label>
        <Input value={backLabel} onChange={(e) => onChange({ ...content, backLabel: e.target.value })} placeholder="KG Family Guide" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Back link URL</label>
        <Input value={backHref} onChange={(e) => onChange({ ...content, backHref: e.target.value })} placeholder="/grade/kg" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Quarter label (e.g. Quarter 1 · September – November · Weeks 1–9)</label>
        <Input value={quarterLabel} onChange={(e) => onChange({ ...content, quarterLabel: e.target.value })} placeholder="Quarter 1 · ..." />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Role / title (e.g. The Nature Investigator)</label>
        <Input value={role} onChange={(e) => onChange({ ...content, role: e.target.value })} placeholder="The Nature Investigator" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <Input value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} placeholder="Foundations" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title (e.g. Explain the System)</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="Explain the System" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Emoji</label>
        <EmojiPickerField value={emoji} onChange={(v) => onChange({ ...content, emoji: v })} placeholder="e.g. 🌱" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Header color</label>
        <select value={color} onChange={(e) => onChange({ ...content, color: e.target.value })} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm">
          <option value="moss">Moss</option>
          <option value="deep-sea">Deep Sea</option>
          <option value="valencia">Valencia</option>
          <option value="sunflower">Sunflower</option>
        </select>
      </div>
    </>
  );
}

function BigIdeaForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const bigIdea = (content?.bigIdea as string) ?? "";
  const quarterNarrative = (content?.quarterNarrative as string) ?? "";
  const problemContext = (content?.problemContext as string) ?? "";
  const story = (content?.story as string) ?? "";
  const buildingToward = (content?.buildingToward as string) ?? "";
  const color = (content?.color as string) ?? "moss";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Big Idea (optional)</label>
        <textarea
          value={bigIdea}
          onChange={(e) => onChange({ ...content, bigIdea: e.target.value })}
          placeholder="Living things have needs that are met by their environment..."
          rows={3}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Quarter Narrative (optional)</label>
        <textarea
          value={quarterNarrative}
          onChange={(e) => onChange({ ...content, quarterNarrative: e.target.value })}
          placeholder="Students investigate as Young Scientists..."
          rows={3}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Problem Context</label>
        <textarea
          value={problemContext}
          onChange={(e) => onChange({ ...content, problemContext: e.target.value })}
          placeholder="Our schoolyard is full of living things..."
          rows={2}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Story</label>
        <textarea
          value={story}
          onChange={(e) => onChange({ ...content, story: e.target.value })}
          placeholder="Your child begins the year as a Nature Investigator..."
          rows={4}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]"
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Building Toward</label>
        <Input
          value={buildingToward}
          onChange={(e) => onChange({ ...content, buildingToward: e.target.value })}
          placeholder="Habitat System Explainer — habitat map, organism-needs charts..."
        />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Accent color</label>
        <select value={color} onChange={(e) => onChange({ ...content, color: e.target.value })} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm">
          <option value="moss">Moss</option>
          <option value="deep-sea">Deep Sea</option>
          <option value="valencia">Valencia</option>
          <option value="sunflower">Sunflower</option>
        </select>
      </div>
    </>
  );
}

function OrionSchoolHeaderForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const label = (content?.label as string) ?? "Orion STEM Schools";
  const title = (content?.title as string) ?? "Learning by Solving Real Problems";
  const subtitle = (content?.subtitle as string) ?? "This year's theme: Water — Every Drop Counts";
  const showBack = content?.showBack !== false;
  const backLabel = (content?.backLabel as string) ?? "Back";
  const backHref = (content?.backHref as string) ?? "/grade/kg";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Label (e.g. Orion STEM Schools)</label>
        <Input value={label} onChange={(e) => onChange({ ...content, label: e.target.value })} placeholder="Orion STEM Schools" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="Learning by Solving Real Problems" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <textarea value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]" placeholder="This year's theme: Water — Every Drop Counts" />
      </div>
      <div className={formRow}>
        <label className="flex items-center gap-2 text-sm text-slate-700 cursor-pointer">
          <input
            type="checkbox"
            checked={showBack}
            onChange={(e) => onChange({ ...content, showBack: e.target.checked })}
          />
          Show Back button
        </label>
      </div>
      {showBack ? (
        <>
          <div className={formRow}>
            <label className={labelCls}>Back label</label>
            <Input value={backLabel} onChange={(e) => onChange({ ...content, backLabel: e.target.value })} placeholder="Back" />
          </div>
          <div className={formRow}>
            <label className={labelCls}>Back fallback URL (used when there is no browser history)</label>
            <Input value={backHref} onChange={(e) => onChange({ ...content, backHref: e.target.value })} placeholder="/grade/kg" />
          </div>
        </>
      ) : null}
    </>
  );
}

function FamiliesExpectHelpForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const label = (content?.label as string) ?? "Orion STEM Schools";
  const title = (content?.title as string) ?? "What Families Can Expect — and How You Can Help";
  const subtitle = (content?.subtitle as string) ?? "PBEL · Water — Every Drop Counts 💧";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Label (e.g. Orion STEM Schools)</label>
        <Input value={label} onChange={(e) => onChange({ ...content, label: e.target.value })} placeholder="Orion STEM Schools" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="What Families Can Expect — and How You Can Help" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <textarea value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]" placeholder="PBEL · Water — Every Drop Counts 💧" />
      </div>
    </>
  );
}

type BenefitsCard = { title?: string; color?: string; items?: string[] };

function BenefitsForYourChildForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "Benefits for Your Child";
  const icon = (content?.icon as string) ?? "🌟";
  const rawCards = content?.cards;
  const cards: BenefitsCard[] = Array.isArray(rawCards) && rawCards.length >= 2
    ? rawCards.slice(0, 6).map((b: unknown) => {
        const x = b as BenefitsCard;
        return { title: String(x?.title ?? ""), color: String(x?.color ?? "primary"), items: Array.isArray(x?.items) ? (x.items as string[]) : [] };
      })
    : [
        { title: "Academic Growth", color: "primary", items: ["Applies science & math to real measurements and data", "Builds literacy through research and clear communication", "Introduces coding, sensors, and design skills"] },
        { title: "Life & Leadership", color: "accent", items: ["Teamwork with rotating roles (lead, builder, data, liaison)", "Growth mindset through testing and iteration", "Community contribution and empathy"] },
      ];

  const setCards = (next: BenefitsCard[]) => onChange({ ...content, cards: next });
  const updateCard = (index: number, field: "title" | "color" | "items", value: string | string[]) => {
    const next = cards.map((c, i) => (i === index ? { ...c, [field]: value } : c));
    setCards(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="Benefits for Your Child" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Icon (emoji)</label>
        <EmojiPickerField value={icon} onChange={(v) => onChange({ ...content, icon: v })} placeholder="🌟" />
      </div>
      <div className={formRow}>
        <CardEditGroup label="Benefit cards" layout="horizontal" hint="Two benefit cards appear side by side on the page.">
          {[0, 1].map((i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={2}
              layout="horizontal"
              label={cards[i]?.title}
              preview={{ title: cards[i]?.title, subtitle: (cards[i]?.items ?? [])[0] }}
              accent={i === 0 ? "left" : "right"}
            >
              <div className="flex gap-2 mb-2">
                <div className="flex-1">
                  <label className={labelCls}>Title</label>
                  <Input value={cards[i]?.title ?? ""} onChange={(e) => updateCard(i, "title", e.target.value)} placeholder="e.g. Academic Growth" />
                </div>
                <div>
                  <label className={labelCls}>Color</label>
                  <select value={cards[i]?.color ?? "primary"} onChange={(e) => updateCard(i, "color", e.target.value)} className="w-28 rounded-md border border-input bg-background px-3 py-2 text-sm">
                    <option value="primary">Primary</option>
                    <option value="accent">Accent</option>
                    <option value="moss">Moss</option>
                    <option value="sunflower">Sunflower</option>
                  </select>
                </div>
              </div>
              <div>
                <label className={labelCls}>Items (one per line)</label>
                <textarea value={(cards[i]?.items ?? []).join("\n")} onChange={(e) => updateCard(i, "items", e.target.value.split(/\r?\n/).map((x) => x.trim()).filter(Boolean))} rows={4} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[70px]" placeholder="One item per line" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

function ServiceLearningIpardForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "Our Service Learning Plan (IPARDE)";
  const icon = (content?.icon as string) ?? "🔗";
  const rawSteps = content?.stepLabels;
  const defaultSix = ["Investigate", "Prepare", "Action", "Reflect", "Demo", "Evaluate"];
  const stepLabels: string[] = Array.isArray(rawSteps) ? (() => { const s = [...(rawSteps as string[]).slice(0, 6)]; while (s.length < 6) s.push(""); return s; })() : [...defaultSix];
  const items = Array.isArray(content?.items) ? (content.items as string[]) : ["**Investigation:** Baseline audits & interviews (campus and neighborhood)", "**Action:** Leak checks, drain adoption, rain‑barrel installs, irrigation improvements", "**Demonstration:** Students share results and hand off maintenance plans to partners"];

  const setStepLabels = (next: string[]) => onChange({ ...content, stepLabels: next });
  const setItems = (next: string[]) => onChange({ ...content, items: next });

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="Our Service Learning Plan (IPARDE)" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Icon (emoji)</label>
        <EmojiPickerField value={icon} onChange={(v) => onChange({ ...content, icon: v })} placeholder="🔗" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Step labels (6 — bar order)</label>
        <div className="grid grid-cols-2 gap-2">
          {stepLabels.slice(0, 6).map((label, i) => (
            <Input key={i} value={label} onChange={(e) => { const n = [...stepLabels]; n[i] = e.target.value; setStepLabels(n); }} placeholder={["Investigate", "Prepare", "Action", "Reflect", "Demo", "Evaluate"][i]} />
          ))}
        </div>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Bullet items (one per line; use **text** for bold)</label>
        <textarea value={items.join("\n")} onChange={(e) => setItems(e.target.value.split(/\r?\n/).map((x) => x.trim()).filter(Boolean))} rows={5} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]" placeholder="**Investigation:** Baseline audits..." />
      </div>
    </>
  );
}

type TimelineCycle = { title?: string; color?: string; items?: string[] };

function YearTimelineAtGlanceForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "Year Timeline at a Glance";
  const icon = (content?.icon as string) ?? "📅";
  const rawCycles = content?.cycles;
  const cycles: TimelineCycle[] = Array.isArray(rawCycles) && rawCycles.length >= 3
    ? rawCycles.slice(0, 6).map((b: unknown) => { const x = b as TimelineCycle; return { title: String(x?.title ?? ""), color: String(x?.color ?? "primary"), items: Array.isArray(x?.items) ? (x.items as string[]) : [] }; })
    : [
        { title: "Cycle 1 · Sep–Oct — Discover & Define", color: "primary", items: ["Investigations & empathy interviews", "Baseline data collected", "Early \"quick‑win\" nudges"] },
        { title: "Cycle 2 · Nov–Jan — Prototype & Pilot", color: "sunflower", items: ["Build simple models and test", "One short pilot per team"] },
        { title: "Cycle 3 · Feb–May — Implement & Demonstrate", color: "accent", items: ["Scale what works with partners", "Track savings & adoption", "Innovation & Impact Showcase (May)"] },
      ];
  const portraitTraits = Array.isArray(content?.portraitTraits) ? (content.portraitTraits as string[]) : ["Resilient Problem Solver", "Caring Citizen", "Respectful Relationship Builder", "Inspiring Communicator", "Bold Visionary Leader", "Balanced Person"];

  const setCycles = (next: TimelineCycle[]) => onChange({ ...content, cycles: next });
  const updateCycle = (index: number, field: "title" | "color" | "items", value: string | string[]) => {
    const next = cycles.map((c, i) => (i === index ? { ...c, [field]: value } : c));
    setCycles(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="Year Timeline at a Glance" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Icon (emoji)</label>
        <EmojiPickerField value={icon} onChange={(v) => onChange({ ...content, icon: v })} placeholder="📅" />
      </div>
      <div className={formRow}>
        <CardEditGroup label="Timeline cycle cards" layout="grid-3" hint="Three cycles appear in a row across the year timeline.">
          {[0, 1, 2].map((i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={3}
              layout="grid-3"
              label={cycles[i]?.title}
              preview={{ title: cycles[i]?.title, subtitle: (cycles[i]?.items ?? [])[0] }}
            >
              <div className="flex gap-2 mb-2">
                <div className="flex-1">
                  <label className={labelCls}>Title</label>
                  <Input value={cycles[i]?.title ?? ""} onChange={(e) => updateCycle(i, "title", e.target.value)} placeholder="e.g. Cycle 1 · Sep–Oct — Discover & Define" />
                </div>
                <div>
                  <label className={labelCls}>Color</label>
                  <select value={cycles[i]?.color ?? "primary"} onChange={(e) => updateCycle(i, "color", e.target.value)} className="w-28 rounded-md border border-input bg-background px-3 py-2 text-sm">
                    <option value="primary">Primary</option>
                    <option value="sunflower">Sunflower</option>
                    <option value="accent">Accent</option>
                  </select>
                </div>
              </div>
              <div>
                <label className={labelCls}>Items (one per line)</label>
                <textarea value={(cycles[i]?.items ?? []).join("\n")} onChange={(e) => updateCycle(i, "items", e.target.value.split(/\r?\n/).map((x) => x.trim()).filter(Boolean))} rows={4} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[70px]" placeholder="One item per line" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Portrait traits (one per line)</label>
        <textarea value={portraitTraits.join("\n")} onChange={(e) => onChange({ ...content, portraitTraits: e.target.value.split(/\r?\n/).map((x) => x.trim()).filter(Boolean) })} rows={6} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]" placeholder="Resilient Problem Solver" />
      </div>
    </>
  );
}

function HowFamiliesCanHelpForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "How Families Can Help";
  const icon = (content?.icon as string) ?? "🏡";
  const rawCols = content?.columns;
  const columns: string[][] = Array.isArray(rawCols) && rawCols.length >= 2
    ? rawCols.slice(0, 4).map((col: unknown) => (Array.isArray(col) ? (col as string[]) : []))
    : [
        ["Try the student's water‑saving tips at home", "Send back quick \"what worked\" notes or photos", "Join a drain‑clean or garden day if you can"],
        ["Talk about where your water comes from", "Celebrate small wins (shorter showers, no‑drip taps)", "Ask your child to teach you one thing they learned"],
      ];

  const setColumns = (next: string[][]) => onChange({ ...content, columns: next });
  const updateColumn = (index: number, value: string[]) => { const n = [...columns]; n[index] = value; setColumns(n); };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="How Families Can Help" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Icon (emoji)</label>
        <EmojiPickerField value={icon} onChange={(v) => onChange({ ...content, icon: v })} placeholder="🏡" />
      </div>
      <div className={formRow}>
        <CardEditGroup label="Help column cards" layout="horizontal" hint="Two columns of tips appear side by side on the page.">
          {[0, 1].map((i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={2}
              layout="horizontal"
              preview={{ title: `Column ${i + 1}`, subtitle: (columns[i] ?? [])[0] }}
              accent={i === 0 ? "left" : "right"}
            >
              <div>
                <label className={labelCls}>Items (one per line)</label>
                <textarea value={(columns[i] ?? []).join("\n")} onChange={(e) => updateColumn(i, e.target.value.split(/\r?\n/).map((x) => x.trim()).filter(Boolean))} rows={5} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type FaqItem = { q?: string; a?: string };

function DeepInquiryQuestionsForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "Deep Inquiry Questions";
  const icon = (content?.icon as string) ?? "🔍";
  const rawQ = content?.questions;
  const questions: FaqItem[] = Array.isArray(rawQ) && rawQ.length > 0
    ? (rawQ as FaqItem[]).slice(0, 20).map((x) => ({ q: String(x?.q ?? ""), a: String(x?.a ?? "") }))
    : [
        { q: "How does solving a real water problem change the way my child thinks about science and math?", a: "When students measure leaks, calculate water savings, or analyze data from sensors, they experience science and math as tools for impact — not just subjects to study. This builds deeper understanding and lasting motivation." },
        { q: "What happens when a student's solution doesn't work — and why is that valuable?", a: "Failure is designed into the PBEL cycle. When a prototype falls short, students revisit their data, rethink assumptions, and iterate. This builds resilience, critical thinking, and the confidence to tackle complex problems." },
        { q: "How will my child's work actually affect our community — not just the classroom?", a: "Students partner with real organizations, adopt real drains, fix real leaks, and present real data. Their solutions are handed off with maintenance plans so impact continues beyond the school year." },
        { q: "How does studying one theme across K–12 create a different kind of learning culture?", a: "When older students mentor younger ones and every grade contributes to the same mission, students see themselves as part of a larger community of problem-solvers — building empathy, purpose, and school-wide collaboration." },
      ];

  const setQuestions = (next: FaqItem[]) => onChange({ ...content, questions: next });
  const updateQuestion = (index: number, field: "q" | "a", value: string) => {
    const next = questions.map((q, i) => (i === index ? { ...q, [field]: value } : q));
    setQuestions(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="Deep Inquiry Questions" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Icon (emoji)</label>
        <EmojiPickerField value={icon} onChange={(v) => onChange({ ...content, icon: v })} placeholder="🔍" />
      </div>
      <div className={formRow}>
        <CardEditGroup label="Q&A cards" layout="vertical" hint="Each question and answer appears as its own card on the page.">
          {questions.slice(0, 8).map((faq, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={Math.min(questions.length, 8)}
              layout="vertical"
              label={faq.q}
              preview={{ title: faq.q, subtitle: faq.a }}
            >
              <div>
                <label className={labelCls}>Question</label>
                <Input value={faq.q ?? ""} onChange={(e) => updateQuestion(i, "q", e.target.value)} placeholder="Question" />
              </div>
              <div>
                <label className={labelCls}>Answer</label>
                <textarea value={faq.a ?? ""} onChange={(e) => updateQuestion(i, "a", e.target.value)} rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" placeholder="Answer" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

function StayInTheLoopForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const leftTitle = (content?.leftTitle as string) ?? "Stay in the Loop";
  const leftBody = (content?.leftBody as string) ?? "Scan the tour QR to see current projects on our Digital Venture Wall and subscribe to Nova, our news update.";
  const leftNote = (content?.leftNote as string) ?? "QR / link placeholder for school use";
  const rightTitle = (content?.rightTitle as string) ?? "Questions?";
  const rightBody = (content?.rightBody as string) ?? "We'd love to talk during your tour. You can also reach our team at:";
  const rightContactLine = (content?.rightContactLine as string) ?? "Email: [your school email] · Phone: [school phone] · Web: [school site]";
  const rightNote = (content?.rightNote as string) ?? "Replace placeholders with your contact info before printing.";

  return (
    <>
      <div className={formRow}>
        <CardEditSplit
          left={{
            label: leftTitle,
            preview: { title: leftTitle, subtitle: leftBody },
            children: (
              <>
                <div>
                  <label className={labelCls}>Title</label>
                  <Input value={leftTitle} onChange={(e) => onChange({ ...content, leftTitle: e.target.value })} placeholder="Stay in the Loop" />
                </div>
                <div>
                  <label className={labelCls}>Body</label>
                  <textarea value={leftBody} onChange={(e) => onChange({ ...content, leftBody: e.target.value })} rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]" placeholder="Scan the tour QR..." />
                </div>
                <div>
                  <label className={labelCls}>Note (italic)</label>
                  <Input value={leftNote} onChange={(e) => onChange({ ...content, leftNote: e.target.value })} placeholder="QR / link placeholder for school use" />
                </div>
              </>
            ),
          }}
          right={{
            label: rightTitle,
            preview: { title: rightTitle, subtitle: rightBody },
            children: (
              <>
                <div>
                  <label className={labelCls}>Title</label>
                  <Input value={rightTitle} onChange={(e) => onChange({ ...content, rightTitle: e.target.value })} placeholder="Questions?" />
                </div>
                <div>
                  <label className={labelCls}>Body</label>
                  <textarea value={rightBody} onChange={(e) => onChange({ ...content, rightBody: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]" placeholder="We'd love to talk..." />
                </div>
                <div>
                  <label className={labelCls}>Contact line</label>
                  <Input value={rightContactLine} onChange={(e) => onChange({ ...content, rightContactLine: e.target.value })} placeholder="Email: ... · Phone: ... · Web: ..." />
                </div>
                <div>
                  <label className={labelCls}>Note (italic)</label>
                  <Input value={rightNote} onChange={(e) => onChange({ ...content, rightNote: e.target.value })} placeholder="Replace placeholders..." />
                </div>
              </>
            ),
          }}
        />
      </div>
    </>
  );
}

function WhatIsPbelForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "What is PBEL?";
  const body = (content?.body as string) ?? "Problem‑Based Experiential Learning is where students learn by tackling real community challenges. They investigate needs, design and test solutions, measure impact, and share results — building academic skills through meaningful action.";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="What is PBEL?" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Body / description</label>
        <textarea
          value={body}
          onChange={(e) => onChange({ ...content, body: e.target.value })}
          rows={4}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]"
          placeholder="Problem‑Based Experiential Learning is where students learn by tackling real community challenges…"
        />
      </div>
    </>
  );
}

function WhyWaterWhyNowForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "Why Water? Why Now?";
  const icon = (content?.icon as string) ?? "🌊";
  const body = (content?.body as string) ?? "Many families around the world cannot access safe water at home. Here at home, our water arrives by pipe — but every drop still matters. We can reduce waste, stop leaks, and protect our creeks and rivers. PBEL helps students connect global challenges to local action.";
  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="Why Water? Why Now?" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Icon (emoji)</label>
        <EmojiPickerField value={icon} onChange={(v) => onChange({ ...content, icon: v })} placeholder="🌊" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Body / description</label>
        <textarea
          value={body}
          onChange={(e) => onChange({ ...content, body: e.target.value })}
          rows={4}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]"
          placeholder="Many families around the world cannot access safe water at home…"
        />
      </div>
    </>
  );
}

type PbelCycleBlockStep = { number?: number; title?: string; description?: string };

function PbelCycleForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "How It Works — The PBEL Cycle";
  const icon = (content?.icon as string) ?? "🔄";
  const rawSteps = content?.steps;
  const steps: PbelCycleBlockStep[] = Array.isArray(rawSteps) && rawSteps.length >= 5
    ? rawSteps.slice(0, 5).map((s: unknown, i: number) => ({
        number: i + 1,
        title: String((s as PbelCycleBlockStep)?.title ?? ""),
        description: String((s as PbelCycleBlockStep)?.description ?? ""),
      }))
    : [
        { number: 1, title: "Investigate & Empathize", description: "Observe, interview, and collect baseline data — restroom taps left on, cafeteria pour‑offs, storm‑drain litter." },
        { number: 2, title: "Define & Ideate", description: "Craft \"How might we…?\" questions and brainstorm solutions that are desirable, feasible, and impactful." },
        { number: 3, title: "Prototype & Test", description: "Build simple models (signage, sensors, barrels) and run small pilots to see what truly works." },
        { number: 4, title: "Implement & Serve", description: "With partners, students implement solutions — drain adoption, leak checks, rain‑barrel installation — and track results." },
        { number: 5, title: "Reflect & Demonstrate", description: "Present data‑backed stories at our Innovation & Impact Showcase and hand off maintenance plans." },
      ];
  const footerLabel = (content?.footerLabel as string) ?? "One Theme · K–12";
  const footerBody = (content?.footerBody as string) ?? "Our whole school studies the same theme, with developmentally appropriate projects for each grade band.";

  const setSteps = (next: PbelCycleBlockStep[]) => onChange({ ...content, steps: next });
  const updateStep = (index: number, field: "title" | "description", value: string) => {
    const next = steps.map((s, i) => (i === index ? { ...s, [field]: value } : s));
    setSteps(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="How It Works — The PBEL Cycle" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Icon (emoji)</label>
        <EmojiPickerField value={icon} onChange={(v) => onChange({ ...content, icon: v })} placeholder="🔄" />
      </div>
      <div className={formRow}>
        <CardEditGroup label="PBEL cycle step cards" layout="vertical" hint="Five steps appear in order down the page.">
          {[0, 1, 2, 3, 4].map((i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={5}
              layout="vertical"
              positionLabel={`Step ${i + 1}`}
              label={steps[i]?.title}
              preview={{ title: steps[i]?.title, subtitle: steps[i]?.description }}
            >
              <div>
                <label className={labelCls}>Title</label>
                <Input value={steps[i]?.title ?? ""} onChange={(e) => updateStep(i, "title", e.target.value)} placeholder={`Step ${i + 1} title`} />
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={steps[i]?.description ?? ""} onChange={(e) => updateStep(i, "description", e.target.value)} rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]" placeholder="Description" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Footer label</label>
        <Input value={footerLabel} onChange={(e) => onChange({ ...content, footerLabel: e.target.value })} placeholder="One Theme · K–12" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Footer body</label>
        <textarea value={footerBody} onChange={(e) => onChange({ ...content, footerBody: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[60px]" placeholder="Our whole school studies..." />
      </div>
    </>
  );
}

type WhatYourChildMightDoBand = { label?: string; color?: string; items?: string[] };

function WhatYourChildMightDoForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "What Your Child Might Do";
  const icon = (content?.icon as string) ?? "🎒";
  const rawBands = content?.gradeBands;
  const bands: WhatYourChildMightDoBand[] = Array.isArray(rawBands) && rawBands.length >= 4
    ? rawBands.slice(0, 4).map((b: unknown) => {
        const x = b as WhatYourChildMightDoBand;
        return { label: String(x?.label ?? ""), color: String(x?.color ?? "primary"), items: Array.isArray(x?.items) ? x.items.filter((i): i is string => typeof i === "string") : [] };
      })
    : [
        { label: "K–2", color: "salmon", items: ["Handwashing \"water‑off‑while‑scrubbing\" routines", "Bathroom \"drip detective\" tallies", "Reminder decals & songs for younger peers"] },
        { label: "3–5", color: "accent", items: ["Cafeteria pour‑off audits & nudge signs", "Adopt‑a‑Drain mapping & maintenance", "Rain‑barrel placement for the garden"] },
        { label: "6–8", color: "sunflower", items: ["Leak‑detection checks with simple sensors", "Sensor‑guided irrigation scheduling", "Low‑cost emergency filter demos (no drinking)"] },
        { label: "9–12", color: "moss", items: ["Watershed & runoff hotspot mapping", "Smart meter retrofit prototypes & ROI tests", "Partner pilots and scale‑up plans"] },
      ];
  const safetyTitle = (content?.safetyTitle as string) ?? "🛡️ Safety & Ethics";
  const safetyItems = Array.isArray(content?.safetyItems) ? (content.safetyItems as string[]) : ["Age‑appropriate tools and supervision", "Water + electricity separation; PPE in labs", "Consent & privacy for interviews/data", "On‑campus service for K–2; approved sites for older grades"];
  const successTitle = (content?.successTitle as string) ?? "📊 What Success Looks Like";
  const successSubtitle = (content?.successSubtitle as string) ?? "Real savings. Real habits. Real pride.";
  const successItems = Array.isArray(content?.successItems) ? (content.successItems as string[]) : ["Liters saved each week", "Leaks found and fixed", "Cleaner drains and gardens", "Students who can explain the science, math, and choices behind their solution"];

  const setBands = (next: WhatYourChildMightDoBand[]) => onChange({ ...content, gradeBands: next });
  const updateBand = (index: number, field: "label" | "color" | "items", value: string | string[]) => {
    const next = bands.map((b, i) => (i === index ? { ...b, [field]: value } : b));
    setBands(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="What Your Child Might Do" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Icon (emoji)</label>
        <EmojiPickerField value={icon} onChange={(v) => onChange({ ...content, icon: v })} placeholder="🎒" />
      </div>
      <div className={formRow}>
        <CardEditGroup label="Grade band cards" layout="grid-4" hint="Four grade bands appear in a row on the page (K–2 through 9–12).">
          {[0, 1, 2, 3].map((i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={4}
              layout="grid-4"
              label={bands[i]?.label}
              preview={{ title: bands[i]?.label, subtitle: (bands[i]?.items ?? [])[0] }}
            >
              <div className="flex gap-2 mb-2">
                <div className="flex-1">
                  <label className={labelCls}>Label</label>
                  <Input value={bands[i]?.label ?? ""} onChange={(e) => updateBand(i, "label", e.target.value)} placeholder="e.g. K–2" />
                </div>
                <div>
                  <label className={labelCls}>Color</label>
                  <select value={bands[i]?.color ?? "primary"} onChange={(e) => updateBand(i, "color", e.target.value)} className="flex w-32 rounded-md border border-input bg-background px-3 py-2 text-sm">
                    <option value="salmon">Salmon</option>
                    <option value="accent">Accent</option>
                    <option value="sunflower">Sunflower</option>
                    <option value="moss">Moss</option>
                    <option value="primary">Primary</option>
                  </select>
                </div>
              </div>
              <div>
                <label className={labelCls}>Items (one per line)</label>
                <textarea value={(bands[i]?.items ?? []).join("\n")} onChange={(e) => updateBand(i, "items", e.target.value.split(/\r?\n/).map((x) => x.trim()).filter(Boolean))} rows={4} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[70px]" placeholder="One item per line" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
      <div className={formRow}>
        <CardEditSplit
          layout="horizontal"
          left={{
            label: safetyTitle,
            preview: { title: safetyTitle, subtitle: safetyItems[0] },
            children: (
              <>
                <div>
                  <label className={labelCls}>Title</label>
                  <Input value={safetyTitle} onChange={(e) => onChange({ ...content, safetyTitle: e.target.value })} placeholder="🛡️ Safety & Ethics" />
                </div>
                <div>
                  <label className={labelCls}>Items (one per line)</label>
                  <textarea value={safetyItems.join("\n")} onChange={(e) => onChange({ ...content, safetyItems: e.target.value.split(/\r?\n/).map((x) => x.trim()).filter(Boolean) })} rows={5} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]" />
                </div>
              </>
            ),
          }}
          right={{
            label: successTitle,
            preview: { title: successTitle, subtitle: successSubtitle },
            children: (
              <>
                <div>
                  <label className={labelCls}>Title</label>
                  <Input value={successTitle} onChange={(e) => onChange({ ...content, successTitle: e.target.value })} placeholder="📊 What Success Looks Like" />
                </div>
                <div>
                  <label className={labelCls}>Subtitle</label>
                  <Input value={successSubtitle} onChange={(e) => onChange({ ...content, successSubtitle: e.target.value })} placeholder="Real savings. Real habits. Real pride." />
                </div>
                <div>
                  <label className={labelCls}>Items (one per line)</label>
                  <textarea value={successItems.join("\n")} onChange={(e) => onChange({ ...content, successItems: e.target.value.split(/\r?\n/).map((x) => x.trim()).filter(Boolean) })} rows={5} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]" />
                </div>
              </>
            ),
          }}
        />
      </div>
    </>
  );
}

function GradeFamilyGuidesForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const heading = (content?.heading as string) ?? "";
  const footerText = (content?.footerText as string) ?? "";
  const rawItems = content?.items;
  const items: GradeItem[] = Array.isArray(rawItems) ? rawItems.map(ensureGradeItem) : [];

  const updateHeading = (v: string) => onChange({ ...content, heading: v });
  const updateFooterText = (v: string) => onChange({ ...content, footerText: v });
  const setItems = (next: GradeItem[]) => onChange({ ...content, items: next });

  const addItem = () => {
    const n = items.length + 1;
    const id = `g${n}-${Math.random().toString(36).slice(2, 8)}`;
    setItems([...items, { id, label: `Grade ${n}`, shortLabel: `G${n}`, route: `/grade/g${n}`, available: false }]);
  };
  const removeItem = (index: number) => setItems(items.filter((_, i) => i !== index));
  const updateItem = (index: number, field: keyof GradeItem, value: string | boolean) => {
    const next = [...items];
    (next[index] as Record<string, unknown>)[field] = value;
    setItems(next);
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Heading</label>
        <Input value={heading} onChange={(e) => updateHeading(e.target.value)} placeholder="e.g. Family Guides by Grade" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Footer text (below grades)</label>
        <Input value={footerText} onChange={(e) => updateFooterText(e.target.value)} placeholder="e.g. KG is live · Other grades coming soon" />
      </div>
      <div className={formRow}>
        <div className="flex items-center justify-between mb-2">
          <label className={labelCls}>Grade options</label>
          <button type="button" onClick={addItem} className="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-sm font-medium rounded-md border border-slate-300 bg-white hover:bg-slate-50">
            <Plus size={14} /> Add grade
          </button>
        </div>
        <div className="space-y-3 border border-slate-200 rounded-lg p-3 bg-slate-50/50">
          {items.length === 0 ? (
            <p className="text-sm text-slate-500">No grades yet. Click “Add grade” to add KG, G1, G2, etc.</p>
          ) : (
            items.map((item, index) => (
              <div key={index} className="flex flex-wrap items-center gap-2 p-2 bg-white rounded border border-slate-200">
                <Input value={item.shortLabel} onChange={(e) => updateItem(index, "shortLabel", e.target.value)} placeholder="Short (e.g. KG)" className="w-16 shrink-0" />
                <Input value={item.label} onChange={(e) => updateItem(index, "label", e.target.value)} placeholder="Label (e.g. Kindergarten)" className="flex-1 min-w-[120px]" />
                <Input value={item.route} onChange={(e) => updateItem(index, "route", e.target.value)} placeholder="Route (e.g. /grade/kg)" className="flex-1 min-w-[100px]" />
                <label className="inline-flex items-center gap-1.5 text-sm whitespace-nowrap">
                  <input type="checkbox" checked={item.available} onChange={(e) => updateItem(index, "available", e.target.checked)} className="rounded border-slate-300" />
                  Available
                </label>
                <button type="button" onClick={() => removeItem(index)} className="p-1.5 text-red-600 hover:bg-red-50 rounded" title="Remove this grade">
                  <Trash2 size={16} />
                </button>
              </div>
            ))
          )}
        </div>
      </div>
    </>
  );
}

function GradeFamilyGuidesApiForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const apiPath = ((content?.apiPath as string) ?? (content?.apiUrl as string) ?? "").trim();
  let resolvedApiUrl = "";
  if (apiPath) {
    try {
      resolvedApiUrl = orionExternalApiUrl(apiPath);
    } catch {
      resolvedApiUrl = "(set VITE_API_URL_ORION in .env and rebuild)";
    }
  }
  const apiMethod = ((content?.apiMethod as string) ?? "GET").toUpperCase();
  const apiHeadersJson = (content?.apiHeadersJson as string) ?? "";
  const apiBodyJson = (content?.apiBodyJson as string) ?? "";

  return (
    <>
      <GradeFamilyGuidesForm content={content} onChange={onChange} />
      <div className={`${formRow} mt-6 pt-4 border-t border-slate-200`}>
        <label className={labelCls}>Orion API endpoint path</label>
        <Input
          value={apiPath}
          onChange={(e) => onChange({ ...content, apiPath: e.target.value })}
          placeholder="DropdownMaster/GetGradesWithShortDescription"
          className="font-mono text-sm"
        />
        <p className="text-xs text-slate-500 mt-1">
          Base URL from <code className="text-[11px]">VITE_API_URL_ORION</code>. Other site APIs use Laravel.
        </p>
        {resolvedApiUrl && (
          <p className="text-xs text-slate-500 mt-1 font-mono break-all">
            Resolved URL: {resolvedApiUrl}
          </p>
        )}
      </div>
      <div className={formRow}>
        <label className={labelCls}>API method</label>
        <div className="flex flex-wrap gap-2">
          {["GET", "POST", "PUT", "PATCH", "DELETE"].map((method) => (
            <button
              key={method}
              type="button"
              onClick={() => onChange({ ...content, apiMethod: method })}
              className={`px-3 py-1.5 rounded-md border text-sm font-medium ${
                apiMethod === method
                  ? "bg-slate-900 text-white border-slate-900"
                  : "bg-white text-slate-700 border-slate-300 hover:bg-slate-50"
              }`}
            >
              {method}
            </button>
          ))}
        </div>
        <p className="text-xs text-slate-500 mt-1">Selected method: {apiMethod}</p>
      </div>
      <div className={formRow}>
        <label className={labelCls}>API headers (JSON object, optional)</label>
        <textarea
          value={apiHeadersJson}
          onChange={(e) => onChange({ ...content, apiHeadersJson: e.target.value })}
          placeholder={`{"Authorization":"Bearer <token>"}`}
          rows={3}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px] font-mono"
        />
      </div>
      {apiMethod !== "GET" && apiMethod !== "HEAD" && (
        <div className={formRow}>
          <label className={labelCls}>API body (raw JSON/string, optional)</label>
          <textarea
            value={apiBodyJson}
            onChange={(e) => onChange({ ...content, apiBodyJson: e.target.value })}
            placeholder='{"schoolId":"kg"}'
            rows={4}
            className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[90px] font-mono"
          />
        </div>
      )}
      <ApiQueryFiltersEditor
        filters={content?.filters}
        onChange={(filters) => onChange({ ...content, filters })}
      />
      <p className="text-xs text-slate-500 -mt-2">
        Notes: response decryption uses VITE_ENCRYPT_KEY_1/2/3. If API data cannot be mapped yet, this block falls back to manually configured grade items.
      </p>
    </>
  );
}

type ImpactLensEdit = { id: number; label: string; emoji: string; hslVar: string; phase: string; description: string };
type MirrorRingEdit = { r: number; label: string; emoji: string; hslVar: string; desc: string };

function ImpactKaleidoscopeForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const eyebrow = (content?.eyebrow as string) ?? "The Impact Kaleidoscope";
  const title = (content?.title as string) ?? "9 Lenses of Inquiry, Design & Impact";
  const helper = (content?.helper as string) ?? "Click any lens to explore that stage of the PBEL journey.";
  const centerImageAlt = (content?.centerImageAlt as string) ?? "SPARK";
  const mirrorDetailEyebrow = (content?.mirrorDetailEyebrow as string) ?? "Cross-Cutting Overlay";
  const lensHoverHint = (content?.lensHoverHint as string) ?? "Click to learn more";

  const defaultLenses: ImpactLensEdit[] = [
    { id: 1, label: "Launch", emoji: "🚀", hslVar: "--deep-sea", phase: "Context & Connection", description: "Hook curiosity — connect a global issue to students' lived reality and local community." },
    { id: 2, label: "Essential Question", emoji: "❓", hslVar: "--deep-sea", phase: "Context & Connection", description: "Student ownership — draft 'How Might We…?' questions that frame the entire inquiry cycle." },
    { id: 3, label: "Community Partners", emoji: "🤝", hslVar: "--mist", phase: "Context & Connection", description: "Authenticity & reciprocity — real community adoption ensures solutions leave the classroom." },
    { id: 4, label: "Empathy & Investigation", emoji: "💛", hslVar: "--sunflower", phase: "Empathy & Insight", description: "Deeply understand users through interviews, observation, and baseline data." },
    { id: 5, label: "POV & Define", emoji: "🎯", hslVar: "--sunflower", phase: "Empathy & Insight", description: "Synthesize insights into a clear point of view. Define measurable targets for impact." },
    { id: 6, label: "Core + Enrichment", emoji: "📚", hslVar: "--moss", phase: "Empathy & Insight", description: "Just-in-time learning — Math, Science, ELA, and AI skills unlock solutions students actually need." },
    { id: 7, label: "Product", emoji: "🔧", hslVar: "--valencia", phase: "Action & Impact", description: "Ideate → Prototype. Low-fidelity sketches evolve into testable models and builds." },
    { id: 8, label: "Critique & Revision", emoji: "🔄", hslVar: "--valencia", phase: "Action & Impact", description: "Test with real users. Iterate based on data, peer critique, and expert feedback." },
    { id: 9, label: "Exhibition", emoji: "🎤", hslVar: "--salmon", phase: "Action & Impact", description: "Storytelling for influence — pilot, implement, and present at the Innovation & Impact Showcase." },
  ];
  const defaultRings: MirrorRingEdit[] = [
    { r: 238, label: "Student Voice & Choice", emoji: "🗣️", hslVar: "--moss", desc: "Learners co-design the inquiry, choose roles, and shape deliverables at every stage." },
    { r: 262, label: "Service Learning (IPARDE)", emoji: "🔁", hslVar: "--deep-sea", desc: "Investigate, Prepare, Action, Reflect, Demonstrate, Evaluate — runs beneath every lens." },
    { r: 286, label: "Safety, Ethics & Equity", emoji: "🛡️", hslVar: "--valencia", desc: "Age-appropriate tools, consent protocols, equitable access, and ethical design thinking." },
  ];

  const lenses: ImpactLensEdit[] = Array.isArray(content?.lenses) && (content.lenses as unknown[]).length > 0
    ? (content.lenses as unknown[]).map((b, i) => {
        const x = b as ImpactLensEdit;
        const idNum = typeof x?.id === "number" ? x.id : Number(x?.id);
        return {
          id: Number.isFinite(idNum) ? idNum : i + 1,
          label: String(x?.label ?? ""),
          emoji: String(x?.emoji ?? "•"),
          hslVar: String(x?.hslVar ?? "--deep-sea"),
          phase: String(x?.phase ?? ""),
          description: String(x?.description ?? ""),
        };
      })
    : defaultLenses;

  const mirrorRings: MirrorRingEdit[] = Array.isArray(content?.mirrorRings) && (content.mirrorRings as unknown[]).length > 0
    ? (content.mirrorRings as unknown[]).map((b, i) => {
        const x = b as MirrorRingEdit;
        const rNum = typeof x?.r === "number" ? x.r : Number(x?.r);
        return {
          r: Number.isFinite(rNum) ? rNum : 238 + i * 24,
          label: String(x?.label ?? ""),
          emoji: String(x?.emoji ?? "•"),
          hslVar: String(x?.hslVar ?? "--moss"),
          desc: String(x?.desc ?? ""),
        };
      })
    : defaultRings;

  const setLenses = (next: ImpactLensEdit[]) => onChange({ ...content, lenses: next });
  const setRings = (next: MirrorRingEdit[]) => onChange({ ...content, mirrorRings: next });
  const updateLens = (index: number, patch: Partial<ImpactLensEdit>) => {
    setLenses(lenses.map((l, i) => (i === index ? { ...l, ...patch } : l)));
  };
  const updateRing = (index: number, patch: Partial<MirrorRingEdit>) => {
    setRings(mirrorRings.map((r, i) => (i === index ? { ...r, ...patch } : r)));
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Eyebrow</label>
        <Input value={eyebrow} onChange={(e) => onChange({ ...content, eyebrow: e.target.value })} placeholder="The Impact Kaleidoscope" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="9 Lenses of Inquiry, Design & Impact" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Helper text</label>
        <Input value={helper} onChange={(e) => onChange({ ...content, helper: e.target.value })} placeholder="Click any lens…" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Center image alt</label>
        <Input value={centerImageAlt} onChange={(e) => onChange({ ...content, centerImageAlt: e.target.value })} placeholder="SPARK" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Mirror detail eyebrow</label>
        <Input value={mirrorDetailEyebrow} onChange={(e) => onChange({ ...content, mirrorDetailEyebrow: e.target.value })} placeholder="Cross-Cutting Overlay" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Lens hover hint</label>
        <Input value={lensHoverHint} onChange={(e) => onChange({ ...content, lensHoverHint: e.target.value })} placeholder="Click to learn more" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Lenses"
          layout="vertical"
          onAdd={() => setLenses([...lenses, { id: lenses.length + 1, label: "New lens", emoji: "•", hslVar: "--deep-sea", phase: "", description: "" }])}
          addLabel="Add lens"
          hint="Nine kaleidoscope lenses around the center."
        >
          {lenses.map((lens, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={lenses.length}
              layout="vertical"
              label={lens.label}
              preview={{ emoji: lens.emoji, title: lens.label, subtitle: lens.phase }}
              onRemove={lenses.length > 1 ? () => setLenses(lenses.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2 flex-wrap">
                <div className="w-20">
                  <label className={labelCls}>ID</label>
                  <Input type="number" value={lens.id} onChange={(e) => updateLens(i, { id: Number(e.target.value) || i + 1 })} />
                </div>
                <div className="flex-1 min-w-[140px]">
                  <label className={labelCls}>Label</label>
                  <Input value={lens.label} onChange={(e) => updateLens(i, { label: e.target.value })} placeholder="Launch" />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={lens.emoji} onChange={(v) => updateLens(i, { emoji: v })} placeholder="🚀" />
                </div>
              </div>
              <HslCssVarField value={lens.hslVar} onChange={(v) => updateLens(i, { hslVar: v })} label="hslVar" />
              <div>
                <label className={labelCls}>Phase</label>
                <Input value={lens.phase} onChange={(e) => updateLens(i, { phase: e.target.value })} placeholder="Context & Connection" />
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={lens.description} onChange={(e) => updateLens(i, { description: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Mirror rings"
          layout="vertical"
          onAdd={() => setRings([...mirrorRings, { r: 238 + mirrorRings.length * 24, label: "New mirror", emoji: "•", hslVar: "--moss", desc: "" }])}
          addLabel="Add ring"
        >
          {mirrorRings.map((ring, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={mirrorRings.length}
              layout="vertical"
              label={ring.label}
              preview={{ emoji: ring.emoji, title: ring.label, subtitle: ring.desc }}
              onRemove={mirrorRings.length > 1 ? () => setRings(mirrorRings.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2 flex-wrap">
                <div className="w-24">
                  <label className={labelCls}>Radius (r)</label>
                  <Input type="number" value={ring.r} onChange={(e) => updateRing(i, { r: Number(e.target.value) || 0 })} />
                </div>
                <div className="flex-1 min-w-[140px]">
                  <label className={labelCls}>Label</label>
                  <Input value={ring.label} onChange={(e) => updateRing(i, { label: e.target.value })} />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={ring.emoji} onChange={(v) => updateRing(i, { emoji: v })} />
                </div>
              </div>
              <HslCssVarField value={ring.hslVar} onChange={(v) => updateRing(i, { hslVar: v })} label="hslVar" />
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={ring.desc} onChange={(e) => updateRing(i, { desc: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type PbelJourneyPhaseEdit = { name: string; lenses: string; emoji: string; color: string; insight: string };

function ThreeJourneyPhasesForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "Three Phases of the Journey";
  const defaultPhases: PbelJourneyPhaseEdit[] = [
    { name: "Context & Connection", lenses: "1–3", emoji: "🌍", color: "--deep-sea", insight: "Every journey begins with a connection to the world outside the classroom." },
    { name: "Empathy & Insight", lenses: "4–6", emoji: "💡", color: "--sunflower", insight: "We don't guess — we learn from users and apply core disciplines." },
    { name: "Action & Impact", lenses: "7–9", emoji: "⚡", color: "--valencia", insight: "Problem → Blueprint → Evidence → Influence." },
  ];
  const phases: PbelJourneyPhaseEdit[] = Array.isArray(content?.phases) && (content.phases as unknown[]).length > 0
    ? (content.phases as unknown[]).map((b) => {
        const x = b as PbelJourneyPhaseEdit;
        return { name: String(x?.name ?? ""), lenses: String(x?.lenses ?? ""), emoji: String(x?.emoji ?? "•"), color: String(x?.color ?? "--deep-sea"), insight: String(x?.insight ?? "") };
      })
    : defaultPhases;

  const setPhases = (next: PbelJourneyPhaseEdit[]) => onChange({ ...content, phases: next });
  const updatePhase = (index: number, patch: Partial<PbelJourneyPhaseEdit>) => {
    setPhases(phases.map((p, i) => (i === index ? { ...p, ...patch } : p)));
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} placeholder="Three Phases of the Journey" />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Phases"
          layout="grid-3"
          onAdd={() => setPhases([...phases, { name: "New phase", lenses: "", emoji: "•", color: "--deep-sea", insight: "" }])}
          addLabel="Add phase"
        >
          {phases.map((phase, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={phases.length}
              layout="grid-3"
              label={phase.name}
              preview={{ emoji: phase.emoji, title: phase.name, subtitle: phase.insight }}
              onRemove={phases.length > 1 ? () => setPhases(phases.filter((_, j) => j !== i)) : undefined}
            >
              <div>
                <label className={labelCls}>Name</label>
                <Input value={phase.name} onChange={(e) => updatePhase(i, { name: e.target.value })} />
              </div>
              <div className="flex gap-2">
                <div className="flex-1">
                  <label className={labelCls}>Lenses</label>
                  <Input value={phase.lenses} onChange={(e) => updatePhase(i, { lenses: e.target.value })} placeholder="1–3" />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={phase.emoji} onChange={(v) => updatePhase(i, { emoji: v })} />
                </div>
              </div>
              <HslCssVarField value={phase.color} onChange={(v) => updatePhase(i, { color: v })} />
              <div>
                <label className={labelCls}>Insight</label>
                <textarea value={phase.insight} onChange={(e) => updatePhase(i, { insight: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type MirrorCardEdit = { label: string; emoji: string; desc: string };

function CrossCuttingMirrorsForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "🪞 The Mirrors: Cross-Cutting Overlays";
  const subtitle = (content?.subtitle as string) ?? "Constraints and values present at every stage.";
  const defaultMirrors: MirrorCardEdit[] = [
    { label: "Student Voice & Choice", emoji: "🗣️", desc: "Learners co-design the inquiry, choose roles, and shape deliverables at every stage." },
    { label: "Service Learning Cycle", emoji: "🔁", desc: "IPARDE — Investigate, Prepare, Action, Reflect, Demonstrate, Evaluate — runs beneath every lens." },
    { label: "Safety, Ethics & Equity", emoji: "🛡️", desc: "Age-appropriate tools, consent protocols, equitable access, and ethical design thinking throughout." },
  ];
  const mirrors: MirrorCardEdit[] = Array.isArray(content?.mirrors) && (content.mirrors as unknown[]).length > 0
    ? (content.mirrors as unknown[]).map((b) => {
        const x = b as MirrorCardEdit;
        return { label: String(x?.label ?? ""), emoji: String(x?.emoji ?? "•"), desc: String(x?.desc ?? "") };
      })
    : defaultMirrors;

  const setMirrors = (next: MirrorCardEdit[]) => onChange({ ...content, mirrors: next });
  const updateMirror = (index: number, patch: Partial<MirrorCardEdit>) => {
    setMirrors(mirrors.map((m, i) => (i === index ? { ...m, ...patch } : m)));
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <Input value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Mirrors"
          layout="grid-3"
          onAdd={() => setMirrors([...mirrors, { label: "New mirror", emoji: "•", desc: "" }])}
          addLabel="Add mirror"
        >
          {mirrors.map((m, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={mirrors.length}
              layout="grid-3"
              label={m.label}
              preview={{ emoji: m.emoji, title: m.label, subtitle: m.desc }}
              onRemove={mirrors.length > 1 ? () => setMirrors(mirrors.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2">
                <div className="flex-1">
                  <label className={labelCls}>Label</label>
                  <Input value={m.label} onChange={(e) => updateMirror(i, { label: e.target.value })} />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={m.emoji} onChange={(v) => updateMirror(i, { emoji: v })} />
                </div>
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={m.desc} onChange={(e) => updateMirror(i, { desc: e.target.value })} rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type AnnualQuarterEdit = { term: string; cycle: string; weeks: string; title: string; focus: string; color: string; emoji: string };

function AnnualFlowQuartersForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "🗓️ Turning the Kaleidoscope: The Annual Flow";
  const defaultQuarters: AnnualQuarterEdit[] = [
    { term: "Quarter 1", cycle: "Cycle 1", weeks: "9 Weeks", title: "Discover & Define", focus: "Empathy, Investigation & Systems Mapping", color: "--deep-sea", emoji: "🔍" },
    { term: "Quarter 2", cycle: "Cycle 2", weeks: "9 Weeks", title: "Ideate & Prototype", focus: "HMW Questions, Concept Sprints & Low-Fi Builds", color: "--sunflower", emoji: "🔧" },
    { term: "Quarter 3", cycle: "Cycle 3", weeks: "9 Weeks", title: "Test & Iterate", focus: "User Testing, Data Collection & Revision Rounds", color: "--moss", emoji: "🔄" },
    { term: "Quarter 4", cycle: "Cycle 4", weeks: "9 Weeks", title: "Implement & Showcase", focus: "Partner Pilots, Impact Metrics & Innovation Exhibition", color: "--valencia", emoji: "🎤" },
  ];
  const quarters: AnnualQuarterEdit[] = Array.isArray(content?.quarters) && (content.quarters as unknown[]).length > 0
    ? (content.quarters as unknown[]).map((b) => {
        const x = b as AnnualQuarterEdit;
        return { term: String(x?.term ?? ""), cycle: String(x?.cycle ?? ""), weeks: String(x?.weeks ?? ""), title: String(x?.title ?? ""), focus: String(x?.focus ?? ""), color: String(x?.color ?? "--deep-sea"), emoji: String(x?.emoji ?? "•") };
      })
    : defaultQuarters;

  const setQuarters = (next: AnnualQuarterEdit[]) => onChange({ ...content, quarters: next });
  const updateQuarter = (index: number, patch: Partial<AnnualQuarterEdit>) => {
    setQuarters(quarters.map((q, i) => (i === index ? { ...q, ...patch } : q)));
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Quarters"
          layout="grid-2"
          onAdd={() => setQuarters([...quarters, { term: "Quarter", cycle: "Cycle", weeks: "9 Weeks", title: "New quarter", focus: "", color: "--deep-sea", emoji: "•" }])}
          addLabel="Add quarter"
        >
          {quarters.map((q, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={quarters.length}
              layout="grid-2"
              label={q.title}
              preview={{ emoji: q.emoji, title: `${q.term} — ${q.title}`, subtitle: q.focus }}
              onRemove={quarters.length > 1 ? () => setQuarters(quarters.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2 flex-wrap">
                <div className="flex-1 min-w-[100px]">
                  <label className={labelCls}>Term</label>
                  <Input value={q.term} onChange={(e) => updateQuarter(i, { term: e.target.value })} />
                </div>
                <div className="flex-1 min-w-[100px]">
                  <label className={labelCls}>Cycle</label>
                  <Input value={q.cycle} onChange={(e) => updateQuarter(i, { cycle: e.target.value })} />
                </div>
                <div className="w-24">
                  <label className={labelCls}>Weeks</label>
                  <Input value={q.weeks} onChange={(e) => updateQuarter(i, { weeks: e.target.value })} />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={q.emoji} onChange={(v) => updateQuarter(i, { emoji: v })} />
                </div>
              </div>
              <div>
                <label className={labelCls}>Title</label>
                <Input value={q.title} onChange={(e) => updateQuarter(i, { title: e.target.value })} />
              </div>
              <div>
                <label className={labelCls}>Focus</label>
                <Input value={q.focus} onChange={(e) => updateQuarter(i, { focus: e.target.value })} />
              </div>
              <HslCssVarField value={q.color} onChange={(v) => updateQuarter(i, { color: v })} />
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type MicroStepEdit = { label: string; emoji: string; fill: string; ring: string; desc: string };
type MacroIterationEdit = { quarter: string; label: string; desc: string };

function DivergeConvergeVizForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const microLabel = (content?.microLabel as string) ?? "Micro cycle";
  const macroLabel = (content?.macroLabel as string) ?? "Macro cycle";
  const defaultMicro: MicroStepEdit[] = [
    { label: "Understand", emoji: "💛", fill: "hsl(195, 80%, 82%)", ring: "hsl(62, 90%, 55%)", desc: "Understand users deeply through interviews, observation, and immersion." },
    { label: "Observe", emoji: "👁️", fill: "hsl(350, 70%, 76%)", ring: "hsl(62, 90%, 55%)", desc: "Collect baseline data, notice patterns, and document what's really happening." },
    { label: "Define Point\nof View", emoji: "🎯", fill: "hsl(72, 45%, 62%)", ring: "hsl(62, 90%, 55%)", desc: "Synthesize insights into a clear Point of View." },
    { label: "Ideate", emoji: "💡", fill: "hsl(30, 80%, 78%)", ring: "hsl(62, 90%, 55%)", desc: "Diverge wide — brainstorm without judgment." },
    { label: "Prototype", emoji: "🔧", fill: "hsl(15, 85%, 66%)", ring: "hsl(62, 90%, 55%)", desc: "Build quick, low-fidelity models." },
    { label: "Test", emoji: "🧪", fill: "hsl(330, 80%, 62%)", ring: "hsl(62, 90%, 55%)", desc: "Put prototypes in front of real users." },
  ];
  const defaultMacro: MacroIterationEdit[] = [
    { quarter: "Q1", label: "Discover & Define", desc: "Wide exploration — students diverge into empathy research." },
    { quarter: "Q2", label: "Ideate & Prototype", desc: "Maximum divergence in ideation, then converging toward prototypes." },
    { quarter: "Q3", label: "Test & Iterate", desc: "Convergence accelerates — data from user testing narrows solutions." },
    { quarter: "Q4", label: "Implement & Showcase", desc: "Strong convergence — refined solutions implemented with partners." },
  ];
  const microSteps: MicroStepEdit[] = Array.isArray(content?.microSteps) && (content.microSteps as unknown[]).length > 0
    ? (content.microSteps as unknown[]).map((b) => {
        const x = b as MicroStepEdit;
        return { label: String(x?.label ?? ""), emoji: String(x?.emoji ?? "•"), fill: String(x?.fill ?? ""), ring: String(x?.ring ?? ""), desc: String(x?.desc ?? "") };
      })
    : defaultMicro;
  const macroIterations: MacroIterationEdit[] = Array.isArray(content?.macroIterations) && (content.macroIterations as unknown[]).length > 0
    ? (content.macroIterations as unknown[]).map((b) => {
        const x = b as MacroIterationEdit;
        return { quarter: String(x?.quarter ?? ""), label: String(x?.label ?? ""), desc: String(x?.desc ?? "") };
      })
    : defaultMacro;

  const divergeTitle = (content?.divergeTitle as string) ?? "Divergent Thinking";
  const divergeSubtitle = (content?.divergeSubtitle as string) ?? "Expand possibilities";
  const divergeBody = (content?.divergeBody as string) ?? "Focused on generating a wide range of ideas, possibilities, and solutions.";
  const divergeItems = Array.isArray(content?.divergeItems) ? (content.divergeItems as string[]).filter((s) => typeof s === "string") : ["Generate as many ideas as possible", "Explore unconventional solutions", "No judgment — quantity over quality", "Sparks new connections & surprises"];
  const divergeEmoji = (content?.divergeEmoji as string) ?? "💡";
  const convergeTitle = (content?.convergeTitle as string) ?? "Convergent Thinking";
  const convergeSubtitle = (content?.convergeSubtitle as string) ?? "Narrow to the best";
  const convergeBody = (content?.convergeBody as string) ?? "Focused on finding the best solution from a range of options.";
  const convergeItems = Array.isArray(content?.convergeItems) ? (content.convergeItems as string[]).filter((s) => typeof s === "string") : ["Evaluate & select the best ideas", "Narrow down to practical solutions", "Logical, focused, evidence-based", "Leads to clear, actionable outcomes"];
  const convergeEmoji = (content?.convergeEmoji as string) ?? "🎯";
  const insightLead = (content?.insightLead as string) ?? "The magic is in the rhythm.";
  const insightBody = (content?.insightBody as string) ?? "Students diverge wide to explore possibilities, then converge to select the best path forward.";
  const axisConverge = (content?.axisConverge as string) ?? "CONVERGE";
  const axisDiverge = (content?.axisDiverge as string) ?? "DIVERGE";
  const axisProblem = (content?.axisProblem as string) ?? "PROBLEM";
  const axisTime = (content?.axisTime as string) ?? "TIME";

  const setMicro = (next: MicroStepEdit[]) => onChange({ ...content, microSteps: next });
  const setMacro = (next: MacroIterationEdit[]) => onChange({ ...content, macroIterations: next });
  const updateMicro = (index: number, patch: Partial<MicroStepEdit>) => {
    setMicro(microSteps.map((s, i) => (i === index ? { ...s, ...patch } : s)));
  };
  const updateMacro = (index: number, patch: Partial<MacroIterationEdit>) => {
    setMacro(macroIterations.map((s, i) => (i === index ? { ...s, ...patch } : s)));
  };

  return (
    <>
      <div className={formRow}>
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className={labelCls}>Micro label</label>
            <Input value={microLabel} onChange={(e) => onChange({ ...content, microLabel: e.target.value })} />
          </div>
          <div>
            <label className={labelCls}>Macro label</label>
            <Input value={macroLabel} onChange={(e) => onChange({ ...content, macroLabel: e.target.value })} />
          </div>
        </div>
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Micro steps"
          layout="vertical"
          onAdd={() => setMicro([...microSteps, { label: "New step", emoji: "•", fill: "hsl(200, 70%, 70%)", ring: "hsl(62, 90%, 55%)", desc: "" }])}
          addLabel="Add micro step"
          hint="Collapsible list of micro-cycle steps (fill/ring are CSS colors)."
        >
          {microSteps.map((s, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={microSteps.length}
              layout="vertical"
              label={s.label}
              preview={{ emoji: s.emoji, title: s.label, subtitle: s.desc }}
              onRemove={microSteps.length > 1 ? () => setMicro(microSteps.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2 flex-wrap">
                <div className="flex-1 min-w-[120px]">
                  <label className={labelCls}>Label</label>
                  <Input value={s.label} onChange={(e) => updateMicro(i, { label: e.target.value })} />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={s.emoji} onChange={(v) => updateMicro(i, { emoji: v })} />
                </div>
              </div>
              <div className="grid grid-cols-2 gap-2">
                <div>
                  <label className={labelCls}>Fill</label>
                  <Input value={s.fill} onChange={(e) => updateMicro(i, { fill: e.target.value })} placeholder="hsl(...)" className="font-mono text-sm" />
                </div>
                <div>
                  <label className={labelCls}>Ring</label>
                  <Input value={s.ring} onChange={(e) => updateMicro(i, { ring: e.target.value })} placeholder="hsl(...)" className="font-mono text-sm" />
                </div>
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={s.desc} onChange={(e) => updateMicro(i, { desc: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Macro iterations"
          layout="grid-2"
          onAdd={() => setMacro([...macroIterations, { quarter: "Q?", label: "New iteration", desc: "" }])}
          addLabel="Add iteration"
        >
          {macroIterations.map((m, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={macroIterations.length}
              layout="grid-2"
              label={m.label}
              preview={{ title: `${m.quarter} — ${m.label}`, subtitle: m.desc }}
              onRemove={macroIterations.length > 1 ? () => setMacro(macroIterations.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2">
                <div className="w-20">
                  <label className={labelCls}>Quarter</label>
                  <Input value={m.quarter} onChange={(e) => updateMacro(i, { quarter: e.target.value })} />
                </div>
                <div className="flex-1">
                  <label className={labelCls}>Label</label>
                  <Input value={m.label} onChange={(e) => updateMacro(i, { label: e.target.value })} />
                </div>
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={m.desc} onChange={(e) => updateMacro(i, { desc: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
      <div className={formRow}>
        <CardEditGroup label="Diverge panel" layout="horizontal">
          <CardEditPanel index={0} total={2} layout="horizontal" label={divergeTitle} preview={{ emoji: divergeEmoji, title: divergeTitle, subtitle: divergeSubtitle }} accent="left">
            <div className="flex gap-2">
              <div className="flex-1">
                <label className={labelCls}>Title</label>
                <Input value={divergeTitle} onChange={(e) => onChange({ ...content, divergeTitle: e.target.value })} />
              </div>
              <div>
                <label className={labelCls}>Emoji</label>
                <EmojiPickerField compact value={divergeEmoji} onChange={(v) => onChange({ ...content, divergeEmoji: v })} />
              </div>
            </div>
            <div>
              <label className={labelCls}>Subtitle</label>
              <Input value={divergeSubtitle} onChange={(e) => onChange({ ...content, divergeSubtitle: e.target.value })} />
            </div>
            <div>
              <label className={labelCls}>Body</label>
              <textarea value={divergeBody} onChange={(e) => onChange({ ...content, divergeBody: e.target.value })} rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
            </div>
            <div>
              <label className={labelCls}>Items (one per line)</label>
              <textarea value={divergeItems.join("\n")} onChange={(e) => onChange({ ...content, divergeItems: linesToList(e.target.value) })} rows={4} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[70px]" />
            </div>
          </CardEditPanel>
          <CardEditPanel index={1} total={2} layout="horizontal" label={convergeTitle} preview={{ emoji: convergeEmoji, title: convergeTitle, subtitle: convergeSubtitle }} accent="right">
            <div className="flex gap-2">
              <div className="flex-1">
                <label className={labelCls}>Title</label>
                <Input value={convergeTitle} onChange={(e) => onChange({ ...content, convergeTitle: e.target.value })} />
              </div>
              <div>
                <label className={labelCls}>Emoji</label>
                <EmojiPickerField compact value={convergeEmoji} onChange={(v) => onChange({ ...content, convergeEmoji: v })} />
              </div>
            </div>
            <div>
              <label className={labelCls}>Subtitle</label>
              <Input value={convergeSubtitle} onChange={(e) => onChange({ ...content, convergeSubtitle: e.target.value })} />
            </div>
            <div>
              <label className={labelCls}>Body</label>
              <textarea value={convergeBody} onChange={(e) => onChange({ ...content, convergeBody: e.target.value })} rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
            </div>
            <div>
              <label className={labelCls}>Items (one per line)</label>
              <textarea value={convergeItems.join("\n")} onChange={(e) => onChange({ ...content, convergeItems: linesToList(e.target.value) })} rows={4} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[70px]" />
            </div>
          </CardEditPanel>
        </CardEditGroup>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Insight lead</label>
        <Input value={insightLead} onChange={(e) => onChange({ ...content, insightLead: e.target.value })} />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Insight body</label>
        <textarea value={insightBody} onChange={(e) => onChange({ ...content, insightBody: e.target.value })} rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Axis labels</label>
        <div className="grid grid-cols-2 gap-2">
          <Input value={axisConverge} onChange={(e) => onChange({ ...content, axisConverge: e.target.value })} placeholder="CONVERGE" />
          <Input value={axisDiverge} onChange={(e) => onChange({ ...content, axisDiverge: e.target.value })} placeholder="DIVERGE" />
          <Input value={axisProblem} onChange={(e) => onChange({ ...content, axisProblem: e.target.value })} placeholder="PROBLEM" />
          <Input value={axisTime} onChange={(e) => onChange({ ...content, axisTime: e.target.value })} placeholder="TIME" />
        </div>
      </div>
    </>
  );
}

type SquadRoleEdit = { role: string; emoji: string; desc: string };

function SquadRolesForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "👥 The Squads: Teaming & Roles";
  const subtitle = (content?.subtitle as string) ?? "Roles rotate each microcycle to ensure balanced growth.";
  const defaultRoles: SquadRoleEdit[] = [
    { role: "Team Lead", emoji: "👑", desc: "Facilitates sprints and keeps the squad on track" },
    { role: "Storyteller", emoji: "📝", desc: "Documents journey maps, writes narratives for exhibition" },
    { role: "Community Liaison", emoji: "🤝", desc: "Manages partner relationships and empathy interviews" },
    { role: "Prototype Engineer", emoji: "🔧", desc: "Leads builds, CAD, code, and physical prototypes" },
    { role: "Data Analyst", emoji: "📊", desc: "Tracks baselines, collects metrics, builds evidence" },
  ];
  const roles: SquadRoleEdit[] = Array.isArray(content?.roles) && (content.roles as unknown[]).length > 0
    ? (content.roles as unknown[]).map((b) => {
        const x = b as SquadRoleEdit;
        return { role: String(x?.role ?? ""), emoji: String(x?.emoji ?? "•"), desc: String(x?.desc ?? "") };
      })
    : defaultRoles;

  const setRoles = (next: SquadRoleEdit[]) => onChange({ ...content, roles: next });
  const updateRole = (index: number, patch: Partial<SquadRoleEdit>) => {
    setRoles(roles.map((r, i) => (i === index ? { ...r, ...patch } : r)));
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <Input value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Roles"
          layout="grid-3"
          onAdd={() => setRoles([...roles, { role: "New role", emoji: "•", desc: "" }])}
          addLabel="Add role"
        >
          {roles.map((r, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={roles.length}
              layout="grid-3"
              label={r.role}
              preview={{ emoji: r.emoji, title: r.role, subtitle: r.desc }}
              onRemove={roles.length > 1 ? () => setRoles(roles.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2">
                <div className="flex-1">
                  <label className={labelCls}>Role</label>
                  <Input value={r.role} onChange={(e) => updateRole(i, { role: e.target.value })} />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={r.emoji} onChange={(v) => updateRole(i, { emoji: v })} />
                </div>
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={r.desc} onChange={(e) => updateRole(i, { desc: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type GradeBandEntEdit = { band: string; color: string; label: string; items: string[] };

function GradeBandEntrepreneurshipForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "🎓 Disciplined Entrepreneurship by Grade Band";
  const defaultBands: GradeBandEntEdit[] = [
    { band: "K–2", color: "--salmon", label: "Discovery", items: ["User needs & simple cost/benefit", "Empathy interviews with picture prompts", "Hands-on prototypes with recycled materials"] },
    { band: "3–5", color: "--moss", label: "Problem Framing", items: ["Value proposition & 'How many people?'", "Data collection with tally charts", "Adopt-a-Drain, rain barrels, garden projects"] },
    { band: "6–8", color: "--sunflower", label: "Solution Concept", items: ["MVP & hypothesis testing", "Sensor-based data & simple coding", "Iteration logs with before/after metrics"] },
    { band: "9–12", color: "--deep-sea", label: "Venture", items: ["Market segmentation & legal/ethical lens", "Smart meter prototypes & ROI analysis", "Partner pilots and scale-up plans"] },
  ];
  const gradeBands: GradeBandEntEdit[] = Array.isArray(content?.gradeBands) && (content.gradeBands as unknown[]).length > 0
    ? (content.gradeBands as unknown[]).map((b) => {
        const x = b as GradeBandEntEdit;
        return { band: String(x?.band ?? ""), color: String(x?.color ?? "--deep-sea"), label: String(x?.label ?? ""), items: Array.isArray(x?.items) ? x.items.filter((i): i is string => typeof i === "string") : [] };
      })
    : defaultBands;

  const setBands = (next: GradeBandEntEdit[]) => onChange({ ...content, gradeBands: next });
  const updateBand = (index: number, patch: Partial<GradeBandEntEdit>) => {
    setBands(gradeBands.map((b, i) => (i === index ? { ...b, ...patch } : b)));
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Grade bands"
          layout="grid-2"
          onAdd={() => setBands([...gradeBands, { band: "New", color: "--deep-sea", label: "", items: [] }])}
          addLabel="Add band"
        >
          {gradeBands.map((b, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={gradeBands.length}
              layout="grid-2"
              label={b.band}
              preview={{ title: `${b.band} — ${b.label}`, subtitle: (b.items ?? [])[0] }}
              onRemove={gradeBands.length > 1 ? () => setBands(gradeBands.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2">
                <div className="w-24">
                  <label className={labelCls}>Band</label>
                  <Input value={b.band} onChange={(e) => updateBand(i, { band: e.target.value })} />
                </div>
                <div className="flex-1">
                  <label className={labelCls}>Label</label>
                  <Input value={b.label} onChange={(e) => updateBand(i, { label: e.target.value })} />
                </div>
              </div>
              <HslCssVarField value={b.color} onChange={(v) => updateBand(i, { color: v })} />
              <div>
                <label className={labelCls}>Items (one per line)</label>
                <textarea value={(b.items ?? []).join("\n")} onChange={(e) => updateBand(i, { items: linesToList(e.target.value) })} rows={4} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[70px]" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type DeliverableEdit = { emoji: string; title: string; desc: string };

function DeliverablesEvidenceForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "📦 Deliverables & Evidence of Impact";
  const defaultDeliverables: DeliverableEdit[] = [
    { emoji: "💛", title: "Empathy Packets", desc: "Journey maps, interview syntheses, and user personas" },
    { emoji: "🔧", title: "Prototype Artifacts", desc: "CAD models, code, physical builds, and iteration logs" },
    { emoji: "📊", title: "Impact Snapshot", desc: "Baseline vs. After — liters saved, leaks fixed, policies changed" },
    { emoji: "📖", title: "PDI Story", desc: "Problem → Blueprint → Evidence → Influence narrative" },
    { emoji: "🎤", title: "Exhibition Deck", desc: "Presentation for the Innovation & Impact Showcase" },
    { emoji: "📋", title: "Handoff Plan", desc: "Maintenance and sustainability plan for community partners" },
  ];
  const deliverables: DeliverableEdit[] = Array.isArray(content?.deliverables) && (content.deliverables as unknown[]).length > 0
    ? (content.deliverables as unknown[]).map((b) => {
        const x = b as DeliverableEdit;
        return { emoji: String(x?.emoji ?? "•"), title: String(x?.title ?? ""), desc: String(x?.desc ?? "") };
      })
    : defaultDeliverables;

  const setDeliverables = (next: DeliverableEdit[]) => onChange({ ...content, deliverables: next });
  const updateItem = (index: number, patch: Partial<DeliverableEdit>) => {
    setDeliverables(deliverables.map((d, i) => (i === index ? { ...d, ...patch } : d)));
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Deliverables"
          layout="grid-3"
          onAdd={() => setDeliverables([...deliverables, { emoji: "•", title: "New deliverable", desc: "" }])}
          addLabel="Add deliverable"
        >
          {deliverables.map((d, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={deliverables.length}
              layout="grid-3"
              label={d.title}
              preview={{ emoji: d.emoji, title: d.title, subtitle: d.desc }}
              onRemove={deliverables.length > 1 ? () => setDeliverables(deliverables.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2">
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={d.emoji} onChange={(v) => updateItem(i, { emoji: v })} />
                </div>
                <div className="flex-1">
                  <label className={labelCls}>Title</label>
                  <Input value={d.title} onChange={(e) => updateItem(i, { title: e.target.value })} />
                </div>
              </div>
              <div>
                <label className={labelCls}>Description</label>
                <textarea value={d.desc} onChange={(e) => updateItem(i, { desc: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type ClubCardEdit = { name: string; purpose: string };

const clubIconColorOptions: { value: string; label: string }[] = [
  { value: "deep-sea", label: "Deep Sea" },
  { value: "valencia", label: "Valencia" },
  { value: "salmon", label: "Salmon" },
  { value: "sunflower", label: "Sunflower" },
  { value: "moss", label: "Moss" },
  { value: "mist", label: "Mist" },
];

function ClubCategoryGridForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const emoji = (content?.emoji as string) ?? "✍️";
  const iconColor = (content?.iconColor as string) ?? "deep-sea";
  const title = (content?.title as string) ?? "Writing & Literature";
  const showCount = content?.showCount !== false;
  const countSuffix = (content?.countSuffix as string) ?? "clubs";
  const defaultCards: ClubCardEdit[] = [
    { name: "Writers' Guild", purpose: "Cultivate creative expression and critical thinking through writing." },
    { name: "The Book Voyagers", purpose: "Foster a love of reading and broaden cultural understanding." },
    { name: "The Quill (SPARKS Magazine)", purpose: "Provide a platform for student voices and foster journalistic skills." },
    { name: "School Newspaper Club", purpose: "Promote responsible journalism and a well-informed school community." },
    { name: "Foreign Languages Club", purpose: "Expose students to different cultures and enhance multilingual communication." },
  ];
  const cards: ClubCardEdit[] = Array.isArray(content?.cards) && (content.cards as unknown[]).length > 0
    ? (content.cards as unknown[]).map((b) => {
        const x = b as ClubCardEdit;
        return { name: String(x?.name ?? ""), purpose: String(x?.purpose ?? "") };
      })
    : defaultCards;

  const setCards = (next: ClubCardEdit[]) => onChange({ ...content, cards: next });
  const updateItem = (index: number, patch: Partial<ClubCardEdit>) => {
    setCards(cards.map((c, i) => (i === index ? { ...c, ...patch } : c)));
  };
  const moveItem = (index: number, direction: -1 | 1) => {
    const target = index + direction;
    if (target < 0 || target >= cards.length) return;
    const next = [...cards];
    [next[index], next[target]] = [next[target], next[index]];
    setCards(next);
  };
  const insertAfter = (index: number) => {
    setCards([...cards.slice(0, index + 1), { name: "New club", purpose: "" }, ...cards.slice(index + 1)]);
  };

  return (
    <>
      <div className={formRow}>
        <div className="flex gap-2">
          <div>
            <label className={labelCls}>Icon</label>
            <EmojiPickerField compact value={emoji} onChange={(v) => onChange({ ...content, emoji: v })} />
          </div>
          <div className="flex-1">
            <label className={labelCls}>Section title</label>
            <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} />
          </div>
        </div>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Icon color</label>
        <select
          value={iconColor}
          onChange={(e) => onChange({ ...content, iconColor: e.target.value })}
          className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
        >
          {clubIconColorOptions.map((o) => (
            <option key={o.value} value={o.value}>{o.label}</option>
          ))}
        </select>
      </div>
      <div className={formRow}>
        <label className="flex items-center gap-2 text-sm font-medium text-slate-700">
          <input
            type="checkbox"
            checked={showCount}
            onChange={(e) => onChange({ ...content, showCount: e.target.checked })}
          />
          Show count badge
        </label>
      </div>
      {showCount ? (
        <div className={formRow}>
          <label className={labelCls}>Count badge label (after the number)</label>
          <Input value={countSuffix} onChange={(e) => onChange({ ...content, countSuffix: e.target.value })} />
        </div>
      ) : null}
      <div className={formRow}>
        <CardEditGroup
          label="Cards"
          layout="grid-3"
          onAdd={() => setCards([...cards, { name: "New club", purpose: "" }])}
          addLabel="Add card"
        >
          {cards.map((c, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={cards.length}
              layout="grid-3"
              label={c.name}
              preview={{ title: c.name, subtitle: c.purpose }}
              onMoveUp={i > 0 ? () => moveItem(i, -1) : undefined}
              onMoveDown={i < cards.length - 1 ? () => moveItem(i, 1) : undefined}
              onInsertAfter={() => insertAfter(i)}
              onRemove={cards.length > 1 ? () => setCards(cards.filter((_, j) => j !== i)) : undefined}
            >
              <div>
                <label className={labelCls}>Card title</label>
                <Input value={c.name} onChange={(e) => updateItem(i, { name: e.target.value })} />
              </div>
              <div>
                <label className={labelCls}>Card description</label>
                <textarea value={c.purpose} onChange={(e) => updateItem(i, { purpose: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
    </>
  );
}

type SummitDayEdit = { day: string; title: string; emoji: string; color: string; items: string[] };

function DesignImpactSummitForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const eyebrow = (content?.eyebrow as string) ?? "Year-End Celebration";
  const title = (content?.title as string) ?? "🏆 Design to Impact Summit";
  const subtitle = (content?.subtitle as string) ?? "A 3-day culminating event where students showcase their year-long journey from problem to impact.";
  const inviteTitle = (content?.inviteTitle as string) ?? "Who's at the Summit?";
  const defaultDays: SummitDayEdit[] = [
    { day: "Day 1", title: "Grades 9–12", emoji: "🎓", color: "--deep-sea", items: ["Venture-level presentations & partner pilots", "ROI analysis and scale-up pitches", "Industry mentor Q&A panels", "Portfolio defense & reflection"] },
    { day: "Day 2", title: "Grades 6–8", emoji: "🔬", color: "--valencia", items: ["Solution concept demos & prototype showcases", "Data-driven impact presentations", "Interactive demo stations for visitors", "Student-led panel discussions"] },
    { day: "Day 3", title: "Grades K–5", emoji: "🌱", color: "--sunflower", items: ["Discovery & problem framing exhibitions", "Hands-on prototype showcase stations", "Family celebration & gratitude walls", "Impact awards & next-year vision casting"] },
  ];
  const days: SummitDayEdit[] = Array.isArray(content?.days) && (content.days as unknown[]).length > 0
    ? (content.days as unknown[]).map((b) => {
        const x = b as SummitDayEdit;
        return { day: String(x?.day ?? ""), title: String(x?.title ?? ""), emoji: String(x?.emoji ?? "•"), color: String(x?.color ?? "--deep-sea"), items: Array.isArray(x?.items) ? x.items.filter((i): i is string => typeof i === "string") : [] };
      })
    : defaultDays;
  const invitees = Array.isArray(content?.invitees)
    ? (content.invitees as unknown[]).map((p) => (typeof p === "string" ? p : String((p as { label?: string })?.label ?? ""))).filter(Boolean)
    : ["Students & Families", "Community Partners", "Industry Mentors", "School Leadership", "Local Government", "Fellow Schools"];

  const setDays = (next: SummitDayEdit[]) => onChange({ ...content, days: next });
  const updateDay = (index: number, patch: Partial<SummitDayEdit>) => {
    setDays(days.map((d, i) => (i === index ? { ...d, ...patch } : d)));
  };

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Eyebrow</label>
        <Input value={eyebrow} onChange={(e) => onChange({ ...content, eyebrow: e.target.value })} />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Subtitle</label>
        <textarea value={subtitle} onChange={(e) => onChange({ ...content, subtitle: e.target.value })} rows={2} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Invite title</label>
        <Input value={inviteTitle} onChange={(e) => onChange({ ...content, inviteTitle: e.target.value })} />
      </div>
      <div className={formRow}>
        <CardEditGroup
          label="Days"
          layout="grid-3"
          onAdd={() => setDays([...days, { day: "Day", title: "New day", emoji: "•", color: "--deep-sea", items: [] }])}
          addLabel="Add day"
        >
          {days.map((d, i) => (
            <CardEditPanel
              key={i}
              index={i}
              total={days.length}
              layout="grid-3"
              label={d.day}
              preview={{ emoji: d.emoji, title: `${d.day} — ${d.title}`, subtitle: (d.items ?? [])[0] }}
              onRemove={days.length > 1 ? () => setDays(days.filter((_, j) => j !== i)) : undefined}
            >
              <div className="flex gap-2 flex-wrap">
                <div className="w-24">
                  <label className={labelCls}>Day</label>
                  <Input value={d.day} onChange={(e) => updateDay(i, { day: e.target.value })} />
                </div>
                <div className="flex-1 min-w-[100px]">
                  <label className={labelCls}>Title</label>
                  <Input value={d.title} onChange={(e) => updateDay(i, { title: e.target.value })} />
                </div>
                <div>
                  <label className={labelCls}>Emoji</label>
                  <EmojiPickerField compact value={d.emoji} onChange={(v) => updateDay(i, { emoji: v })} />
                </div>
              </div>
              <HslCssVarField value={d.color} onChange={(v) => updateDay(i, { color: v })} />
              <div>
                <label className={labelCls}>Items (one per line)</label>
                <textarea value={(d.items ?? []).join("\n")} onChange={(e) => updateDay(i, { items: linesToList(e.target.value) })} rows={4} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[70px]" />
              </div>
            </CardEditPanel>
          ))}
        </CardEditGroup>
      </div>
      <div className={formRow}>
        <label className={labelCls}>Invitees (one per line)</label>
        <textarea
          value={invitees.join("\n")}
          onChange={(e) => onChange({ ...content, invitees: linesToList(e.target.value) })}
          rows={5}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[80px]"
          placeholder="Students & Families"
        />
      </div>
    </>
  );
}

function ClosingVisionForm({ content, onChange }: { content: BlockContent; onChange: (c: BlockContent) => void }) {
  const title = (content?.title as string) ?? "Where Learning Meets Legacy";
  const body = (content?.body as string) ?? "Sparking the mindset: Acceptance, Belonging, Big Dreams.";
  const target = (content?.target as string) ?? "Target: Resilient Problem Solvers & Caring Citizens.";
  const traits = Array.isArray(content?.traits)
    ? (content.traits as unknown[]).map((p) => (typeof p === "string" ? p : String((p as { label?: string })?.label ?? ""))).filter(Boolean)
    : ["Resilient Problem Solver", "Caring Citizen", "Respectful Relationship Builder", "Inspiring Communicator", "Bold Visionary Leader", "Balanced Person"];

  return (
    <>
      <div className={formRow}>
        <label className={labelCls}>Title</label>
        <Input value={title} onChange={(e) => onChange({ ...content, title: e.target.value })} />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Body</label>
        <textarea value={body} onChange={(e) => onChange({ ...content, body: e.target.value })} rows={3} className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm" />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Target</label>
        <Input value={target} onChange={(e) => onChange({ ...content, target: e.target.value })} />
      </div>
      <div className={formRow}>
        <label className={labelCls}>Traits (one per line)</label>
        <textarea
          value={traits.join("\n")}
          onChange={(e) => onChange({ ...content, traits: linesToList(e.target.value) })}
          rows={6}
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]"
          placeholder="Resilient Problem Solver"
        />
      </div>
    </>
  );
}

export function BlockEditForm({
  componentName,
  blockSlug: blockSlugProp,
  initialContent,
  libraryContent,
  placeholderVars = {},
  siteChromeKey = "default-default",
  showGlobalFooter = true,
  onSave,
  onClose,
  onError,
  onEnsurePageComponent,
  onApplyAndOpenBlock,
}: {
  componentName: string;
  /** When provided (e.g. from component lookup after copy/paste), used to select the form instead of resolving from componentName. */
  blockSlug?: string;
  initialContent: BlockContent;
  /** Latest component library template merged under page overrides for display/preview. */
  libraryContent?: Record<string, unknown>;
  placeholderVars?: ContentPlaceholderVars;
  siteChromeKey?: string;
  showGlobalFooter?: boolean;
  onSave: (content: BlockContent) => void;
  onClose: () => void;
  onError: (message: string) => void;
  onEnsurePageComponent?: (target: EnsurePageComponentTarget) => EnsurePageComponentResult | null;
  onApplyAndOpenBlock?: (
    nextContent: BlockContent,
    location: { sectionIndex: number; blockIndex: number },
  ) => void;
}) {
  const slug = blockSlugProp ?? getSlug(componentName.trim());

  const initializeContent = (base: BlockContent): BlockContent => {
    const merged = prepareBlockContentForEditor(base, libraryContent, slug) as BlockContent;
    if ((slug === "grade-family-guides" || slug === "grade-family-guides-api") && (!Array.isArray(merged.items) || merged.items.length === 0)) {
      merged.items = defaultGrades.map((g) => ({ id: g.id, label: g.label, shortLabel: g.shortLabel, route: g.route, available: g.available }));
    }
    if (slug === "grade-family-guides-api") {
      if (typeof merged.apiPath !== "string" && typeof merged.apiUrl === "string" && merged.apiUrl.trim()) {
        merged.apiPath = merged.apiUrl.trim();
      }
      if (typeof merged.apiPath !== "string") merged.apiPath = "";
      if (typeof merged.apiMethod !== "string") merged.apiMethod = "GET";
      if (typeof merged.apiHeadersJson !== "string") merged.apiHeadersJson = "";
      if (typeof merged.apiBodyJson !== "string") merged.apiBodyJson = "";
      merged.filters = normalizeApiQueryFilters(merged.filters);
    }
    if (slug === "course-hero") {
      return normalizeCourseHeroContent(merged, placeholderVars) as BlockContent;
    }
    if (slug === "grade-hero" || slug === "design-to-impact-hero") {
      return normalizeGradeHeroContent(merged) as BlockContent;
    }
    if (
      slug === "how-each-course-sees" ||
      slug === "quarter-courses" ||
      slug === "quarter-learning-tabs" ||
      slug === "quarter-courses-and-learning"
    ) {
      return normalizeHowEachCourseSeesContent(merged) as BlockContent;
    }
    return merged;
  };

  const [content, setContent] = useState<BlockContent>(() => initializeContent({ ...initialContent }));

  const previewContent = useMemo(
    () =>
      resolveEditorBlockContent(content, {
        blockSlug: slug,
        libraryContent,
        pageVars: placeholderVars,
      }),
    [content, libraryContent, placeholderVars, slug]
  );

  const PreviewBlock = getBlockComponent(slug);

  const handleSave = () => {
    const errors = validateRequiredContent(content);
    if (errors.length > 0) {
      onError(errors[0]);
      return;
    }
    let payload = JSON.parse(JSON.stringify(content)) as BlockContent;
    if (slug === "hero") {
      payload = normalizeHeroContent(payload) as BlockContent;
    }
    if (slug === "course-core-skills") {
      payload = normalizeCourseCoreSkillsContent(payload) as BlockContent;
    }
    if (slug === "grade-hero" || slug === "design-to-impact-hero") {
      payload = normalizeGradeHeroContent(payload) as BlockContent;
    }
    if (slug === "course-hero") {
      payload = normalizeCourseHeroContent(payload, placeholderVars) as BlockContent;
    }
    if (
      slug === "how-each-course-sees" ||
      slug === "quarter-courses" ||
      slug === "quarter-learning-tabs" ||
      slug === "quarter-courses-and-learning"
    ) {
      payload = normalizeHowEachCourseSeesContent(payload) as BlockContent;
    }
    // Pass a deep clone so the parent gets a new reference and preview updates reliably
    onSave(payload);
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-6">
      <div className={`bg-white rounded-2xl shadow-xl ${slug === "parent-course-overview" || slug === "hero" || slug === "grade-hero" || slug === "design-to-impact-hero" || slug === "how-each-course-sees" || slug === "quarter-courses-and-learning" || slug === "quarter-courses" || slug === "quarter-learning-tabs" || slug === "competition-tabs" ? "max-w-5xl" : "max-w-3xl"} w-full max-h-[90vh] overflow-hidden flex flex-col`}>
        <div className="flex items-center justify-between px-6 py-4 border-b border-slate-200">
          <h2 className="text-lg font-semibold text-slate-900">Edit — {componentName}</h2>
          <button type="button" onClick={onClose} className="p-2 text-slate-500 hover:text-slate-700 rounded-lg hover:bg-slate-100">
            <X size={20} />
          </button>
        </div>
        <div className="px-6 py-4 overflow-y-auto flex-1">
          <p className="text-[11px] text-slate-500 mb-4 rounded-lg bg-slate-50 border border-slate-200 px-3 py-2">
            {CONTENT_PLACEHOLDER_HINT}
          </p>
          {slug === "hero" && <HeroContentForm content={content} onChange={setContent} />}
          {slug === "footer" && <FooterForm content={content} onChange={setContent} />}
          {slug === "pbel-guide-footer" && <PbelGuideFooterForm content={content} onChange={setContent} />}
          {slug === "dimension-detail" && <DimensionDetailForm content={content} onChange={setContent} />}
          {(slug === "grade-hero" || slug === "design-to-impact-hero") && (
            <GradeHeroForm
              content={content}
              onChange={setContent}
              onEnsurePageComponent={onEnsurePageComponent}
              onApplyAndOpenBlock={onApplyAndOpenBlock}
            />
          )}
          {slug === "grade-kaleidoscope" && <KaleidoscopeForm content={content} onChange={setContent} />}
          {slug === "curriculum-hero" && <CurriculumHeroForm content={content} onChange={setContent} />}
          {slug === "essential-question" && <EssentialQuestionForm content={content} onChange={setContent} />}
          {slug === "core-courses" && <CoreCoursesForm content={content} onChange={setContent} />}
          {slug === "dna-strands" && <DnaStrandsForm content={content} onChange={setContent} />}
          {slug === "year-at-glance" && <YearAtGlanceForm content={content} onChange={setContent} />}
          {slug === "year-long-story" && <YearLongStoryForm content={content} onChange={setContent} />}
          {slug === "developing-the-whole-child" && <DevelopingWholeChildForm content={content} onChange={setContent} />}
          {slug === "finks-taxonomy" && <FinksTaxonomyForm content={content} onChange={setContent} />}
          {slug === "one-project-not-13-tests" && <OneProjectNot13TestsForm content={content} onChange={setContent} />}
          {slug === "curriculum-architecture" && <CurriculumArchitectureForm content={content} onChange={setContent} />}
          {slug === "pbel" && <PbelForm content={content} onChange={setContent} />}
          {slug === "course-hero" && <CourseHeroForm content={content} onChange={setContent} />}
          {slug === "why-this-course-matters" && <WhyThisCourseMattersForm content={content} onChange={setContent} />}
          {slug === "how-connects" && <HowConnectsForm content={content} onChange={setContent} />}
          {slug === "smarter-assessment" && <SmarterAssessmentForm content={content} onChange={setContent} />}
          {slug === "what-your-child-will-gain" && <WhatYourChildWillGainForm content={content} onChange={setContent} />}
          {slug === "course-portrait" && <CoursePortraitForm content={content} onChange={setContent} />}
          {slug === "course-core-skills" && <CourseCoreSkillsForm content={content} onChange={setContent} />}
          {slug === "course-journey" && <CourseJourneyForm content={content} onChange={setContent} />}
          {slug === "course-what-they-create" && <CourseWhatTheyCreateForm content={content} onChange={setContent} />}
          {slug === "course-inquiry-questions" && <CourseInquiryQuestionsForm content={content} onChange={setContent} />}
          {slug === "course-support-at-home" && <CourseSupportAtHomeForm content={content} onChange={setContent} />}
          {slug === "course-quarter-celebration" && <CourseQuarterCelebrationForm content={content} onChange={setContent} />}
          {slug === "quarter-hero" && <QuarterHeroForm content={content} onChange={setContent} />}
          {slug === "big-idea" && <BigIdeaForm content={content} onChange={setContent} />}
          {slug === "how-each-course-sees" && <HowEachCourseSeesForm content={content} onChange={setContent} />}
          {(slug === "quarter-courses" || slug === "quarter-learning-tabs" || slug === "quarter-courses-and-learning") && (
            <HowEachCourseSeesForm content={content} onChange={setContent} />
          )}
          {slug === "orion-school-header" && <OrionSchoolHeaderForm content={content} onChange={setContent} />}
          {slug === "what-is-pbel" && <WhatIsPbelForm content={content} onChange={setContent} />}
          {slug === "why-water-why-now" && <WhyWaterWhyNowForm content={content} onChange={setContent} />}
          {slug === "pbel-cycle" && <PbelCycleForm content={content} onChange={setContent} />}
          {slug === "what-your-child-might-do" && <WhatYourChildMightDoForm content={content} onChange={setContent} />}
          {slug === "families-expect-help" && <FamiliesExpectHelpForm content={content} onChange={setContent} />}
          {slug === "benefits-for-your-child" && <BenefitsForYourChildForm content={content} onChange={setContent} />}
          {slug === "service-learning-ipard" && <ServiceLearningIpardForm content={content} onChange={setContent} />}
          {slug === "year-timeline-at-glance" && <YearTimelineAtGlanceForm content={content} onChange={setContent} />}
          {slug === "how-families-can-help" && <HowFamiliesCanHelpForm content={content} onChange={setContent} />}
          {slug === "deep-inquiry-questions" && <DeepInquiryQuestionsForm content={content} onChange={setContent} />}
          {slug === "stay-in-the-loop" && <StayInTheLoopForm content={content} onChange={setContent} />}
          {slug === "grade-family-guides" && <GradeFamilyGuidesForm content={content} onChange={setContent} />}
          {slug === "grade-family-guides-api" && <GradeFamilyGuidesApiForm content={content} onChange={setContent} />}
          {slug === "parent-course-overview" && <ParentCourseOverviewForm content={content} onChange={setContent} />}
          {slug === "impact-kaleidoscope" && <ImpactKaleidoscopeForm content={content} onChange={setContent} />}
          {slug === "three-journey-phases" && <ThreeJourneyPhasesForm content={content} onChange={setContent} />}
          {slug === "cross-cutting-mirrors" && <CrossCuttingMirrorsForm content={content} onChange={setContent} />}
          {slug === "annual-flow-quarters" && <AnnualFlowQuartersForm content={content} onChange={setContent} />}
          {slug === "diverge-converge-viz" && <DivergeConvergeVizForm content={content} onChange={setContent} />}
          {slug === "squad-roles" && <SquadRolesForm content={content} onChange={setContent} />}
          {slug === "grade-band-entrepreneurship" && <GradeBandEntrepreneurshipForm content={content} onChange={setContent} />}
          {slug === "deliverables-evidence" && <DeliverablesEvidenceForm content={content} onChange={setContent} />}
          {slug === "design-impact-summit" && <DesignImpactSummitForm content={content} onChange={setContent} />}
          {slug === "closing-vision" && <ClosingVisionForm content={content} onChange={setContent} />}
          {slug === "club-category-grid" && <ClubCategoryGridForm content={content} onChange={setContent} />}
          {slug === "steering-committees-grid" && (
            <SteeringCommitteesGridForm content={content} onChange={setContent} />
          )}
          {slug === "orion-competitions" && (
            <CompetitionPanelForm content={content} onChange={setContent} variant="orion" />
          )}
          {slug === "public-competitions" && (
            <CompetitionPanelForm content={content} onChange={setContent} variant="public" />
          )}
          {slug === "competition-tabs" && <CompetitionTabsForm content={content} onChange={setContent} />}
          {slug === "swot-analysis-grid" && <SwotAnalysisGridForm content={content} onChange={setContent} />}
          {slug === "root-cause-fishbone" && <RootCauseFishboneForm content={content} onChange={setContent} />}
          {slug === "portrait-goals-grid" && <PortraitGoalsGridForm content={content} onChange={setContent} />}
          {slug === "growth-radar-chart" && <GrowthRadarChartForm content={content} onChange={setContent} />}
          {slug === "progress-how-it-works" && <ProgressHowItWorksForm content={content} onChange={setContent} />}
          {slug === "progress-sample-report" && <ProgressSampleReportForm content={content} onChange={setContent} />}
          {!["hero", "footer", "pbel-guide-footer", "dimension-detail", "grade-hero", "grade-kaleidoscope", "curriculum-hero", "essential-question", "core-courses", "dna-strands", "year-at-glance", "year-long-story", "developing-the-whole-child", "finks-taxonomy", "one-project-not-13-tests", "curriculum-architecture", "pbel", "course-hero", "why-this-course-matters", "how-connects", "smarter-assessment", "what-your-child-will-gain", "course-portrait", "course-core-skills", "course-journey", "course-what-they-create", "course-inquiry-questions", "course-support-at-home", "course-quarter-celebration", "quarter-hero", "big-idea", "how-each-course-sees", "quarter-learning-tabs", "quarter-courses", "quarter-courses-and-learning", "orion-school-header", "what-is-pbel", "why-water-why-now", "pbel-cycle", "what-your-child-might-do", "families-expect-help", "benefits-for-your-child", "service-learning-ipard", "year-timeline-at-glance", "how-families-can-help", "deep-inquiry-questions", "stay-in-the-loop", "parent-course-overview", "grade-family-guides", "grade-family-guides-api", "design-to-impact-hero", "impact-kaleidoscope", "three-journey-phases", "cross-cutting-mirrors", "annual-flow-quarters", "diverge-converge-viz", "squad-roles", "grade-band-entrepreneurship", "deliverables-evidence", "design-impact-summit", "closing-vision", "club-category-grid", "steering-committees-grid", "orion-competitions", "public-competitions", "competition-tabs", "swot-analysis-grid", "root-cause-fishbone", "portrait-goals-grid", "growth-radar-chart", "progress-how-it-works", "progress-sample-report"].includes(slug) && (
            <DynamicContentForm content={content} onChange={setContent} />
          )}

          {PreviewBlock && (
            <div className="mt-6 border-t border-slate-200 pt-4">
              <p className="text-xs font-semibold text-slate-600 mb-2">Live preview (latest site settings + component design)</p>
              <SiteChromeFrame
                key={siteChromeKey}
                previewMode
                showGlobalFooter={showGlobalFooter}
                className="rounded-xl overflow-hidden border border-slate-200"
              >
                <div className="p-4 max-h-[min(420px,40vh)] overflow-auto bg-background">
                  <PreviewBlock content={previewContent} />
                </div>
              </SiteChromeFrame>
            </div>
          )}
        </div>
        <div className="px-6 py-4 border-t border-slate-200 flex justify-end gap-3">
          <button type="button" onClick={onClose} className="px-4 py-2 rounded-lg border border-slate-300 bg-white font-medium text-slate-700 hover:bg-slate-50">
            Cancel
          </button>
          <button type="button" onClick={handleSave} className="px-4 py-2 rounded-lg bg-slate-900 text-white font-medium hover:bg-slate-800">
            Save
          </button>
        </div>
      </div>
    </div>
  );
}
