/* Timeless Totes — Products list + Product detail */
const { useState, useEffect } = React;

function FilterGroup({ title, opts, sel, onToggle }) {
  return (
    <div style={{ paddingBottom: 18, marginBottom: 18, borderBottom: '1px solid var(--line)' }}>
      <div style={{ fontWeight: 700, fontSize: '.95rem', marginBottom: 12 }}>{title}</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {opts.map(o => {
          const on = sel.includes(o);
          return (
            <label key={o} onClick={() => onToggle(o)}
              style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer', fontSize: '.94rem', color: on ? 'var(--ink)' : 'var(--ink-soft)', fontWeight: on ? 600 : 400 }}>
              <span style={{ width: 19, height: 19, borderRadius: 5, border: '1.5px solid ' + (on ? 'var(--pink-600)' : 'var(--line)'), background: on ? 'var(--pink-600)' : '#fff', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{on && <Icon name="check" size={12} />}</span>
              {o}
            </label>
          );
        })}
      </div>
    </div>
  );
}

function ProductsPage({ ctx }) {
  const CATS = ['Project bags', 'Cases', 'Pouches', 'Caddies', 'Totes'];
  const USES = ['Needlepoint', 'Quilting', 'Knitting & yarn', 'Events', 'Retail & samples'];
  const SIZES = ['Small', 'Medium', 'Large'];
  const [cats, setCats] = useState([]);
  const [uses, setUses] = useState([]);
  const [sizes, setSizes] = useState([]);
  const [sort, setSort] = useState('featured');

  const tog = (arr, set) => (v) => set(arr.includes(v) ? arr.filter(x => x !== v) : [...arr, v]);
  const clearAll = () => { setCats([]); setUses([]); setSizes([]); };
  const activeCount = cats.length + uses.length + sizes.length;
  const sizeCount = p => p.variants ? p.variants.length : (p.sizes ? p.sizes.length : 0);

  let list = PRODUCTS.filter(p =>
    (cats.length === 0 || cats.includes(p.category)) &&
    (uses.length === 0 || (p.useTags || []).some(u => uses.includes(u))) &&
    (sizes.length === 0 || (p.sizeTags || []).some(s => sizes.includes(s)))
  );
  if (sort === 'name') list = [...list].sort((a, b) => a.name.localeCompare(b.name));
  if (sort === 'sizes') list = [...list].sort((a, b) => sizeCount(b) - sizeCount(a));

  const chips = [...cats.map(c => ['cat', c]), ...uses.map(u => ['use', u]), ...sizes.map(s => ['size', s])];
  const removeChip = (type, val) => {
    if (type === 'cat') tog(cats, setCats)(val);
    if (type === 'use') tog(uses, setUses)(val);
    if (type === 'size') tog(sizes, setSizes)(val);
  };

  return (
    <main>
      <section className="section" style={{ paddingTop: 'clamp(26px,4vw,40px)' }}>
        <div className="wrap">
          <nav style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: '.88rem', color: 'var(--ink-faint)', marginBottom: 14 }}>
            <a onClick={() => ctx.navigate('#/')} style={{ cursor: 'pointer', color: 'var(--ink-soft)' }}>Home</a>
            <span>/</span>
            <span style={{ color: 'var(--ink)', fontWeight: 600 }}>Products</span>
          </nav>
          <h1 style={{ fontSize: 'clamp(2rem,3.4vw,2.8rem)', marginBottom: 10 }}>Products</h1>
          <p style={{ fontSize: '1.08rem', color: 'var(--ink-soft)', maxWidth: 580, margin: 0, lineHeight: 1.55 }}>
            Clear-vinyl totes, cases, and project bags — every style customizable with 1–4 color silkscreen, your choice of zipper and trim.
          </p>

          <div className="catalog-layout" style={{ display: 'grid', gridTemplateColumns: '248px 1fr', gap: 38, marginTop: 30, alignItems: 'start' }}>
            <aside className="catalog-rail" style={{ position: 'sticky', top: 92 }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
                <span style={{ fontFamily: 'var(--serif)', fontSize: '1.25rem' }}>Filters</span>
                {activeCount > 0 && <button onClick={clearAll} style={{ background: 'none', border: 'none', color: 'var(--pink-600)', fontWeight: 600, fontSize: '.88rem', cursor: 'pointer' }}>Clear all</button>}
              </div>
              <FilterGroup title="Size" opts={SIZES} sel={sizes} onToggle={tog(sizes, setSizes)} />
              <div style={{ marginBottom: 20, fontSize: '.86rem', color: 'var(--ink-soft)', display: 'flex', flexDirection: 'column', gap: 8 }}>
                {['1–4 color logo silkscreen', 'Zipper color & trim options', 'Custom sizes on request', 'All quote-ready, no checkout'].map(t => <span key={t} style={{ display: 'flex', gap: 8, alignItems: 'center' }}><Icon name="check" size={15} style={{ color: 'var(--pink-600)', flexShrink: 0 }} /> {t}</span>)}
              </div>
              <div className="card" style={{ padding: 18, background: 'var(--pink-faint)', border: '1px solid var(--pink-tint)' }}>
                <strong style={{ fontSize: '1.02rem', display: 'block', marginBottom: 6 }}>Need help choosing?</strong>
                <p style={{ fontSize: '.9rem', color: 'var(--ink-soft)', margin: '0 0 13px', lineHeight: 1.5 }}>Tell us your project and quantity — we'll recommend the right bag and send a quote.</p>
                <button className="btn btn-accent btn-sm btn-block" onClick={() => ctx.navigate('#/quote')}>Start a Quote</button>
              </div>
            </aside>

            <div>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 14, flexWrap: 'wrap', marginBottom: 18, paddingBottom: 16, borderBottom: '1px solid var(--line)' }}>
                <span style={{ fontWeight: 600, color: 'var(--ink)', fontSize: '.98rem' }}>{list.length} {list.length === 1 ? 'product' : 'products'}<span style={{ color: 'var(--ink-faint)', fontWeight: 400 }}>{activeCount > 0 ? ' · filtered' : ' · made to order in the USA'}</span></span>
                <label style={{ display: 'flex', alignItems: 'center', gap: 9, fontSize: '.92rem', color: 'var(--ink-soft)' }}>
                  Sort
                  <select className="select" value={sort} onChange={e => setSort(e.target.value)} style={{ width: 'auto', padding: '9px 14px', fontSize: '.92rem' }}>
                    <option value="featured">Featured</option>
                    <option value="name">Name A–Z</option>
                    <option value="sizes">Most sizes</option>
                  </select>
                </label>
              </div>
              {chips.length > 0 && (
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 22 }}>
                  {chips.map(([type, val]) => (
                    <button key={type + val} onClick={() => removeChip(type, val)}
                      style={{ display: 'inline-flex', alignItems: 'center', gap: 7, padding: '6px 12px', borderRadius: 100, background: 'var(--pink-tint)', color: 'var(--pink-700)', border: 'none', fontWeight: 600, fontSize: '.85rem', cursor: 'pointer' }}>
                      {val} <Icon name="x" size={13} />
                    </button>
                  ))}
                </div>
              )}
              {list.length === 0 ? (
                <div style={{ padding: '64px 20px', textAlign: 'center', color: 'var(--ink-soft)', border: '1px dashed var(--line)', borderRadius: 'var(--r-lg)' }}>
                  <p style={{ fontWeight: 600, color: 'var(--ink)', marginBottom: 14 }}>No products match those filters.</p>
                  <button className="btn btn-ghost btn-sm" onClick={clearAll}>Clear filters</button>
                </div>
              ) : (
                <div className="catalog-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: 24 }}>
                  {list.map(p => <ProductCard key={p.slug} p={p} ctx={ctx} />)}
                </div>
              )}
            </div>
          </div>
        </div>
      </section>
      <SampleCTA ctx={ctx} />
    </main>
  );
}

