@primestyleai/tryon 3.16.0 → 3.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -305,6 +305,9 @@ const en = {
305
305
  "Size Chart": "Size Chart",
306
306
  "tap to compare": "tap to compare",
307
307
  "Comparing size": "Comparing size",
308
+ "Compare with another size": "Compare with another size",
309
+ "recommended": "recommended",
310
+ "size": "size",
308
311
  "Fit Analysis": "Fit Analysis",
309
312
  "Show more": "Show more",
310
313
  "Done": "Done",
@@ -1,5 +1,5 @@
1
- import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage } from "./index-DvAzTRFF.js";
2
- import { P, b, T, d, r } from "./index-DvAzTRFF.js";
1
+ import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage } from "./index-Lf4qO_jW.js";
2
+ import { P, b, T, d, r } from "./index-Lf4qO_jW.js";
3
3
  function detectProductImage() {
4
4
  const ogImage = document.querySelector(
5
5
  'meta[property="og:image"]'
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
3
  import { useState, useEffect, useMemo, useRef, useCallback } from "react";
4
- import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage, P as PrimeStyleError, L as LOCALE_LABELS, b as SUPPORTED_LOCALES } from "../index-DvAzTRFF.js";
4
+ import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage, P as PrimeStyleError, L as LOCALE_LABELS, b as SUPPORTED_LOCALES } from "../index-Lf4qO_jW.js";
5
5
  const HEADER_ALIASES = {
6
6
  // ── Size label columns (skipped during field derivation) ──
7
7
  size: "__size__",
@@ -860,8 +860,12 @@ function PrimeStyleTryonInner({
860
860
  if (!isNaN(v)) userMeas[k] = sizingUnit === "in" ? inToCm(v) : v;
861
861
  }
862
862
  if (Object.keys(userMeas).length === 0) return null;
863
- const sizeColIdx = sizeGuide.headers.findIndex((h) => /^size$/i.test(h.trim()));
864
- const idx = sizeColIdx >= 0 ? sizeColIdx : 0;
863
+ let idx = sizeGuide.headers.findIndex((h) => /^size$/i.test(h.trim()));
864
+ if (idx < 0) idx = sizeGuide.headers.findIndex((h) => /size|taglia|größe|taille/i.test(h.trim()));
865
+ if (idx < 0) {
866
+ const firstColVals = sizeGuide.rows.map((r) => r[0]?.trim() || "");
867
+ idx = firstColVals.some((v) => /^(XXS|XS|S|M|L|XL|XXL|XXXL|\d{1,3})$/i.test(v)) ? 0 : 0;
868
+ }
865
869
  const colMap = [];
866
870
  const intlCols = [];
867
871
  sizeGuide.headers.forEach((h, i) => {
@@ -872,7 +876,11 @@ function PrimeStyleTryonInner({
872
876
  intlCols.push({ hi: i, code: clean.toUpperCase() });
873
877
  return;
874
878
  }
875
- const fk = HEADER_MAP[clean];
879
+ let fk = HEADER_MAP[clean];
880
+ if (!fk) {
881
+ const pk = Object.keys(HEADER_MAP).find((k) => clean.includes(k));
882
+ if (pk) fk = HEADER_MAP[pk];
883
+ }
876
884
  if (fk && userMeas[fk] !== void 0) colMap.push({ hi: i, formKey: fk, label: h.trim() });
877
885
  });
878
886
  if (colMap.length === 0) return null;
@@ -1574,100 +1582,65 @@ function PrimeStyleTryonInner({
1574
1582
  ] }, `form-${formGender}-${sizingUnit}-${heightUnit}-${sizingCountry}-${formKey}`);
1575
1583
  }
1576
1584
  function SizeResultView() {
1577
- const [activeSize, setActiveSize] = useState(sizingResult?.recommendedSize || "");
1578
- const [editedValues, setEditedValues] = useState({});
1579
- const isCmResult = sizingUnit === "cm";
1580
- const chartData = useMemo(() => {
1585
+ const isCmR = sizingUnit === "cm";
1586
+ const unitLbl = isCmR ? t("cm") : t("in");
1587
+ const allSizes = useMemo(() => {
1588
+ if (!sizeGuide?.found || !sizeGuide.headers || !sizeGuide.rows) return [];
1589
+ const idx = sizeGuide.headers.findIndex((h) => /^size$/i.test(h.trim()));
1590
+ const col = idx >= 0 ? idx : 0;
1591
+ return sizeGuide.rows.map((r) => r[col]?.trim()).filter(Boolean);
1592
+ }, [sizeGuide]);
1593
+ const [compareSize, setCompareSize] = useState("");
1594
+ const [editVals, setEditVals] = useState({});
1595
+ const parseNumFromDetail = (s) => {
1596
+ const n = parseFloat(s.replace(/[^\d.]/g, ""));
1597
+ return isNaN(n) ? 0 : n;
1598
+ };
1599
+ const parseRangeFromDetail = (s) => {
1600
+ const nums = s.replace(/[^\d.\-–]/g, " ").trim().split(/[\s\-–]+/).filter(Boolean).map(Number).filter((n) => !isNaN(n));
1601
+ if (nums.length === 0) return { min: 0, max: 0 };
1602
+ return { min: Math.min(...nums), max: Math.max(...nums) };
1603
+ };
1604
+ const getChartRangeForSize = useCallback((measurement, size) => {
1581
1605
  if (!sizeGuide?.found || !sizeGuide.headers || !sizeGuide.rows) return null;
1582
- const INTL = /* @__PURE__ */ new Set(["eu", "us", "uk", "it", "fr", "de", "jp", "cn", "kr", "au", "br", "eur"]);
1583
- const MEAS_MAP = {
1584
- chest: "chest",
1585
- bust: "bust",
1586
- waist: "waist",
1587
- hips: "hips",
1588
- hip: "hips",
1589
- shoulder: "shoulderWidth",
1590
- shoulders: "shoulderWidth",
1591
- "shoulder width": "shoulderWidth",
1592
- sleeve: "sleeveLength",
1593
- "sleeve length": "sleeveLength",
1594
- inseam: "inseam",
1595
- neck: "neckCircumference",
1596
- "neck circumference": "neckCircumference",
1597
- foot: "footLengthCm",
1598
- "foot length": "footLengthCm"
1599
- };
1600
- const sizeColIdx = sizeGuide.headers.findIndex((h) => /^size$/i.test(h.trim()));
1601
- const idx = sizeColIdx >= 0 ? sizeColIdx : 0;
1602
- const measCols = [];
1603
- const intlCols = [];
1604
- sizeGuide.headers.forEach((h, i) => {
1605
- if (i === idx) return;
1606
- const lower = h.toLowerCase().trim().replace(/\s*\(.*\)/, "");
1607
- const clean = lower.replace(/\s*size\s*/gi, "").trim();
1608
- if (INTL.has(clean)) {
1609
- intlCols.push({ headerIdx: i, code: clean.toUpperCase() });
1610
- } else if (MEAS_MAP[clean]) {
1611
- measCols.push({ headerIdx: i, label: h.trim(), formKey: MEAS_MAP[clean] });
1612
- } else if (lower !== "size") {
1613
- measCols.push({ headerIdx: i, label: h.trim(), formKey: lower.replace(/\s+/g, "") });
1614
- }
1606
+ const sizeCol = sizeGuide.headers.findIndex((h) => /^size$/i.test(h.trim()));
1607
+ const sc = sizeCol >= 0 ? sizeCol : 0;
1608
+ const measCol = sizeGuide.headers.findIndex((h) => {
1609
+ const a = h.toLowerCase().trim();
1610
+ const b = measurement.toLowerCase().trim();
1611
+ return a === b || a.includes(b) || b.includes(a);
1615
1612
  });
1616
- const sizes = sizeGuide.rows.map((row) => {
1617
- const label = row[idx] || "";
1618
- const measurements = {};
1619
- for (const col of measCols) {
1620
- const cell = row[col.headerIdx] || "";
1621
- const nums = cell.replace(/[^\d.\-–]/g, " ").trim().split(/[\s\-–]+/).filter(Boolean).map(Number).filter((n) => !isNaN(n));
1622
- if (nums.length > 0) {
1623
- measurements[col.formKey] = { raw: cell, min: Math.min(...nums), max: Math.max(...nums) };
1613
+ if (measCol < 0) return null;
1614
+ const row = sizeGuide.rows.find((r) => r[sc]?.trim() === size);
1615
+ if (!row || !row[measCol]) return null;
1616
+ const cell = row[measCol];
1617
+ const parsed = parseRangeFromDetail(cell);
1618
+ return { range: cell, ...parsed };
1619
+ }, [sizeGuide]);
1620
+ const fitRows = useMemo(() => {
1621
+ const base = sizingResult?.matchDetails;
1622
+ if (!base || base.length === 0) return [];
1623
+ compareSize || sizingResult?.recommendedSize || "";
1624
+ return base.map((m) => {
1625
+ const editedRaw = editVals[m.measurement];
1626
+ const origNum = parseNumFromDetail(m.userValue);
1627
+ const userNum = editedRaw !== void 0 && editedRaw !== "" ? parseFloat(editedRaw) : origNum;
1628
+ let chartRange = m.chartRange;
1629
+ let rangeMin = parseRangeFromDetail(m.chartRange).min;
1630
+ let rangeMax = parseRangeFromDetail(m.chartRange).max;
1631
+ if (compareSize && compareSize !== sizingResult?.recommendedSize) {
1632
+ const alt = getChartRangeForSize(m.measurement, compareSize);
1633
+ if (alt) {
1634
+ chartRange = alt.range;
1635
+ rangeMin = alt.min;
1636
+ rangeMax = alt.max;
1624
1637
  }
1625
1638
  }
1626
- const intl = {};
1627
- for (const col of intlCols) {
1628
- if (row[col.headerIdx]) intl[col.code] = row[col.headerIdx];
1629
- }
1630
- return { label, measurements, intl };
1639
+ const fit = userNum >= rangeMin && userNum <= rangeMax ? "good" : userNum < rangeMin ? "tight" : "loose";
1640
+ return { measurement: m.measurement, userNum, userDisplay: `${userNum}`, chartRange, fit };
1631
1641
  });
1632
- return { sizes, measCols, intlCols };
1633
- }, [sizeGuide]);
1634
- const getUserVal = useCallback((formKey2) => {
1635
- const edited = editedValues[formKey2];
1636
- if (edited !== void 0 && edited !== "") {
1637
- const v2 = parseFloat(edited);
1638
- return isNaN(v2) ? null : isCmResult ? v2 : inToCm(v2);
1639
- }
1640
- const raw = formRef.current[formKey2];
1641
- if (!raw) return null;
1642
- const v = parseFloat(raw);
1643
- return isNaN(v) ? null : isCmResult ? v : inToCm(v);
1644
- }, [editedValues, isCmResult]);
1645
- const activeFit = useMemo(() => {
1646
- if (!chartData) return null;
1647
- const sizeRow = chartData.sizes.find((s) => s.label === activeSize);
1648
- if (!sizeRow) return null;
1649
- const details = [];
1650
- for (const col of chartData.measCols) {
1651
- const range = sizeRow.measurements[col.formKey];
1652
- if (!range) continue;
1653
- const userVal = getUserVal(col.formKey);
1654
- if (userVal === null) continue;
1655
- const fit = userVal >= range.min && userVal <= range.max ? "good" : userVal < range.min ? "tight" : "loose";
1656
- details.push({ label: col.label, formKey: col.formKey, userVal, chartMin: range.min, chartMax: range.max, chartRaw: range.raw, fit });
1657
- }
1658
- return details;
1659
- }, [chartData, activeSize, getUserVal]);
1660
- const activeIntl = useMemo(() => {
1661
- if (!chartData) return sizingResult?.internationalSizes || {};
1662
- const sizeRow = chartData.sizes.find((s) => s.label === activeSize);
1663
- return sizeRow?.intl || sizingResult?.internationalSizes || {};
1664
- }, [chartData, activeSize, sizingResult]);
1665
- const fmtRange = (min, max) => {
1666
- if (isCmResult) return min === max ? `${Math.round(min)}` : `${Math.round(min)}–${Math.round(max)}`;
1667
- return min === max ? `${cmToIn(min)}` : `${cmToIn(min)}–${cmToIn(max)}`;
1668
- };
1669
- const unitLabel = isCmResult ? t("cm") : t("in");
1670
- const isRecommended = activeSize === sizingResult?.recommendedSize;
1642
+ }, [sizingResult, compareSize, editVals, getChartRangeForSize]);
1643
+ const intlSizes = sizingResult?.internationalSizes || {};
1671
1644
  return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr", children: [
1672
1645
  sizingLoading && !sizingResult && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-loading", children: [
1673
1646
  /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner" }),
@@ -1681,100 +1654,65 @@ function PrimeStyleTryonInner({
1681
1654
  /* @__PURE__ */ jsx("div", { className: `ps-tryon-sr-hero-conf ps-conf-${sizingResult.confidence}`, children: sizingResult.confidence === "high" ? t("High Confidence") : sizingResult.confidence === "medium" ? t("Medium Confidence") : t("Low Confidence") })
1682
1655
  ] })
1683
1656
  ] }),
1684
- Object.keys(activeIntl).length > 0 && (() => {
1685
- const PRIMARY_CODES = ["US", "UK", "EU", "IT", "FR", "DE"];
1686
- const primary = PRIMARY_CODES.filter((c) => activeIntl[c]).map((c) => ({ code: c, val: activeIntl[c] }));
1687
- const rest = Object.entries(activeIntl).filter(([c]) => !PRIMARY_CODES.includes(c)).map(([code, val]) => ({ code, val }));
1688
- return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl", children: [
1689
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-label", children: t("Equivalent Sizes") }),
1690
- primary.length > 0 && /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-intl-primary", children: primary.map((s) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl-card", children: [
1691
- /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-val", children: s.val }),
1692
- /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-code", children: s.code })
1693
- ] }, s.code)) }),
1694
- rest.length > 0 && /* @__PURE__ */ jsxs("details", { className: "ps-tryon-sr-intl-more", children: [
1695
- /* @__PURE__ */ jsxs("summary", { className: "ps-tryon-sr-intl-more-btn", children: [
1696
- t("Show more"),
1697
- " (",
1698
- rest.length,
1699
- ")"
1700
- ] }),
1701
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-intl-grid", children: rest.map((s) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl-item", children: [
1702
- /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-code", children: s.code }),
1703
- /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-val", children: s.val })
1704
- ] }, s.code)) })
1705
- ] })
1706
- ] });
1707
- })(),
1708
- chartData && chartData.sizes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-sizes", children: [
1657
+ Object.keys(intlSizes).length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl", children: [
1658
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-label", children: t("Equivalent Sizes") }),
1659
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-intl-primary", children: Object.entries(intlSizes).map(([code, val]) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl-card", children: [
1660
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-val", children: val }),
1661
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-code", children: code })
1662
+ ] }, code)) })
1663
+ ] }),
1664
+ allSizes.length > 1 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-compare", children: [
1665
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-label", children: t("Compare with another size") }),
1666
+ /* @__PURE__ */ jsx(
1667
+ "select",
1668
+ {
1669
+ className: "ps-tryon-sr-compare-select",
1670
+ value: compareSize || sizingResult.recommendedSize,
1671
+ onChange: (e) => setCompareSize(e.target.value),
1672
+ children: allSizes.map((s) => /* @__PURE__ */ jsxs("option", { value: s, children: [
1673
+ s,
1674
+ s === sizingResult.recommendedSize ? ` ${t("recommended")}` : ""
1675
+ ] }, s))
1676
+ }
1677
+ )
1678
+ ] }),
1679
+ fitRows.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit", children: [
1709
1680
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-label", children: [
1710
- t("Size Chart"),
1711
- " ",
1712
- /* @__PURE__ */ jsxs("span", { className: "ps-tryon-sr-label-hint", children: [
1713
- "",
1714
- t("tap to compare")
1681
+ t("Fit Analysis"),
1682
+ compareSize && compareSize !== sizingResult.recommendedSize && /* @__PURE__ */ jsxs("span", { className: "ps-tryon-sr-label-hint", children: [
1683
+ " ",
1684
+ t("size"),
1685
+ " ",
1686
+ compareSize
1715
1687
  ] })
1716
1688
  ] }),
