const { useState, useRef, useEffect } = React;

// Catalogue loaded from catalogue.json on Cloudflare; null in artifact = AI fallback
const RING_CATALOGUE = null;
const STORAGE_PREFIX = "savoys-studio";
const ACTIVE_DRAFT_STORAGE_KEY = "active-draft";
const DRAFT_STORAGE_VERSION = 1;
const AI_PROXY_URL = "/api/ai";
const SUBMIT_PROXY_URL = "/api/submit";

const storageKey = (key) => `${STORAGE_PREFIX}:${key}`;
const isBlobUrl = (url) => typeof url === "string" && url.startsWith("blob:");
const revokeObjectUrls = (urls) => {
  (urls || []).forEach((url) => {
    if (isBlobUrl(url)) URL.revokeObjectURL(url);
  });
};
const safeJsonParse = (value, fallback = null) => {
  if (!value || typeof value !== "string") return fallback;
  try {
    return JSON.parse(value);
  } catch (err) {
    return fallback;
  }
};
const extractJsonArray = (text) => {
  const cleaned = String(text || "").replace(/```json|```/gi, "").trim();
  const start = cleaned.indexOf("[");
  const end = cleaned.lastIndexOf("]");
  const candidate = start !== -1 && end !== -1 && end > start
    ? cleaned.slice(start, end + 1)
    : cleaned;
  const parsed = JSON.parse(candidate);
  return Array.isArray(parsed) ? parsed : [];
};
const draftStorageKey = (sessionId) => `draft:${sessionId}`;
const normalizeBudgetBracket = (budgetId) => {
  const map = {
    "under-500": "under-500",
    "500-1000": "under-1000",
    "1000-2500": "1000-3000",
    "2500-5000": "3000-5000",
    "5000-10000": "5000-10000",
    "10000-plus": "10000-plus",
  };
  return map[budgetId] || budgetId || null;
};
const buildFallbackSvgMarkup = (concept, metalColor, gemColors) => {
  const desc = `${concept?.name || ""} ${concept?.description || ""}`.toLowerCase();
  const variant = desc.includes("pendant") || desc.includes("necklace")
    ? "pendant"
    : desc.includes("bracelet") || desc.includes("cuff")
      ? "bracelet"
      : desc.includes("earring") || desc.includes("stud")
        ? "earring"
        : "ring";

  const primaryMetal = metalColor && metalColor.startsWith("#") ? metalColor : "#D4A843";
  const gemOuter = gemColors?.[0] || "#B8D4E3";
  const gemInner = gemColors?.[1] || "#FFFFFF";
  const bodyMarkup = variant === "pendant"
    ? `
      <path d="M200 78c18 0 32 15 32 33 0 7-2 14-6 20l-18 24c-4 5-12 5-16 0l-18-24c-4-6-6-13-6-20 0-18 14-33 32-33z" fill="url(#metalGrad)"/>
      <circle cx="200" cy="110" r="18" fill="url(#gemGrad)" stroke="rgba(255,255,255,0.35)" stroke-width="2"/>
      <path d="M200 42c0 10 0 18 0 26" stroke="url(#metalGrad)" stroke-width="8" stroke-linecap="round"/>
      <ellipse cx="200" cy="216" rx="54" ry="12" fill="rgba(0,0,0,0.18)" filter="url(#shadow)"/>
    `
    : variant === "bracelet"
      ? `
        <ellipse cx="200" cy="150" rx="92" ry="56" fill="none" stroke="url(#metalGrad)" stroke-width="18"/>
        <ellipse cx="200" cy="150" rx="72" ry="38" fill="none" stroke="rgba(255,255,255,0.12)" stroke-width="3"/>
        <rect x="180" y="84" width="40" height="28" rx="10" fill="url(#gemGrad)" stroke="rgba(255,255,255,0.35)" stroke-width="2"/>
        <ellipse cx="200" cy="228" rx="78" ry="10" fill="rgba(0,0,0,0.18)" filter="url(#shadow)"/>
      `
      : variant === "earring"
        ? `
          <path d="M165 82c0 0 8-18 18-18s18 18 18 18" fill="none" stroke="url(#metalGrad)" stroke-width="7" stroke-linecap="round"/>
          <path d="M165 82c-16 16-24 34-24 53 0 33 26 58 59 58s59-25 59-58c0-19-8-37-24-53" fill="none" stroke="url(#metalGrad)" stroke-width="18" stroke-linecap="round"/>
          <circle cx="200" cy="150" r="22" fill="url(#gemGrad)" stroke="rgba(255,255,255,0.35)" stroke-width="2"/>
          <ellipse cx="200" cy="232" rx="62" ry="10" fill="rgba(0,0,0,0.18)" filter="url(#shadow)"/>
        `
        : `
          <ellipse cx="200" cy="176" rx="74" ry="40" fill="none" stroke="url(#metalGrad)" stroke-width="18"/>
          <ellipse cx="200" cy="176" rx="52" ry="24" fill="none" stroke="rgba(255,255,255,0.12)" stroke-width="3"/>
          <path d="M165 150c8-28 24-43 35-43 11 0 27 15 35 43" fill="none" stroke="url(#metalGrad)" stroke-width="14" stroke-linecap="round"/>
          <circle cx="200" cy="102" r="26" fill="url(#gemGrad)" stroke="rgba(255,255,255,0.35)" stroke-width="2"/>
          <path d="M184 102l8-12M216 102l-8-12M184 102l-8 12M216 102l8 12" stroke="url(#metalGrad)" stroke-width="4" stroke-linecap="round"/>
          <ellipse cx="200" cy="236" rx="68" ry="10" fill="rgba(0,0,0,0.18)" filter="url(#shadow)"/>
        `;

  return `
    <svg viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
      <defs>
        <linearGradient id="metalGrad" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stop-color="${primaryMetal}" stop-opacity="0.45" />
          <stop offset="45%" stop-color="${primaryMetal}" />
          <stop offset="100%" stop-color="${primaryMetal}" stop-opacity="0.82" />
        </linearGradient>
        <radialGradient id="gemGrad" cx="40%" cy="35%" r="65%">
          <stop offset="0%" stop-color="${gemInner}" />
          <stop offset="100%" stop-color="${gemOuter}" />
        </radialGradient>
        <filter id="shadow">
          <feGaussianBlur stdDeviation="4" />
        </filter>
      </defs>
      <rect width="400" height="300" fill="#1A1814" />
      ${bodyMarkup}
      <path d="M150 78c30-18 71-24 108-16" fill="none" stroke="rgba(255,255,255,0.14)" stroke-width="4" stroke-linecap="round"/>
      <path d="M142 198c30 18 90 24 120 8" fill="none" stroke="rgba(255,255,255,0.08)" stroke-width="3" stroke-linecap="round"/>
    </svg>
  `.trim();
};

// Polyfill window.storage for non-artifact environments
if (typeof window !== "undefined" && !window.storage) {
  window.storage = {
    get: async (key) => {
      try {
        return window.localStorage.getItem(storageKey(key));
      } catch (err) {
        return null;
      }
    },
    set: async (key, value) => {
      try {
        window.localStorage.setItem(storageKey(key), typeof value === "string" ? value : JSON.stringify(value));
        return true;
      } catch (err) {
        return false;
      }
    },
    delete: async (key) => {
      try {
        window.localStorage.removeItem(storageKey(key));
        return true;
      } catch (err) {
        return false;
      }
    },
    list: async () => {
      try {
        const prefix = `${STORAGE_PREFIX}:`;
        const keys = [];
        for (let i = 0; i < window.localStorage.length; i++) {
          const key = window.localStorage.key(i);
          if (key && key.startsWith(prefix)) {
            keys.push(key.slice(prefix.length));
          }
        }
        return { keys };
      } catch (err) {
        return { keys: [] };
      }
    },
  };
}


const STEPS = [
  "welcome",
  "project",
  "existing",
  "intro",
  "type",
  "occasion",
  "metal",
  "gemstone",
  "style",
  "inspiration",
  "budget",
  "timeline",
  "preview",
  "details",
  "summary",
];

const JEWELLERY_TYPES = [
  { id: "ring", label: "Ring", icon: "💍" },
  { id: "necklace", label: "Necklace", icon: "📿" },
  { id: "bracelet", label: "Bracelet", icon: "⌚" },
  { id: "earrings", label: "Earrings", icon: "✨" },
  { id: "pendant", label: "Pendant", icon: "🔶" },
  { id: "brooch", label: "Brooch", icon: "🌸" },
  { id: "cufflinks", label: "Cuff Links", icon: "🔗" },
  { id: "other", label: "Something Else", icon: "💎" },
];

const OCCASIONS = [
  { id: "engagement", label: "Engagement", desc: "A ring to start forever" },
  { id: "wedding", label: "Wedding", desc: "Bands to seal the vow" },
  { id: "anniversary", label: "Anniversary", desc: "Celebrating your journey" },
  { id: "birthday", label: "Birthday", desc: "A milestone gift" },
  { id: "graduation", label: "Graduation", desc: "Marking an achievement" },
  { id: "self", label: "Treat Myself", desc: "You deserve it" },
  { id: "gift", label: "Gift for Someone", desc: "Something truly special" },
  { id: "memorial", label: "Memorial / Heirloom", desc: "Honouring a memory" },
  { id: "other", label: "Other Occasion", desc: "Tell us more later" },
];

const METALS = [
  { id: "yellow-gold", label: "Yellow Gold", color: "#D4A843" },
  { id: "white-gold", label: "White Gold", color: "#E8E8E8" },
  { id: "rose-gold", label: "Rose Gold", color: "#D4917A" },
  { id: "platinum", label: "Platinum", color: "#C0C0C8" },
  { id: "silver", label: "Sterling Silver", color: "#A8A8B0" },
  { id: "mixed", label: "Mixed Metals", color: "linear-gradient(135deg, #D4A843, #E8E8E8, #D4917A)" },
  { id: "unsure", label: "Not Sure Yet", color: "#888" },
];

const GEMSTONES = [
  { id: "diamond", label: "Diamond", color: "#E8F4F8", emoji: "💎" },
  { id: "sapphire", label: "Sapphire", color: "#1E3A8A", emoji: "🔵" },
  { id: "ruby", label: "Ruby", color: "#9B1B30", emoji: "🔴" },
  { id: "emerald", label: "Emerald", color: "#1B6B3A", emoji: "🟢" },
  { id: "moissanite", label: "Moissanite", color: "#D1D5DB", emoji: "⬜" },
  { id: "amethyst", label: "Amethyst", color: "#6B21A8", emoji: "🟣" },
  { id: "opal", label: "Opal", color: "#E0E7FF", emoji: "🌈" },
  { id: "garnet", label: "Garnet", color: "#8B1A1A", emoji: "🔻" },
  { id: "aquamarine", label: "Aquamarine", color: "#48A9C5", emoji: "🩵" },
  { id: "pearl", label: "Pearl", color: "#F5F0E0", emoji: "⚪" },
  { id: "peridot", label: "Peridot", color: "#6B8E23", emoji: "🟡" },
  { id: "topaz", label: "Topaz", color: "#D4900A", emoji: "🟠" },
  { id: "tanzanite", label: "Tanzanite", color: "#4A3B8F", emoji: "🔮" },
  { id: "other", label: "Other Stone", color: "#78716C", emoji: "💠" },
  { id: "none", label: "No Gemstone", color: "#44403C", emoji: "⬛" },
  { id: "unsure", label: "Not Sure Yet", color: "#888", emoji: "❓" },
];

const STYLES = [
  { id: "classic", label: "Classic & Timeless", desc: "Clean lines, enduring elegance", img: "🏛️" },
  { id: "modern", label: "Modern & Minimalist", desc: "Sleek, contemporary simplicity", img: "▫️" },
  { id: "vintage", label: "Vintage & Art Deco", desc: "Old-world charm, intricate detail", img: "🎭" },
  { id: "nature", label: "Nature-Inspired", desc: "Organic shapes, floral motifs", img: "🌿" },
  { id: "bold", label: "Bold & Statement", desc: "Eye-catching, conversation-starting", img: "🔥" },
  { id: "delicate", label: "Delicate & Dainty", desc: "Subtle beauty, fine details", img: "🦋" },
];

const BUDGETS = [
  { id: "under-500", label: "Under $500" },
  { id: "500-1000", label: "$500 – $1,000" },
  { id: "1000-2500", label: "$1,000 – $2,500" },
  { id: "2500-5000", label: "$2,500 – $5,000" },
  { id: "5000-10000", label: "$5,000 – $10,000" },
  { id: "10000-plus", label: "$10,000+" },
  { id: "flexible", label: "Flexible / Not Sure" },
];

const DESIGNERS = [
  { id: "cartier", label: "Cartier", desc: "Timeless French elegance" },
  { id: "tiffany", label: "Tiffany & Co.", desc: "Iconic American luxury" },
  { id: "harrywinston", label: "Harry Winston", desc: "The King of Diamonds" },
  { id: "bvlgari", label: "Bvlgari", desc: "Bold Italian glamour" },
  { id: "vancleef", label: "Van Cleef & Arpels", desc: "Poetic & nature-inspired" },
  { id: "graff", label: "Graff", desc: "Extraordinary rare gems" },
  { id: "davidyurman", label: "David Yurman", desc: "Sculptural & artistic" },
  { id: "chopard", label: "Chopard", desc: "Swiss haute joaillerie" },
  { id: "buccellati", label: "Buccellati", desc: "Renaissance-inspired lace work" },
  { id: "piaget", label: "Piaget", desc: "Ultra-thin, colourful & daring" },
  { id: "mikimoto", label: "Mikimoto", desc: "World's finest pearls" },
  { id: "debeers", label: "De Beers", desc: "Diamond heritage since 1888" },
  { id: "pomellato", label: "Pomellato", desc: "Milanese colour & character" },
  { id: "jar", label: "JAR", desc: "Ultra-exclusive, museum-level artistry" },
];

const TIMELINES = [
  { id: "asap", label: "As Soon As Possible", desc: "Within 2-3 weeks" },
  { id: "1-2months", label: "1–2 Months", desc: "Some time to craft" },
  { id: "3-6months", label: "3–6 Months", desc: "Planning ahead" },
  { id: "no-rush", label: "No Rush", desc: "Take the time it needs" },
  { id: "specific", label: "Specific Date", desc: "I have a deadline" },
];

const RING_SUBTYPES = [
  { id: "solitaire", label: "Solitaire" },
  { id: "halo", label: "Halo" },
  { id: "three-stone", label: "Three Stone" },
  { id: "pave", label: "Pavé" },
  { id: "cluster", label: "Cluster" },
  { id: "signet", label: "Signet" },
  { id: "band", label: "Simple Band" },
  { id: "unsure", label: "Not Sure" },
];

const EARRING_SUBTYPES = [
  { id: "studs", label: "Studs" },
  { id: "hoops", label: "Hoops" },
  { id: "drops", label: "Drops / Dangles" },
  { id: "huggies", label: "Huggies" },
  { id: "climbers", label: "Climbers / Crawlers" },
  { id: "unsure", label: "Not Sure" },
];

const BIRTHSTONES = [
  { month: "January", stones: ["garnet"], desc: "Deep red garnet symbolizes trust, friendship, and vitality. Perfect for those who love rich, warm tones.", color: "#8B1A1A" },
  { month: "February", stones: ["amethyst"], desc: "Purple amethyst represents wisdom, courage, and peace. A regal stone with stunning violet hues.", color: "#6B21A8" },
  { month: "March", stones: ["aquamarine"], desc: "Pale blue aquamarine evokes the sea — symbolizing serenity, clarity, and calm.", color: "#48A9C5" },
  { month: "April", stones: ["diamond"], desc: "The iconic diamond symbolizes eternal love and strength. The hardest natural material on Earth.", color: "#E8F4F8" },
  { month: "May", stones: ["emerald"], desc: "Rich green emerald represents rebirth, love, and wisdom. Treasured by royalty for centuries.", color: "#1B6B3A" },
  { month: "June", stones: ["pearl", "opal"], desc: "June has two gems: luminous pearls symbolizing purity, and opals with their mesmerizing play of colour.", color: "#F5F0E0" },
  { month: "July", stones: ["ruby"], desc: "Fiery red ruby is the king of gemstones — symbolizing passion, protection, and prosperity.", color: "#9B1B30" },
  { month: "August", stones: ["peridot"], desc: "Vibrant green peridot is born from volcanoes, symbolizing strength and good fortune.", color: "#6B8E23" },
  { month: "September", stones: ["sapphire"], desc: "Deep blue sapphire symbolizes loyalty, nobility, and truth. A favourite of engagement rings worldwide.", color: "#1E3A8A" },
  { month: "October", stones: ["opal"], desc: "Opal's kaleidoscope of colours symbolizes creativity and inspiration. Each stone is completely unique.", color: "#E0E7FF" },
  { month: "November", stones: ["topaz"], desc: "Golden topaz radiates warmth and energy, symbolizing love, affection, and good fortune.", color: "#D4900A" },
  { month: "December", stones: ["tanzanite"], desc: "Rare blue-violet tanzanite is found only in Tanzania. It symbolizes transformation and new beginnings.", color: "#4A3B8F" },
];

// ── Configuration ──
const SAVOYS_LOGO = "data:image/jpeg;base64,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";

