google-site-verification=QxSR5RbKx1TEFVqBUBRSw6h5pSmcCfukQEj_nzdr3vQ 100546119797916 297200882177665 import React, { useEffect, useState } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Download, Image as ImageIcon, Lock, LockOpen, Save, Trash2, } from "lucide-react"; // ------------------------------------------------------------- // Minimal Freesongs Arc Builder (no Shadcn UI) // ------------------------------------------------------------- const COLUMN_TITLES = ["Phenomena", "Action / Verb", "Outcome"] as const; const PROMPTS = [ "What does this image say is happening?", "What does this image say you are doing?", "What does this image say has happened?", ]; type Cell = { text: string; imageUrl: string; seed: string }; type Columns = [Cell[], Cell[], Cell[]]; function newEmptyColumns(): Columns { return [0, 1, 2].map(() => Array.from({ length: 12 }, () => ({ text: "", imageUrl: "", seed: "" })) ) as Columns; } function randomSeed() { return ( Math.random().toString(36).slice(2) + Date.now().toString(36).slice(-4) ); } function picsumUrl(seed: string, w = 800, h = 600) { return `https://picsum.photos/seed/${seed}/${w}/${h}`; } function useLocalStorage(key: string, initial: T) { const [state, setState] = useState(() => { try { const raw = localStorage.getItem(key); return raw ? (JSON.parse(raw) as T) : initial; } catch (err) { console.warn(`Failed to load localStorage key "${key}"`, err); return initial; } }); useEffect(() => { try { localStorage.setItem(key, JSON.stringify(state)); } catch (err) { console.warn(`Failed to save localStorage key "${key}"`, err); } }, [key, state]); return [state, setState] as const; } // 👉 Minimal replacements for UI components const Button: React.FC> = ({ children, ...props }) => ( ); const Input: React.FC> = ( props ) => ( ); const Textarea: React.FC> = ( props ) => (