1717
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-size-row", children: chartData.sizes.map((s) => /* @__PURE__ */ jsxs(
1718
- "button",
1719
- {
1720
- onClick: () => setActiveSize(s.label),
1721
- className: `ps-tryon-sr-size-chip${s.label === activeSize ? " ps-active" : ""}${s.label === sizingResult.recommendedSize ? " ps-recommended" : ""}`,
1722
- children: [
1723
- s.label,
1724
- s.label === sizingResult.recommendedSize && /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-rec-dot" })
1725
- ]
1726
- },
1727
- s.label
1728
- )) }),
1729
- !isRecommended && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-comparing", children: [
1730
- t("Comparing size"),
1731
- " ",
1732
- /* @__PURE__ */ jsx("strong", { children: activeSize })
1733
- ] })
1734
- ] }),
1735
- activeFit && activeFit.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit", children: [
1736
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-label", children: t("Fit Analysis") }),
1737
1689
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-table", children: [
1738
1690
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-header", children: [
1739
1691
  /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-area", children: t("Area") }),
1740
- /* @__PURE__ */ jsxs("span", { className: "ps-tryon-sr-fit-col-you", children: [
1741
- t("You"),
1742
- " (",
1743
- unitLabel,
1744
- ")"
1745
- ] }),
1746
- /* @__PURE__ */ jsxs("span", { className: "ps-tryon-sr-fit-col-chart", children: [
1747
- t("Chart"),
1748
- " (",
1749
- unitLabel,
1750
- ")"
1751
- ] }),
1692
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-you", children: t("You") }),
1693
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-chart", children: t("Chart") }),
1752
1694
  /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-fit", children: t("Fit") })
