const { useState, useRef, useEffect } = React;

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 draftStorageKey = (sessionId) => `draft:${sessionId}`;
const clearStoredDrafts = async () => {
  try {
    const listed = await window.storage.list();
    const keys = (listed?.keys || []).filter((key) =>
      key === ACTIVE_DRAFT_STORAGE_KEY || key.startsWith("draft:")
    );
    await Promise.all(keys.map((key) => window.storage.delete(key)));
  } catch (err) {
    console.warn("Draft cleanup failed:", err);
  }
};
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",
  "type",
  "occasion",
  "metal",
  "gemstone",
  "style",
  "inspiration",
  "timeline",
  "preview",
  "refine",
  "budget",
  "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 REFINEMENT_SHIFTS = [
  { id: "timeless", label: "Quieter & Timeless", desc: "Soften the drama and elevate the proportions.", prompt: "Refine it toward timeless elegance, balanced proportions, quieter luxury, and enduring sophistication." },
  { id: "sculptural", label: "More Sculptural", desc: "Push the form into something bolder and more expressive.", prompt: "Refine it toward a more sculptural, statement-making presence with stronger form, bolder architecture, and more expressive volume." },
  { id: "airy", label: "Lighter & Airier", desc: "Open the design up and reduce visual weight.", prompt: "Refine it toward a lighter, airier expression with more openness, cleaner spacing, and less visual heaviness." },
  { id: "detailed", label: "Richer in Detail", desc: "Add crafted nuance and more jewellery character.", prompt: "Refine it with richer crafted detail, more nuanced setting language, and a greater sense of artisanal finish." },
];

const REFINEMENT_EMPHASIS = [
  { id: "center-stone", label: "Center Stone", desc: "Make the gem the obvious hero.", prompt: "Let the center stone become the clear focal point with stronger presence, framing, and visual priority." },
  { id: "setting", label: "Setting Detail", desc: "Focus on claws, bezels, halos, or structure around the stone.", prompt: "Put more emphasis on the setting details, prongs, bezels, metal transitions, and the crafted architecture around the stone." },
  { id: "profile", label: "Side Profile", desc: "Make the silhouette and side view more distinctive.", prompt: "Push the side profile and overall silhouette so the piece feels more distinctive from multiple angles." },
  { id: "band", label: "Band & Metalwork", desc: "Let the shank and metal architecture carry more of the design.", prompt: "Let the band, shank, gallery, and metal architecture take more of the spotlight while still feeling premium and cohesive." },
];

const REFINEMENT_MOODS = [
  { id: "understated", label: "Understated", desc: "Quiet, polished, and luxuriously restrained.", prompt: "Keep the mood understated, quiet, polished, and luxuriously restrained." },
  { id: "romantic", label: "Romantic", desc: "Softer lines with more warmth and emotion.", prompt: "Give the piece a softer, more romantic, graceful, and emotionally expressive feel." },
  { id: "architectural", label: "Architectural", desc: "Sharper, cleaner, more design-forward.", prompt: "Give the piece a sharper, cleaner, more architectural and design-forward mood." },
  { id: "glamorous", label: "Glamorous", desc: "Increase drama, radiance, and evening presence.", prompt: "Give the piece a more glamorous, radiant, and high-impact mood without becoming costume-like." },
];

const REFINEMENT_WEARABILITY = [
  { id: "everyday", label: "More Everyday", desc: "Keep it practical, elegant, and easy to wear often.", prompt: "Keep the design practical, wearable, and elegant for frequent everyday use." },
  { id: "low-profile", label: "Lower Profile", desc: "Reduce height and make the setting feel more tucked in.", prompt: "Lower the profile and bring the design closer to the hand or body so it feels more tucked in and refined." },
  { id: "ceremonial", label: "More Occasion-Driven", desc: "Let it feel more dramatic and special-event oriented.", prompt: "Push the design toward a more occasion-driven, dramatic, special-piece presence." },
  { id: "comfort", label: "More Comfortable", desc: "Prioritize softness, smoothness, and ease on the body.", prompt: "Prioritize comfort, smooth transitions, and an ease-of-wear feeling in the final form." },
];

