// data.jsx — occasions, fallback templates, and live AI generation via window.claude.complete const OCCASIONS = [ { id: "birthday", emoji: "🎂", mood: "happy" }, { id: "wedding", emoji: "💍", mood: "happy" }, { id: "newbaby", emoji: "👶", mood: "happy" }, { id: "graduation", emoji: "🎓", mood: "happy" }, { id: "newjob", emoji: "💼", mood: "happy" }, { id: "anniversary", emoji: "💕", mood: "happy" }, { id: "recovery", emoji: "🌷", mood: "soft" }, { id: "holiday", emoji: "🎄", mood: "happy" }, { id: "condolences", emoji: "🕊️", mood: "solemn" }, ]; // ---- English fallback templates if Claude API fails ---- const FALLBACK_TEMPLATES = { birthday: "Dear {recipient},\n\nAnother trip around the sun, another reason to celebrate the wonderful person you are{age_clause}. May this year bring laughter that wakes the neighbours and plans that actually come together.\n\nWith love,\n{sender}", wedding: "Dear {recipient},\n\nWishing you a marriage as warm as morning coffee, as sturdy as your favourite chair, and as full of laughter as the loudest dinner table you've ever sat at.\n\nWith love,\n{sender}", newbaby: "Welcome to the world, tiny human — and congratulations, {recipient}. May the sleep be deep, the tiny socks plentiful, and every milestone met with awe.\n\nWith love,\n{sender}", graduation: "{recipient}, you did the thing. So proud of you. Whatever comes next, go be brilliant.\n\nOnward,\n{sender}", newjob: "{recipient}, congratulations on the new gig. May your inbox be merciful and your colleagues be the kind that bring snacks.\n\nCheers,\n{sender}", anniversary: "Happy Anniversary, {recipient}. Here's to another year of inside jokes and the easy comfort of being known.\n\nLove,\n{sender}", recovery: "Dear {recipient},\n\nTake it slow. Drink the tea, ignore the unread emails, let the people who love you take care of you for a while.\n\nWith care,\n{sender}", holiday: "Dear {recipient},\n\nWishing you a season of warm kitchens, soft light, and the kind of quiet joy that creeps up while no one's looking.\n\n{sender}", condolences: "Dear {recipient},\n\nThere are no words that fit a loss this size, so I won't pretend to find them. I'm thinking of you, and holding you in my heart.\n\nWith love,\n{sender}", }; function fallbackMessage({ occasionId, recipient, family, age, sender }) { const tmpl = FALLBACK_TEMPLATES[occasionId] || FALLBACK_TEMPLATES.birthday; const fullName = [recipient, family].filter(Boolean).join(" ") || "friend"; const ageClause = age ? ` (${age} looks great on you, by the way)` : ""; return tmpl .replace(/\{recipient\}/g, fullName) .replace(/\{sender\}/g, sender || "Anonymous") .replace(/\{age_clause\}/g, ageClause); } /** * Live AI message generation. * Uses window.claude.complete inside the artifact (free, built-in). * In PRODUCTION, swap this for a fetch to your backend at sentwithlove.vip, which proxies to: * - Google Gemini 2.0 Flash (free tier, ~1,500 req/day) * POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent * - Or Groq (Llama 3.3 70B) for extra speed. * NEVER call these APIs directly from the browser — your key would be exposed. */ async function generateAIMessage({ occasionId, recipient, family, age, sender, langCode, langLabel, occasionName }) { const occ = OCCASIONS.find(o => o.id === occasionId); if (!occ) return ""; const fullName = [recipient, family].filter(Boolean).join(" ").trim() || recipient || "friend"; const ageNote = age ? ` They are turning ${age}.` : ""; const isSolemn = occ.mood === "solemn"; const isSoft = occ.mood === "soft"; const toneGuide = isSolemn ? "Tone: gentle, sincere, brief. Never performative or saccharine. Do not say things like 'I know how you feel'. Acknowledge the loss, offer presence, sign off with warmth." : isSoft ? "Tone: warm, caring, encouraging. A little gentle humor only if natural." : "Tone: warm, witty, a little playful but never saccharine or generic. Specific, human, conversational."; const prompt = `You are writing a short personal message for the "${occasionName}" occasion. Write the entire message in ${langLabel} (language code: ${langCode}). Native, idiomatic, NOT translated from English. Recipient: ${fullName}.${ageNote} From: ${sender || "the sender"}. ${toneGuide} Length: 3 to 5 short paragraphs. Conversational sentences. No bullet points. No markdown. No emoji. Sign off with the sender's name on its own line. Output ONLY the message body. No preamble. No explanation. No quote marks around the message.`; try { const text = await window.claude.complete(prompt); return (text || "").trim(); } catch (err) { console.warn("[Sendly] AI generation failed, using fallback:", err); return fallbackMessage({ occasionId, recipient, family, age, sender }); } } Object.assign(window, { OCCASIONS, generateAIMessage, fallbackMessage });