// ── Image compression ──
const MAX_TOTAL_BYTES = 10 * 1024 * 1024;
const MAX_DIMENSION = 1600;
const IMAGE_COMPRESSION_TIMEOUT_MS = 12000;
const BACKEND_FETCH_TIMEOUT_MS = 12000;
const compressImage = (file, maxBytes) => new Promise((resolve) => {
  const img = new Image();
  const url = URL.createObjectURL(file);
  let settled = false;
  let timeoutId = null;

  const finish = (value) => {
    if (settled) return;
    settled = true;
    if (timeoutId) clearTimeout(timeoutId);
    URL.revokeObjectURL(url);
    resolve(value);
  };

  const fallbackToFileReader = () => {
    const r = new FileReader();
    r.onload = () => finish(r.result);
    r.onerror = () => finish(null);
    r.readAsDataURL(file);
  };

  img.onload = () => {
    if (settled) return;
    let { width, height } = img;
    if (Math.max(width, height) > MAX_DIMENSION) {
      const scale = MAX_DIMENSION / Math.max(width, height);
      width = Math.round(width * scale);
      height = Math.round(height * scale);
    }
    const canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height;
    canvas.getContext("2d").drawImage(img, 0, 0, width, height);
    let quality = 0.75;
    let dataUrl = canvas.toDataURL("image/jpeg", quality);
    while (dataUrl.length * 0.75 > maxBytes && quality > 0.15) {
      quality -= 0.1;
      dataUrl = canvas.toDataURL("image/jpeg", quality);
    }
    finish(dataUrl);
  };
  img.onerror = () => {
    fallbackToFileReader();
  };
  timeoutId = setTimeout(() => {
    console.warn("Image compression timed out, falling back to raw data URL for", file?.name || "unknown file");
    fallbackToFileReader();
  }, IMAGE_COMPRESSION_TIMEOUT_MS);
  img.src = url;
});

const compressAllImages = async (files) => {
  if (!files || files.length === 0) return [];
  const perImage = Math.floor(MAX_TOTAL_BYTES / files.length);
  return Promise.all(files.map(f => f instanceof File ? compressImage(f, perImage) : f));
};