function SampleCTA({ ctx }) {
  return (
    <section className="section-sm" style={{ background: 'var(--cream)', borderTop: '1px solid var(--line)' }}>
      <div className="wrap">
        <div className="card" style={{ padding: 'clamp(24px,3vw,40px)', display: 'flex', alignItems: 'center', gap: 28, flexWrap: 'wrap', justifyContent: 'space-between' }}>
          <div style={{ display: 'flex', gap: 18, alignItems: 'center', flex: 1, minWidth: 280 }}>
            <span style={{ width: 54, height: 54, borderRadius: 14, background: 'var(--pink-tint)', color: 'var(--pink-700)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><Icon name="layers" size={26} /></span>
            <div>
              <h3 style={{ fontSize: '1.3rem' }}>Ready to get a quote?</h3>
              <p style={{ margin: '6px 0 0', color: 'var(--ink-soft)' }}>Tell us your product, quantity, and logo — we review everything and send a confirmed quote via QuickBooks.</p>
            </div>
          </div>
          <button className="btn btn-primary" onClick={() => ctx.navigate('#/quote')}>Start your quote <Icon name="arrow" size={16} className="arr" /></button>
        </div>
      </div>
    </section>
  );
}

function ProductDetailPage({ ctx, slug }) {
  const p = PRODUCTS.find(x => x.slug === slug) || PRODUCTS[0];
  const variants = p.variants;
  const hasVar = !!variants;
  const firstImgIdx = hasVar ? variants.findIndex(v => v.img) : -1;
  const startIdx = firstImgIdx < 0 ? 0 : firstImgIdx;
  const [vIdx, setVIdx] = React.useState(startIdx);
  const [size, setSize] = React.useState(0);
  const [qty, setQty] = React.useState(50);
  const [colors, setColors] = React.useState(1);
  const [zipIdx, setZipIdx] = React.useState(0);
  const [pantone, setPantone] = React.useState("");
  const [placement, setPlacement] = React.useState("Centered");
  const [trimMatchZipper, setTrimMatchZipper] = React.useState(false);
  const [trimNotes, setTrimNotes] = React.useState("");
  const [printAreaNotes, setPrintAreaNotes] = React.useState("");
  const [doubleSided, setDoubleSided] = React.useState(false);
  const [added, setAdded] = React.useState(false);

  React.useEffect(() => {
    setVIdx(startIdx); setSize(0); setQty(50); setColors(1); setZipIdx(0);
    setPantone(""); setPlacement("Centered"); setTrimMatchZipper(false);
    setTrimNotes(""); setPrintAreaNotes(""); setDoubleSided(false); setAdded(false);
    window.scrollTo(0, 0);
  }, [slug]);

  const ZIPPERS = ["Black", "White", "Navy", "Clear", "Match brand"];
  const ZIP_SWATCH = { Black: "#1B2333", White: "#FFFFFF", Navy: "#15233B", Clear: "linear-gradient(135deg,#EAF1F7,#fff)", "Match brand": "var(--pink)" };
  const PLACEMENTS = ["Centered", "Top left", "Top right", "Bottom left", "Bottom right", "See mockup"];

  const variant = hasVar ? variants[vIdx] : null;
  const isCraftCase = p.slug === "craft-case";
  const setupFee = { 1: 100, 2: 150, 3: 200, 4: 250 }[colors];
  const perUnit = 6.5 + (colors - 1) * 2;
  const volDisc = qty > 200 ? 0.10 : 0;
  const est = setupFee + perUnit * qty * (1 - volDisc);
  const related = PRODUCTS.filter(x => x.slug !== p.slug).slice(0, 3);
  const slugify = s => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");

  const buildItem = () => ({
    itemId: Date.now() + Math.random(),
    slug: p.slug,
    name: p.name,
    accent: p.accent,
    cardImg: p.cardImg,
    size: variant ? variant.code : (p.sizes ? p.sizes[size] : ""),
    qty,
    colors,
    zipperColor: ZIPPERS[zipIdx],
    trimMatchZipper,
    trimNotes,
    pantone,
    placement,
    printAreaNotes,
    doubleSided,
    variant: "",
    customDescription: "",
    customDimensions: "",
    customIntendedUse: "",
    customConstructionNotes: "",
    notes: "",
  });

  const handleAdd = () => {
    ctx.addToQuote(buildItem());
    setAdded(true);
  };

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

  const sizeCol = hasVar
    ? { icon: "ruler", t: "Build & material", items: [p.material, variants.length + " sizes available", "Reinforced binding", "Custom sizes on request"] }
    : { icon: "ruler", t: "Available sizes", items: p.sizes || ["Standard size"] };

  return (
    <main>
      <div className="wrap" style={{ paddingTop: 26 }}>
        <nav style={{ display: "flex", alignItems: "center", gap: 8, fontSize: ".88rem", color: "var(--ink-faint)", flexWrap: "wrap" }}>
          <a onClick={() => ctx.navigate("#/")} style={{ cursor: "pointer", color: "var(--ink-soft)" }}>Home</a>
          <span>/</span>
          <a onClick={() => ctx.navigate("#/products")} style={{ cursor: "pointer", color: "var(--ink-soft)" }}>Products</a>
          <span>/</span>
          <span style={{ color: "var(--ink)", fontWeight: 600 }}>{p.name}</span>
        </nav>
      </div>
      <section style={{ padding: "28px 0 clamp(56px,7vw,90px)" }}>
        <div className="wrap">
          <div className="detail-grid" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 52, alignItems: "start" }}>
            {/* Gallery */}
            <div style={{ position: "sticky", top: 96 }}>
              {hasVar && variant && variant.img ? (
                <ProductImage src={variant.img} label={p.name + " - " + variant.code} accent={p.accent}
                  style={{ aspectRatio: "1/1", borderRadius: "var(--r-xl)", border: "1px solid var(--line)" }} />
              ) : (
                <Mock label={p.name} sub={variant ? variant.code : "Product photo"} icon="camera" accent={p.accent}
                  style={{ aspectRatio: "1/1", borderRadius: "var(--r-xl)", border: "1px solid var(--line)" }} />
              )}
              <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 9, marginTop: 12 }}>
                {[["front view", "camera"], ["logo detail", "palette"], ["in use", "heart"], ["color options", "swatch"]].map(([l, ic]) => (
                  <Mock key={l} icon={ic} accent={p.accent} compact style={{ aspectRatio: "1/1", borderRadius: 12 }} />
                ))}
              </div>
            </div>
            {/* Config panel */}
            <div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 14 }}>
                {p.tag && <span className={"chip solid-" + p.accent}><span className="dot" />{p.tag}</span>}
              </div>
              <h1 style={{ fontSize: "clamp(2.2rem,3.6vw,3rem)", marginBottom: hasVar ? 8 : 16 }}>{p.name}</h1>
              {hasVar && variant && (
                <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap", marginBottom: 16, fontSize: "1rem" }}>
                  <strong style={{ color: "var(--pink-600)" }}>{variant.code}</strong>
                  {variant.panel && <span style={{ color: "var(--ink-soft)", fontSize: ".9rem" }}>{variant.panel}</span>}
                  {isCraftCase && variant.pocket !== undefined && (
                    <span className={"chip " + (variant.pocket ? "solid-pink" : "solid-navy")} style={{ fontSize: ".74rem" }}>
                      {variant.pocket ? "With pocket" : "No pocket"}
                    </span>
                  )}
                </div>
              )}
              <p className="lede" style={{ marginBottom: 26 }}>{p.desc}</p>

              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20, padding: "20px 0", borderTop: "1px solid var(--line)", borderBottom: "1px solid var(--line)", marginBottom: 26 }}>
                <div>
                  <div style={{ fontSize: ".82rem", fontWeight: 600, color: "var(--ink-soft)", marginBottom: 6 }}>Minimum order</div>
                  <div style={{ fontWeight: 700, fontSize: "1.08rem" }}>{p.moq}</div>
                </div>
                <div>
                  <div style={{ fontSize: ".82rem", fontWeight: 600, color: "var(--ink-soft)", marginBottom: 6 }}>Lead time</div>
                  <div style={{ fontWeight: 700, fontSize: "1.08rem" }}>{p.lead} <span style={{ fontWeight: 400, color: "var(--ink-faint)", fontSize: ".82rem" }}>after proof</span></div>
                </div>
              </div>

              {/* ── Size ── */}
              <div className="field">
                <label>Size{hasVar && <span className="hint"> ({variants.length} options)</span>}</label>
                {hasVar ? (
                  variants.length > 6 ? (
                    <select className="select" value={vIdx} onChange={e => setVIdx(+e.target.value)}>
                      {variants.map((v, i) => (
                        <option key={i} value={i}>{v.code}{v.pocket !== undefined ? (v.pocket ? " (with pocket)" : " (no pocket)") : ""}</option>
                      ))}
                    </select>
                  ) : (
                    <div style={{ display: "flex", flexWrap: "wrap", gap: 9 }}>
                      {variants.map((v, i) => (
                        <button key={i} onClick={() => setVIdx(i)}
                          style={{ padding: "9px 14px", borderRadius: 100, border: "1.5px solid " + (vIdx === i ? "var(--navy)" : "var(--line)"), background: vIdx === i ? "var(--navy)" : "#fff", color: vIdx === i ? "#fff" : "var(--ink)", fontWeight: 600, fontSize: ".86rem" }}>
                          {v.code}
                        </button>
                      ))}
                    </div>
                  )
                ) : p.sizes ? (
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 9 }}>
                    {p.sizes.map((s, i) => (
                      <button key={s} onClick={() => setSize(i)}
                        style={{ padding: "10px 15px", borderRadius: 100, border: "1.5px solid " + (size === i ? "var(--navy)" : "var(--line)"), background: size === i ? "var(--navy)" : "#fff", color: size === i ? "#fff" : "var(--ink)", fontWeight: 600, fontSize: ".88rem" }}>{s}</button>
                    ))}
                  </div>
                ) : null}
                {variant && variant.panel && (
                  <div style={{ fontSize: ".86rem", color: "var(--ink-soft)", marginTop: 8 }}>Panel size: {variant.panel}</div>
                )}
                {isCraftCase && (
                  <div style={{ fontSize: ".85rem", color: "var(--ink-soft)", marginTop: 8, padding: "10px 14px", background: "var(--cream)", borderRadius: 8, border: "1px solid var(--line)" }}>
                    Pocket and no-pocket variants are priced differently. Your selection is confirmed in your quote.
                  </div>
                )}
              </div>

              {/* ── Quantity ── */}
              <div className="field">
                <label>Quantity</label>
                <input className="input" type="number" min="1" step="1" value={qty} onChange={e => setQty(Math.max(1, +e.target.value))} />
                {qty > 200 && <div style={{ fontSize: ".82rem", color: "var(--forest)", marginTop: 4 }}>10% volume discount applied above 200 units</div>}
              </div>

              {/* ── Ink colors ── */}
              <div className="field">
                <label>Ink colors <span className="hint">(1 included · +$2/unit per added color)</span></label>
                <div style={{ display: "flex", gap: 9 }}>
                  {[1, 2, 3, 4].map(c => (
                    <button key={c} onClick={() => setColors(c)}
                      style={{ flex: 1, padding: "11px 0", borderRadius: 8, border: "1.5px solid " + (colors === c ? "var(--pink-600)" : "var(--line)"), background: colors === c ? "var(--pink-tint)" : "#fff", color: colors === c ? "var(--pink-700)" : "var(--ink)", fontWeight: 700 }}>{c}</button>
                  ))}
                </div>
              </div>

              {/* ── Pantone / hex ── */}
              <div className="field">
                <label>Pantone / hex ink color <span className="hint">(optional)</span></label>
                <input className="input" placeholder="e.g. PMS 322 C, #0F766E" value={pantone} onChange={e => setPantone(e.target.value)} />
                <div className="hint" style={{ marginTop: 5 }}>Custom ink colors may require a larger minimum — confirmed on your quote.</div>
              </div>

              {/* ── Zipper color ── */}
              <div className="field">
                <label>Zipper / trim color</label>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 9 }}>
                  {ZIPPERS.map((z, i) => (
                    <button key={z} onClick={() => setZipIdx(i)}
                      style={{ display: "flex", alignItems: "center", gap: 9, padding: "8px 13px 8px 9px", borderRadius: 100, border: "1.5px solid " + (zipIdx === i ? "var(--navy)" : "var(--line)"), background: "#fff", color: "var(--ink)", fontWeight: 600, fontSize: ".86rem" }}>
                      <span style={{ width: 18, height: 18, borderRadius: "50%", background: ZIP_SWATCH[z], border: "1px solid var(--line)", flexShrink: 0 }} />
                      {z}
                    </button>
                  ))}
                </div>
              </div>

              {/* ── Print placement ── */}
              <div className="field">
                <label>Print placement</label>
                <select className="select" value={placement} onChange={e => setPlacement(e.target.value)}>
                  {PLACEMENTS.map(opt => <option key={opt}>{opt}</option>)}
                </select>
                {placement === "See mockup" && (
                  <button onClick={() => ctx.navigate("#/design-lab")}
                    style={{ marginTop: 8, fontSize: ".82rem", background: "var(--cream)", border: "1px solid var(--line)", borderRadius: 8, padding: "5px 11px", color: "var(--navy)", fontWeight: 600, fontFamily: "var(--sans)", cursor: "pointer", display: "flex", alignItems: "center", gap: 6 }}>
                    <Icon name="image" size={14} /> Open Design Lab
                  </button>
                )}
              </div>

              {/* ── Match trim ── */}
              <div className="field">
                <Toggle label="Match trim to zipper color (Default)"
                  hint="Trim / webbing matches the same finish as your selected zipper"
                  on={trimMatchZipper}
                  onChange={v => setTrimMatchZipper(v)} />
                {!trimMatchZipper && (
                  <input className="input" style={{ marginTop: 8 }} placeholder="Trim / taping color notes (optional)"
                    value={trimNotes} onChange={e => setTrimNotes(e.target.value)} />
                )}
              </div>

              {/* ── Special print area notes ── */}
              <div className="field">
                <label>Special print area or placement notes <span className="hint">(optional)</span></label>
                <input className="input" placeholder="e.g. front pocket only, 4-inch wide centered, wrap print..."
                  value={printAreaNotes} onChange={e => setPrintAreaNotes(e.target.value)} />
              </div>

              {/* ── Double-sided ── */}
              <div className="field" style={{ marginBottom: 0 }}>
                <Toggle label="Double-sided print"
                  hint="Second screen setup + per-unit upcharge — confirmed on your quote"
                  on={doubleSided}
                  onChange={v => setDoubleSided(v)} />
              </div>

              {/* ── Rough estimate ── */}
              <div className="card" style={{ padding: 20, background: "var(--cream)", margin: "22px 0" }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
                  <span style={{ fontWeight: 600 }}>Rough estimate</span>
                  <span className="serif" style={{ fontSize: "1.9rem", color: "var(--navy)" }}>${est.toLocaleString(undefined, { maximumFractionDigits: 0 })}</span>
                </div>
                <div style={{ fontSize: ".84rem", color: "var(--ink-soft)", marginTop: 4 }}>
                  ${setupFee} setup ({colors}-color screen) + ~${perUnit.toFixed(2)}/unit x {qty}{volDisc ? " - 10% vol. discount" : ""}
                </div>
                <p style={{ fontSize: ".78rem", color: "var(--ink-faint)", margin: "12px 0 0", display: "flex", gap: 7 }}>
                  <Icon name="shield" size={15} style={{ color: "var(--pink-600)", flexShrink: 0 }} />
                  Estimate only. Final quote confirmed after artwork and production review.
                </p>
              </div>

              {/* ── CTA ── */}
              <div style={{ display: "flex", gap: 12 }}>
                <button className="btn btn-primary btn-lg" style={{ flex: 1 }} onClick={handleRequestQuote}>
                  Request Quote <Icon name="arrow" size={17} className="arr" />
                </button>
                <button className="btn btn-ghost btn-lg" onClick={handleAdd} title="Add to quote builder">
                  <Icon name="plus" size={18} /> Add
                </button>
              </div>
              {added && (
                <div style={{ marginTop: 12, padding: "14px 18px", borderRadius: "var(--r-md)", background: "var(--teal-tint)", border: "1.5px solid var(--teal)", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
                  <span style={{ display: "flex", alignItems: "center", gap: 10, fontWeight: 600, color: "var(--teal-600)" }}>
                    <Icon name="check" size={18} /> Added to your quote!
                  </span>
                  <div style={{ display: "flex", gap: 10 }}>
                    <button className="btn btn-ghost btn-sm" onClick={() => ctx.navigate("#/products")}>Browse more</button>
                    <button className="btn btn-primary btn-sm" onClick={() => ctx.navigate("#/quote")}>Go to quote <Icon name="arrow" size={14} className="arr" /></button>
                  </div>
                </div>
              )}
            </div>
          </div>

          {/* All sizes list */}
          {hasVar && (
            <div style={{ marginTop: "clamp(48px,6vw,80px)", paddingTop: "clamp(40px,5vw,64px)", borderTop: "1px solid var(--line)" }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", flexWrap: "wrap", gap: 12, marginBottom: 28 }}>
                <div>
                  <h2 style={{ fontSize: "clamp(1.7rem,2.6vw,2.2rem)", marginBottom: 8 }}>All {p.name} sizes</h2>
                  <p style={{ color: "var(--ink-soft)", margin: 0, maxWidth: 520 }}>
                    {p.material ? p.material + " - " : ""}{variants.length} sizes. Mix and match in one order (50-unit combined minimum).
                  </p>
                </div>
                <span className="chip solid-navy">{variants.length} sizes</span>
              </div>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(260px, 1fr))", gap: 10 }}>
                {variants.map((v, i) => (
                  <button key={i} onClick={() => { setVIdx(i); window.scrollTo({ top: 0, behavior: "smooth" }); }}
                    style={{ textAlign: "left", padding: "13px 16px", borderRadius: "var(--r-md)", border: i === vIdx ? "2px solid var(--pink-600)" : "1.5px solid var(--line)", background: i === vIdx ? "var(--pink-faint)" : "#fff", cursor: "pointer", display: "flex", flexDirection: "column", gap: 3 }}>
                    <span style={{ fontWeight: 700, fontSize: ".93rem", color: i === vIdx ? "var(--pink-700)" : "var(--ink)" }}>{v.code}</span>
                    {v.panel && <span style={{ fontSize: ".82rem", color: "var(--ink-soft)" }}>{v.panel}</span>}
                    {v.pocket !== undefined && (
                      <span style={{ fontSize: ".79rem", fontWeight: 600, color: v.pocket ? "var(--pink-700)" : "var(--navy)" }}>
                        {v.pocket ? "With pocket" : "No pocket"}
                      </span>
                    )}
                  </button>
                ))}
              </div>
            </div>
          )}

          {/* Artwork reassurance */}
          <div className="card" style={{ marginTop: "clamp(44px,5vw,68px)", padding: "clamp(22px,3vw,34px)", background: "var(--cream)", display: "flex", gap: 26, alignItems: "center", flexWrap: "wrap", justifyContent: "space-between" }}>
            <div style={{ display: "flex", gap: 18, alignItems: "center", flex: 1, minWidth: 290 }}>
              <span style={{ width: 56, height: 56, borderRadius: 14, background: "var(--pink-tint)", color: "var(--pink-700)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}><Icon name="upload" size={26} /></span>
              <div>
                <h3 style={{ fontSize: "1.3rem", marginBottom: 6 }}>Send your logo - we handle the rest</h3>
                <p style={{ margin: 0, color: "var(--ink-soft)", maxWidth: 520 }}>Upload vector (.ai .eps .pdf) or high-res PNG with your quote. We review every file and send a digital proof before anything prints.</p>
              </div>
            </div>
            <button className="btn btn-primary" onClick={handleRequestQuote}>Upload &amp; request quote <Icon name="arrow" size={16} className="arr" /></button>
          </div>

          {/* Detail columns */}
          <div className="detail-cols" style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 28, marginTop: "clamp(48px,6vw,80px)", paddingTop: "clamp(40px,5vw,64px)", borderTop: "1px solid var(--line)" }}>
            {[
              sizeCol,
              { icon: "heart", t: "Common uses", items: p.useTags || [] },
              { icon: "palette", t: "Customization", items: p.customization },
              { icon: "upload", t: "Artwork requirements", items: ["Vector preferred (.ai .eps .pdf)", "PNG/JPG accepted with prep note", "Pantone / hex for color matching", "Digital proof before production"] },
            ].map(col => (
              <div key={col.t}>
                <span style={{ color: "var(--pink-600)", display: "inline-flex", marginBottom: 12 }}><Icon name={col.icon} size={22} /></span>
                <h3 style={{ fontSize: "1.1rem", marginBottom: 14 }}>{col.t}</h3>
                <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 9 }}>
                  {col.items.map(it => (
                    <li key={it} style={{ display: "flex", gap: 9, fontSize: ".9rem", color: "var(--ink-soft)" }}>
                      <Icon name="check" size={16} style={{ color: "var(--navy)", flexShrink: 0, marginTop: 2 }} /> {it}
                    </li>
                  ))}
                </ul>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Related */}
      <section className="section-sm" style={{ background: "var(--cream)", borderTop: "1px solid var(--line)" }}>
        <div className="wrap">
          <SectionHead title="More clear-vinyl styles" />
          <div className="cat-grid" style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 24 }}>
            {related.map(r => <ProductCard key={r.slug} p={r} ctx={ctx} />)}
          </div>
        </div>
      </section>
    </main>
  );
}

Object.assign(window, { ProductsPage, ProductDetailPage });
