/* Timeless Totes — Design Lab (MVP) */
const { useState, useEffect, useRef } = React;

const INK_COLORS = [
  { label: "Navy",   hex: "#15233B" },
  { label: "Black",  hex: "#1a1a1a" },
  { label: "Pink",   hex: "#EC4E91" },
  { label: "Red",    hex: "#C0392B" },
  { label: "Forest", hex: "#2E6B4F" },
  { label: "Gold",   hex: "#B98A2E" },
  { label: "White",  hex: "#ffffff" },
];

const DL_MAX_FILE_BYTES  = 16 * 1024 * 1024;
const DL_PREVIEWABLE_EXT = ['PNG', 'JPG', 'JPEG', 'SVG', 'GIF', 'WEBP'];
const DL_RASTER_EXT      = ['PNG', 'JPG', 'JPEG'];

/* — Clear vinyl tote bag SVG outline — */
function DesignBag({ showGuide }) {
  return (
    <svg viewBox="0 0 400 520" xmlns="http://www.w3.org/2000/svg"
      style={{ position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
      <defs>
        <pattern id="dl-vinyl" width="40" height="40" patternUnits="userSpaceOnUse">
          <path d="M40 0 L0 0 0 40" fill="none" stroke="rgba(160,190,220,.09)" strokeWidth=".6" />
        </pattern>
        <linearGradient id="dl-body" x1="0%" y1="0%" x2="100%" y2="100%">
          <stop offset="0%"   stopColor="rgba(230,242,255,.32)" />
          <stop offset="60%"  stopColor="rgba(210,232,252,.16)" />
          <stop offset="100%" stopColor="rgba(200,222,248,.24)" />
        </linearGradient>
        <filter id="dl-shadow">
          <feDropShadow dx="0" dy="6" stdDeviation="10" floodOpacity=".1" />
        </filter>
      </defs>

      {/* ground shadow */}
      <ellipse cx="200" cy="508" rx="138" ry="8" fill="rgba(20,40,80,.07)" />

      {/* handles */}
      <path d="M 110 96 C 110 50 138 26 166 26 C 188 26 194 48 194 96"
        fill="none" stroke="#AFC4DA" strokeWidth="14" strokeLinecap="round" />
      <path d="M 206 96 C 206 48 212 26 234 26 C 262 26 290 50 290 96"
        fill="none" stroke="#AFC4DA" strokeWidth="14" strokeLinecap="round" />

      {/* handle sheen */}
      <path d="M 115 88 C 115 53 140 30 164 30"
        fill="none" stroke="rgba(255,255,255,.45)" strokeWidth="4" strokeLinecap="round" />
      <path d="M 211 88 C 211 53 215 30 236 30"
        fill="none" stroke="rgba(255,255,255,.45)" strokeWidth="4" strokeLinecap="round" />

      {/* bag body */}
      <rect x="34" y="96" width="332" height="400" rx="8" filter="url(#dl-shadow)"
        fill="url(#dl-body)" stroke="#A8BDD2" strokeWidth="1.5" />
      <rect x="34" y="96" width="332" height="400" rx="8" fill="url(#dl-vinyl)" />

      {/* top sheen */}
      <rect x="34" y="96" width="332" height="72" rx="8" fill="rgba(255,255,255,.16)" />

      {/* zipper strip */}
      <rect x="34" y="96" width="332" height="24" rx="5"
        fill="rgba(170,196,222,.38)" stroke="#A2BAD0" strokeWidth="1" />
      {[58,78,98,118,138,158,178,198,218,238,258,278,298,318,338].map((x) => (
        <rect key={x} x={x} y={101} width="5" height="12" rx="1.5" fill="rgba(150,178,206,.55)" />
      ))}
      <rect x="192" y="99" width="16" height="11" rx="3" fill="#8FAFC8" />
      <ellipse cx="200" cy="104.5" rx="2.5" ry="2" fill="rgba(255,255,255,.55)" />

      {/* print area guide */}
      {showGuide && (
        <g>
          <rect x="76" y="138" width="248" height="304" rx="5"
            fill="none" stroke="rgba(145,175,208,.5)" strokeWidth="1.2" strokeDasharray="7,5" />
          <text x="200" y="458" textAnchor="middle" fontSize="9" letterSpacing=".08em"
            fill="rgba(130,162,198,.75)" fontFamily="system-ui,sans-serif">PRINT AREA</text>
          <text x="200" y="470" textAnchor="middle" fontSize="7.5"
            fill="rgba(130,162,198,.55)" fontFamily="system-ui,sans-serif">Silkscreen · 1–4 colors</text>
        </g>
      )}
    </svg>
  );
}

/* — Draggable / resizable artwork overlay — */
function ArtworkLayer({ artwork, pos, size, interaction, onDragStart, onResizeStart }) {
  const isDragging = interaction && interaction.type === "drag";
  const corners = [
    { key: "tl", style: { top: -6,    left: -6,  cursor: "nwse-resize" } },
    { key: "tr", style: { top: -6,    right: -6, cursor: "nesw-resize" } },
    { key: "bl", style: { bottom: -6, left: -6,  cursor: "nesw-resize" } },
    { key: "br", style: { bottom: -6, right: -6, cursor: "nwse-resize" } },
  ];

  /* Non-previewable file (PDF, AI, EPS) — show placeholder instead of broken image */
  if (!artwork.src) {
    return (
      <div style={{
        position: "absolute",
        left: "19%", top: "26.5%", width: "62%", height: "58.5%",
        display: "flex", flexDirection: "column", alignItems: "center",
        justifyContent: "center", gap: 8, pointerEvents: "none",
      }}>
        <div style={{
          width: 52, height: 52, borderRadius: 12,
          background: "rgba(255,255,255,.9)", border: "1.5px solid var(--line)",
          display: "flex", alignItems: "center", justifyContent: "center",
        }}>
          <Icon name="check" size={26} style={{ color: "var(--forest)" }} />
        </div>
        <div style={{ fontSize: ".82rem", fontWeight: 700, color: "var(--ink)", textAlign: "center", padding: "0 8px", wordBreak: "break-word" }}>
          {artwork.name}
        </div>
        <div style={{ fontSize: ".74rem", color: "var(--ink-soft)" }}>Ready for quote</div>
      </div>
    );
  }

  return (
    <div
      style={{
        position: "absolute",
        left:  (pos.x / 400 * 100) + "%",
        top:   (pos.y / 520 * 100) + "%",
        width: (size.w / 400 * 100) + "%",
        height:(size.h / 520 * 100) + "%",
        cursor: isDragging ? "grabbing" : "grab", touchAction: "none", zIndex: 5,
      }}
      onMouseDown={onDragStart}
      onTouchStart={onDragStart}
    >
      {/* selection border */}
      <div style={{
        position: "absolute", inset: -2, pointerEvents: "none",
        border: "1.5px dashed rgba(21,35,59,.4)", borderRadius: 3,
      }} />

      <img src={artwork.src} alt="Your artwork"
        style={{ width: "100%", height: "100%", objectFit: "contain", display: "block", pointerEvents: "none", userSelect: "none" }} />

      {/* corner resize handles */}
      {corners.map(({ key, style }) => (
        <div key={key} data-resize={key}
          onMouseDown={(e) => onResizeStart(e, key)}
          onTouchStart={(e) => onResizeStart(e, key)}
          style={{
            position: "absolute", width: 14, height: 14, zIndex: 10,
            background: "var(--navy)", border: "2px solid #fff", borderRadius: 3,
            boxShadow: "0 1px 4px rgba(0,0,0,.3)", ...style,
          }} />
      ))}

      {/* size badge */}
      <div style={{
        position: "absolute", bottom: -24, left: "50%", transform: "translateX(-50%)",
        fontSize: "10px", fontFamily: "var(--mono)", color: "rgba(21,35,59,.55)",
        whiteSpace: "nowrap", pointerEvents: "none",
        background: "rgba(255,255,255,.85)", padding: "2px 6px", borderRadius: 4,
      }}>
        {Math.round(size.w)} &times; {Math.round(size.h)}
      </div>
    </div>
  );
}

/* — Design Lab page — */
function DesignLabPage({ ctx }) {
  const [selectedProduct, setSelectedProduct] = useState(PRODUCTS[0]);
  const [artwork, setArtwork] = useState(null);
  const [pos,  setPos]  = useState({ x: 112, y: 168 });
  const [size, setSize] = useState({ w: 176, h: 120 });
  const [interaction, setInteraction] = useState(null);
  const sizeRef = useRef(size);
  sizeRef.current = size;
  const [showGuide, setShowGuide] = useState(true);
  const [inkColor, setInkColor] = useState("#15233B");
  const [uploadError, setUploadError] = useState('');
  const fileRef = useRef(null);
  const canvasRef = useRef(null);

  /* Restore canvas artwork from shared quote context (e.g. returning from quote flow) */
  useEffect(function() {
    var qa = ctx.quoteArtwork;
    if (qa && !artwork) {
      if (qa.previewSrc) {
        var img = new Image();
        img.onload = function() {
          var maxW = 180, maxH = 200;
          var ratio = img.naturalWidth / img.naturalHeight;
          var w = maxW, h = maxW / ratio;
          if (h > maxH) { h = maxH; w = maxH * ratio; }
          w = Math.round(w); h = Math.round(h);
          setSize({ w: w, h: h });
          setPos({ x: Math.round(76 + (248 - w) / 2), y: Math.round(138 + (304 - h) / 2) });
          setArtwork({ src: qa.previewSrc, name: qa.fileName });
        };
        img.src = qa.previewSrc;
      } else {
        /* Non-previewable file (PDF, AI, EPS) — show name on canvas */
        setArtwork({ src: null, name: qa.fileName });
      }
    }
  }, []);

  const getXY = (e) => {
    const t = e.touches ? e.touches[0] : e;
    return { x: t.clientX, y: t.clientY };
  };

  const startDrag = (e) => {
    if (e.target.dataset.resize) return;
    e.preventDefault();
    const { x, y } = getXY(e);
    setInteraction({ type: "drag", ox: x, oy: y, op: { ...pos } });
  };

  const startResize = (e, corner) => {
    e.preventDefault();
    e.stopPropagation();
    const { x, y } = getXY(e);
    setInteraction({ type: "resize", corner, ox: x, oy: y, op: { ...pos }, os: { ...size } });
  };

  useEffect(() => {
    if (!interaction) return;
    const MIN = 40;
    const onMove = (e) => {
      if (e.cancelable) e.preventDefault();
      const { x, y } = getXY(e);
      const rect = canvasRef.current ? canvasRef.current.getBoundingClientRect() : { width: 400 };
      const scale = 400 / rect.width;
      const dx = (x - interaction.ox) * scale;
      const dy = (y - interaction.oy) * scale;
      if (interaction.type === "drag") {
        setPos({
          x: Math.min(Math.max(interaction.op.x + dx, 8), 400 - 8 - sizeRef.current.w),
          y: Math.min(Math.max(interaction.op.y + dy, 8), 520 - 8 - sizeRef.current.h),
        });
        return;
      }
      const { corner, op, os } = interaction;
      let nx = op.x, ny = op.y, nw = os.w, nh = os.h;
      if (corner === "br") {
        nw = Math.max(MIN, os.w + dx);
        nh = Math.max(MIN, os.h + dy);
      } else if (corner === "bl") {
        nw = Math.max(MIN, os.w - dx);
        nx = op.x + (os.w - nw);
        nh = Math.max(MIN, os.h + dy);
      } else if (corner === "tr") {
        nw = Math.max(MIN, os.w + dx);
        nh = Math.max(MIN, os.h - dy);
        ny = op.y + (os.h - nh);
      } else if (corner === "tl") {
        nw = Math.max(MIN, os.w - dx);
        nx = op.x + (os.w - nw);
        nh = Math.max(MIN, os.h - dy);
        ny = op.y + (os.h - nh);
      }
      setPos({ x: nx, y: ny });
      setSize({ w: nw, h: nh });
    };
    const onUp = () => setInteraction(null);
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseup",   onUp);
    window.addEventListener("touchmove", onMove, { passive: false });
    window.addEventListener("touchend",  onUp);
    return () => {
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseup",   onUp);
      window.removeEventListener("touchmove", onMove);
      window.removeEventListener("touchend",  onUp);
    };
  }, [interaction]);

  const handleFile = (e) => {
    const file = e.target.files[0];
    if (!file) return;
    e.target.value = '';

    if (file.size > DL_MAX_FILE_BYTES) {
      setUploadError('Maximum artwork file size is 16 MB. If your file is larger, please submit the quote without attaching it and contact Timeless Totes about sending the artwork separately.');
      return;
    }
    setUploadError('');

    const ext = file.name.split('.').pop().toUpperCase();
    const isRaster = DL_RASTER_EXT.includes(ext);
    const canPreview = DL_PREVIEWABLE_EXT.includes(ext);

    const saveToCtx = function(previewSrc) {
      ctx.setQuoteArtwork({
        fileName: file.name,
        fileType: ext,
        fileSize: file.size,
        file: file,
        previewSrc: previewSrc || null,
        artworkPrepFlag: isRaster,
      });
    };

    if (canPreview) {
      const reader = new FileReader();
      reader.onload = (ev) => {
        const img = new Image();
        img.onload = () => {
          const maxW = 180, maxH = 200;
          const ratio = img.naturalWidth / img.naturalHeight;
          let w = maxW, h = maxW / ratio;
          if (h > maxH) { h = maxH; w = maxH * ratio; }
          w = Math.round(w); h = Math.round(h);
          setSize({ w, h });
          setPos({ x: Math.round(76 + (248 - w) / 2), y: Math.round(138 + (304 - h) / 2) });
          setArtwork({ src: ev.target.result, name: file.name });
          saveToCtx(ev.target.result);
        };
        img.onerror = () => {
          setArtwork({ src: null, name: file.name });
          saveToCtx(null);
        };
        img.src = ev.target.result;
      };
      reader.readAsDataURL(file);
    } else {
      /* PDF, AI, EPS — no canvas preview, but file is saved to quote context */
      setArtwork({ src: null, name: file.name });
      saveToCtx(null);
    }
  };

  const clearArtwork = () => {
    setArtwork(null);
    ctx.clearQuoteArtwork();
    setUploadError('');
  };

  const centerArtwork = () => setPos({
    x: Math.round(76 + (248 - size.w) / 2),
    y: Math.round(138 + (304 - size.h) / 2),
  });

  const addToQuote = () => {
    ctx.addToQuote(selectedProduct);
    ctx.navigate("#/quote");
  };

  return (
    <main>
      {/* breadcrumb + heading bar */}
      <div style={{ background: "var(--bone)", borderBottom: "1px solid var(--line)", padding: "14px 0" }}>
        <div className="wrap" style={{ display: "flex", alignItems: "center", gap: 16, flexWrap: "wrap", justifyContent: "space-between" }}>
          <div>
            <nav aria-label="Breadcrumb" style={{ display: "flex", gap: 8, alignItems: "center", fontSize: ".86rem", color: "var(--ink-faint)", marginBottom: 5 }}>
              <a href="#/" onClick={(e) => { e.preventDefault(); ctx.navigate("#/"); }}
                style={{ color: "var(--ink-soft)", textDecoration: "none" }}>Home</a>
              <span>/</span>
              <span style={{ color: "var(--ink)", fontWeight: 600 }}>Design Lab</span>
            </nav>
            <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <h1 style={{ margin: 0, fontSize: "clamp(1.4rem,2.2vw,1.9rem)" }}>Design Lab</h1>
              <span style={{
                fontFamily: "var(--sans)", fontSize: ".68rem", fontWeight: 700, letterSpacing: ".09em",
                textTransform: "uppercase", color: "var(--pink-600)", background: "var(--pink-tint)",
                padding: "3px 9px", borderRadius: 100,
              }}>Beta</span>
            </div>
          </div>
          <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
            <button className="btn btn-ghost btn-sm" onClick={() => fileRef.current && fileRef.current.click()}>
              <Icon name="upload" size={15} /> Upload Artwork
            </button>
            <button className="btn btn-primary btn-sm" onClick={addToQuote}>
              Add to Quote <Icon name="arrow" size={15} className="arr" />
            </button>
          </div>
        </div>
      </div>

      {/* main two-column layout */}
      <div className="wrap" style={{ paddingTop: 32, paddingBottom: 72 }}>
        <div className="design-lab-grid" style={{ display: "grid", gridTemplateColumns: "1fr 320px", gap: 40, alignItems: "start" }}>

          {/* left — canvas */}
          <div>
            {/* product tabs */}
            <div style={{ display: "flex", gap: 8, marginBottom: 20, flexWrap: "wrap" }}>
              {PRODUCTS.slice(0, 4).map((p) => (
                <button key={p.slug} onClick={() => setSelectedProduct(p)}
                  style={{
                    padding: "7px 14px", borderRadius: 10, fontFamily: "var(--sans)",
                    fontWeight: 600, fontSize: ".86rem", cursor: "pointer", transition: "all .15s",
                    border: selectedProduct.slug === p.slug ? "1.5px solid var(--navy)" : "1.5px solid var(--line)",
                    background: selectedProduct.slug === p.slug ? "var(--navy)" : "var(--white)",
                    color: selectedProduct.slug === p.slug ? "#fff" : "var(--ink-soft)",
                  }}>
                  {p.name}
                </button>
              ))}
            </div>

            {/* the bag canvas */}
            <div ref={canvasRef} style={{
              position: "relative", width: "min(400px, 100%)", aspectRatio: "400 / 520",
              background: "var(--cream)", borderRadius: "var(--r-lg)",
              border: "1px solid var(--line)", overflow: "visible", userSelect: "none",
            }}>
              <DesignBag showGuide={showGuide} />

              {/* empty state */}
              {!artwork && (
                <div style={{
                  position: "absolute", left: "19%", top: "26.5%", width: "62%", height: "58.5%",
                  display: "flex", flexDirection: "column", alignItems: "center",
                  justifyContent: "center", gap: 12,
                }}>
                  <div style={{
                    width: 56, height: 56, borderRadius: 16,
                    background: "rgba(255,255,255,.88)", border: "1.5px dashed #AECDE0",
                    display: "flex", alignItems: "center", justifyContent: "center",
                  }}>
                    <Icon name="upload" size={26} style={{ color: "#90B4CA" }} />
                  </div>
                  <button className="btn btn-ghost btn-sm"
                    onClick={() => fileRef.current && fileRef.current.click()}
                    style={{ background: "rgba(255,255,255,.9)", fontSize: ".84rem" }}>
                    Upload your logo
                  </button>
                  <p style={{ margin: 0, fontSize: ".74rem", color: "#90B4CA", textAlign: "center", lineHeight: 1.4, maxWidth: 130 }}>
                    .ai &middot; .eps &middot; .pdf &middot; .svg &middot; .png
                  </p>
                </div>
              )}

              {/* artwork layer — handles both previewable and non-previewable */}
              {artwork && (
                <ArtworkLayer artwork={artwork} pos={pos} size={size} interaction={interaction}
                  onDragStart={startDrag} onResizeStart={startResize} />
              )}
            </div>

            {/* canvas toolbar */}
            <div style={{
              display: "flex", alignItems: "center", gap: 12, marginTop: 14,
              padding: "10px 14px", background: "var(--white)", borderRadius: "var(--r-md)",
              border: "1px solid var(--line)", flexWrap: "wrap",
            }}>
              <label style={{ display: "flex", alignItems: "center", gap: 7, fontSize: ".86rem", fontWeight: 600, color: "var(--ink-soft)", cursor: "pointer" }}>
                <input type="checkbox" checked={showGuide} onChange={(e) => setShowGuide(e.target.checked)}
                  style={{ accentColor: "var(--navy)" }} />
                Print area guide
              </label>
              {artwork && (
                <>
                  <div style={{ width: 1, height: 18, background: "var(--line)" }} />
                  {artwork.src && (
                    <>
                      <span style={{ fontSize: ".82rem", color: "var(--ink-faint)", fontFamily: "var(--mono)" }}>
                        {Math.round(size.w)} &times; {Math.round(size.h)} px
                      </span>
                      <div style={{ width: 1, height: 18, background: "var(--line)" }} />
                      <button className="btn btn-ghost btn-sm" onClick={centerArtwork}
                        style={{ fontSize: ".82rem", padding: "5px 11px" }}>
                        Center
                      </button>
                    </>
                  )}
                  <button className="btn btn-ghost btn-sm" onClick={clearArtwork}
                    style={{ fontSize: ".82rem", padding: "5px 11px", marginLeft: "auto" }}>
                    Clear
                  </button>
                </>
              )}
            </div>
          </div>

          {/* right — sidebar */}
          <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>

            {/* artwork upload card */}
            <div className="card" style={{ padding: 22 }}>
              <h3 style={{ fontSize: "1.05rem", margin: "0 0 14px" }}>Your artwork</h3>

              {uploadError && (
                <div style={{ marginBottom: 12, padding: "10px 13px", background: "#FEE2E2", border: "1px solid #FCA5A5", borderRadius: 8, fontSize: ".83rem", color: "#991B1B", lineHeight: 1.5 }}>
                  {uploadError}
                </div>
              )}

              {artwork ? (
                <div>
                  <div style={{
                    display: "flex", gap: 11, alignItems: "center",
                    padding: "10px 11px", background: "var(--cream)",
                    borderRadius: "var(--r-md)", marginBottom: 12,
                  }}>
                    <div style={{
                      width: 42, height: 42, borderRadius: 7, overflow: "hidden", flexShrink: 0,
                      background: "#fff", border: "1px solid var(--line)",
                      display: "flex", alignItems: "center", justifyContent: "center",
                    }}>
                      {artwork.src ? (
                        <img src={artwork.src} alt="" style={{ maxWidth: "100%", maxHeight: "100%", objectFit: "contain" }} />
                      ) : (
                        <Icon name="check" size={20} style={{ color: "var(--forest)" }} />
                      )}
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{
                        fontSize: ".86rem", fontWeight: 700, color: "var(--ink)",
                        overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
                      }}>{artwork.name}</div>
                      <div style={{ fontSize: ".76rem", color: "var(--ink-faint)", marginTop: 2 }}>
                        {artwork.src ? "Drag to position · handles to resize" : "File ready · not previewable in browser"}
                      </div>
                    </div>
                  </div>
                  <div style={{ display: "flex", gap: 8 }}>
                    <button style={{ flex: 1 }} className="btn btn-ghost btn-sm"
                      onClick={() => fileRef.current && fileRef.current.click()}>
                      <Icon name="upload" size={14} /> Replace
                    </button>
                    <button style={{ flex: 1 }} className="btn btn-ghost btn-sm" onClick={clearArtwork}>
                      <Icon name="x" size={14} /> Remove
                    </button>
                  </div>
                </div>
              ) : (
                <div>
                  <div
                    onClick={() => fileRef.current && fileRef.current.click()}
                    style={{
                      border: "2px dashed var(--line)", borderRadius: "var(--r-md)",
                      padding: "26px 16px", textAlign: "center", cursor: "pointer",
                      background: "var(--cream)", transition: "border-color .15s",
                    }}
                    onMouseEnter={(e) => e.currentTarget.style.borderColor = "var(--navy)"}
                    onMouseLeave={(e) => e.currentTarget.style.borderColor = "var(--line)"}>
                    <Icon name="upload" size={26} style={{ color: "var(--ink-faint)", display: "block", margin: "0 auto 9px" }} />
                    <div style={{ fontWeight: 700, fontSize: ".92rem", marginBottom: 3 }}>Upload your logo</div>
                    <div style={{ fontSize: ".78rem", color: "var(--ink-faint)" }}>PNG, SVG, PDF, AI, EPS &middot; Max 16 MB</div>
                  </div>
                  <p style={{ margin: "10px 0 0", fontSize: ".78rem", color: "var(--ink-faint)", lineHeight: 1.5 }}>
                    Any format for placement preview. Vector files (.ai, .eps, .svg) required for production.
                  </p>
                </div>
              )}
            </div>

            {/* ink color card */}
            <div className="card" style={{ padding: 22 }}>
              <h3 style={{ fontSize: "1.05rem", margin: "0 0 5px" }}>Ink color</h3>
              <p style={{ margin: "0 0 13px", fontSize: ".8rem", color: "var(--ink-soft)" }}>
                We match Pantone or hex on the final quote.
              </p>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 12 }}>
                {INK_COLORS.map((c) => (
                  <button key={c.hex} title={c.label} onClick={() => setInkColor(c.hex)}
                    style={{
                      width: 30, height: 30, borderRadius: "50%", cursor: "pointer",
                      border: inkColor === c.hex ? "3px solid var(--navy)" : "2px solid rgba(0,0,0,.12)",
                      background: c.hex,
                      outline:      inkColor === c.hex ? "2px solid #fff" : "none",
                      outlineOffset: "-4px",
                      boxShadow: c.hex === "#ffffff" ? "0 0 0 1px #ccc inset" : "none",
                      transform:  inkColor === c.hex ? "scale(1.18)" : "scale(1)",
                      transition: "transform .12s",
                    }} />
                ))}
              </div>
              <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                <input type="color" value={inkColor} onChange={(e) => setInkColor(e.target.value)}
                  style={{ width: 36, height: 34, borderRadius: 7, border: "1.5px solid var(--line)", cursor: "pointer", padding: 2 }} />
                <input type="text" value={inkColor.toUpperCase()}
                  onChange={(e) => { const v = e.target.value; if (/^#[0-9A-Fa-f]{0,6}$/.test(v)) setInkColor(v); }}
                  className="input"
                  style={{ flex: 1, fontSize: ".86rem", padding: "8px 10px", height: 34, fontFamily: "var(--mono)" }}
                  placeholder="#HEX" />
              </div>
            </div>

            {/* product specs card */}
            <div className="card" style={{ padding: 22 }}>
              <h3 style={{ fontSize: "1.05rem", margin: "0 0 13px" }}>{selectedProduct.name}</h3>
              {[
                ["Print method", "Silkscreen · 1–4 colors"],
                ["Print area",   '~8" x 10" standard'],
                ["Material",     "Clear PVC vinyl"],
                ["Min. order",   selectedProduct.moq  || "Ask on quote"],
                ["Lead time",    selectedProduct.lead || "3–4 weeks"],
              ].map(([k, v]) => (
                <div key={k} style={{
                  display: "flex", justifyContent: "space-between", gap: 10,
                  fontSize: ".86rem", padding: "7px 0", borderBottom: "1px solid var(--line-soft)",
                }}>
                  <span style={{ color: "var(--ink-soft)" }}>{k}</span>
                  <span style={{ fontWeight: 600, color: "var(--ink)", textAlign: "right" }}>{v}</span>
                </div>
              ))}
            </div>

            {/* CTA */}
            <div style={{ display: "flex", flexDirection: "column", gap: 9 }}>
              <button style={{ width: "100%" }} className="btn btn-primary btn-lg" onClick={addToQuote}>
                Add to Quote <Icon name="arrow" size={16} className="arr" />
              </button>
              <p style={{ margin: 0, fontSize: ".78rem", color: "var(--ink-faint)", textAlign: "center", lineHeight: 1.5 }}>
                No payment now. Final proof and quote before any charge.
              </p>
            </div>
          </div>
        </div>
      </div>

      <input ref={fileRef} type="file"
        accept=".png,.jpg,.jpeg,.svg,.pdf,.ai,.eps,.gif,.webp"
        style={{ display: "none" }} onChange={handleFile} />
    </main>
  );
}

Object.assign(window, { DesignLabPage });