const DEFAULT_REFINEMENT = {
  shift: "",
  emphasis: "",
  mood: "",
  wearability: "",
  notes: "",
};

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,
  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 [sampleImages, setSampleImages] = useState([]);
  const [sampleImagesLoading, setSampleImagesLoading] = useState(false);
  const [sampleImagesError, setSampleImagesError] = useState("");
  const [selectedSampleId, setSelectedSampleId] = useState("");
  const [refinedSample, setRefinedSample] = useState(null);
  const [refinementAnswers, setRefinementAnswers] = useState(DEFAULT_REFINEMENT);
  const [refinementLoading, setRefinementLoading] = useState(false);
  const [refinementError, setRefinementError] = useState("");
  const [approvedPreview, setApprovedPreview] = useState(false);
  const [saveStatus, setSaveStatus] = useState(""); // "" | "saving" | "saved"
  const [submitState, setSubmitState] = useState("idle"); // idle | sending | sent | error
  const [submitDetail, setSubmitDetail] = useState("");
  const [submitError, setSubmitError] = 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 resetDesigner = async () => {
    revokeObjectUrls(photoPreviewUrlsRef.current);
    revokeObjectUrls(existingPhotoUrlsRef.current);
    photoPreviewUrlsRef.current = [];
    existingPhotoUrlsRef.current = [];
    setPhotoPreviewUrls([]);
    setExistingPhotoUrls([]);
    setAnswers(DEFAULT_ANSWERS);
    setSampleImages([]);
    setSampleImagesLoading(false);
    setSampleImagesError("");
    setSelectedSampleId("");
    setRefinedSample(null);
    setRefinementAnswers(DEFAULT_REFINEMENT);
    setRefinementLoading(false);
    setRefinementError("");
    setApprovedPreview(false);
    setSaveStatus("");
    setSubmitState("idle");
    setSubmitDetail("");
    setSubmitError("");
    setStep(0);
    setSessionId(genId());
    await clearStoredDrafts();
  };

  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 "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 "refine": return approvedPreview;
      case "details": return answers.name.trim() && answers.email.trim();
      default: return true;
    }
  };

  const getLabelFor = (key, id, list) => {
    const item = list.find((i) => i.id === id);
    return item ? item.label : id;
  };
  const baseSelectedSample = sampleImages.find((image) => image.id === selectedSampleId) || null;
  const activeSelectedSample = refinedSample || baseSelectedSample;
  const getRefinementSelections = () => {
    const selections = [];
    const shift = REFINEMENT_SHIFTS.find((item) => item.id === refinementAnswers.shift);
    const emphasis = REFINEMENT_EMPHASIS.find((item) => item.id === refinementAnswers.emphasis);
    const mood = REFINEMENT_MOODS.find((item) => item.id === refinementAnswers.mood);
    const wearability = REFINEMENT_WEARABILITY.find((item) => item.id === refinementAnswers.wearability);
    if (shift) selections.push(shift.label);
    if (emphasis) selections.push(emphasis.label);
    if (mood) selections.push(mood.label);
    if (wearability) selections.push(wearability.label);
    if (refinementAnswers.notes.trim()) selections.push(refinementAnswers.notes.trim());
    return selections;
  };
  const buildRefinementSummary = () => {
    return getRefinementSelections().map((item) => item.toLowerCase()).join(" • ");
  };
  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 refinementSummary = buildRefinementSummary();
    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: "Chosen direction", value: activeSelectedSample ? `${activeSelectedSample.title} — ${activeSelectedSample.description}` : "None selected" },
          { label: "Refinement notes", value: refinementSummary || "None provided" },
          { 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 initialize = async () => {
      await clearStoredDrafts();
      if (!cancelled) setDraftReady(true);
    };
    initialize();
    return () => {
      cancelled = true;
      revokeObjectUrls(photoPreviewUrlsRef.current);
      revokeObjectUrls(existingPhotoUrlsRef.current);
    };
  }, []);

  // ── Progressive save: keep a lightweight local checkpoint after each step ──
  useEffect(() => {
    if (!draftReady) return;
    if (step < 2) 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,
        // 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]);

  useEffect(() => {
    if (!draftReady) return;
    if (currentStepName === "preview" && !sampleImagesLoading && sampleImages.length === 0) {
      generateSampleImages();
    }
  }, [currentStepName, draftReady]);

  const buildSampleImageBaseBrief = () => {
    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 budgetLabel = answers.budget ? getLabelFor("budget", answers.budget, BUDGETS) : "";
    const inspirationBits = [];
    if (answers.inspirationDesigners.length > 0) {
      inspirationBits.push(`Designer inspiration: ${answers.inspirationDesigners.map((id) => (DESIGNERS.find((d) => d.id === id) || {}).label || id).join(", ")}`);
    }
    if (answers.inspirationText) {
      inspirationBits.push(`Customer vision: ${answers.inspirationText}`);
    }
    if (answers.projectType === "reimagine") {
      inspirationBits.push(`This is a redesign of an existing piece. Existing piece notes: ${answers.existingDescription || "Customer will bring the original piece to discuss in person."}`);
      inspirationBits.push(`Preservation preference: ${
        answers.existingPreservation === "preserve-all" ? "keep the overall design recognizable" :
        answers.existingPreservation === "preserve-parts" ? "preserve select stones or features while redesigning the rest" :
        answers.existingPreservation === "use-materials" ? "reuse the metals and stones in a completely new design" :
        "open to discussion"
      }.`);
    }

    return [
      "Create a single polished concept image for a bespoke jewellery commission.",
      `Piece type: ${typeLabel}${subtypeLabel ? ` (${subtypeLabel})` : ""}.`,
      `Occasion: ${occasionLabel}.`,
      `Preferred metal: ${metalLabel}.`,
      `Gemstones: ${gemLabels || "none specified"}.`,
      `Overall style: ${styleLabel}.`,
      budgetLabel ? `Budget range: ${budgetLabel}. Keep the scale, stone size, and level of complexity plausible for that range.` : "",
      answers.ringSize ? `Ring size: ${answers.ringSize}.` : "",
      inspirationBits.join(" "),
      "Render one hero product image only.",
      "Photoreal luxury jewellery photography, studio-lit, clean background, no text, no collage, no extra props, no hands unless subtle and elegant.",
      "Make the metal and gemstones read clearly, with believable reflections and premium craftsmanship.",
    ].filter(Boolean).join(" ");
  };
  const buildSampleImageRequests = () => {
    const baseBrief = buildSampleImageBaseBrief();
    return [
      {
        id: "sample-1",
        title: "Refined Heirloom Direction",
        description: "A timeless interpretation with balanced proportions, classic stone presentation, and quietly luxurious craftsmanship.",
        prompt: `${baseBrief} Direction one: refined heirloom elegance. Use a harmonious, symmetrical composition with graceful proportions, crisp setting details, and an elevated but restrained luxury feel. Prioritize classic wearability, soft sophistication, and enduring appeal.`,
      },
      {
        id: "sample-2",
        title: "Sculptural Statement Direction",
        description: "A bolder direction with stronger volume, more dramatic structure, and richer emphasis on silhouette and presence.",
        prompt: `${baseBrief} Direction two: sculptural statement luxury. Push the silhouette into a more dramatic, fashion-forward interpretation with bolder metal architecture, stronger height or spread, and more expressive stone framing. Keep it realistic, premium, and faithful to the chosen style rather than costume-like.`,
      },
      {
        id: "sample-3",
        title: "Modern Atelier Direction",
        description: "A cleaner contemporary approach with sharper lines, elegant negative space, and a lighter architectural feel.",
        prompt: `${baseBrief} Direction three: modern atelier minimalism. Explore cleaner geometry, lighter visual weight, elegant negative space, and a more contemporary gallery-like presentation. Make the design noticeably different from the first two directions while still respecting the same materials, gemstones, and overall brief.`,
      },
    ];
  };
  const openRefinementStep = (sample) => {
    setSelectedSampleId(sample.id);
    setRefinedSample(null);
    setRefinementAnswers(DEFAULT_REFINEMENT);
    setRefinementError("");
    setApprovedPreview(false);
    const refineIndex = STEPS.indexOf("refine");
    if (refineIndex >= 0) goTo(refineIndex);
  };

  const generateSampleImages = async () => {
    const requests = buildSampleImageRequests();
    if (!requests.length) return;

    setSampleImages([]);
    setSampleImagesError("");
    setSelectedSampleId("");
    setRefinedSample(null);
    setRefinementAnswers(DEFAULT_REFINEMENT);
    setRefinementLoading(false);
    setRefinementError("");
    setApprovedPreview(false);
    setSampleImagesLoading(true);

    try {
      const results = await Promise.all(requests.map(async (request) => {
        const data = await callAiProxy({
          task: "sample-image",
          input: request.prompt,
          instructions: "Generate a single photoreal luxury jewellery concept image with no text overlays or watermarks.",
        });
        return {
          id: request.id,
          title: request.title,
          description: request.description,
          imageDataUrl: data.imageDataUrl,
        };
      }));
      setSampleImages(results.filter((item) => item.imageDataUrl));
      if (!results.some((item) => item.imageDataUrl)) {
        throw new Error("No sample images were returned.");
      }
    } catch (err) {
      console.error("Sample image generation error:", err);
      setSampleImagesError(err?.message || "We couldn't generate sample images right now.");
      setSampleImages([]);
    } finally {
      setSampleImagesLoading(false);
    }
  };
  const updateRefinement = (key, value) => {
    setRefinementAnswers((current) => ({ ...current, [key]: value }));
    setRefinementError("");
    setApprovedPreview(false);
  };
  const generateRefinedSample = async () => {
    if (!activeSelectedSample) return;

    const refinementBits = [];
    const shift = REFINEMENT_SHIFTS.find((item) => item.id === refinementAnswers.shift);
    const emphasis = REFINEMENT_EMPHASIS.find((item) => item.id === refinementAnswers.emphasis);
    const mood = REFINEMENT_MOODS.find((item) => item.id === refinementAnswers.mood);
    const wearability = REFINEMENT_WEARABILITY.find((item) => item.id === refinementAnswers.wearability);
    if (shift) refinementBits.push(shift.prompt);
    if (emphasis) refinementBits.push(emphasis.prompt);
    if (mood) refinementBits.push(mood.prompt);
    if (wearability) refinementBits.push(wearability.prompt);
    if (refinementAnswers.notes.trim()) {
      refinementBits.push(`Customer refinement notes: ${refinementAnswers.notes.trim()}`);
    }

    const prompt = [
      buildSampleImageBaseBrief(),
      `Current chosen direction: ${activeSelectedSample.title}. ${activeSelectedSample.description}`,
      "Generate one refined version of this exact direction, not a completely new concept.",
      "Keep it recognizably connected to the chosen image while applying the requested changes.",
      refinementBits.join(" "),
      "Photoreal luxury jewellery photography, one hero product only, no text, no collage, no extra props.",
    ].filter(Boolean).join(" ");

    setRefinementLoading(true);
    setRefinementError("");
    setApprovedPreview(false);

    try {
      const data = await callAiProxy({
        task: "sample-image",
        input: prompt,
        instructions: "Generate a single refined photoreal jewellery concept image. Respect the existing direction while applying the requested refinements.",
      });
      const refinementSummary = buildRefinementSummary();
      setRefinedSample({
        ...activeSelectedSample,
        id: `${selectedSampleId}-refined`,
        imageDataUrl: data.imageDataUrl,
        description: refinementSummary
          ? `Refined toward ${refinementSummary}.`
          : "A refined version of the selected direction.",
      });
    } catch (err) {
      console.error("Sample refinement error:", err);
      setRefinementError(err?.message || "We couldn't generate a refined version right now.");
    } finally {
      setRefinementLoading(false);
    }
  };

  // Determine whether the Continue button should appear (auto-advance steps hide it)
  const showContinueButton = (() => {
    const alwaysContinue = ["existing", "gemstone", "inspiration", "refine", "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;
  })();
  const refinementSelections = getRefinementSelections();

  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; }
        .sample-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
        .sample-card { background: rgba(255,255,255,0.03); border: 1px solid rgba(201,169,110,0.12); border-radius: 18px; overflow: hidden; transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease; }
        .sample-card:hover { transform: translateY(-3px); box-shadow: 0 16px 36px rgba(0,0,0,0.22); border-color: rgba(201,169,110,0.28); }
        .sample-card.selected { border-color: rgba(201,169,110,0.55); box-shadow: 0 0 0 1px rgba(201,169,110,0.35), 0 16px 36px rgba(0,0,0,0.22); }
        .sample-stage { aspect-ratio: 4 / 5; background:
          radial-gradient(circle at top, rgba(201,169,110,0.16), transparent 45%),
          linear-gradient(180deg, #211c16 0%, #16120f 100%);
          display: flex; align-items: center; justify-content: center; padding: 24px; }
        .sample-stage img { width: 100%; height: 100%; object-fit: contain; display: block; filter: drop-shadow(0 18px 30px rgba(0,0,0,0.28)); }
        .sample-stage-large { min-height: clamp(320px, 40vh, 500px); max-height: clamp(320px, 40vh, 500px); padding: 22px; border-radius: 24px; }
        .refine-page { display: grid; gap: 14px; width: 100%; max-width: none; margin: 0; }
        .refine-hero { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; flex-wrap: wrap; }
        .refine-shell { display: grid; grid-template-columns: minmax(420px, 0.92fr) minmax(560px, 1.08fr); gap: 16px; align-items: stretch; }
        .refine-panel { background: linear-gradient(180deg, rgba(255,255,255,0.045), rgba(255,255,255,0.02)); border: 1px solid rgba(201,169,110,0.14); border-radius: 24px; padding: 22px; box-shadow: 0 18px 50px rgba(0,0,0,0.18); backdrop-filter: blur(10px); }
        .refine-visual-card { padding: 20px; position: relative; overflow: hidden; }
        .refine-visual-card::before { content: ""; position: absolute; inset: 0; background: radial-gradient(circle at top right, rgba(201,169,110,0.16), transparent 35%); pointer-events: none; }
        .refine-controls { display: grid; gap: 12px; align-content: start; }
        .refine-decision-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
        .refine-choice-section { background: rgba(255,255,255,0.025); border: 1px solid rgba(255,255,255,0.05); border-radius: 18px; padding: 14px; }
        .refine-choice-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
        .refine-choice-card { transition: transform 0.2s ease, border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease; cursor: pointer; border-radius: 15px; padding: 11px 11px 10px; min-height: 78px; border: 1px solid rgba(255,255,255,0.08); background: rgba(255,255,255,0.02); }
        .refine-choice-card:hover { transform: translateY(-1px); border-color: rgba(201,169,110,0.35); box-shadow: 0 10px 22px rgba(0,0,0,0.14); }
        .refine-choice-card.selected { border-color: rgba(201,169,110,0.7); background: linear-gradient(180deg, rgba(201,169,110,0.18), rgba(201,169,110,0.06)); box-shadow: 0 0 0 1px rgba(201,169,110,0.22); }
        .refine-choice-kicker { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(201,169,110,0.78); margin-bottom: 6px; }
        .refine-choice-title { font-size: 14px; color: #F5F0E8; margin-bottom: 2px; font-weight: 600; line-height: 1.35; }
        .refine-choice-desc { font-size: 11px; line-height: 1.45; color: rgba(245,240,232,0.5); }
        .refine-notes { background: rgba(255,255,255,0.025); border: 1px solid rgba(255,255,255,0.05); border-radius: 18px; padding: 14px; }
        .refine-summary { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
        .refine-summary-pill { padding: 8px 12px; border-radius: 999px; background: rgba(201,169,110,0.12); border: 1px solid rgba(201,169,110,0.22); color: #E9D4A5; font-size: 12px; line-height: 1.3; }
        .refine-actions { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin-top: 4px; }
        .refine-status { font-size: 12px; color: rgba(245,240,232,0.42); line-height: 1.6; }
        @media (min-width: 981px) {
          .refine-shell { min-height: calc(100vh - 250px); }
          .refine-controls { max-height: calc(100vh - 250px); overflow: auto; padding-right: 6px; }
        }
        @media (max-width: 980px) {
          .sample-grid { grid-template-columns: 1fr; }
          .refine-shell { grid-template-columns: 1fr; }
          .refine-decision-grid { grid-template-columns: 1fr; }
          .refine-choice-grid { grid-template-columns: 1fr; }
          .sample-stage-large { min-height: auto; max-height: none; }
        }
        @media (max-width: 960px) {
          .sample-grid { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
        }
        @media (max-width: 640px) {
          .refine-panel { padding: 18px; border-radius: 20px; }
          .refine-visual-card { padding: 18px; }
          .sample-stage { padding: 18px; }
        }
        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={() => { resetDesigner(); }}>
          <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("type")), 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>
        )}

        {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}>One last practical detail: budget</h2>
            <p style={styles.stepDesc}>This helps our team tailor stone size, metal weight, and construction details to the range that makes sense for you.</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}>
            <div style={{ marginTop: 12 }}>
              <h2 style={styles.stepTitle}>Your Custom Design Samples</h2>

              {!sampleImagesLoading && sampleImages.length === 0 && (
                <button
                  className="btn-primary"
                  style={{ ...styles.ctaButton, padding: "12px 28px", fontSize: 13 }}
                  onClick={generateSampleImages}
                >
                  Generate 3 Sample Images
                </button>
              )}

              {sampleImagesLoading && (
                <div style={{ marginTop: 22 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 18 }}>
                    <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)" }}>Generating three sample images...</span>
                  </div>
                  <div className="sample-grid">
                    {[1, 2, 3].map((item) => (
                      <div key={item} style={{ background: "rgba(255,255,255,0.03)", border: "1px solid rgba(201,169,110,0.12)", borderRadius: 14, overflow: "hidden" }}>
                        <div style={{ aspectRatio: "1 / 1", background: "rgba(201,169,110,0.08)", animation: "skeletonPulse 1.5s ease-in-out infinite" }} />
                        <div style={{ padding: 14 }}>
                          <div style={{ height: 14, width: "70%", borderRadius: 4, background: "rgba(201,169,110,0.08)", animation: "skeletonPulse 1.5s ease-in-out infinite", marginBottom: 8 }} />
                          <div style={{ height: 12, width: "100%", borderRadius: 4, background: "rgba(255,255,255,0.05)", animation: "skeletonPulse 1.5s ease-in-out infinite" }} />
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {sampleImagesError && (
                <div style={{ marginTop: 16 }}>
                  <p style={{ fontSize: 14, color: "rgba(220,120,120,0.9)", marginBottom: 12 }}>{sampleImagesError}</p>
                  <button
                    className="btn-primary"
                    style={{ ...styles.ctaButton, padding: "12px 28px", fontSize: 13 }}
                    onClick={generateSampleImages}
                  >
                    Try Again
                  </button>
                </div>
              )}

              {sampleImages.length > 0 && (
                <div style={{ marginTop: 22 }}>
                  <div className="sample-grid">
                    {sampleImages.map((image, index) => (
                      <div key={image.id || index} className={`sample-card ${selectedSampleId === image.id ? "selected" : ""}`}>
                        <div className="sample-stage">
                          <img
                            src={image.imageDataUrl}
                            alt={image.title}
                            style={{ display: "block" }}
                          />
                        </div>
                        <div style={{ padding: 18 }}>
                          <div style={{ fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "rgba(201,169,110,0.7)", marginBottom: 6 }}>
                            Sample {index + 1}
                          </div>
                          <div style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: 24, color: "#F5F0E8", marginBottom: 6 }}>
                            {image.title}
                          </div>
                          <p style={{ fontSize: 14, lineHeight: 1.6, color: "rgba(245,240,232,0.55)" }}>
                            {image.description}
                          </p>
                          <button
                            className="btn-primary"
                            style={{
                              ...styles.ctaButton,
                              width: "100%",
                              marginTop: 14,
                              padding: "11px 16px",
                              fontSize: 13,
                              background: selectedSampleId === image.id
                                ? "linear-gradient(135deg, #E2C992, #C9A96E)"
                                : "linear-gradient(135deg, #C9A96E, #B8944F)",
                            }}
                            onClick={() => openRefinementStep(image)}
                          >
                            {selectedSampleId === image.id ? "Continue Refining This Direction" : "Choose This Direction"}
                          </button>
                        </div>
                      </div>
                    ))}
                  </div>
                  <div style={{ textAlign: "center", marginTop: 14 }}>
                    <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={generateSampleImages}
                    >
                      🔄 Generate Other Examples
                    </button>
                  </div>
                </div>
              )}
            </div>
          </div>
        )}

        {currentStepName === "refine" && (
          <div style={{ ...styles.stepContent, maxWidth: "none", margin: 0, width: "100%" }}>
            {!baseSelectedSample ? (
              <div style={{ marginTop: 12, background: "rgba(255,255,255,0.03)", border: "1px solid rgba(201,169,110,0.14)", borderRadius: 18, padding: 24 }}>
                <h2 style={styles.stepTitle}>Refine Your Direction</h2>
                <p style={styles.stepDesc}>Choose one of the three sample directions first, then we’ll shape it into something more precise.</p>
                <button
                  className="btn-primary"
                  style={{ ...styles.ctaButton, marginTop: 14, padding: "12px 22px", fontSize: 13 }}
                  onClick={() => goTo(STEPS.indexOf("preview"))}
                >
                  Back to Sample Choices
                </button>
              </div>
            ) : (
              <div className="refine-page" style={{ marginTop: 12 }}>
                <div className="refine-hero">
                  <div>
                    <div style={{ fontSize: 12, letterSpacing: "0.1em", textTransform: "uppercase", color: "rgba(201,169,110,0.72)", marginBottom: 8 }}>
                      Tailoring Your Design
                    </div>
                    <h2 style={{ ...styles.stepTitle, marginBottom: 8 }}>{activeSelectedSample.title}</h2>
                    <p style={{ ...styles.stepDesc, maxWidth: 720, marginBottom: 0 }}>
                      {refinedSample
                        ? "We’ve already shaped this concept once. Keep fine-tuning until it feels unmistakably right."
                        : "Start from this chosen concept. Make a few thoughtful decisions below, add any personal notes you want, and we’ll generate a more tailored direction."}
                    </p>
                  </div>
                  <button
                    className="btn-back"
                    style={{ background: "none", border: "1px solid rgba(201,169,110,0.24)", borderRadius: 999, color: "rgba(245,240,232,0.78)", fontSize: 13, padding: "10px 16px", cursor: "pointer", fontFamily: "'Nunito Sans', sans-serif" }}
                    onClick={() => goTo(STEPS.indexOf("preview"))}
                  >
                    ← Choose a Different Sample
                  </button>
                </div>

                <div className="refine-shell">
                  <div className="refine-panel refine-visual-card">
                    <div style={{ position: "relative", zIndex: 1 }}>
                      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12, marginBottom: 10, flexWrap: "wrap" }}>
                        <div style={{ fontSize: 12, letterSpacing: "0.1em", textTransform: "uppercase", color: "rgba(201,169,110,0.72)" }}>
                          {refinedSample ? "Latest Refined Direction" : "Selected Direction"}
                        </div>
                        {approvedPreview && (
                          <div style={{ fontSize: 12, color: "#E9D4A5", border: "1px solid rgba(201,169,110,0.32)", borderRadius: 999, padding: "7px 12px", background: "rgba(201,169,110,0.08)" }}>
                            Approved for next step
                          </div>
                        )}
                      </div>
                      <p style={{ fontSize: 14, lineHeight: 1.6, color: "rgba(245,240,232,0.58)", marginBottom: 16, maxWidth: 620 }}>
                        {activeSelectedSample.description}
                      </p>
                      <div className="sample-stage sample-stage-large">
                        <img
                          src={activeSelectedSample.imageDataUrl}
                          alt={activeSelectedSample.title}
                          style={{ display: "block" }}
                        />
                      </div>
                    </div>
                  </div>

                  <div className="refine-panel refine-controls">
                    <div>
                      <div style={{ fontSize: 12, letterSpacing: "0.1em", textTransform: "uppercase", color: "rgba(201,169,110,0.72)", marginBottom: 8 }}>
                        Design Decisions
                      </div>
                      <p style={{ fontSize: 14, lineHeight: 1.6, color: "rgba(245,240,232,0.55)" }}>
                        Answer these like a jeweller and client shaping the same piece together. We’ll keep the overall direction, but sharpen it around the choices you make here.
                      </p>
                    </div>

                    <div className="refine-decision-grid">
                      <div className="refine-choice-section">
                        <label style={styles.inputLabel}>What should change most?</label>
                        <div className="refine-choice-grid">
                          {REFINEMENT_SHIFTS.map((option) => (
                            <div
                              key={option.id}
                              className={`refine-choice-card ${refinementAnswers.shift === option.id ? "selected" : ""}`}
                              onClick={() => updateRefinement("shift", refinementAnswers.shift === option.id ? "" : option.id)}
                            >
                              <div className="refine-choice-kicker">Direction</div>
                              <div className="refine-choice-title">{option.label}</div>
                              <div className="refine-choice-desc">{option.desc}</div>
                            </div>
                          ))}
                        </div>
                      </div>

                      <div className="refine-choice-section">
                        <label style={styles.inputLabel}>What should the eye notice first?</label>
                        <div className="refine-choice-grid">
                          {REFINEMENT_EMPHASIS.map((option) => (
                            <div
                              key={option.id}
                              className={`refine-choice-card ${refinementAnswers.emphasis === option.id ? "selected" : ""}`}
                              onClick={() => updateRefinement("emphasis", refinementAnswers.emphasis === option.id ? "" : option.id)}
                            >
                              <div className="refine-choice-kicker">Focus</div>
                              <div className="refine-choice-title">{option.label}</div>
                              <div className="refine-choice-desc">{option.desc}</div>
                            </div>
                          ))}
                        </div>
                      </div>

                      <div className="refine-choice-section">
                        <label style={styles.inputLabel}>What emotional tone should it carry?</label>
                        <div className="refine-choice-grid">
                          {REFINEMENT_MOODS.map((option) => (
                            <div
                              key={option.id}
                              className={`refine-choice-card ${refinementAnswers.mood === option.id ? "selected" : ""}`}
                              onClick={() => updateRefinement("mood", refinementAnswers.mood === option.id ? "" : option.id)}
                            >
                              <div className="refine-choice-kicker">Mood</div>
                              <div className="refine-choice-title">{option.label}</div>
                              <div className="refine-choice-desc">{option.desc}</div>
                            </div>
                          ))}
                        </div>
                      </div>

                      <div className="refine-choice-section">
                        <label style={styles.inputLabel}>How should it wear in real life?</label>
                        <div className="refine-choice-grid">
                          {REFINEMENT_WEARABILITY.map((option) => (
                            <div
                              key={option.id}
                              className={`refine-choice-card ${refinementAnswers.wearability === option.id ? "selected" : ""}`}
                              onClick={() => updateRefinement("wearability", refinementAnswers.wearability === option.id ? "" : option.id)}
                            >
                              <div className="refine-choice-kicker">Wearability</div>
                              <div className="refine-choice-title">{option.label}</div>
                              <div className="refine-choice-desc">{option.desc}</div>
                            </div>
                          ))}
                        </div>
                      </div>
                    </div>

                    <div className="refine-notes">
                      <label style={styles.inputLabel}>Add your own direction in your own words</label>
                      <textarea
                        rows={3}
                        placeholder="For example: keep this elegant overall shape, but make the center stone feel a little more prominent, reduce the height, and make the band cleaner and more refined."
                        value={refinementAnswers.notes}
                        onChange={(e) => updateRefinement("notes", e.target.value)}
                        style={{ resize: "vertical" }}
                      />
                      <div style={{ fontSize: 12, color: "rgba(245,240,232,0.42)", marginTop: 10, lineHeight: 1.6 }}>
                        The more specific you are here, the more tailored the next variation will feel.
                      </div>
                    </div>

                    <div className="refine-choice-section">
                      <label style={styles.inputLabel}>Your refinement brief</label>
                      <p style={{ fontSize: 13, lineHeight: 1.6, color: "rgba(245,240,232,0.5)" }}>
                        This is the design language we’ll use for the next image.
                      </p>
                      <div className="refine-summary">
                        {refinementSelections.length > 0 ? (
                          refinementSelections.map((item, index) => (
                            <div key={`${item}-${index}`} className="refine-summary-pill">{item}</div>
                          ))
                        ) : (
                          <div className="refine-summary-pill" style={{ color: "rgba(245,240,232,0.5)", background: "rgba(255,255,255,0.04)", borderColor: "rgba(255,255,255,0.08)" }}>
                            No refinements chosen yet
                          </div>
                        )}
                      </div>
                    </div>

                    {refinementError && (
                      <p style={{ fontSize: 14, color: "rgba(220,120,120,0.9)", marginBottom: 0 }}>
                        {refinementError}
                      </p>
                    )}

                    <div className="refine-actions">
                      <button
                        className="btn-primary"
                        style={{ ...styles.ctaButton, padding: "13px 22px", fontSize: 13 }}
                        onClick={generateRefinedSample}
                        disabled={refinementLoading}
                      >
                        {refinementLoading ? "Generating Your Next Variation..." : "Generate Refined Version"}
                      </button>
                      <button
                        className="btn-back"
                        style={{
                          background: approvedPreview ? "rgba(201,169,110,0.16)" : "none",
                          border: "1px solid rgba(201,169,110,0.28)",
                          color: approvedPreview ? "#E9D4A5" : "rgba(245,240,232,0.72)",
                          borderRadius: 999,
                          padding: "13px 18px",
                          fontSize: 13,
                          cursor: "pointer",
                          fontFamily: "'Nunito Sans', sans-serif",
                        }}
                        onClick={() => setApprovedPreview((current) => !current)}
                      >
                        {approvedPreview ? "✓ I’m Happy With This Direction" : "I’m Happy With This Direction"}
                      </button>
                    </div>

                    <p className="refine-status">
                      {approvedPreview
                        ? "This direction is approved. You can continue whenever you’re ready."
                        : "Stay in this step as long as you like. Generate new variations until the piece feels right, then approve it to continue."}
                    </p>
                  </div>
                </div>
              </div>
            )}
          </div>
        )}

        {currentStepName === "details" && (
          <div style={styles.stepContent}>
            <h2 style={styles.stepTitle}>Where should we send your brief?</h2>
            <p style={styles.stepDesc}>Add your contact details and any final notes so we can follow up with the right next steps.</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)} />
              </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}` : "")} />
              {activeSelectedSample && <SummaryRow label="Chosen Direction" value={activeSelectedSample.title} />}
              {buildRefinementSummary() && <SummaryRow label="Refinement Notes" value={buildRefinementSummary()} />}
              <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 () => {
                  setSubmitError("");
                  setSubmitState("sending");
                  setSubmitDetail("Preparing your design brief...");
                  try {
                    // Build full payload — this one includes compressed photos 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,
                      selectedPreview: activeSelectedSample ? {
                        title: activeSelectedSample.title,
                        description: activeSelectedSample.description,
                        imageDataUrl: activeSelectedSample.imageDataUrl,
                      } : null,
                      selectedPreviewRefinement: buildRefinementSummary(),
                      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));
                      setSubmitError("");
                    } else {
                      setSubmitError(result.error || "The design brief could not be sent.");
                    }
                    setSubmitState(result.success ? "sent" : "error");
                  } catch (err) {
                    console.error("Submit failed unexpectedly:", err);
                    setSubmitError(err?.message || "The design brief could not be sent.");
                    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>
                  {submitError && (
                    <p style={{ fontSize: 14, color: "rgba(220,120,120,0.9)", lineHeight: 1.6, marginBottom: 14 }}>
                      {submitError}
                    </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: "20px 28px 32px",
  },
  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 />);