1753
1695
  ] }),
1754
- activeFit.map((row, i) => /* @__PURE__ */ jsxs("div", { className: `ps-tryon-sr-fit-row ps-fit-${row.fit}`, children: [
1755
- /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-area", children: row.label }),
1756
- /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-you", children: /* @__PURE__ */ jsx(
1757
- "input",
1758
- {
1759
- type: "number",
1760
- className: "ps-tryon-sr-fit-input",
1761
- defaultValue: isCmResult ? Math.round(row.userVal) : cmToIn(row.userVal),
1762
- onBlur: (e) => {
1763
- const val = e.target.value;
1764
- setEditedValues((prev) => ({ ...prev, [row.formKey]: val }));
1696
+ fitRows.map((row, i) => /* @__PURE__ */ jsxs("div", { className: `ps-tryon-sr-fit-row ps-fit-${row.fit}`, children: [
1697
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-area", children: row.measurement }),
1698
+ /* @__PURE__ */ jsxs("span", { className: "ps-tryon-sr-fit-col-you", children: [
1699
+ /* @__PURE__ */ jsx(
1700
+ "input",
1701
+ {
1702
+ type: "number",
1703
+ className: "ps-tryon-sr-fit-input",
1704
+ value: editVals[row.measurement] !== void 0 ? editVals[row.measurement] : row.userNum,
1705
+ onChange: (e) => setEditVals((prev) => ({ ...prev, [row.measurement]: e.target.value }))
1765
1706
  }
1766
- }
1767
- ) }),
1768
- /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-chart", children: fmtRange(row.chartMin, row.chartMax) }),
1769
- /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-fit", children: /* @__PURE__ */ jsxs("span", { className: `ps-tryon-sr-fit-badge ps-fit-${row.fit}`, children: [
1770
- row.fit === "good" ? "✓" : row.fit === "tight" ? "↑" : "↓",
1771
- " ",
1772
- row.fit === "good" ? t("within range") : row.fit === "tight" ? t("may be snug") : t("may be loose")
1773
- ] }) })
1707
+ ),
1708
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-unit", children: unitLbl })
1709
+ ] }),
1710
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-chart", children: row.chartRange }),
1711
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-fit", children: /* @__PURE__ */ jsx("span", { className: `ps-tryon-sr-fit-badge ps-fit-${row.fit}`, children: row.fit === "good" ? "✓ " + t("within range") : row.fit === "tight" ? "↑ " + t("may be snug") : "↓ " + t("may be loose") }) })
1774
1712
  ] }, i))