// ── Helpers ──
const genId = () => Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
const callAiProxy = async ({ task, input, instructions, reasoningEffort = "low", maxOutputTokens }) => {
  const resp = await fetch(AI_PROXY_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      task,
      input,
      instructions,
      reasoningEffort,
      maxOutputTokens,
    }),
  });
  const data = await resp.json().catch(() => null);
  if (!resp.ok) {
    throw new Error(data?.error || `AI proxy error ${resp.status}`);
  }
  return data;
};
const DEFAULT_ANSWERS = {
  type: null,
  ringSubtype: null,
  earringSubtype: null,
  occasion: null,
  metal: null,
  gemstones: [],
  style: null,
  photos: [],
  budget: null,
  timeline: null,
  specificDate: "",
  name: "",
  email: "",
  phone: "",
  notes: "",
  ringSize: "",
  projectType: null,
  existingPhotos: [],
  existingDescription: "",
  existingPreservation: null,
  favoriteConceptIndex: null,
  favoriteConcepts: [],
  likedProducts: [],
  inspirationMethod: null,
  inspirationPath: null,
  inspirationDesigners: [],
  inspirationText: "",
};
const serializeDraftAnswers = (answers) => ({
  ...answers,
  photos: [],
  existingPhotos: [],
  inspirationPhotoCount: answers.photos.length,
  existingPhotoCount: answers.existingPhotos.length,
});
const hydrateDraftAnswers = (storedAnswers) => ({
  ...DEFAULT_ANSWERS,
  ...(storedAnswers || {}),
  photos: [],
  existingPhotos: [],
});
const fetchWithTimeout = async (url, options, timeoutMs) => {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(new Error(`Request timed out after ${timeoutMs}ms`)), timeoutMs);
  try {
    return await fetch(url, { ...options, signal: controller.signal });
  } finally {
    clearTimeout(timer);
  }
};
const escapeHtml = (value) => String(value ?? "")
  .replace(/&/g, "&amp;")
  .replace(/</g, "&lt;")
  .replace(/>/g, "&gt;")
  .replace(/"/g, "&quot;")
  .replace(/'/g, "&#39;");
const nl2br = (value) => escapeHtml(value).replace(/\n/g, "<br />");
const formatSubmissionDate = () => {
  try {
    return new Intl.DateTimeFormat("en-CA", {
      weekday: "long",
      year: "numeric",
      month: "long",
      day: "numeric",
    }).format(new Date());
  } catch (err) {
    return new Date().toDateString();
  }
};
const buildEmailText = (subject, sections) => {
  const lines = [subject, "", formatSubmissionDate(), ""];
  sections.forEach((section) => {
    lines.push(section.title.toUpperCase());
    lines.push("-".repeat(section.title.length));
    section.rows.forEach((row) => {
      lines.push(`${row.label}: ${row.value || "—"}`);
    });
    lines.push("");
  });
  return lines.join("\n").trim();
};
const buildEmailHtml = (subject, sections) => {
  const sectionHtml = sections.map((section) => {
    const rows = section.rows.map((row) => `
      <tr>
        <td style="padding:14px 0;border-bottom:1px solid #e8e3d8;width:180px;vertical-align:top;font:700 13px/1.4 Arial, Helvetica, sans-serif;letter-spacing:0.08em;text-transform:uppercase;color:#8f7442;">
          ${escapeHtml(row.label)}
        </td>
        <td style="padding:14px 0;border-bottom:1px solid #e8e3d8;vertical-align:top;font:400 16px/1.65 Arial, Helvetica, sans-serif;color:#1f1c17;">
          ${row.isHtml ? row.value : nl2br(row.value || "—")}
        </td>
      </tr>
    `).join("");
    return `
      <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;margin-top:28px;">
        <tr>
          <td style="padding:0 0 12px 0;font:700 14px/1.3 Arial, Helvetica, sans-serif;letter-spacing:0.14em;text-transform:uppercase;color:#8f7442;">
            ${escapeHtml(section.title)}
          </td>
        </tr>
        <tr>
          <td style="padding:0;">
            <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;background:#ffffff;">
              ${rows}
            </table>
          </td>
        </tr>
      </table>
    `;
  }).join("");

  return `
    <!DOCTYPE html>
    <html>
      <body style="margin:0;padding:24px;background:#f5f2eb;color:#1f1c17;">
        <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;background:#f5f2eb;">
          <tr>
            <td align="center">
              <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border-collapse:separate;max-width:980px;background:#ffffff;border:1px solid #e8e3d8;border-radius:20px;overflow:hidden;">
                <tr>
                  <td style="padding:40px 48px;background:#f8f5ef;border-bottom:1px solid #e8e3d8;text-align:center;">
                    <div style="font:700 44px/1.12 Arial, Helvetica, sans-serif;color:#1f1c17;">${escapeHtml(subject)}</div>
                    <div style="margin-top:14px;font:400 22px/1.4 Arial, Helvetica, sans-serif;color:#65594b;">${escapeHtml(formatSubmissionDate())}</div>
                  </td>
                </tr>
                <tr>
                  <td style="padding:36px 48px 44px 48px;">
                    ${sectionHtml}
                  </td>
                </tr>
              </table>
            </td>
          </tr>
        </table>
      </body>
    </html>
  `.trim();
};

const postToBackend = async (payload) => {
  try {
    await window.storage.set(`lead:${payload.sessionId}`, JSON.stringify(payload));
  } catch(e) { /* local backup failed, ok */ }

  if (payload?._action !== "submit") {
    return { success: true, action: "local" };
  }

  try {
    const resp = await fetchWithTimeout(SUBMIT_PROXY_URL, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    }, BACKEND_FETCH_TIMEOUT_MS);
    const data = await resp.json().catch(() => null);
    if (!resp.ok) {
      return { success: false, error: data?.error || `Submit failed with status ${resp.status}` };
    }
    return data || { success: true, action: "sent" };
  } catch(err) {
    console.warn("Submit proxy failed:", err.message);
    return { success: false, error: err.message };
  }
};

function SavoysCustomDesigner() {
  const [step, setStep] = useState(0);
  const [sessionId, setSessionId] = useState(() => genId());
  const [answers, setAnswers] = useState(DEFAULT_ANSWERS);
  const [photoPreviewUrls, setPhotoPreviewUrls] = useState([]);
  const [existingPhotoUrls, setExistingPhotoUrls] = useState([]);
  const [animating, setAnimating] = useState(false);
  const [direction, setDirection] = useState(1);
  const [showBirthstoneHelper, setShowBirthstoneHelper] = useState(false);
  const [showRingSizer, setShowRingSizer] = useState(false);
  const [previewConcepts, setPreviewConcepts] = useState(null);
  const [previewLoading, setPreviewLoading] = useState(false);
  const [previewError, setPreviewError] = useState(null);
  const [catalogue, setCatalogue] = useState(null);
  const [catalogueMatches, setCatalogueMatches] = useState(null);
  const [saveStatus, setSaveStatus] = useState(""); // "" | "saving" | "saved"
  const [submitState, setSubmitState] = useState("idle"); // idle | sending | sent | error
  const [submitDetail, setSubmitDetail] = useState("");
  const [draftReady, setDraftReady] = useState(false);
  const fileInputRef = useRef(null);
  const existingFileInputRef = useRef(null);
  const contentRef = useRef(null);
  const photoPreviewUrlsRef = useRef([]);
  const existingPhotoUrlsRef = useRef([]);

  const currentStepName = STEPS[step];
  const replacePhotoPreviewUrls = (urls) => {
    revokeObjectUrls(photoPreviewUrlsRef.current);
    photoPreviewUrlsRef.current = urls;
    setPhotoPreviewUrls(urls);
  };
  const replaceExistingPhotoUrls = (urls) => {
    revokeObjectUrls(existingPhotoUrlsRef.current);
    existingPhotoUrlsRef.current = urls;
    setExistingPhotoUrls(urls);
  };

  const goTo = (nextStep) => {
    if (animating) return;
    setDirection(nextStep > step ? 1 : -1);
    setAnimating(true);
    setTimeout(() => {
      setStep(nextStep);
      setAnimating(false);
    }, 300);
  };

  const next = () => {
    let nextStep = step + 1;
    // Skip "existing" step if they chose to start from scratch
    if (STEPS[nextStep] === "existing" && answers.projectType === "new") {
      nextStep++;
    }
    if (nextStep < STEPS.length) goTo(nextStep);
  };
  const back = () => {
    let prevStep = step - 1;
    // Skip "existing" step going backwards if they chose new
    if (STEPS[prevStep] === "existing" && answers.projectType === "new") {
      prevStep--;
    }
    if (prevStep >= 0) goTo(prevStep);
  };

  const update = (key, value) => setAnswers((a) => ({ ...a, [key]: value }));
  const toggleGemstone = (id) => {
    setAnswers((a) => {
      const gems = a.gemstones.includes(id)
        ? a.gemstones.filter((g) => g !== id)
        : [...a.gemstones.filter((g) => g !== "none" && g !== "unsure"), id];
      if (id === "none" || id === "unsure") return { ...a, gemstones: [id] };
      return { ...a, gemstones: gems };
    });
  };

  const selectBirthstone = (stones) => {
    setAnswers((a) => {
      const newGems = [...new Set([...a.gemstones.filter(g => g !== "none" && g !== "unsure"), ...stones])];
      return { ...a, gemstones: newGems };
    });
    setShowBirthstoneHelper(false);
  };

  const handleExistingPhotos = (e) => {
    const files = Array.from(e.target.files);
    if (files.length + answers.existingPhotos.length > 5) {
      alert("Maximum 5 photos allowed");
      return;
    }
    const newPhotos = [...answers.existingPhotos, ...files].slice(0, 5);
    update("existingPhotos", newPhotos);
    replaceExistingPhotoUrls(newPhotos.map((f) => URL.createObjectURL(f)));
  };

  const removeExistingPhoto = (idx) => {
    const newPhotos = answers.existingPhotos.filter((_, i) => i !== idx);
    update("existingPhotos", newPhotos);
    replaceExistingPhotoUrls(newPhotos.map((f) => URL.createObjectURL(f)));
  };

  const handlePhotos = (e) => {
    const files = Array.from(e.target.files);
    if (files.length + answers.photos.length > 5) {
      alert("Maximum 5 photos allowed");
      return;
    }
    const newPhotos = [...answers.photos, ...files].slice(0, 5);
    update("photos", newPhotos);
    replacePhotoPreviewUrls(newPhotos.map((f) => URL.createObjectURL(f)));
  };

  const removePhoto = (idx) => {
    const newPhotos = answers.photos.filter((_, i) => i !== idx);
    update("photos", newPhotos);
    replacePhotoPreviewUrls(newPhotos.map((f) => URL.createObjectURL(f)));
  };

  const canProceed = () => {
    switch (currentStepName) {
      case "welcome": return true;
      case "project": return !!answers.projectType;
      case "existing": return !!answers.existingPreservation;
      case "intro": return answers.email.trim().length > 0;
      case "type": return !!answers.type;
      case "occasion": return !!answers.occasion;
      case "metal": return !!answers.metal;
      case "gemstone": return answers.gemstones.length > 0;
      case "style": return !!answers.style;
      case "inspiration": return true;
      case "budget": return !!answers.budget;
      case "timeline": return !!answers.timeline && (answers.timeline !== "specific" || answers.specificDate);
      case "preview": return true;
      case "details": return answers.name.trim() && (answers.email.trim() || answers.phone.trim());
      default: return true;
    }
  };

  const getLabelFor = (key, id, list) => {
    const item = list.find((i) => i.id === id);
    return item ? item.label : id;
  };
  const buildSubmitEmail = () => {
    const projectValue = answers.projectType === "reimagine"
      ? "Reimagining existing jewellery"
      : "New custom piece";
    const jewelleryValue = getLabelFor("type", answers.type, JEWELLERY_TYPES)
      + (answers.ringSubtype && answers.ringSubtype !== "unsure" ? ` — ${getLabelFor("ringSubtype", answers.ringSubtype, RING_SUBTYPES)}` : "")
      + (answers.earringSubtype && answers.earringSubtype !== "unsure" ? ` — ${getLabelFor("earringSubtype", answers.earringSubtype, EARRING_SUBTYPES)}` : "")
      + (answers.ringSize ? ` (Size: ${answers.ringSize})` : "");
    const inspirationValue =
      answers.inspirationMethod === "photos" && answers.photos.length > 0
        ? `${answers.photos.length} photo(s) uploaded`
        : answers.inspirationDesigners.length > 0
          ? "Designers: " + answers.inspirationDesigners.map(function(id) { return (DESIGNERS.find(function(d) { return d.id === id; }) || {}).label; }).join(", ")
          : answers.inspirationText
            ? answers.inspirationText
            : "None provided";
    const sections = [
      {
        title: "Contact",
        rows: [
          { label: "Name", value: answers.name || "—" },
          { label: "Email", value: answers.email || "—" },
          { label: "Phone", value: answers.phone || "—" },
        ],
      },
      {
        title: "Project",
        rows: [
          { label: "Type", value: projectValue },
          { label: "Jewellery", value: jewelleryValue },
          { label: "Occasion", value: getLabelFor("occasion", answers.occasion, OCCASIONS) || "—" },
          { label: "Metal", value: getLabelFor("metal", answers.metal, METALS) || "—" },
          { label: "Gemstones", value: answers.gemstones.map((g) => getLabelFor("gem", g, GEMSTONES)).join(", ") || "—" },
          { label: "Style", value: getLabelFor("style", answers.style, STYLES) || "—" },
          { label: "Budget", value: getLabelFor("budget", answers.budget, BUDGETS) || "—" },
          { label: "Timeline", value: (getLabelFor("timeline", answers.timeline, TIMELINES) || "—") + (answers.specificDate ? ` — ${answers.specificDate}` : "") },
        ],
      },
      {
        title: "Design",
        rows: [
          { label: "Inspiration", value: inspirationValue },
          { label: "Existing piece", value: answers.projectType === "reimagine" ? (answers.existingDescription || "Photos attached") : "N/A" },
          { label: "Preservation", value: answers.projectType === "reimagine"
            ? (
              answers.existingPreservation === "preserve-all" ? "Keep overall design" :
              answers.existingPreservation === "preserve-parts" ? "Preserve certain elements" :
              answers.existingPreservation === "use-materials" ? "Use the metals & stones" :
              "Not sure yet — discuss"
            )
            : "N/A" },
          { label: "Favourite concept", value: answers.favoriteConceptIndex !== null && previewConcepts?.[answers.favoriteConceptIndex]
            ? previewConcepts[answers.favoriteConceptIndex].name
            : "None selected" },
          { label: "Notes", value: answers.notes || "—" },
          { label: "Attached photos", value: `${answers.existingPhotos.length + answers.photos.length}` },
        ],
      },
    ];
    const subject = "Custom Design Brief";
    return {
      subject,
      html: buildEmailHtml(subject, sections),
      text: buildEmailText(subject, sections),
    };
  };

  const effectiveSteps = STEPS.filter(s => {
    if (s === "existing" && answers.projectType === "new") return false;
    if (s === "welcome" || s === "summary") return false;
    return true;
  });
  const effectiveStepIndex = effectiveSteps.indexOf(currentStepName);

  useEffect(() => {
    window.scrollTo(0, 0);
    if (contentRef.current) {
      contentRef.current.scrollTop = 0;
    }
  }, [step]);

  useEffect(() => {
    let cancelled = false;
    const restoreDraft = async () => {
      const activeDraftSession = await window.storage.get(ACTIVE_DRAFT_STORAGE_KEY);
      if (!activeDraftSession) {
        if (!cancelled) setDraftReady(true);
        return;
      }
      const rawDraft = await window.storage.get(draftStorageKey(activeDraftSession));
      const storedDraft = safeJsonParse(rawDraft);
      if (!storedDraft || storedDraft.version !== DRAFT_STORAGE_VERSION) {
        if (!cancelled) setDraftReady(true);
        return;
      }
      if (cancelled) return;
      setSessionId(storedDraft.sessionId || activeDraftSession || genId());
      setStep(Math.max(0, Math.min(STEPS.length - 1, Number(storedDraft.step) || 0)));
      setAnswers(hydrateDraftAnswers(storedDraft.answers));
      setPreviewConcepts(Array.isArray(storedDraft.previewConcepts) ? storedDraft.previewConcepts : null);
      if (Array.isArray(storedDraft.catalogueMatches) && storedDraft.catalogueMatches.length > 0) {
        setCatalogueMatches(storedDraft.catalogueMatches);
      }
      setDraftReady(true);
    };
    restoreDraft();
    return () => {
      cancelled = true;
      revokeObjectUrls(photoPreviewUrlsRef.current);
      revokeObjectUrls(existingPhotoUrlsRef.current);
    };
  }, []);

  useEffect(() => {
    if (!draftReady) return;
    const persistDraft = async () => {
      const payload = {
        version: DRAFT_STORAGE_VERSION,
        sessionId,
        step,
        answers: serializeDraftAnswers(answers),
        previewConcepts: previewConcepts || null,
        catalogueMatches: catalogueMatches || null,
        savedAt: new Date().toISOString(),
      };
      try {
        await window.storage.set(ACTIVE_DRAFT_STORAGE_KEY, sessionId);
        await window.storage.set(draftStorageKey(sessionId), JSON.stringify(payload));
      } catch (err) {
        console.warn("Draft persistence failed:", err);
      }
    };
    persistDraft();
  }, [draftReady, sessionId, step, answers, previewConcepts, catalogueMatches]);

  // ── Progressive save: keep a lightweight local checkpoint after each step ──
  useEffect(() => {
    if (!draftReady) return;
    if (step < 2) return;
    // Only checkpoint after we have an email (the intro step captures it)
    const hasEmail = answers.email && answers.email.trim().length > 0;
    if (!hasEmail) return;

    const saveProgress = async () => {
      setSaveStatus("saving");
      // Lightweight payload — no photos, no SVG (those go on final submit only)
      const payload = {
        _action: "save",
        sessionId,
        lastStep: currentStepName,
        completed: currentStepName === "summary",
        email: answers.email || "",
        name: answers.name || "",
        phone: answers.phone || "",
        projectType: answers.projectType,
        existingDescription: answers.existingDescription,
        existingPreservation: answers.existingPreservation,
        type: answers.type,
        ringSubtype: answers.ringSubtype,
        earringSubtype: answers.earringSubtype,
        ringSize: answers.ringSize,
        occasion: answers.occasion,
        metal: answers.metal,
        gemstones: answers.gemstones,
        style: answers.style,
        budget: answers.budget,
        timeline: answers.timeline,
        specificDate: answers.specificDate,
        notes: answers.notes,
        favoriteConceptIndex: answers.favoriteConceptIndex,
        concepts: previewConcepts || [],
        // Photo counts only (actual files sent on final submit)
        existingPhotoCount: answers.existingPhotos.length,
        inspirationPhotoCount: answers.photos.length,
        inspirationMethod: answers.inspirationMethod,
        inspirationDesigners: answers.inspirationDesigners,
        inspirationText: answers.inspirationText,
      };

      const result = await postToBackend(payload);
      setSaveStatus(result.success ? "saved" : "error");
      setTimeout(() => setSaveStatus(""), 3000);
    };
    saveProgress();
  }, [step]);

  // Generate preview concepts when entering the preview step
  useEffect(() => {
    if (!draftReady) return;
    if (currentStepName === "preview" && !previewConcepts && !previewLoading && !catalogueMatches) {
      loadMatches();
    }
  }, [currentStepName, draftReady, previewConcepts, previewLoading, catalogueMatches]);

  const matchCatalogue = (items, ans) => {
    const targetMetal = ans.metal || null;
    const targetStones = ans.gemstones || [];
    const targetStyle = ans.style || null;
    const targetBudget = normalizeBudgetBracket(ans.budget || null);
    const targetSubtype = ans.ringSubtype || null;
    return items.map((item) => {
      let score = 0;
      if (targetMetal && item.m !== "unknown") {
        if (item.m === targetMetal) score += 30;
        else if (targetMetal.includes("gold") && item.m.includes("gold")) score += 10;
      }
      if (targetStones.length) {
        for (const gem of targetStones) {
          if (item.st.includes(gem)) score += 25;
          if (gem === "diamond" && item.n.toLowerCase().includes("diamond")) score += 5;
        }
      }
      if (targetSubtype && item.sub && item.sub === targetSubtype) score += 20;
      if (targetStyle && item.stl && item.stl.length) {
        if (item.stl.includes(targetStyle)) score += 15;
      }
      if (targetBudget && targetBudget !== "unsure" && item.pb && item.pb !== "unknown") {
        if (item.pb === targetBudget) score += 10;
        else {
          const bk = ["under-500","under-1000","1000-3000","3000-5000","5000-10000","10000-plus"];
          const targetIndex = bk.indexOf(targetBudget);
          const itemIndex = bk.indexOf(item.pb);
          if (targetIndex !== -1 && itemIndex !== -1 && Math.abs(targetIndex - itemIndex) === 1) score += 5;
        }
      }
      if (item.p) score += 3;
      return { ...item, score };
    }).filter(i => i.score > 0).sort((a, b) => b.score - a.score).slice(0, 6);
  };

  const loadMatches = async () => {
    setPreviewLoading(true);
    setPreviewError(null);
    setCatalogueMatches(null);
    setPreviewConcepts(null);
    try {
      let cat = catalogue;
      if (!cat && answers.type === "ring") {
        const resp = await fetch("./catalogue.json");
        if (resp.ok) {
          cat = await resp.json();
          setCatalogue(cat);
        }
      }
      if (cat && cat.items && answers.type === "ring") {
        const items = cat.items.map(function(i) {
          return { s: i.sku, n: i.name, d: i.designer, m: i.metal, st: (i.stones || []).filter(function(s){ return s !== "unknown"; }), sub: i.subtype || "", stl: i.style_tags || [], p: i.price || 0, pb: i.price_bracket || "", it: i.image_thumb, u: i.detail_url, md: i.metal_detail || "", tc: i.total_carat || 0, ts: i.total_stones || 0 };
        });
        const matches = matchCatalogue(items, answers);
        if (matches.length > 0) {
          setCatalogueMatches(matches);
          setPreviewLoading(false);
          return;
        }
      }
    } catch (e) { console.warn("Catalogue load failed:", e); }
    await generatePreview();
  };

  const generatePreview = async () => {
    setPreviewLoading(true);
    setPreviewError(null);
    setPreviewConcepts(null);

    const typeLabel = getLabelFor("type", answers.type, JEWELLERY_TYPES);
    const subtypeLabel = answers.ringSubtype ? getLabelFor("sub", answers.ringSubtype, RING_SUBTYPES) : (answers.earringSubtype ? getLabelFor("sub", answers.earringSubtype, EARRING_SUBTYPES) : "");
    const metalLabel = getLabelFor("metal", answers.metal, METALS);
    const gemLabels = answers.gemstones.map(g => getLabelFor("gem", g, GEMSTONES)).join(", ");
    const styleLabel = getLabelFor("style", answers.style, STYLES);
    const occasionLabel = getLabelFor("occ", answers.occasion, OCCASIONS);

    const prompt = `You are an expert jewellery design consultant. A customer wants a custom piece with these preferences:

- Type: ${typeLabel}${subtypeLabel ? ` (${subtypeLabel} style)` : ""}
- Occasion: ${occasionLabel}
- Metal: ${metalLabel}
- Gemstone(s): ${gemLabels}
- Style: ${styleLabel}${answers.inspirationDesigners.length > 0 ? `
- Designer inspiration: ${answers.inspirationDesigners.map(id => (DESIGNERS.find(d => d.id === id) || {}).label || id).join(", ")}` : ""}${answers.inspirationText ? `
- Customer's vision: "${answers.inspirationText}"` : ""}${answers.projectType === "reimagine" ? `

IMPORTANT CONTEXT: This customer is reimagining an existing piece of jewellery.
${answers.existingDescription ? `Their existing piece: ${answers.existingDescription}` : ""}
Preservation preference: ${
  answers.existingPreservation === "preserve-all" ? "They want to keep the overall design — just update or modernize it" :
  answers.existingPreservation === "preserve-parts" ? "They want to preserve certain elements (specific stones or features) but redesign the rest" :
  answers.existingPreservation === "use-materials" ? "They want to melt down the metal and re-set any stones into an entirely new design" :
  "They're unsure and want to discuss options"
}
Your concepts should reflect this transformation — describe how the existing materials could be reimagined.` : ""}

Please suggest exactly 3 distinct design concepts that match these preferences. For each concept, provide:
1. A short creative name (3-5 words)
2. A vivid description (2-3 sentences) of what the piece would look like
3. A specific web search query (5-8 words) that would find a real reference image of a similar existing jewellery piece

Respond ONLY with valid JSON, no markdown backticks, in this exact format:
[
  {"name": "...", "description": "...", "searchQuery": "..."},
  {"name": "...", "description": "...", "searchQuery": "..."},
  {"name": "...", "description": "...", "searchQuery": "..."}
]`;

    try {
      const data = await callAiProxy({
        task: "preview",
        input: prompt,
        instructions: "You are an expert jewellery design consultant. Return only valid JSON when asked for structured design concepts.",
        maxOutputTokens: 1000,
      });
      const concepts = extractJsonArray(data.text).slice(0, 3);
      if (!concepts.length) {
        throw new Error("The AI response did not contain usable concepts.");
      }
      setPreviewConcepts(concepts);
    } catch (err) {
      console.error("Preview generation error:", err);
      const leadingStyleWord = (styleLabel || "Signature").split(/[ &]/).filter(Boolean)[0] || "Signature";
      const leadGem = gemLabels.split(",")[0] || "gemstone";
      const fallbackConcepts = [
        {
          name: `${leadingStyleWord} Heirloom ${typeLabel}`,
          description: `A refined ${metalLabel.toLowerCase()} ${typeLabel.toLowerCase()} centered around ${leadGem.toLowerCase()} details, with proportions tailored to feel ${styleLabel.toLowerCase()}. It is designed to feel custom from the first sketch while staying flexible for your consultation.`,
          searchQuery: `${metalLabel} ${styleLabel} ${typeLabel} ${leadGem}`.replace(/\s+/g, " ").trim(),
        },
        {
          name: `${occasionLabel} Statement ${typeLabel}`,
          description: `A bolder interpretation that leans into the ${occasionLabel.toLowerCase()} story with stronger lines, sculpted settings, and elevated metalwork. This direction gives Savoy's team room to personalize scale, stone placement, and finishing details in person.`,
          searchQuery: `${occasionLabel} statement ${typeLabel} ${metalLabel}`.replace(/\s+/g, " ").trim(),
        },
        {
          name: `Modern Atelier ${typeLabel}`,
          description: `A cleaner, contemporary concept with crisp silhouettes, balanced negative space, and a focus on wearability. It keeps the design premium and distinctive while leaving room to adapt around your notes and inspiration.`,
          searchQuery: `modern ${typeLabel} ${metalLabel} ${leadGem}`.replace(/\s+/g, " ").trim(),
        },
      ];
      setPreviewConcepts(fallbackConcepts);
    } finally {
      setPreviewLoading(false);
    }
  };

  // Determine whether the Continue button should appear (auto-advance steps hide it)
  const showContinueButton = (() => {
    const alwaysContinue = ["existing", "intro", "gemstone", "inspiration", "preview", "details"];
    if (alwaysContinue.includes(currentStepName)) return true;
    if (currentStepName === "type" && (answers.type === "ring" || answers.type === "earrings")) return true;
    if (currentStepName === "timeline" && answers.timeline === "specific") return true;
    return false;
  })();

  return (
    <div style={styles.wrapper}>
      <style>{`
        @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400&family=Nunito+Sans:wght@300;400;600&display=swap');
        * { box-sizing: border-box; margin: 0; padding: 0; }
        .fade-in { animation: fadeIn 0.4s ease-out forwards; }
        .fade-out { animation: fadeOut 0.3s ease-in forwards; }
        @keyframes fadeIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
        @keyframes fadeOut { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-12px); } }
        @keyframes shimmer { 0% { background-position: -200% center; } 100% { background-position: 200% center; } }
        @keyframes pulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 0.7; } }
        @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
        @keyframes skeletonPulse { 0%, 100% { opacity: 0.15; } 50% { opacity: 0.3; } }
        .option-card { transition: all 0.25s ease; cursor: pointer; }
        .option-card:hover { transform: translateY(-2px); box-shadow: 0 6px 24px rgba(180,150,100,0.15); }
        .option-card.selected { border-color: #C9A96E !important; box-shadow: 0 0 0 2px #C9A96E, 0 6px 24px rgba(180,150,100,0.2); }
        .gem-chip { transition: all 0.2s ease; cursor: pointer; }
        .gem-chip:hover { transform: scale(1.05); }
        .gem-chip.selected { box-shadow: 0 0 0 2px #C9A96E; }
        .btn-primary { transition: all 0.25s ease; }
        .btn-primary:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 4px 16px rgba(180,150,100,0.3); }
        .btn-primary:disabled { opacity: 0.35; cursor: not-allowed; }
        .btn-back { transition: all 0.2s ease; }
        .btn-back:hover { color: #C9A96E; }
        .photo-thumb { position: relative; border-radius: 8px; overflow: hidden; }
        .photo-remove { position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; background: rgba(0,0,0,0.7); border: none; border-radius: 50%; color: #fff; font-size: 12px; cursor: pointer; display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.2s; }
        .photo-thumb:hover .photo-remove { opacity: 1; }
        .birthstone-btn { transition: all 0.25s ease; cursor: pointer; }
        .birthstone-btn:hover { background: rgba(201,169,110,0.15) !important; border-color: #C9A96E !important; }
        .month-card { transition: all 0.2s ease; cursor: pointer; }
        .month-card:hover { transform: translateY(-2px); border-color: rgba(201,169,110,0.4) !important; background: rgba(201,169,110,0.08) !important; }
        .concept-card { transition: all 0.3s ease; }
        .concept-card:hover { transform: translateY(-3px); box-shadow: 0 8px 30px rgba(180,150,100,0.2); }
        .concept-img { transition: transform 0.4s ease; }
        .concept-card:hover .concept-img { transform: scale(1.05); }
        .gen-img-btn:hover { background: rgba(201,169,110,0.15) !important; border-color: #C9A96E !important; transform: translateY(-1px); box-shadow: 0 4px 16px rgba(201,169,110,0.15); }
        .like-btn:hover { background: rgba(201,169,110,0.12) !important; border-color: rgba(201,169,110,0.5) !important; color: #C9A96E !important; }
        input[type="text"], input[type="email"], input[type="tel"], input[type="date"], textarea {
          background: rgba(255,255,255,0.04); border: 1px solid rgba(201,169,110,0.25); border-radius: 8px; padding: 12px 16px;
          color: #F5F0E8; font-family: 'Nunito Sans', sans-serif; font-size: 16px; width: 100%; outline: none; transition: border-color 0.2s;
        }
        input:focus, textarea:focus { border-color: #C9A96E; }
        input::placeholder, textarea::placeholder { color: rgba(245,240,232,0.35); }
        ::-webkit-scrollbar { width: 4px; }
        ::-webkit-scrollbar-track { background: transparent; }
        ::-webkit-scrollbar-thumb { background: rgba(201,169,110,0.3); border-radius: 4px; }
      `}</style>

      {/* Background texture */}
      <div style={styles.bgTexture} />
      <div style={styles.bgGlow} />

      {/* Header */}
      <header style={styles.header}>
        <div style={{ ...styles.logoArea, cursor: "pointer" }} onClick={() => goTo(0)}>
          <img src={SAVOYS_LOGO} alt="Savoy's Jewellers" style={styles.logoImg} />
          <div style={{ width: 1, height: 36, background: "rgba(201,169,110,0.25)", flexShrink: 0 }} />
          <span style={styles.brandSub}>Custom Design Studio</span>
        </div>
        {step > 0 && step < STEPS.length - 1 && (
          <div style={styles.progressWrap}>
            <div style={styles.progressTrack}>
              <div style={{ ...styles.progressBar, width: `${((effectiveStepIndex + 1) / effectiveSteps.length) * 100}%` }} />
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
              <span style={styles.progressLabel}>Step {effectiveStepIndex + 1} of {effectiveSteps.length}</span>
              {saveStatus && (
                <span style={{ fontSize: 10, color: saveStatus === "error" ? "rgba(220,80,80,0.7)" : "rgba(201,169,110,0.5)", transition: "opacity 0.3s" }}>
                  {saveStatus === "saving" ? "Saving..." : saveStatus === "error" ? "⚠ Save failed" : "✓ Saved"}
                </span>
              )}
            </div>
          </div>
        )}
      </header>

      {/* Content */}
      <main ref={contentRef} style={styles.main} className={animating ? "fade-out" : "fade-in"} key={step}>
        {currentStepName === "welcome" && (
          <div style={styles.centeredContent}>
            <div style={styles.heroIcon}>✦</div>
            <h2 style={styles.heroTitle}>Design Something<br />Truly Yours</h2>
            <p style={styles.heroDesc}>
              For over 70 years, Savoy's master goldsmiths have brought visions to life — 
              whether designing something new or reimagining a cherished piece. 
              This guided experience will help you share your dream with our artisans.
            </p>
            <p style={styles.heroDuration}>
              ◷ About 3–5 minutes
            </p>
            <button className="btn-primary" style={styles.ctaButton} onClick={next}>
              Begin Your Design Journey
            </button>
            <p style={styles.heroFootnote}>
              Your responses help our team prepare a personalized consultation for you.
            </p>
          </div>
        )}

        {/* ── PROJECT TYPE STEP ── */}
        {currentStepName === "project" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>How would you like to begin?</h2>
            <p style={styles.stepDesc}>Are you starting with a blank canvas, or do you have existing jewellery you'd like to transform into something new?</p>
            <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
              <div
                className={`option-card ${answers.projectType === "new" ? "selected" : ""}`}
                style={{ ...styles.occasionCard, padding: "22px 24px", display: "flex", flexDirection: "row", alignItems: "center", gap: 18 }}
                onClick={() => { update("projectType", "new"); setTimeout(() => goTo(STEPS.indexOf("intro")), 150); }}
              >
                <span style={{ fontSize: 32, flexShrink: 0 }}>✨</span>
                <div>
                  <span style={{ ...styles.occasionLabel, fontSize: 16 }}>Start From Scratch</span>
                  <span style={{ ...styles.occasionDesc, marginTop: 4, display: "block" }}>
                    Design a brand new piece — we'll guide you through every choice from metal to gemstone.
                  </span>
                </div>
              </div>
              <div
                className={`option-card ${answers.projectType === "reimagine" ? "selected" : ""}`}
                style={{ ...styles.occasionCard, padding: "22px 24px", display: "flex", flexDirection: "row", alignItems: "center", gap: 18 }}
                onClick={() => { update("projectType", "reimagine"); setTimeout(() => goTo(STEPS.indexOf("existing")), 150); }}
              >
                <span style={{ fontSize: 32, flexShrink: 0 }}>🔄</span>
                <div>
                  <span style={{ ...styles.occasionLabel, fontSize: 16 }}>Reimagine Existing Jewellery</span>
                  <span style={{ ...styles.occasionDesc, marginTop: 4, display: "block" }}>
                    Turn a family heirloom, inherited piece, or jewellery you no longer wear into something you'll love.
                  </span>
                </div>
              </div>
            </div>
          </div>
        )}

        {/* ── EXISTING JEWELLERY DETAIL STEP ── */}
        {currentStepName === "existing" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>Tell us about your existing piece</h2>
            <p style={styles.stepDesc}>
              If you have photos or details about the piece, they'll help our goldsmiths plan your transformation — but don't worry if you don't, we can discuss in person.
            </p>

            {/* Photo upload — optional */}
            <div
              style={styles.dropZone}
              onClick={() => existingFileInputRef.current?.click()}
            >
              <input
                ref={existingFileInputRef}
                type="file"
                multiple
                accept="image/*"
                onChange={handleExistingPhotos}
                style={{ display: "none" }}
              />
              <div style={styles.dropIcon}>📷</div>
              <p style={styles.dropText}>Upload photos of your piece <span style={{ fontWeight: 300, opacity: 0.6 }}>(optional)</span></p>
              <p style={styles.dropSubtext}>Up to 5 images · Show from multiple angles if possible</p>
            </div>
            {existingPhotoUrls.length > 0 && (
              <div style={styles.photoRow}>
                {existingPhotoUrls.map((url, idx) => (
                  <div key={idx} className="photo-thumb" style={styles.photoThumb}>
                    <img src={url} alt={`Existing piece ${idx + 1}`} style={styles.photoImg} />
                    <button className="photo-remove" onClick={() => removeExistingPhoto(idx)}>✕</button>
                  </div>
                ))}
              </div>
            )}

            {/* Description */}
            <div style={{ marginTop: 24 }}>
              <label style={styles.inputLabel}>Describe the piece (optional)</label>
              <textarea
                rows={3}
                placeholder="e.g. My grandmother's gold engagement ring with a small diamond — the band is yellow gold, possibly 14k. There are tiny diamonds on either side of the center stone..."
                value={answers.existingDescription}
                onChange={(e) => update("existingDescription", e.target.value)}
                style={{ resize: "vertical", marginTop: 8 }}
              />
              <p style={{ fontSize: 13, color: "rgba(245,240,232,0.3)", marginTop: 6, fontStyle: "italic" }}>
                Include any details you know: type of metal, stones, approximate age, sentimental significance
              </p>
            </div>
            <p style={{ fontSize: 14, color: "rgba(201,169,110,0.5)", marginTop: 20, marginBottom: 4, textAlign: "center", fontStyle: "italic" }}>
              No photos or description? No problem — you can bring the piece to your consultation.
            </p>

            {/* Preservation preference */}
            <div style={{ marginTop: 28 }}>
              <label style={{ ...styles.inputLabel, marginBottom: 12, display: "block" }}>
                What would you like to preserve? *
              </label>
              <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
                {[
                  { id: "preserve-all", label: "Keep the overall design", desc: "Repair, resize, or subtly update while keeping the original piece recognizable", icon: "🏛️" },
                  { id: "preserve-parts", label: "Preserve certain elements", desc: "Keep specific stones or features, but redesign the rest into something new", icon: "💎" },
                  { id: "use-materials", label: "Use the metals & stones", desc: "Melt down the gold/silver and re-set the stones in an entirely new design", icon: "🔥" },
                  { id: "unsure", label: "Not sure yet — let's discuss", desc: "Our goldsmiths will assess the piece and walk you through the options", icon: "💬" },
                ].map((opt) => (
                  <div
                    key={opt.id}
                    className={`option-card ${answers.existingPreservation === opt.id ? "selected" : ""}`}
                    style={{ ...styles.occasionCard, display: "flex", flexDirection: "row", alignItems: "center", gap: 14, padding: "14px 18px" }}
                    onClick={() => update("existingPreservation", opt.id)}
                  >
                    <span style={{ fontSize: 22, flexShrink: 0 }}>{opt.icon}</span>
                    <div>
                      <span style={styles.occasionLabel}>{opt.label}</span>
                      <span style={{ ...styles.occasionDesc, display: "block", marginTop: 2 }}>{opt.desc}</span>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        )}

        {/* ── INTRO / EMAIL CAPTURE STEP ── */}
        {currentStepName === "intro" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>Before we dive in — where should we send your design brief?</h2>
            <p style={styles.stepDesc}>
              We'll save your progress as you go, so you can pick up where you left off if you need to step away.
            </p>
            <div style={{ display: "flex", flexDirection: "column", gap: 16, maxWidth: 420 }}>
              <div style={styles.formGroup}>
                <label style={styles.inputLabel}>Email address *</label>
                <input type="email" placeholder="you@example.com" value={answers.email} onChange={(e) => update("email", e.target.value)} />
              </div>
              <div style={styles.formGroup}>
                <label style={styles.inputLabel}>First name (optional — you can add it later)</label>
                <input type="text" placeholder="Your first name" value={answers.name} onChange={(e) => update("name", e.target.value)} />
              </div>
            </div>
            <p style={styles.privacyNote}>🔒 We'll never share your info. This just lets us save your design preferences and follow up when you're ready.</p>
          </div>
        )}

        {currentStepName === "type" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>
              {answers.projectType === "reimagine" ? "What would you like it to become?" : "What would you like us to create?"}
            </h2>
            <p style={styles.stepDesc}>
              {answers.projectType === "reimagine"
                ? "Select the type of jewellery you'd like your existing piece transformed into."
                : "Select the type of jewellery you're envisioning."}
            </p>
            <div style={styles.optionGrid}>
              {JEWELLERY_TYPES.map((t) => (
                <div key={t.id} className={`option-card ${answers.type === t.id ? "selected" : ""}`} style={styles.optionCard} onClick={() => {
                  update("type", t.id);
                  if (t.id !== "ring" && t.id !== "earrings") setTimeout(next, 150);
                }}>
                  <span style={styles.optionIcon}>{t.icon}</span>
                  <span style={styles.optionLabel}>{t.label}</span>
                </div>
              ))}
            </div>
            {answers.type === "ring" && (
              <div style={{ marginTop: 28 }}>
                <p style={{ ...styles.stepDesc, marginBottom: 14 }}>Any particular ring style in mind?</p>
                <div style={styles.chipRow}>
                  {RING_SUBTYPES.map((s) => (
                    <div key={s.id} className={`gem-chip ${answers.ringSubtype === s.id ? "selected" : ""}`}
                      style={{ ...styles.chip, background: answers.ringSubtype === s.id ? "rgba(201,169,110,0.2)" : "rgba(255,255,255,0.05)", borderColor: answers.ringSubtype === s.id ? "#C9A96E" : "rgba(255,255,255,0.1)" }}
                      onClick={() => update("ringSubtype", s.id)}>{s.label}</div>
                  ))}
                </div>
              </div>
            )}
            {answers.type === "ring" && (
              <div style={{ marginTop: 24 }}>
                <label style={styles.inputLabel}>Ring size (if known)</label>
                <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                  <input type="text" placeholder="e.g. 7, or 'not sure'" value={answers.ringSize} onChange={(e) => update("ringSize", e.target.value)} style={{ maxWidth: 200 }} />
                  <button onClick={() => setShowRingSizer(true)}
                    style={{ fontSize: 13, color: "#C9A96E", background: "none", border: "none", cursor: "pointer", whiteSpace: "nowrap", borderBottom: "1px solid rgba(201,169,110,0.3)", paddingBottom: 1, fontFamily: "'Nunito Sans', sans-serif" }}>
                    📏 Find my size
                  </button>
                </div>
                <p style={{ fontSize: 13, color: "rgba(245,240,232,0.35)", marginTop: 8, lineHeight: 1.5 }}>
                  Don't know your size? Use our ring sizer tool, or we'll measure during your consultation.
                </p>
              </div>
            )}
            {answers.type === "earrings" && (
              <div style={{ marginTop: 28 }}>
                <p style={{ ...styles.stepDesc, marginBottom: 14 }}>What style of earring?</p>
                <div style={styles.chipRow}>
                  {EARRING_SUBTYPES.map((s) => (
                    <div key={s.id} className={`gem-chip ${answers.earringSubtype === s.id ? "selected" : ""}`}
                      style={{ ...styles.chip, background: answers.earringSubtype === s.id ? "rgba(201,169,110,0.2)" : "rgba(255,255,255,0.05)", borderColor: answers.earringSubtype === s.id ? "#C9A96E" : "rgba(255,255,255,0.1)" }}
                      onClick={() => update("earringSubtype", s.id)}>{s.label}</div>
                  ))}
                </div>
              </div>
            )}
          </div>
        )}

        {currentStepName === "occasion" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>What's the occasion?</h2>
            <p style={styles.stepDesc}>This helps our designers understand the sentiment behind your piece.</p>
            <div style={styles.occasionGrid}>
              {OCCASIONS.map((o) => (
                <div key={o.id} className={`option-card ${answers.occasion === o.id ? "selected" : ""}`} style={styles.occasionCard} onClick={() => { update("occasion", o.id); setTimeout(next, 150); }}>
                  <span style={styles.occasionLabel}>{o.label}</span>
                  <span style={styles.occasionDesc}>{o.desc}</span>
                </div>
              ))}
            </div>
          </div>
        )}

        {currentStepName === "metal" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>Choose your metal</h2>
            <p style={styles.stepDesc}>
              {answers.projectType === "reimagine"
                ? "Would you like to keep the same metal, or change to something different? Our team can advise during your consultation."
                : "Which metal speaks to you? Our team can advise further during your consultation."}
            </p>
            <div style={styles.metalGrid}>
              {METALS.map((m) => (
                <div key={m.id} className={`option-card ${answers.metal === m.id ? "selected" : ""}`} style={styles.metalCard} onClick={() => { update("metal", m.id); setTimeout(next, 150); }}>
                  <div style={{ ...styles.metalSwatch, background: m.color }} />
                  <span style={styles.metalLabel}>{m.label}</span>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* ── GEMSTONE STEP WITH HELPER ── */}
        {currentStepName === "gemstone" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>Gemstone preferences</h2>
            <p style={styles.stepDesc}>Select one or more — you can always refine later with our team.</p>
            
            {/* Help Me Pick Button */}
            <div className="birthstone-btn" onClick={() => setShowBirthstoneHelper(true)}
              style={{ display: "flex", alignItems: "center", gap: 10, padding: "14px 18px", background: "rgba(201,169,110,0.06)", border: "1px solid rgba(201,169,110,0.2)", borderRadius: 12, marginBottom: 20, cursor: "pointer" }}>
              <span style={{ fontSize: 22 }}>💡</span>
              <div>
                <span style={{ fontSize: 14, fontWeight: 600, color: "#C9A96E", display: "block" }}>Help Me Pick</span>
                <span style={{ fontSize: 14, fontWeight: 300, color: "rgba(245,240,232,0.5)" }}>Not sure? Explore birthstones, meanings & recommendations</span>
              </div>
              <span style={{ marginLeft: "auto", color: "rgba(201,169,110,0.5)", fontSize: 18 }}>→</span>
            </div>

            <div style={styles.gemGrid}>
              {GEMSTONES.map((g) => (
                <div key={g.id} className={`gem-chip ${answers.gemstones.includes(g.id) ? "selected" : ""}`}
                  style={{ ...styles.gemChip, background: answers.gemstones.includes(g.id) ? "rgba(201,169,110,0.15)" : "rgba(255,255,255,0.04)", borderColor: answers.gemstones.includes(g.id) ? "#C9A96E" : "rgba(255,255,255,0.1)" }}
                  onClick={() => toggleGemstone(g.id)}>
                  <div style={{ ...styles.gemDot, background: g.color, border: ["diamond","moissanite","opal","pearl"].includes(g.id) ? "1px solid rgba(255,255,255,0.3)" : "none" }} />
                  <span>{g.label}</span>
                </div>
              ))}
            </div>
          </div>
        )}

        {currentStepName === "style" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>What style resonates with you?</h2>
            <p style={styles.stepDesc}>Think about the overall feel you're drawn to.</p>
            <div style={styles.styleGrid}>
              {STYLES.map((s) => (
                <div key={s.id} className={`option-card ${answers.style === s.id ? "selected" : ""}`} style={styles.styleCard} onClick={() => { update("style", s.id); setTimeout(next, 150); }}>
                  <span style={styles.styleEmoji}>{s.img}</span>
                  <span style={styles.styleLabel}>{s.label}</span>
                  <span style={styles.styleDesc}>{s.desc}</span>
                </div>
              ))}
            </div>
          </div>
        )}

        {currentStepName === "inspiration" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>Share your inspiration</h2>
            <p style={styles.stepDesc}>Help our designers understand your vision. Choose whichever way feels easiest for you.</p>

            {/* Method picker */}
            {!answers.inspirationMethod && (
              <div style={{ display: "flex", flexDirection: "column", gap: 12, marginTop: 8 }}>
                <div className="option-card" style={{ ...styles.optionCard, padding: "20px 18px", display: "flex", gap: 14, alignItems: "center" }}
                  onClick={() => update("inspirationMethod", "photos")}>
                  <span style={{ fontSize: 28 }}>📸</span>
                  <div>
                    <div style={{ fontSize: 15, fontWeight: 600, color: "#F5F0E8" }}>Upload photos</div>
                    <div style={{ fontSize: 13, color: "rgba(245,240,232,0.45)", marginTop: 2 }}>Pinterest saves, screenshots, sketches — anything visual</div>
                  </div>
                </div>
                <div className="option-card" style={{ ...styles.optionCard, padding: "20px 18px", display: "flex", gap: 14, alignItems: "center" }}
                  onClick={() => update("inspirationMethod", "guided")}>
                  <span style={{ fontSize: 28 }}>💬</span>
                  <div>
                    <div style={{ fontSize: 15, fontWeight: 600, color: "#F5F0E8" }}>Describe your vision</div>
                    <div style={{ fontSize: 13, color: "rgba(245,240,232,0.45)", marginTop: 2 }}>Pick designers you love, or tell us in your own words</div>
                  </div>
                </div>
              </div>
            )}

            {/* ── Photo upload path ── */}
            {answers.inspirationMethod === "photos" && (
              <div>
                <div style={styles.dropZone} onClick={() => fileInputRef.current?.click()}>
                  <input ref={fileInputRef} type="file" multiple accept="image/*" onChange={handlePhotos} style={{ display: "none" }} />
                  <div style={styles.dropIcon}>📸</div>
                  <p style={styles.dropText}>Tap to upload photos</p>
                  <p style={styles.dropSubtext}>Up to 5 images · JPG, PNG, HEIC</p>
                </div>
                {photoPreviewUrls.length > 0 && (
                  <div style={styles.photoRow}>
                    {photoPreviewUrls.map((url, idx) => (
                      <div key={idx} className="photo-thumb" style={styles.photoThumb}>
                        <img src={url} alt={"Inspiration " + (idx + 1)} style={styles.photoImg} />
                        <button className="photo-remove" onClick={() => removePhoto(idx)}>✕</button>
                      </div>
                    ))}
                  </div>
                )}
                <button style={{ background: "none", border: "none", color: "rgba(201,169,110,0.5)", fontSize: 13, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif", marginTop: 16 }}
                  onClick={() => update("inspirationMethod", null)}>
                  ← Choose a different method
                </button>
              </div>
            )}

            {/* ── Guided path ── */}
            {answers.inspirationMethod === "guided" && !answers.inspirationPath && (
              <div style={{ display: "flex", flexDirection: "column", gap: 12, marginTop: 8 }}>
                <div className="option-card" style={{ ...styles.optionCard, padding: "20px 18px", display: "flex", gap: 14, alignItems: "center" }}
                  onClick={() => update("inspirationPath", "designers")}>
                  <span style={{ fontSize: 28 }}>✨</span>
                  <div>
                    <div style={{ fontSize: 15, fontWeight: 600, color: "#F5F0E8" }}>Designers I love</div>
                    <div style={{ fontSize: 13, color: "rgba(245,240,232,0.45)", marginTop: 2 }}>Select from world-renowned jewellery houses</div>
                  </div>
                </div>
                <div className="option-card" style={{ ...styles.optionCard, padding: "20px 18px", display: "flex", gap: 14, alignItems: "center" }}
                  onClick={() => update("inspirationPath", "freeform")}>
                  <span style={{ fontSize: 28 }}>✍️</span>
                  <div>
                    <div style={{ fontSize: 15, fontWeight: 600, color: "#F5F0E8" }}>Describe it myself</div>
                    <div style={{ fontSize: 13, color: "rgba(245,240,232,0.45)", marginTop: 2 }}>Tell us in your own words what inspires you</div>
                  </div>
                </div>
                <button style={{ background: "none", border: "none", color: "rgba(201,169,110,0.5)", fontSize: 13, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif", marginTop: 8 }}
                  onClick={() => update("inspirationMethod", null)}>
                  ← Choose a different method
                </button>
              </div>
            )}

            {/* ── Designer selection ── */}
            {answers.inspirationPath === "designers" && (
              <div>
                <p style={{ fontSize: 14, color: "rgba(245,240,232,0.5)", marginBottom: 14 }}>Select any designers whose aesthetic resonates with you. This helps our goldsmiths understand your taste.</p>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 10 }}>
                  {DESIGNERS.map((d) => {
                    const sel = answers.inspirationDesigners.includes(d.id);
                    return (
                      <div key={d.id} className={"gem-chip " + (sel ? "selected" : "")}
                        onClick={() => {
                          const cur = answers.inspirationDesigners;
                          update("inspirationDesigners", sel ? cur.filter(x => x !== d.id) : [...cur, d.id]);
                        }}
                        style={{
                          padding: "10px 16px", borderRadius: 20, cursor: "pointer",
                          border: sel ? "1px solid #C9A96E" : "1px solid rgba(255,255,255,0.08)",
                          background: sel ? "rgba(201,169,110,0.12)" : "rgba(255,255,255,0.03)",
                          transition: "all 0.2s",
                        }}>
                        <span style={{ fontSize: 14, fontWeight: sel ? 600 : 400, color: sel ? "#C9A96E" : "#F5F0E8" }}>{d.label}</span>
                        <span style={{ display: "block", fontSize: 11, color: "rgba(245,240,232,0.35)", marginTop: 2 }}>{d.desc}</span>
                      </div>
                    );
                  })}
                </div>
                {answers.inspirationDesigners.length > 0 && (
                  <p style={{ fontSize: 13, color: "#C9A96E", marginTop: 14 }}>
                    {"Selected: " + answers.inspirationDesigners.map(id => DESIGNERS.find(d => d.id === id)?.label).join(", ")}
                  </p>
                )}
                <div style={{ display: "flex", gap: 12, marginTop: 16 }}>
                  <button style={{ background: "none", border: "none", color: "rgba(201,169,110,0.5)", fontSize: 13, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif" }}
                    onClick={() => update("inspirationPath", null)}>
                    ← Back
                  </button>
                </div>
              </div>
            )}

            {/* ── Free-form text ── */}
            {answers.inspirationPath === "freeform" && (
              <div>
                <p style={{ fontSize: 14, color: "rgba(245,240,232,0.5)", marginBottom: 14 }}>Describe the look, feel, or references that inspire you — anything goes. Think about shapes, textures, eras, nature, architecture, or art that speak to you.</p>
                <textarea
                  placeholder="e.g. I love the Art Deco era — geometric lines, emerald-cut stones, platinum settings. I want something that feels like the Chrysler Building in ring form..."
                  value={answers.inspirationText}
                  onChange={(e) => update("inspirationText", e.target.value)}
                  rows={5}
                  style={{ width: "100%", padding: 14, borderRadius: 10, border: "1px solid rgba(201,169,110,0.2)", background: "rgba(255,255,255,0.04)", color: "#F5F0E8", fontSize: 14, fontFamily: "'Nunito Sans', sans-serif", resize: "vertical", lineHeight: 1.6 }}
                />
                <div style={{ display: "flex", gap: 12, marginTop: 16 }}>
                  <button style={{ background: "none", border: "none", color: "rgba(201,169,110,0.5)", fontSize: 13, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif" }}
                    onClick={() => update("inspirationPath", null)}>
                    ← Back
                  </button>
                </div>
              </div>
            )}

            <p style={styles.skipHint}>Not sure yet? No problem — you can skip this step.</p>
          </div>
        )}

        {currentStepName === "budget" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>What's your budget range?</h2>
            <p style={styles.stepDesc}>This helps us recommend the best materials and techniques. All consultations are obligation-free.</p>
            <div style={styles.budgetGrid}>
              {BUDGETS.map((b) => (
                <div key={b.id} className={`option-card ${answers.budget === b.id ? "selected" : ""}`} style={styles.budgetCard} onClick={() => { update("budget", b.id); setTimeout(next, 150); }}>
                  {b.label}
                </div>
              ))}
            </div>
          </div>
        )}

        {currentStepName === "timeline" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>When do you need it?</h2>
            <p style={styles.stepDesc}>Custom pieces typically take 4–8 weeks, but we can accommodate most timelines.</p>
            <div style={styles.timelineGrid}>
              {TIMELINES.map((t) => (
                <div key={t.id} className={`option-card ${answers.timeline === t.id ? "selected" : ""}`} style={styles.timelineCard} onClick={() => {
                  update("timeline", t.id);
                  if (t.id !== "specific") setTimeout(next, 150);
                }}>
                  <span style={styles.timelineLabel}>{t.label}</span>
                  <span style={styles.timelineDesc}>{t.desc}</span>
                </div>
              ))}
            </div>
            {answers.timeline === "specific" && (
              <div style={{ marginTop: 20 }}>
                <label style={styles.inputLabel}>Target date</label>
                <input type="date" value={answers.specificDate} onChange={(e) => update("specificDate", e.target.value)} style={{ maxWidth: 220 }} />
              </div>
            )}
          </div>
        )}

        {/* ── DESIGN PREVIEW STEP ── */}
        {currentStepName === "preview" && (
          <div style={styles.stepContent}>

            {/* Catalogue match view (rings only, when catalogue loaded) */}
            {catalogueMatches && (
              <div>
                <h2 style={styles.stepTitle}>✨ Pieces From Our Collection</h2>
                <p style={styles.stepDesc}>
                  Based on your preferences, here are rings from our catalogue that match your vision. 
                  These can serve as inspiration — or as a starting point your goldsmith can customize.
                </p>
                <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
                  {catalogueMatches.map((item) => {
                    const isLiked = (answers.likedProducts || []).includes(item.s);
                    return (
                      <div key={item.s} style={{
                        background: isLiked ? "rgba(201,169,110,0.08)" : "rgba(255,255,255,0.03)",
                        border: isLiked ? "1px solid rgba(201,169,110,0.3)" : "1px solid rgba(255,255,255,0.06)",
                        borderRadius: 14, overflow: "hidden", transition: "all 0.2s",
                      }}>
                        <div style={{ display: "flex", gap: 14, padding: 14 }}>
                          <div style={{ width: 110, height: 110, flexShrink: 0, borderRadius: 10, overflow: "hidden", background: "rgba(255,255,255,0.05)", position: "relative" }}>
                            <img src={item.it} alt={item.n} style={{ width: "100%", height: "100%", objectFit: "contain", position: "relative", zIndex: 1 }} loading="lazy" onError={(e) => { e.target.style.display = "none"; }} />
                            <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", background: "linear-gradient(135deg, rgba(201,169,110,0.08), rgba(201,169,110,0.02))" }}>
                              <span style={{ fontSize: 32, opacity: 0.3 }}>💍</span>
                              <span style={{ fontSize: 9, color: "rgba(201,169,110,0.35)", marginTop: 4, textAlign: "center", padding: "0 6px" }}>{item.d}</span>
                            </div>
                          </div>
                          <div style={{ flex: 1, minWidth: 0 }}>
                            <h3 style={{ fontSize: 15, fontWeight: 600, color: "#F5F0E8", margin: "0 0 4px", lineHeight: 1.3 }}>{item.n}</h3>
                            <p style={{ fontSize: 12, color: "rgba(201,169,110,0.6)", margin: "0 0 6px" }}>{item.d}{item.md ? (" · " + item.md) : ""}</p>
                            {item.tc > 0 && <p style={{ fontSize: 12, color: "rgba(245,240,232,0.4)", margin: "0 0 6px" }}>{item.tc.toFixed(2)}ct total{item.ts > 0 ? (" · " + item.ts + " stones") : ""}</p>}
                            <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 6 }}>
                              {item.p > 0 ? (
                                <span style={{ fontSize: 16, fontWeight: 600, color: "#C9A96E", fontFamily: "'Playfair Display', serif" }}>{"$" + item.p.toLocaleString()}</span>
                              ) : (
                                <span style={{ fontSize: 12, color: "rgba(245,240,232,0.3)", fontStyle: "italic" }}>Contact for price</span>
                              )}
                            </div>
                          </div>
                        </div>
                        <div style={{ display: "flex", borderTop: "1px solid rgba(255,255,255,0.04)" }}>
                          <button onClick={() => {
                            const liked = answers.likedProducts || [];
                            update("likedProducts", isLiked ? liked.filter(x => x !== item.s) : [...liked, item.s]);
                          }} style={{
                            flex: 1, padding: "10px 0", background: "none", border: "none", borderRight: "1px solid rgba(255,255,255,0.04)",
                            color: isLiked ? "#C9A96E" : "rgba(245,240,232,0.4)", fontSize: 13, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif",
                          }}>
                            {isLiked ? "♥ Saved" : "♡ Save this"}
                          </button>
                          <a href={item.u} target="_blank" rel="noopener noreferrer" style={{
                            flex: 1, padding: "10px 0", textAlign: "center", textDecoration: "none",
                            color: "rgba(201,169,110,0.5)", fontSize: 13, fontFamily: "'Nunito Sans', sans-serif",
                          }}>View details →</a>
                        </div>
                      </div>
                    );
                  })}
                </div>
                <div style={{ background: "rgba(201,169,110,0.06)", border: "1px solid rgba(201,169,110,0.12)", borderRadius: 12, padding: "16px 20px", marginTop: 14 }}>
                  <p style={{ fontSize: 15, color: "rgba(245,240,232,0.55)", lineHeight: 1.6 }}>
                    💬 <strong style={{ color: "#C9A96E" }}>These are starting points.</strong> Save your favourites — our designers will use them as references during your in-store consultation to craft something uniquely yours.
                  </p>
                </div>
                <div style={{ textAlign: "center", marginTop: 10 }}>
                  <button className="btn-back" style={{ background: "none", border: "none", color: "rgba(201,169,110,0.6)", fontSize: 14, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif" }}
                    onClick={() => { setCatalogueMatches(null); setPreviewConcepts(null); loadMatches(); }}>
                    🔄 Show different matches
                  </button>
                </div>
              </div>
            )}

            {/* AI concepts fallback (non-ring types, or no catalogue) */}
            {!catalogueMatches && (
              <div>
                <h2 style={styles.stepTitle}>✨ Design Concepts For You</h2>
                <p style={styles.stepDesc}>
                  Based on your selections, here are three design directions our artisans might explore. 
                  These are starting points — your final piece will be uniquely yours.
                </p>

            {previewLoading && (
              <div style={{ textAlign: "center", padding: "40px 0" }}>
                <div style={{ width: 40, height: 40, border: "2px solid rgba(201,169,110,0.2)", borderTopColor: "#C9A96E", borderRadius: "50%", animation: "spin 1s linear infinite", margin: "0 auto 20px" }} />
                <p style={{ fontSize: 15, color: "rgba(245,240,232,0.6)", marginBottom: 8 }}>Crafting personalized concepts...</p>
                <p style={{ fontSize: 15, color: "rgba(245,240,232,0.35)" }}>Our AI is designing concepts matching your vision</p>
                <div style={{ display: "flex", flexDirection: "column", gap: 16, marginTop: 28 }}>
                  {[1,2,3].map(i => (
                    <div key={i} style={{ background: "rgba(255,255,255,0.03)", borderRadius: 14, padding: 20, display: "flex", gap: 16, alignItems: "center" }}>
                      <div style={{ width: 90, height: 90, borderRadius: 10, background: "rgba(201,169,110,0.08)", animation: "skeletonPulse 1.5s ease-in-out infinite", flexShrink: 0 }} />
                      <div style={{ flex: 1 }}>
                        <div style={{ height: 16, width: "60%", borderRadius: 4, background: "rgba(201,169,110,0.08)", animation: "skeletonPulse 1.5s ease-in-out infinite", marginBottom: 10 }} />
                        <div style={{ height: 12, width: "100%", borderRadius: 4, background: "rgba(255,255,255,0.04)", animation: "skeletonPulse 1.5s ease-in-out infinite", marginBottom: 6 }} />
                        <div style={{ height: 12, width: "80%", borderRadius: 4, background: "rgba(255,255,255,0.04)", animation: "skeletonPulse 1.5s ease-in-out infinite" }} />
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {previewError && (
              <div style={{ textAlign: "center", padding: "40px 0" }}>
                <p style={{ fontSize: 14, color: "rgba(245,240,232,0.5)", marginBottom: 16 }}>{previewError}</p>
                <button className="btn-primary" style={{ ...styles.ctaButton, padding: "12px 28px", fontSize: 13 }} onClick={generatePreview}>
                  Try Again
                </button>
              </div>
            )}

            {previewConcepts && (
              <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
                {previewConcepts.map((concept, idx) => (
                  <ConceptCard
                    key={idx}
                    concept={concept}
                    index={idx}
                    metalColor={METALS.find(m => m.id === answers.metal)?.color || "#C9A96E"}
                    isLiked={answers.favoriteConceptIndex === idx}
                    onLike={(i) => {
                      const newFav = answers.favoriteConceptIndex === i ? null : i;
                      update("favoriteConceptIndex", newFav);
                    }}
                    onSvgGenerated={(i, svg) => {
                      setAnswers(a => {
                        const favs = [...(a.favoriteConcepts || [])];
                        favs[i] = { ...concept, svg };
                        return { ...a, favoriteConcepts: favs };
                      });
                      try {
                        window.storage.set(`svg:${sessionId}:${i}`, JSON.stringify({
                          index: i, name: concept.name, description: concept.description, svg,
                          generatedAt: new Date().toISOString(),
                        }));
                      } catch(e) { /* best effort */ }
                    }}
                  />
                ))}
                <div style={{ background: "rgba(201,169,110,0.06)", border: "1px solid rgba(201,169,110,0.12)", borderRadius: 12, padding: "16px 20px", marginTop: 8 }}>
                  <p style={{ fontSize: 15, color: "rgba(245,240,232,0.55)", lineHeight: 1.6 }}>
                    💬 <strong style={{ color: "#C9A96E" }}>These are just starting points.</strong> Tap ♡ to mark your favourite, or "Illustrate This Concept" to see an AI-generated visual. Our designers will refine the direction during your consultation.
                  </p>
                </div>
                <div style={{ textAlign: "center", marginTop: 8 }}>
                  <button className="btn-back" style={{ background: "none", border: "none", color: "rgba(201,169,110,0.6)", fontSize: 15, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif" }} onClick={() => { setPreviewConcepts(null); generatePreview(); }}>
                    🔄 Generate new concepts
                  </button>
                </div>
              </div>
            )}
              </div>
            )}
          </div>
        )}

        {currentStepName === "details" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>A few final details</h2>
            <p style={styles.stepDesc}>Help us prepare the best possible consultation for you.</p>
            <div style={styles.formGrid}>
              <div style={styles.formGroup}>
                <label style={styles.inputLabel}>Your full name *</label>
                <input type="text" placeholder="First and last name" value={answers.name} onChange={(e) => update("name", e.target.value)} />
              </div>
              <div style={styles.formGroup}>
                <label style={styles.inputLabel}>Email</label>
                <input type="email" placeholder="you@example.com" value={answers.email} onChange={(e) => update("email", e.target.value)} />
                {answers.email && <p style={{ fontSize: 12, color: "rgba(201,169,110,0.5)", marginTop: 4 }}>✓ Captured earlier — update if needed</p>}
              </div>
              <div style={styles.formGroup}>
                <label style={styles.inputLabel}>Phone (optional)</label>
                <input type="tel" placeholder="(705) 000-0000" value={answers.phone} onChange={(e) => update("phone", e.target.value)} />
              </div>
              <div style={{ ...styles.formGroup, gridColumn: "1 / -1" }}>
                <label style={styles.inputLabel}>Anything else you'd like us to know?</label>
                <textarea rows={3} placeholder="Special engravings, allergies to certain metals, sentimental details..." value={answers.notes} onChange={(e) => update("notes", e.target.value)} style={{ resize: "vertical" }} />
              </div>
            </div>
            <p style={styles.privacyNote}>🔒 Your information is kept private and only used to prepare your consultation.</p>
          </div>
        )}

        {currentStepName === "summary" && (
          <div style={styles.stepContent}>
            <div style={styles.summaryHeader}>
              <div style={styles.checkmark}>✓</div>
              <h2 style={styles.stepTitle}>Your Custom Design Brief</h2>
              <p style={styles.stepDesc}>Here's a summary of what you've shared. Our team will review this and reach out to schedule your consultation.</p>
            </div>
            <div style={styles.summaryCard}>
              <SummaryRow label="Project" value={answers.projectType === "reimagine" ? "Reimagining existing jewellery" : "New custom piece"} />
              {answers.projectType === "reimagine" && (
                <>
                  <SummaryRow label="Existing Piece" value={
                    (answers.existingPhotos.length > 0 ? `${answers.existingPhotos.length} photo(s)` : "") +
                    (answers.existingPhotos.length > 0 && answers.existingDescription ? " + " : "") +
                    (answers.existingDescription || (answers.existingPhotos.length === 0 ? "—" : ""))
                  } />
                  <SummaryRow label="Preservation" value={
                    answers.existingPreservation === "preserve-all" ? "Keep overall design" :
                    answers.existingPreservation === "preserve-parts" ? "Preserve certain elements" :
                    answers.existingPreservation === "use-materials" ? "Use the metals & stones" :
                    "Not sure yet — discuss"
                  } />
                </>
              )}
              <SummaryRow label="Jewellery Type" value={getLabelFor("type", answers.type, JEWELLERY_TYPES) + (answers.ringSubtype && answers.ringSubtype !== "unsure" ? ` — ${getLabelFor("ringSubtype", answers.ringSubtype, RING_SUBTYPES)}` : "") + (answers.earringSubtype && answers.earringSubtype !== "unsure" ? ` — ${getLabelFor("earringSubtype", answers.earringSubtype, EARRING_SUBTYPES)}` : "") + (answers.ringSize ? ` (Size: ${answers.ringSize})` : "")} />
              <SummaryRow label="Occasion" value={getLabelFor("occasion", answers.occasion, OCCASIONS)} />
              <SummaryRow label="Metal" value={getLabelFor("metal", answers.metal, METALS)} />
              <SummaryRow label="Gemstone(s)" value={answers.gemstones.map((g) => getLabelFor("gem", g, GEMSTONES)).join(", ")} />
              <SummaryRow label="Style" value={getLabelFor("style", answers.style, STYLES)} />
              <SummaryRow label="Inspiration" value={
                answers.inspirationMethod === "photos" && answers.photos.length > 0
                  ? answers.photos.length + " photo(s) uploaded"
                  : answers.inspirationDesigners.length > 0
                    ? "Designers: " + answers.inspirationDesigners.map(function(id) { return (DESIGNERS.find(function(d) { return d.id === id; }) || {}).label; }).join(", ")
                    : answers.inspirationText
                      ? "\"" + answers.inspirationText.substring(0, 60) + (answers.inspirationText.length > 60 ? "..." : "") + "\""
                      : "None provided"
              } />
              <SummaryRow label="Budget" value={getLabelFor("budget", answers.budget, BUDGETS)} />
              <SummaryRow label="Timeline" value={getLabelFor("timeline", answers.timeline, TIMELINES) + (answers.specificDate ? ` — ${answers.specificDate}` : "")} />
              {answers.favoriteConceptIndex !== null && previewConcepts?.[answers.favoriteConceptIndex] && (
                <SummaryRow label="Favourite Concept" value={`♥ ${previewConcepts[answers.favoriteConceptIndex].name}`} />
              )}
              <SummaryRow label="Name" value={answers.name} />
              <SummaryRow label="Email" value={answers.email} />
              {answers.phone && <SummaryRow label="Phone" value={answers.phone} />}
              {answers.notes && <SummaryRow label="Notes" value={answers.notes} />}
            </div>
            <div style={styles.summaryActions}>
              {submitState === "idle" && (
                <button className="btn-primary" style={styles.ctaButton} onClick={async () => {
                  setSubmitState("sending");
                  setSubmitDetail("Preparing your design brief...");
                  try {
                    // Build full payload — this one includes compressed photos + SVGs for the email
                    const payload = {
                      _action: "submit",
                      sessionId,
                      email: answers.email, name: answers.name, phone: answers.phone,
                      projectType: answers.projectType,
                      existingDescription: answers.existingDescription,
                      existingPreservation: answers.existingPreservation,
                      type: answers.type, ringSubtype: answers.ringSubtype, earringSubtype: answers.earringSubtype, ringSize: answers.ringSize,
                      occasion: answers.occasion, metal: answers.metal,
                      gemstones: answers.gemstones, style: answers.style,
                      budget: answers.budget, timeline: answers.timeline,
                      specificDate: answers.specificDate, notes: answers.notes,
                      favoriteConceptIndex: answers.favoriteConceptIndex,
                      favoriteConcepts: (answers.favoriteConcepts || []).map(c => c ? { name: c.name, description: c.description, svg: c.svg } : null),
                      concepts: previewConcepts || [],
                      lastStep: "summary",
                      completed: true,
                      existingPhotoCount: answers.existingPhotos.length,
                      inspirationPhotoCount: answers.photos.length,
                      inspirationMethod: answers.inspirationMethod,
                      inspirationDesigners: answers.inspirationDesigners.length > 0 ? answers.inspirationDesigners.map(function(id) { return (DESIGNERS.find(function(d) { return d.id === id; }) || {}).label || id; }) : [],
                      inspirationText: answers.inspirationText,
                    };
                    const emailTemplate = buildSubmitEmail();
                    payload.emailSubject = emailTemplate.subject;
                    payload.emailHtml = emailTemplate.html;
                    payload.emailText = emailTemplate.text;

                    // Compress and attach photos
                    try {
                      const existingFiles = answers.existingPhotos || [];
                      const inspirationFiles = answers.photos || [];
                      if (existingFiles.length > 0 || inspirationFiles.length > 0) {
                        setSubmitDetail("Compressing photos for upload...");
                        const [compressedExisting, compressedInspiration] = await Promise.all([
                          compressAllImages(existingFiles),
                          compressAllImages(inspirationFiles),
                        ]);
                        payload.existingPhotos = compressedExisting.filter(Boolean);
                        payload.inspirationPhotos = compressedInspiration.filter(Boolean);
                      }
                    } catch(e) {
                      console.warn("Photo compression failed during submit:", e);
                    }

                    setSubmitDetail("Sending your design brief...");
                    const result = await postToBackend(payload);
                    if (result.success) {
                      await window.storage.delete(ACTIVE_DRAFT_STORAGE_KEY);
                      await window.storage.delete(draftStorageKey(sessionId));
                    }
                    setSubmitState(result.success ? "sent" : "error");
                  } catch (err) {
                    console.error("Submit failed unexpectedly:", err);
                    setSubmitState("error");
                  } finally {
                    setSubmitDetail("");
                  }
                }}>
                  Submit My Design Brief
                </button>
              )}

              {submitState === "sending" && (
                <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "16px 0" }}>
                  <div style={{ width: 24, height: 24, border: "2px solid rgba(201,169,110,0.2)", borderTopColor: "#C9A96E", borderRadius: "50%", animation: "spin 1s linear infinite" }} />
                  <span style={{ fontSize: 15, color: "rgba(245,240,232,0.6)" }}>{submitDetail || "Sending your design brief..."}</span>
                </div>
              )}

              {submitState === "sent" && (
                <div style={{ textAlign: "center", padding: "12px 0" }}>
                  <div style={{ fontSize: 36, marginBottom: 12 }}>✉️</div>
                  <p style={{ fontSize: 16, color: "#C9A96E", fontWeight: 500, marginBottom: 8 }}>Design brief submitted!</p>
                  <p style={{ fontSize: 15, color: "rgba(245,240,232,0.5)", lineHeight: 1.6 }}>
                    Our team will review your selections and reach out within 1–2 business days to schedule your consultation.
                  </p>
                </div>
              )}

              {submitState === "error" && (
                <div style={{ textAlign: "center", padding: "12px 0" }}>
                  <p style={{ fontSize: 15, color: "rgba(245,240,232,0.5)", marginBottom: 14 }}>
                    There was a hiccup sending your brief, but your responses have been saved locally. Please try again, or call us directly.
                  </p>
                  <button className="btn-primary" style={styles.ctaButton} onClick={() => setSubmitState("idle")}>
                    Try Again
                  </button>
                </div>
              )}

              {submitState !== "sending" && submitState !== "sent" && (
                <button className="btn-back" style={styles.editBtn} onClick={() => goTo(1)}>
                  ← Edit responses
                </button>
              )}
            </div>
            <div style={styles.contactFooter}>
              <p style={styles.contactLine}>Or visit us in person:</p>
              <p style={styles.contactDetail}><strong>Queen St.</strong> — 290 Queen Street East · (705) 253-9703</p>
              <p style={styles.contactDetail}><strong>Station Mall</strong> — 293 Bay Street · (705) 942-3400</p>
              <p style={styles.contactDetail}>savoysjewellers.com</p>
            </div>
          </div>
        )}
      </main>

      {/* Footer Nav */}
      {currentStepName !== "welcome" && currentStepName !== "project" && currentStepName !== "summary" && (
        <footer style={styles.footer}>
          <button className="btn-back" style={styles.backBtn} onClick={back}>
            ← Back
          </button>
          {showContinueButton && (
            <button className="btn-primary" style={styles.nextBtn} disabled={!canProceed()} onClick={next}>
              {currentStepName === "details" ? "Review My Brief" : "Continue →"}
            </button>
          )}
        </footer>
      )}

      {/* ── BIRTHSTONE HELPER MODAL ── */}
      {showBirthstoneHelper && (
        <div style={styles.modalOverlay} onClick={() => setShowBirthstoneHelper(false)}>
          <div style={styles.modal} onClick={(e) => e.stopPropagation()}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <h3 style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: 24, fontWeight: 400, color: "#F5F0E8" }}>
                Gemstone Guide
              </h3>
              <button onClick={() => setShowBirthstoneHelper(false)}
                style={{ background: "none", border: "none", color: "rgba(245,240,232,0.5)", fontSize: 20, cursor: "pointer", padding: "4px 8px" }}>✕</button>
            </div>
            <p style={{ fontSize: 15, color: "rgba(245,240,232,0.5)", marginBottom: 6, lineHeight: 1.6 }}>
              Every month has a birthstone with special meaning. Tap a month to add its gemstone to your selection.
            </p>
            <p style={{ fontSize: 14, color: "rgba(201,169,110,0.5)", marginBottom: 20, fontStyle: "italic" }}>
              Birthstones also make wonderful gifts — choose the recipient's birth month!
            </p>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10, maxHeight: "55vh", overflowY: "auto", paddingRight: 4 }}>
              {BIRTHSTONES.map((b) => (
                <div key={b.month} className="month-card"
                  style={{ background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)", borderRadius: 10, padding: "14px 16px", cursor: "pointer" }}
                  onClick={() => selectBirthstone(b.stones)}>
                  <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8 }}>
                    <div style={{ width: 24, height: 24, borderRadius: "50%", background: b.color, border: ["April","June","October"].includes(b.month) ? "1px solid rgba(255,255,255,0.3)" : "none", flexShrink: 0 }} />
                    <span style={{ fontSize: 14, fontWeight: 600, color: "#F5F0E8" }}>{b.month}</span>
                  </div>
                  <p style={{ fontSize: 13, fontWeight: 300, color: "rgba(245,240,232,0.45)", lineHeight: 1.5 }}>{b.desc}</p>
                  <div style={{ marginTop: 8, display: "flex", gap: 6, flexWrap: "wrap" }}>
                    {b.stones.map(s => (
                      <span key={s} style={{ fontSize: 13, background: "rgba(201,169,110,0.12)", color: "#C9A96E", padding: "3px 10px", borderRadius: 12 }}>
                        {getLabelFor("s", s, GEMSTONES)}
                      </span>
                    ))}
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      )}

      {/* ── RING SIZER MODAL ── */}
      {showRingSizer && (
        <div style={styles.modalOverlay} onClick={() => setShowRingSizer(false)}>
          <div style={{ ...styles.modal, maxWidth: 520 }} onClick={(e) => e.stopPropagation()}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <h3 style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: 24, fontWeight: 400, color: "#F5F0E8" }}>
                Ring Size Finder
              </h3>
              <button onClick={() => setShowRingSizer(false)}
                style={{ background: "none", border: "none", color: "rgba(245,240,232,0.4)", fontSize: 22, cursor: "pointer", padding: 4 }}>✕</button>
            </div>
            <RingSizerTool onSelectSize={(size) => { update("ringSize", size); setShowRingSizer(false); }} />
          </div>
        </div>
      )}
    </div>
  );
}

const RING_SIZES = [
  { size: "3", dia: 14.0, circ: 44.2 },
  { size: "3.5", dia: 14.4, circ: 45.2 },
  { size: "4", dia: 14.8, circ: 46.5 },
  { size: "4.5", dia: 15.2, circ: 47.8 },
  { size: "5", dia: 15.7, circ: 49.3 },
  { size: "5.5", dia: 16.1, circ: 50.6 },
  { size: "6", dia: 16.5, circ: 51.9 },
  { size: "6.5", dia: 16.9, circ: 53.1 },
  { size: "7", dia: 17.3, circ: 54.4 },
  { size: "7.5", dia: 17.7, circ: 55.7 },
  { size: "8", dia: 18.1, circ: 57.0 },
  { size: "8.5", dia: 18.5, circ: 58.3 },
  { size: "9", dia: 18.9, circ: 59.5 },
  { size: "9.5", dia: 19.4, circ: 60.8 },
  { size: "10", dia: 19.8, circ: 62.1 },
  { size: "10.5", dia: 20.2, circ: 63.4 },
  { size: "11", dia: 20.6, circ: 64.6 },
  { size: "11.5", dia: 21.0, circ: 65.9 },
  { size: "12", dia: 21.4, circ: 67.2 },
  { size: "13", dia: 22.2, circ: 69.7 },
];

function RingSizerTool({ onSelectSize }) {
  const [method, setMethod] = useState("ring"); // "ring" | "string"
  const [pxPerMm, setPxPerMm] = useState(null);
  const [diameterMm, setDiameterMm] = useState(17.3); // default size 7
  const [circumMm, setCircumMm] = useState("");

  const isMobile = typeof window !== "undefined" && window.innerWidth < 500;

  const CAL_OBJECTS = [
    { id: "quarter", label: "Quarter", mm: 23.88, shape: "circle", emoji: "🪙" },
    { id: "loonie", label: "Loonie", mm: 26.5, shape: "circle", emoji: "🪙" },
    { id: "toonie", label: "Toonie", mm: 28.0, shape: "circle", emoji: "🪙" },
    { id: "card", label: "Credit Card", mm: 85.6, shape: "bar", emoji: "💳", note: "Turn phone sideways" },
  ];

  const [calObject, setCalObject] = useState(isMobile ? null : "card"); // null = show picker on mobile
  const [calPx, setCalPx] = useState(isMobile ? 80 : 280);

  const activeRef = CAL_OBJECTS.find(o => o.id === calObject);
  const isCircle = activeRef?.shape === "circle";

  const calibrate = () => {
    if (!activeRef) return;
    setPxPerMm(calPx / activeRef.mm);
  };

  // Find closest ring size from diameter
  const sizeFromDia = (dia) => {
    let closest = RING_SIZES[0];
    for (const s of RING_SIZES) {
      if (Math.abs(s.dia - dia) < Math.abs(closest.dia - dia)) closest = s;
    }
    return closest;
  };

  // Find closest ring size from circumference
  const sizeFromCirc = (circ) => {
    let closest = RING_SIZES[0];
    for (const s of RING_SIZES) {
      if (Math.abs(s.circ - circ) < Math.abs(closest.circ - circ)) closest = s;
    }
    return closest;
  };

  const matched = method === "ring" ? sizeFromDia(diameterMm) : (circumMm ? sizeFromCirc(parseFloat(circumMm)) : null);

  const tabStyle = (active) => ({
    flex: 1, padding: "10px 0", fontSize: 13, fontWeight: active ? 600 : 400,
    color: active ? "#C9A96E" : "rgba(245,240,232,0.5)",
    background: active ? "rgba(201,169,110,0.1)" : "transparent",
    border: "none", borderBottom: active ? "2px solid #C9A96E" : "2px solid transparent",
    cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif", transition: "all 0.2s",
  });

  return (
    <div style={{ overflowY: "auto", maxHeight: "65vh", paddingRight: 4 }}>
      {/* Method tabs */}
      <div style={{ display: "flex", marginBottom: 20, borderBottom: "1px solid rgba(255,255,255,0.06)" }}>
        <button style={tabStyle(method === "ring")} onClick={() => setMethod("ring")}>
          I Have a Ring
        </button>
        <button style={tabStyle(method === "string")} onClick={() => setMethod("string")}>
          Measure My Finger
        </button>
      </div>

      {method === "ring" && (
        <div>
          {/* Step 1: Calibration */}
          {!pxPerMm ? (
            <div>
              {/* Mobile: show object picker first */}
              {isMobile && !calObject ? (
                <div>
                  <p style={{ fontSize: 14, color: "rgba(245,240,232,0.6)", marginBottom: 16, lineHeight: 1.6 }}>
                    <strong style={{ color: "#C9A96E" }}>Step 1:</strong> What do you have handy to calibrate your screen?
                  </p>
                  <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                    {CAL_OBJECTS.map(obj => (
                      <div key={obj.id} className="option-card" onClick={() => {
                        setCalObject(obj.id);
                        setCalPx(obj.shape === "circle" ? 80 : 280);
                      }} style={{
                        display: "flex", alignItems: "center", gap: 12,
                        padding: "14px 16px", borderRadius: 10, cursor: "pointer",
                        background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.08)",
                      }}>
                        <span style={{ fontSize: 22 }}>{obj.emoji}</span>
                        <div>
                          <span style={{ fontSize: 14, fontWeight: 500, color: "#F5F0E8", display: "block" }}>{obj.label}</span>
                          {obj.note && <span style={{ fontSize: 12, color: "rgba(201,169,110,0.5)" }}>{obj.note}</span>}
                          <span style={{ fontSize: 12, color: "rgba(245,240,232,0.3)" }}>{obj.mm}mm {obj.shape === "circle" ? "diameter" : "width"}</span>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              ) : (
                <div>
                  <p style={{ fontSize: 14, color: "rgba(245,240,232,0.6)", marginBottom: 6, lineHeight: 1.6 }}>
                    <strong style={{ color: "#C9A96E" }}>{isMobile ? "Step 2" : "Step 1"}:</strong> Place your {activeRef?.label.toLowerCase()} on the screen and drag the slider until the gold {isCircle ? "circle" : "bar"} matches {isCircle ? "the coin" : "the card's width"} exactly.
                  </p>
                  {activeRef?.id === "card" && isMobile && (
                    <p style={{ fontSize: 13, color: "#C9A96E", marginBottom: 12 }}>📱 Rotate your phone to landscape mode first.</p>
                  )}
                  <div style={{ display: "flex", justifyContent: "center", margin: "20px 0 12px" }}>
                    {isCircle ? (
                      <div style={{
                        width: calPx, height: calPx, borderRadius: "50%",
                        background: "rgba(201,169,110,0.15)",
                        border: "2px solid #C9A96E",
                        transition: "all 0.1s",
                      }} />
                    ) : (
                      <div>
                        <div style={{
                          width: calPx, height: 8, background: "linear-gradient(90deg, #C9A96E, #E2C992)",
                          borderRadius: 4, transition: "width 0.1s",
                        }} />
                        <div style={{ width: calPx, height: 1, borderLeft: "2px solid rgba(201,169,110,0.5)", borderRight: "2px solid rgba(201,169,110,0.5)", marginTop: 4 }} />
                      </div>
                    )}
                  </div>
                  <input type="range" min={isCircle ? 40 : 150} max={isCircle ? 200 : 600} value={calPx} onChange={(e) => setCalPx(Number(e.target.value))}
                    style={{ width: "100%", accentColor: "#C9A96E", marginBottom: 16 }} />
                  <p style={{ fontSize: 12, color: "rgba(245,240,232,0.35)", textAlign: "center", marginBottom: 16 }}>
                    {activeRef?.label}: {activeRef?.mm}mm {isCircle ? "diameter" : "width"}
                  </p>
                  <button className="btn-primary" onClick={calibrate}
                    style={{ width: "100%", background: "linear-gradient(135deg, #C9A96E, #B8944F)", color: "#1A1814", border: "none", borderRadius: 50, padding: "12px 0", fontSize: 14, fontWeight: 600, fontFamily: "'Nunito Sans', sans-serif", cursor: "pointer" }}>
                    It matches — continue
                  </button>
                  {isMobile && (
                    <button onClick={() => setCalObject(null)}
                      style={{ display: "block", margin: "12px auto 0", fontSize: 12, color: "rgba(201,169,110,0.5)", background: "none", border: "none", cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif" }}>
                      ← Use a different object
                    </button>
                  )}
                </div>
              )}
            </div>
          ) : (
            <div>
              <p style={{ fontSize: 14, color: "rgba(245,240,232,0.6)", marginBottom: 16, lineHeight: 1.6 }}>
                <strong style={{ color: "#C9A96E" }}>Step 2:</strong> Place your ring on the circle below and adjust the slider until the circle matches the <em>inside edge</em> of your ring.
              </p>
              {/* Ring circle */}
              <div style={{ display: "flex", justifyContent: "center", alignItems: "center", margin: "16px 0" }}>
                <svg width={Math.max(diameterMm * pxPerMm + 40, 100)} height={Math.max(diameterMm * pxPerMm + 40, 100)} style={{ overflow: "visible" }}>
                  <circle
                    cx={(diameterMm * pxPerMm + 40) / 2}
                    cy={(diameterMm * pxPerMm + 40) / 2}
                    r={(diameterMm * pxPerMm) / 2}
                    fill="none"
                    stroke="#C9A96E"
                    strokeWidth="2"
                  />
                  <circle
                    cx={(diameterMm * pxPerMm + 40) / 2}
                    cy={(diameterMm * pxPerMm + 40) / 2}
                    r={(diameterMm * pxPerMm) / 2}
                    fill="rgba(201,169,110,0.06)"
                    stroke="none"
                  />
                </svg>
              </div>
              <input type="range" min="14" max="23" step="0.1" value={diameterMm} onChange={(e) => setDiameterMm(Number(e.target.value))}
                style={{ width: "100%", accentColor: "#C9A96E", marginBottom: 8 }} />
              <p style={{ fontSize: 13, color: "rgba(245,240,232,0.4)", textAlign: "center", marginBottom: 20 }}>
                Diameter: {diameterMm.toFixed(1)}mm
              </p>
              <button style={{ fontSize: 12, color: "rgba(201,169,110,0.5)", background: "none", border: "none", cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif", marginBottom: 16, display: "block" }}
                onClick={() => setPxPerMm(null)}>
                ← Re-calibrate screen
              </button>
            </div>
          )}
        </div>
      )}

      {method === "string" && (
        <div>
          <p style={{ fontSize: 14, color: "rgba(245,240,232,0.6)", marginBottom: 12, lineHeight: 1.6 }}>
            <strong style={{ color: "#C9A96E" }}>1.</strong> Wrap a thin strip of paper or string snugly around the base of your finger.
          </p>
          <p style={{ fontSize: 14, color: "rgba(245,240,232,0.6)", marginBottom: 12, lineHeight: 1.6 }}>
            <strong style={{ color: "#C9A96E" }}>2.</strong> Mark where it overlaps, then measure the length in millimetres with a ruler.
          </p>
          <p style={{ fontSize: 14, color: "rgba(245,240,232,0.6)", marginBottom: 20, lineHeight: 1.6 }}>
            <strong style={{ color: "#C9A96E" }}>3.</strong> Enter the measurement below:
          </p>
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8 }}>
            <input type="number" placeholder="e.g. 54" value={circumMm}
              onChange={(e) => setCircumMm(e.target.value)}
              style={{ width: 100, background: "rgba(255,255,255,0.04)", border: "1px solid rgba(201,169,110,0.25)", borderRadius: 8, padding: "10px 14px", color: "#F5F0E8", fontSize: 16, fontFamily: "'Nunito Sans', sans-serif", outline: "none" }} />
            <span style={{ fontSize: 14, color: "rgba(245,240,232,0.4)" }}>mm circumference</span>
          </div>
          <p style={{ fontSize: 12, color: "rgba(245,240,232,0.3)", marginBottom: 20, lineHeight: 1.5 }}>
            Tip: measure 2–3 times for accuracy. Fingers are slightly larger in the evening and in warm weather.
          </p>
        </div>
      )}

      {/* Result */}
      {matched && (method === "ring" ? pxPerMm : circumMm) && (
        <div style={{ background: "rgba(201,169,110,0.08)", border: "1px solid rgba(201,169,110,0.2)", borderRadius: 12, padding: "18px 20px", marginBottom: 16, textAlign: "center" }}>
          <p style={{ fontSize: 13, color: "rgba(245,240,232,0.5)", marginBottom: 6 }}>Your estimated ring size</p>
          <p style={{ fontSize: 36, fontFamily: "'Cormorant Garamond', serif", fontWeight: 400, color: "#C9A96E", marginBottom: 4 }}>
            {matched.size}
          </p>
          <p style={{ fontSize: 12, color: "rgba(245,240,232,0.35)" }}>
            {matched.dia}mm diameter · {matched.circ}mm circumference
          </p>
          <button className="btn-primary" onClick={() => onSelectSize(matched.size)}
            style={{ marginTop: 14, background: "linear-gradient(135deg, #C9A96E, #B8944F)", color: "#1A1814", border: "none", borderRadius: 50, padding: "11px 28px", fontSize: 14, fontWeight: 600, fontFamily: "'Nunito Sans', sans-serif", cursor: "pointer" }}>
            Use size {matched.size}
          </button>
        </div>
      )}

      {/* Reference chart */}
      <details style={{ marginTop: 8 }}>
        <summary style={{ fontSize: 13, color: "rgba(201,169,110,0.5)", cursor: "pointer", marginBottom: 10 }}>
          Full size chart (US/Canada)
        </summary>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: "1px", fontSize: 12, color: "rgba(245,240,232,0.5)", marginTop: 8 }}>
          <span style={{ fontWeight: 600, color: "#C9A96E", padding: "6px 0" }}>Size</span>
          <span style={{ fontWeight: 600, color: "#C9A96E", padding: "6px 0" }}>Diameter</span>
          <span style={{ fontWeight: 600, color: "#C9A96E", padding: "6px 0" }}>Circumf.</span>
          {RING_SIZES.map(s => (
            <React.Fragment key={s.size}>
              <span style={{ padding: "4px 0", borderTop: "1px solid rgba(255,255,255,0.04)" }}>{s.size}</span>
              <span style={{ padding: "4px 0", borderTop: "1px solid rgba(255,255,255,0.04)" }}>{s.dia}mm</span>
              <span style={{ padding: "4px 0", borderTop: "1px solid rgba(255,255,255,0.04)" }}>{s.circ}mm</span>
            </React.Fragment>
          ))}
        </div>
      </details>

      <p style={{ fontSize: 11, color: "rgba(245,240,232,0.25)", marginTop: 16, lineHeight: 1.5, textAlign: "center" }}>
        This is an estimate. For the best fit, we'll confirm your size during your in-store consultation.
      </p>
    </div>
  );
}

function ConceptCard({ concept, index, metalColor, isLiked, onLike, onSvgGenerated }) {
  const [imgState, setImgState] = useState("idle"); // idle, loading, loaded, error
  const [svgMarkup, setSvgMarkup] = useState(null);
  const [statusMsg, setStatusMsg] = useState("");
  const MAX_RETRIES = 3;

  // Gem color lookup
  const gemColors = (() => {
    const desc = (concept.description + " " + concept.name).toLowerCase();
    const map = {
      diamond: ["#B8D4E3", "#FFFFFF"], sapphire: ["#1E3A8A", "#6090D0"],
      ruby: ["#9B1B30", "#E05070"], emerald: ["#1B6B3A", "#50C080"],
      amethyst: ["#6B21A8", "#B070E0"], opal: ["#C8D8E8", "#E8D0F0"],
      garnet: ["#8B1A1A", "#D05050"], aquamarine: ["#48A9C5", "#90E0F0"],
      pearl: ["#F0EBD8", "#FFFFFF"], morganite: ["#E8A898", "#F8D0C8"],
      tanzanite: ["#4A3B8F", "#8878C8"], moissanite: ["#D8DCE0", "#FFFFFF"],
      topaz: ["#D4900A", "#F8C850"], peridot: ["#6B8E23", "#A8D050"],
    };
    for (const [gem, cols] of Object.entries(map)) {
      if (desc.includes(gem)) return cols;
    }
    return ["#B8D4E3", "#FFFFFF"];
  })();

  // Safe metal color
  const mc = metalColor && metalColor.startsWith("#") && metalColor.length >= 7 ? metalColor : "#D4A843";

  // Extract SVG from arbitrary text — handles all model output patterns
  const extractSvg = (text) => {
    if (!text) return null;

    // Strip markdown fences
    let cleaned = text.replace(/```(?:svg|xml|html)?\n?/gi, "").replace(/```/g, "");

    // Try to find <svg ... </svg> (non-greedy on attributes, greedy on body)
    const m = cleaned.match(/<svg[^>]*>[\s\S]*<\/svg>/i);
    if (m) return m[0];

    // Maybe the model output <svg but got cut off before </svg>
    const svgStart = cleaned.indexOf("<svg");
    if (svgStart !== -1) {
      let fragment = cleaned.slice(svgStart);
      // Close any unclosed tags and add </svg>
      if (!fragment.includes("</svg>")) fragment += "</svg>";
      return fragment;
    }

    return null;
  };

  // Minimal validation — just needs to be parseable SVG with some content
  const isValidSvg = (svg) => {
    if (!svg || svg.length < 100) return false;
    if (!svg.includes("<svg")) return false;
    // Must have SOME drawing content — any element inside the SVG
    const hasContent = /<(path|circle|rect|ellipse|polygon|line|polyline|g|use|text)\b/i.test(svg);
    return hasContent;
  };

  // Clean up SVG for safe inline rendering
  const sanitize = (svg) => {
    let s = svg;
    // Remove scripts and event handlers
    s = s.replace(/<script[\s\S]*?<\/script>/gi, "");
    s = s.replace(/\bon\w+\s*=\s*["'][^"']*["']/gi, "");
    // Ensure xmlns
    if (!s.includes("xmlns")) {
      s = s.replace("<svg", '<svg xmlns="http://www.w3.org/2000/svg"');
    }
    // Force viewBox if missing
    if (!s.includes("viewBox")) {
      s = s.replace("<svg", '<svg viewBox="0 0 400 300"');
    }
    // Force dimensions for inline rendering
    if (!/width\s*=/.test(s.split(">")[0])) {
      s = s.replace("<svg", '<svg width="100%" height="100%"');
    }
    return s;
  };

  const callApi = async (prompt, systemPrompt) => {
    const data = await callAiProxy({
      task: "svg",
      input: prompt,
      instructions: systemPrompt,
      maxOutputTokens: 2600,
    });
    return data.text || "";
  };

  const generateImage = async (retryNum = 0) => {
    setImgState("loading");
    const msgs = [
      "Crafting your illustration...",
      "Trying a different approach...",
      "One more attempt...",
    ];
    setStatusMsg(msgs[Math.min(retryNum, msgs.length - 1)]);

    const system = `You are an SVG jewellery illustrator. You ONLY output SVG markup — never explanations, never markdown. Your SVGs are elegant, detailed vector illustrations of fine jewellery on dark backgrounds. You use gradients, filters, layered shapes, and subtle highlights to create premium-looking results. Every SVG you create has at least 15-20 shape elements for rich detail.`;

    const prompts = [
      // Attempt 1 — full detail
      `Draw an exquisite vector illustration of this jewellery piece and return only complete SVG markup:

"${concept.name}" — ${concept.description}

Technical palette:
• Background: #1A1814
• Metal: base ${mc}, highlights brighter, shadows darker
• Gemstone: base ${gemColors[0]}, highlight center ${gemColors[1]}

Use:
1. <svg viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"> as the root element
2. <defs> block with: metalGrad (linearGradient, 3+ stops from dark to light ${mc}), gemGrad (radialGradient from ${gemColors[1]} center to ${gemColors[0]} edge), shadowFilter (feGaussianBlur stdDeviation="4"), shineGrad (linear, transparent to white at 0.15 opacity to transparent)
3. Background rect filling #1A1814
4. Soft shadow ellipse under the piece (black, 15% opacity, filtered)
5. Main jewellery body using metalGrad — build it from multiple overlapping paths/shapes for 3D depth
6. Gemstone(s) using gemGrad with a small white specular highlight ellipse offset from center
7. Edge highlights: thin strokes or shapes in white at 10-20% opacity tracing the top edges
8. Fine detail elements: prong settings, engravings, texture lines

Make it look as realistic as vector art can — use many gradient stops, layered transparency, and gaussian blur for soft shadows. Return only the final SVG string, and close with </svg>.`,

      // Attempt 2 — more structured, less room for model to go off track
      `Return only complete SVG markup for "${concept.name}" (${concept.description}).
Background: #1A1814. Metal: ${mc}. Gem: ${gemColors[0]}.

Output a full SVG with these elements in order:
<svg viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg">
<defs>
  <linearGradient id="metal" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stop-color="${mc}" stop-opacity="0.6"/><stop offset="50%" stop-color="${mc}"/><stop offset="100%" stop-color="${mc}" stop-opacity="0.8"/></linearGradient>
  <radialGradient id="gem"><stop offset="0%" stop-color="${gemColors[1]}"/><stop offset="100%" stop-color="${gemColors[0]}"/></radialGradient>
  <filter id="shadow"><feGaussianBlur stdDeviation="3"/></filter>
</defs>
<rect width="400" height="300" fill="#1A1814"/>
<ellipse cx="200" cy="246" rx="62" ry="10" fill="black" opacity="0.2" filter="url(#shadow)"/>

Then draw the jewellery piece centered on the canvas with at least 15 shapes. Use url(#metal) for metal parts, url(#gem) for stones, url(#shadow) for soft shadows, and low-opacity white highlight strokes. Close with </svg>.`,

      // Attempt 3 — ultra-safe fallback prompt
      `Return only a complete SVG illustration for "${concept.name}". The scene should show a premium jewellery rendering on a dark background.
Requirements:
<svg viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg">
<defs> with a metal gradient and gemstone gradient
One dark background rectangle
One blurred shadow ellipse near the bottom
At least 10 visible jewellery shapes
Use ${mc} for metal and ${gemColors[0]} / ${gemColors[1]} for the stone
No markdown fences, no prose, and include the closing </svg> tag.`,
    ];

    try {
      const raw = await callApi(prompts[Math.min(retryNum, prompts.length - 1)], system);
      const svg = extractSvg(raw);

      if (svg && isValidSvg(svg)) {
        const cleaned = sanitize(svg);
        setSvgMarkup(cleaned);
        setImgState("loaded");
        setStatusMsg("");
        if (onSvgGenerated) onSvgGenerated(index, cleaned);
        return;
      }

      // Validation failed — retry with next prompt
      console.warn(`SVG attempt ${retryNum + 1} failed validation. Length: ${raw?.length}, hasContent: ${svg ? "yes" : "no"}`);
      if (retryNum < MAX_RETRIES - 1) {
        await new Promise(r => setTimeout(r, 600));
        return generateImage(retryNum + 1);
      }

      // Last resort: if we got ANY svg-like content, try to show it anyway
      if (svg) {
        const cleaned = sanitize(svg);
        setSvgMarkup(cleaned);
        setImgState("loaded");
        setStatusMsg("");
        if (onSvgGenerated) onSvgGenerated(index, cleaned);
        return;
      }

      setImgState("error");
      setStatusMsg("");
    } catch (err) {
      console.error(`Attempt ${retryNum + 1} error:`, err);
      if (retryNum < MAX_RETRIES - 1) {
        await new Promise(r => setTimeout(r, 800));
        return generateImage(retryNum + 1);
      }
      const fallbackSvg = sanitize(buildFallbackSvgMarkup(concept, mc, gemColors));
      setSvgMarkup(fallbackSvg);
      setImgState("loaded");
      setStatusMsg("");
      if (onSvgGenerated) onSvgGenerated(index, fallbackSvg);
    }
  };

  const hasImage = imgState === "loaded" && svgMarkup;

  return (
    <div className="concept-card" style={{
      background: "rgba(255,255,255,0.03)",
      border: isLiked ? "1px solid rgba(201,169,110,0.35)" : "1px solid rgba(201,169,110,0.12)",
      borderRadius: 14,
      overflow: "hidden",
      transition: "border-color 0.3s ease",
    }}>
      {/* Content section */}
      <div style={{ padding: "20px 22px" }}>
        {/* Header row: swatch + concept label + like button */}
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 10 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <div style={{ width: 28, height: 28, borderRadius: "50%", background: metalColor, border: "1px solid rgba(255,255,255,0.12)", flexShrink: 0 }} />
            <span style={{ fontSize: 10, fontWeight: 600, color: "#C9A96E", letterSpacing: "0.1em", textTransform: "uppercase", opacity: 0.7 }}>Concept {index + 1}</span>
          </div>
          <button onClick={() => onLike && onLike(index)}
            className="like-btn"
            style={{
              display: "inline-flex", alignItems: "center", gap: 5,
              background: isLiked ? "rgba(201,169,110,0.15)" : "transparent",
              border: `1px solid ${isLiked ? "#C9A96E" : "rgba(201,169,110,0.2)"}`,
              borderRadius: 20, padding: "5px 12px",
              color: isLiked ? "#C9A96E" : "rgba(201,169,110,0.5)",
              fontSize: 13, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif",
              transition: "all 0.25s ease",
              flexShrink: 0,
            }}>
            {isLiked ? "♥ Favourite" : "♡ Like"}
          </button>
        </div>

        <h4 style={{
          fontFamily: "'Cormorant Garamond', serif",
          fontSize: 20, fontWeight: 500, color: "#F5F0E8",
          marginBottom: 10, lineHeight: 1.3,
        }}>{concept.name}</h4>
        <p style={{
          fontSize: 15, fontWeight: 300, color: "rgba(245,240,232,0.55)",
          lineHeight: 1.7, marginBottom: 16,
        }}>{concept.description}</p>

        {/* SVG illustration area — below description */}
        {hasImage && (
          <div style={{
            width: "100%", height: 260, position: "relative", overflow: "hidden",
            borderRadius: 10, background: "#1A1814", marginBottom: 12,
            border: "1px solid rgba(201,169,110,0.08)",
          }}>
            <div
              dangerouslySetInnerHTML={{ __html: svgMarkup }}
              style={{ width: "100%", height: "100%" }}
            />
            <div style={{
              position: "absolute", bottom: 0, left: 0, right: 0, height: 50,
              background: "linear-gradient(to top, rgba(26,24,20,0.6), transparent)",
              pointerEvents: "none",
            }} />
            <span style={{
              position: "absolute", top: 10, left: 12,
              fontSize: 9, fontWeight: 600, color: "#C9A96E", letterSpacing: "0.12em", textTransform: "uppercase",
              background: "rgba(26,24,20,0.75)", backdropFilter: "blur(4px)",
              padding: "3px 8px", borderRadius: 4,
            }}>AI Concept Illustration</span>
          </div>
        )}

        {/* Generate / loading / error / regenerate controls */}
        {imgState === "idle" && (
          <button
            onClick={() => generateImage(0)}
            className="gen-img-btn"
            style={{
              display: "inline-flex", alignItems: "center", gap: 8,
              background: "rgba(201,169,110,0.08)",
              border: "1px solid rgba(201,169,110,0.25)",
              borderRadius: 8, padding: "10px 18px",
              color: "#C9A96E", fontSize: 14, fontWeight: 600,
              fontFamily: "'Nunito Sans', sans-serif",
              cursor: "pointer", letterSpacing: "0.03em",
              transition: "all 0.25s ease",
            }}
          >
            <span style={{ fontSize: 16 }}>🎨</span>
            Illustrate This Concept
          </button>
        )}

        {imgState === "loading" && (
          <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "10px 0" }}>
            <div style={{
              width: 18, height: 18,
              border: "2px solid rgba(201,169,110,0.2)", borderTopColor: "#C9A96E",
              borderRadius: "50%", animation: "spin 1s linear infinite",
            }} />
            <span style={{ fontSize: 14, color: "rgba(201,169,110,0.6)" }}>{statusMsg}</span>
          </div>
        )}

        {imgState === "error" && (
          <div style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 0", flexWrap: "wrap" }}>
            <span style={{ fontSize: 14, color: "rgba(245,240,232,0.4)" }}>
              Illustration didn't come through.
            </span>
            <button onClick={() => generateImage(0)}
              style={{
                background: "rgba(201,169,110,0.08)", border: "1px solid rgba(201,169,110,0.2)",
                borderRadius: 6, color: "#C9A96E", padding: "6px 14px",
                fontSize: 14, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif",
              }}>Try again</button>
          </div>
        )}

        {hasImage && (
          <button onClick={() => { setSvgMarkup(null); generateImage(0); }}
            style={{
              background: "none", border: "none", color: "rgba(201,169,110,0.4)",
              fontSize: 13, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif",
              padding: "4px 0",
            }}>🔄 Generate a different version</button>
        )}
      </div>
    </div>
  );
}

function SummaryRow({ label, value }) {
  return (
    <div style={styles.summaryRow}>
      <span style={styles.summaryLabel}>{label}</span>
      <span style={styles.summaryValue}>{value || "—"}</span>
    </div>
  );
}

const styles = {
  wrapper: {
    position: "relative",
    width: "100%",
    minHeight: "100vh",
    background: "#1A1814",
    fontFamily: "'Nunito Sans', sans-serif",
    color: "#F5F0E8",
  },
  bgTexture: {
    position: "absolute",
    inset: 0,
    background: `radial-gradient(ellipse at 20% 0%, rgba(201,169,110,0.06) 0%, transparent 60%),
                 radial-gradient(ellipse at 80% 100%, rgba(201,169,110,0.04) 0%, transparent 50%)`,
    pointerEvents: "none",
    zIndex: 0,
  },
  bgGlow: {
    position: "absolute",
    top: "-30%",
    right: "-10%",
    width: "50%",
    height: "60%",
    background: "radial-gradient(circle, rgba(201,169,110,0.03) 0%, transparent 70%)",
    pointerEvents: "none",
    zIndex: 0,
  },
  header: {
    position: "sticky",
    top: 0,
    zIndex: 10,
    padding: "20px 28px 16px",
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    borderBottom: "1px solid rgba(201,169,110,0.1)",
    background: "#1A1814",
  },
  logoArea: {
    display: "flex",
    flexDirection: "row",
    alignItems: "center",
    gap: 14,
  },
  logoImg: {
    height: 72,
    width: "auto",
    objectFit: "contain",
  },
  brandSub: {
    fontSize: 19,
    fontWeight: 300,
    color: "rgba(201,169,110,0.7)",
    letterSpacing: "0.15em",
    textTransform: "uppercase",
  },
  progressWrap: {
    display: "flex",
    flexDirection: "column",
    alignItems: "flex-end",
    gap: 6,
  },
  progressTrack: {
    width: 120,
    height: 3,
    background: "rgba(255,255,255,0.08)",
    borderRadius: 2,
    overflow: "hidden",
  },
  progressBar: {
    height: "100%",
    background: "linear-gradient(90deg, #C9A96E, #E2C992)",
    borderRadius: 2,
    transition: "width 0.4s ease",
  },
  progressLabel: {
    fontSize: 11,
    color: "rgba(245,240,232,0.4)",
    letterSpacing: "0.05em",
  },
  main: {
    position: "relative",
    zIndex: 5,
    padding: "32px 28px 40px",
  },
  centeredContent: {
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    justifyContent: "center",
    textAlign: "center",
    minHeight: "60vh",
    maxWidth: 520,
    margin: "0 auto",
  },
  heroIcon: {
    fontSize: 36,
    color: "#C9A96E",
    marginBottom: 24,
    animation: "pulse 3s ease-in-out infinite",
  },
  heroTitle: {
    fontFamily: "'Cormorant Garamond', serif",
    fontSize: 42,
    fontWeight: 300,
    lineHeight: 1.15,
    color: "#F5F0E8",
    marginBottom: 20,
    letterSpacing: "0.01em",
  },
  heroDesc: {
    fontSize: 17,
    fontWeight: 300,
    lineHeight: 1.7,
    color: "rgba(245,240,232,0.65)",
    marginBottom: 12,
    maxWidth: 520,
  },
  heroDuration: {
    fontSize: 15,
    color: "rgba(201,169,110,0.6)",
    marginBottom: 36,
    letterSpacing: "0.03em",
  },
  ctaButton: {
    background: "linear-gradient(135deg, #C9A96E, #B8944F)",
    color: "#1A1814",
    border: "none",
    borderRadius: 50,
    padding: "16px 40px",
    fontSize: 15,
    fontWeight: 600,
    fontFamily: "'Nunito Sans', sans-serif",
    cursor: "pointer",
    letterSpacing: "0.03em",
  },
  heroFootnote: {
    fontSize: 14,
    color: "rgba(245,240,232,0.3)",
    marginTop: 20,
    fontStyle: "italic",
  },
  stepContent: {
    maxWidth: 600,
    margin: "0 auto",
  },
  stepTitle: {
    fontFamily: "'Cormorant Garamond', serif",
    fontSize: 30,
    fontWeight: 400,
    color: "#F5F0E8",
    marginBottom: 10,
    lineHeight: 1.2,
  },
  stepDesc: {
    fontSize: 16,
    fontWeight: 300,
    color: "rgba(245,240,232,0.5)",
    marginBottom: 28,
    lineHeight: 1.65,
  },
  optionGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fill, minmax(130px, 1fr))",
    gap: 12,
  },
  optionCard: {
    background: "rgba(255,255,255,0.03)",
    border: "1px solid rgba(255,255,255,0.08)",
    borderRadius: 12,
    padding: "20px 14px",
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    gap: 10,
    textAlign: "center",
  },
  optionIcon: { fontSize: 28 },
  optionLabel: { fontSize: 15, fontWeight: 400, color: "#F5F0E8", letterSpacing: "0.02em" },
  occasionGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fill, minmax(170px, 1fr))",
    gap: 10,
  },
  occasionCard: {
    background: "rgba(255,255,255,0.03)",
    border: "1px solid rgba(255,255,255,0.08)",
    borderRadius: 10,
    padding: "16px 18px",
    display: "flex",
    flexDirection: "column",
    gap: 4,
  },
  occasionLabel: { fontSize: 15, fontWeight: 600, color: "#F5F0E8" },
  occasionDesc: { fontSize: 14, fontWeight: 300, color: "rgba(245,240,232,0.4)" },
  metalGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fill, minmax(140px, 1fr))",
    gap: 12,
  },
  metalCard: {
    background: "rgba(255,255,255,0.03)",
    border: "1px solid rgba(255,255,255,0.08)",
    borderRadius: 12,
    padding: "20px 14px",
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    gap: 12,
    textAlign: "center",
  },
  metalSwatch: {
    width: 40,
    height: 40,
    borderRadius: "50%",
    border: "1px solid rgba(255,255,255,0.12)",
  },
  metalLabel: { fontSize: 15, fontWeight: 400, color: "#F5F0E8" },
  gemGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fill, minmax(140px, 1fr))",
    gap: 10,
  },
  gemChip: {
    border: "1px solid rgba(255,255,255,0.1)",
    borderRadius: 10,
    padding: "14px 16px",
    display: "flex",
    alignItems: "center",
    gap: 10,
    cursor: "pointer",
    transition: "all 0.2s ease",
  },
  gemDot: {
    width: 18,
    height: 18,
    borderRadius: "50%",
    flexShrink: 0,
  },
  styleGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fill, minmax(160px, 1fr))",
    gap: 12,
  },
  styleCard: {
    background: "rgba(255,255,255,0.03)",
    border: "1px solid rgba(255,255,255,0.08)",
    borderRadius: 12,
    padding: "22px 16px",
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    textAlign: "center",
    gap: 8,
  },
  styleEmoji: { fontSize: 28 },
  styleLabel: { fontSize: 14, fontWeight: 600, color: "#F5F0E8" },
  styleDesc: { fontSize: 14, fontWeight: 300, color: "rgba(245,240,232,0.45)", lineHeight: 1.5 },
  dropZone: {
    border: "2px dashed rgba(201,169,110,0.25)",
    borderRadius: 16,
    padding: "40px 20px",
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    gap: 8,
    cursor: "pointer",
    transition: "border-color 0.2s",
    background: "rgba(201,169,110,0.02)",
  },
  dropIcon: { fontSize: 36, marginBottom: 4 },
  dropText: { fontSize: 16, fontWeight: 400, color: "#C9A96E" },
  dropSubtext: { fontSize: 14, color: "rgba(245,240,232,0.35)" },
  photoRow: { display: "flex", gap: 10, marginTop: 20, flexWrap: "wrap" },
  photoThumb: { width: 80, height: 80, borderRadius: 8, overflow: "hidden", flexShrink: 0 },
  photoImg: { width: "100%", height: "100%", objectFit: "cover" },
  skipHint: { fontSize: 15, color: "rgba(245,240,232,0.35)", marginTop: 20, fontStyle: "italic" },
  budgetGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fill, minmax(160px, 1fr))",
    gap: 10,
  },
  budgetCard: {
    background: "rgba(255,255,255,0.03)",
    border: "1px solid rgba(255,255,255,0.08)",
    borderRadius: 10,
    padding: "18px 20px",
    fontSize: 15,
    fontWeight: 400,
    color: "#F5F0E8",
    textAlign: "center",
    cursor: "pointer",
  },
  timelineGrid: { display: "flex", flexDirection: "column", gap: 10 },
  timelineCard: {
    background: "rgba(255,255,255,0.03)",
    border: "1px solid rgba(255,255,255,0.08)",
    borderRadius: 10,
    padding: "16px 20px",
    display: "flex",
    justifyContent: "space-between",
    alignItems: "center",
    cursor: "pointer",
  },
  timelineLabel: { fontSize: 15, fontWeight: 600, color: "#F5F0E8" },
  timelineDesc: { fontSize: 14, fontWeight: 300, color: "rgba(245,240,232,0.4)" },
  chipRow: { display: "flex", flexWrap: "wrap", gap: 8 },
  chip: {
    border: "1px solid rgba(255,255,255,0.1)",
    borderRadius: 20,
    padding: "8px 16px",
    fontSize: 15,
    color: "#F5F0E8",
    cursor: "pointer",
  },
  formGrid: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 18 },
  formGroup: { display: "flex", flexDirection: "column", gap: 6 },
  inputLabel: {
    fontSize: 13,
    fontWeight: 600,
    color: "rgba(201,169,110,0.7)",
    letterSpacing: "0.05em",
    textTransform: "uppercase",
  },
  privacyNote: { fontSize: 14, color: "rgba(245,240,232,0.35)", marginTop: 24 },
  summaryHeader: { textAlign: "center", marginBottom: 28 },
  checkmark: {
    width: 52, height: 52, borderRadius: "50%",
    background: "linear-gradient(135deg, #C9A96E, #B8944F)",
    color: "#1A1814",
    display: "inline-flex", alignItems: "center", justifyContent: "center",
    fontSize: 26, fontWeight: 700, marginBottom: 18,
  },
  summaryCard: {
    background: "rgba(255,255,255,0.03)",
    border: "1px solid rgba(201,169,110,0.15)",
    borderRadius: 14,
    padding: "4px 0",
    marginBottom: 28,
  },
  summaryRow: {
    display: "flex",
    justifyContent: "space-between",
    alignItems: "flex-start",
    padding: "14px 22px",
    borderBottom: "1px solid rgba(255,255,255,0.04)",
    gap: 16,
  },
  summaryLabel: {
    fontSize: 13, fontWeight: 600, color: "rgba(201,169,110,0.65)",
    letterSpacing: "0.04em", textTransform: "uppercase", flexShrink: 0, minWidth: 100,
  },
  summaryValue: { fontSize: 15, color: "#F5F0E8", textAlign: "right" },
  summaryActions: {
    display: "flex", flexDirection: "column", alignItems: "center", gap: 16, marginBottom: 40,
  },
  editBtn: {
    background: "none", border: "none", color: "rgba(245,240,232,0.5)",
    fontSize: 15, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif",
  },
  contactFooter: {
    textAlign: "center", padding: "24px 0 0",
    borderTop: "1px solid rgba(201,169,110,0.1)",
  },
  contactLine: { fontSize: 15, color: "rgba(245,240,232,0.5)", marginBottom: 10 },
  contactDetail: { fontSize: 15, color: "rgba(245,240,232,0.4)", lineHeight: 1.8 },
  footer: {
    position: "sticky", bottom: 0, zIndex: 20,
    display: "flex", justifyContent: "space-between", alignItems: "center",
    padding: "16px 28px",
    background: "linear-gradient(to top, #1A1814 60%, transparent)",
    backdropFilter: "blur(8px)",
  },
  backBtn: {
    background: "none", border: "none", color: "rgba(245,240,232,0.5)",
    fontSize: 15, cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif", padding: "10px 16px",
  },
  nextBtn: {
    background: "linear-gradient(135deg, #C9A96E, #B8944F)",
    color: "#1A1814", border: "none", borderRadius: 50,
    padding: "14px 32px", fontSize: 15, fontWeight: 600,
    fontFamily: "'Nunito Sans', sans-serif", cursor: "pointer", letterSpacing: "0.02em",
  },
  // Modal
  modalOverlay: {
    position: "fixed", inset: 0, zIndex: 100,
    background: "rgba(10,8,6,0.85)",
    backdropFilter: "blur(6px)",
    display: "flex", alignItems: "center", justifyContent: "center",
    padding: 20,
  },
  modal: {
    background: "#1A1814",
    border: "1px solid rgba(201,169,110,0.2)",
    borderRadius: 16,
    padding: "28px 24px",
    maxWidth: 520,
    width: "100%",
    maxHeight: "85vh",
    overflow: "hidden",
    display: "flex",
    flexDirection: "column",
  },
};

// Mount the app
ReactDOM.createRoot(document.getElementById("root")).render(<SavoysCustomDesigner />);