1775
1713
  ] })
1776
1714
  ] }),
1777
- (!activeFit || activeFit.length === 0) && sizingResult.reasoning && /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-reasoning", children: /* @__PURE__ */ jsx("p", { children: sizingResult.reasoning }) }),
1715
+ fitRows.length === 0 && sizingResult.reasoning && /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-reasoning", children: /* @__PURE__ */ jsx("p", { children: sizingResult.reasoning }) }),
1778
1716
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-ctas", children: [
1779
1717
  /* @__PURE__ */ jsxs("button", { className: "ps-tryon-cta", onClick: () => setView("upload"), children: [
1780
1718
  t("See how it looks on you"),
@@ -2557,6 +2495,19 @@ const STYLES = `
2557
2495
  .ps-tryon-sr-fit-input::-webkit-outer-spin-button,
2558
2496
  .ps-tryon-sr-fit-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
2559
2497
  .ps-tryon-sr-fit-input:focus { border-color: #bb945c; }
2498
+ .ps-tryon-sr-fit-unit { font-size: 0.57vw; color: #666; margin-left: 0.2vw; }
2499
+
2500
+ /* Compare dropdown */
2501
+ .ps-tryon-sr-compare { }
2502
+ .ps-tryon-sr-compare-select {
2503
+ width: 100%; padding: 0.52vw 2vw 0.52vw 0.73vw; border: 1.5px solid #333; border-radius: 0.52vw;
2504
+ background: #1a1b1a; color: #fff; font-size: 0.83vw; font-weight: 600; font-family: inherit;
2505
+ appearance: none; -webkit-appearance: none; cursor: pointer; outline: none;
2506
+ background-image: url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.5 4.5L6 8L9.5 4.5' stroke='%23999' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
2507
+ background-repeat: no-repeat; background-position: right 0.73vw center;
2508
+ }
2509
+ .ps-tryon-sr-compare-select:focus { border-color: #bb945c; }
2510
+ .ps-tryon-sr-compare-select option { background: #1a1b1a; color: #fff; }
2560
2511
 
2561
2512
  .ps-tryon-sr-fit-badge {
2562
2513
  display: inline-flex; align-items: center; gap: 0.26vw; padding: 0.21vw 0.52vw;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "3.16.0",
3
+ "version": "3.18.0",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",