@primestyleai/tryon 4.2.2 → 4.3.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.
Files changed (2) hide show
  1. package/dist/react/index.js +109 -88
  2. package/package.json +2 -2
@@ -426,7 +426,6 @@ const SIZE_CONVERSIONS = {
426
426
  "48": { US: "XXXL", UK: "20", EU: "48", IT: "52", FR: "48", DE: "48", JP: "19", KR: "105", AU: "20" },
427
427
  "50": { US: "XXXL", UK: "22", EU: "50", IT: "54", FR: "50", DE: "50", JP: "21", KR: "110", AU: "22" }
428
428
  };
429
- const STEP_LABELS = ["", "Welcome", "Size", "Your Fit", "Try On"];
430
429
  const TOTAL_STEPS = 4;
431
430
  function detectLocale() {
432
431
  if (typeof window === "undefined") return "US";
@@ -1014,7 +1013,7 @@ function PrimeStyleTryonInner({
1014
1013
  if (p.weightUnit) setWeightUnit(p.weightUnit);
1015
1014
  setFormKey((k) => k + 1);
1016
1015
  }, [profiles]);
1017
- useCallback((name, asNew) => {
1016
+ const saveProfile = useCallback((name, asNew) => {
1018
1017
  const id = (asNew ? null : activeProfileId) || `p_${Date.now()}`;
1019
1018
  const p = {
1020
1019
  id,
@@ -1162,13 +1161,7 @@ function PrimeStyleTryonInner({
1162
1161
  const cssVars = Object.fromEntries(Object.entries(rootVars).filter(([, v]) => v !== void 0));
1163
1162
  function Stepper() {
1164
1163
  if (view === "error" || view === "idle") return null;
1165
- return /* @__PURE__ */ jsx("div", { className: "ps-tryon-stepper", children: /* @__PURE__ */ jsx("div", { className: "ps-tryon-stepper-track", children: Array.from({ length: TOTAL_STEPS }, (_, i) => i + 1).map((i) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-stepper-fragment", children: [
1166
- i > 1 && /* @__PURE__ */ jsx("div", { className: `ps-tryon-stepper-line${i <= stepIndex ? " ps-done" : ""}` }),
1167
- /* @__PURE__ */ jsxs("div", { className: `ps-tryon-stepper-step${i < stepIndex ? " ps-done" : i === stepIndex ? " ps-active" : ""}`, children: [
1168
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-stepper-circle", children: i < stepIndex ? /* @__PURE__ */ jsx(CheckIcon, {}) : i }),
1169
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-stepper-label", children: t(STEP_LABELS[i]) })
1170
- ] })
1171
- ] }, i)) }) });
1164
+ return /* @__PURE__ */ jsx("div", { className: "ps-tryon-dots", children: Array.from({ length: TOTAL_STEPS }, (_, i) => i + 1).map((i) => /* @__PURE__ */ jsx("div", { className: `ps-tryon-dot${i < stepIndex ? " ps-done" : i === stepIndex ? " ps-active" : ""}` }, i)) });
1172
1165
  }
1173
1166
  function WelcomeView() {
1174
1167
  return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-welcome", children: [
@@ -1246,12 +1239,17 @@ function PrimeStyleTryonInner({
1246
1239
  ) });
1247
1240
  }
1248
1241
  function SizingChoiceView() {
1249
- const [mode, setMode] = useState(sizingMethod === "exact" ? "exact" : "quick");
1242
+ const [mode, setMode] = useState("exact");
1243
+ const [saveToggle, setSaveToggle] = useState(false);
1244
+ const [saveFormName, setSaveFormName] = useState("");
1250
1245
  const isCm = sizingUnit === "cm";
1251
1246
  const sgAvailable = sizeGuide?.found === true;
1252
1247
  const sgChecked = !sizeGuideFetching && sizeGuide !== null;
1253
1248
  const exactAvailable = sgChecked ? sgAvailable : true;
1254
1249
  const handleSubmit = async () => {
1250
+ if (saveToggle && saveFormName.trim()) {
1251
+ saveProfile(saveFormName.trim());
1252
+ }
1255
1253
  setSizingMethod(mode);
1256
1254
  setSizingLoading(true);
1257
1255
  setView("size-result");
@@ -1362,6 +1360,22 @@ function PrimeStyleTryonInner({
1362
1360
  setMode("quick");
1363
1361
  setSizingMethod("quick");
1364
1362
  }, children: t("Not sure? Use height & weight instead") }) : null }),
1363
+ /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sf-save", children: [
1364
+ /* @__PURE__ */ jsxs("label", { className: "ps-tryon-sf-save-check", children: [
1365
+ /* @__PURE__ */ jsx("input", { type: "checkbox", checked: saveToggle, onChange: (e) => setSaveToggle(e.target.checked) }),
1366
+ /* @__PURE__ */ jsx("span", { children: t("Save as profile") })
1367
+ ] }),
1368
+ saveToggle && /* @__PURE__ */ jsx(
1369
+ "input",
1370
+ {
1371
+ type: "text",
1372
+ className: "ps-tryon-sf-save-name",
1373
+ placeholder: t("Profile name (e.g. John, Sarah)"),
1374
+ value: saveFormName,
1375
+ onChange: (e) => setSaveFormName(e.target.value)
1376
+ }
1377
+ )
1378
+ ] }),
1365
1379
  /* @__PURE__ */ jsx("button", { className: "ps-tryon-sf-next", onClick: handleSubmit, children: t("Next") })
1366
1380
  ] })
1367
1381
  ] });
@@ -1751,7 +1765,7 @@ function PrimeStyleTryonInner({
1751
1765
  ] }),
1752
1766
  view !== "idle" && /* @__PURE__ */ jsx("div", { className: cx("ps-tryon-overlay", cn.overlay), onClick: (e) => {
1753
1767
  if (e.target === e.currentTarget) handleClose();
1754
- }, children: /* @__PURE__ */ jsxs("div", { className: cx(`ps-tryon-modal${view === "result" && resultImageUrl && sizingResult || view === "size-result" ? " ps-tryon-modal-wide" : ""}`, cn.modal), onClick: (e) => e.stopPropagation(), children: [
1768
+ }, children: /* @__PURE__ */ jsxs("div", { className: cx(`ps-tryon-modal${view === "result" && resultImageUrl && sizingResult || view === "size-result" || view === "sizing-choice" ? " ps-tryon-modal-wide" : ""}`, cn.modal), onClick: (e) => e.stopPropagation(), children: [
1755
1769
  /* @__PURE__ */ jsxs("div", { className: cx("ps-tryon-header", cn.header), children: [
1756
1770
  /* @__PURE__ */ jsx("span", { className: cx("ps-tryon-title", cn.title), children: t("Virtual Try-On") }),
1757
1771
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-header-actions", children: [
@@ -1807,13 +1821,13 @@ const STYLES = `
1807
1821
  .ps-tryon-modal {
1808
1822
  background: var(--ps-modal-bg, #111211); color: var(--ps-modal-color, #fff);
1809
1823
  border-radius: var(--ps-modal-radius, 0.83vw); width: var(--ps-modal-width, 100%);
1810
- max-width: var(--ps-modal-max-width, 32vw); max-height: 92vh; overflow-y: auto;
1824
+ max-width: var(--ps-modal-max-width, 36vw); max-height: 92vh; overflow-y: auto;
1811
1825
  font-family: var(--ps-modal-font, system-ui, -apple-system, sans-serif);
1812
1826
  box-shadow: 0 1.3vw 2.6vw rgba(0,0,0,0.4); animation: ps-slide-up 0.3s ease;
1813
1827
  scrollbar-width: thin; scrollbar-color: #333 transparent;
1814
1828
  flex-shrink: 0;
1815
1829
  }
1816
- .ps-tryon-modal-wide { max-width: 48vw; }
1830
+ .ps-tryon-modal-wide { max-width: 52vw; }
1817
1831
  .ps-tryon-modal:has(.ps-tryon-drawer-open) { overflow: hidden; }
1818
1832
  @keyframes ps-slide-up { from { transform: translateY(1.04vw) scale(0.97); opacity: 0; } to { transform: translateY(0) scale(1); opacity: 1; } }
1819
1833
 
@@ -1900,25 +1914,14 @@ const STYLES = `
1900
1914
  .ps-tryon-lang-check { color: #bb945c; display: flex; align-items: center; }
1901
1915
 
1902
1916
  /* Stepper */
1903
- .ps-tryon-stepper { padding: 1.04vw 1.25vw 0.63vw; }
1904
- .ps-tryon-stepper-track { display: flex; align-items: flex-start; }
1905
- .ps-tryon-stepper-fragment { display: flex; align-items: flex-start; flex: 1; }
1906
- .ps-tryon-stepper-fragment:first-child { flex: 0 0 auto; }
1907
- .ps-tryon-stepper-line { flex: 1; height: 2px; background: #333; margin-top: 0.73vw; transition: background 0.4s; }
1908
- .ps-tryon-stepper-line.ps-done { background: #bb945c; }
1909
- .ps-tryon-stepper-step { display: flex; flex-direction: column; align-items: center; }
1910
- .ps-tryon-stepper-circle {
1911
- width: 1.46vw; height: 1.46vw; border-radius: 50%;
1912
- display: flex; align-items: center; justify-content: center;
1913
- border: 2px solid #333; font-size: 0.63vw; font-weight: 600; color: #666;
1914
- transition: all 0.3s;
1915
- }
1916
- .ps-tryon-stepper-step.ps-done .ps-tryon-stepper-circle { background: #bb945c; border-color: #bb945c; color: #111; }
1917
- .ps-tryon-stepper-step.ps-done .ps-tryon-stepper-circle svg { stroke: #111; }
1918
- .ps-tryon-stepper-step.ps-active .ps-tryon-stepper-circle { border-color: #bb945c; color: #bb945c; box-shadow: 0 0 0 0.21vw rgba(187,148,92,0.15); }
1919
- .ps-tryon-stepper-label { font-size: 0.52vw; margin-top: 0.26vw; color: #666; font-weight: 500; text-align: center; white-space: nowrap; }
1920
- .ps-tryon-stepper-step.ps-done .ps-tryon-stepper-label { color: #bb945c; }
1921
- .ps-tryon-stepper-step.ps-active .ps-tryon-stepper-label { color: #bb945c; font-weight: 700; }
1917
+ /* Dots progress */
1918
+ .ps-tryon-dots { display: flex; align-items: center; gap: 0.42vw; padding: 0.83vw 1.25vw; }
1919
+ .ps-tryon-dot {
1920
+ width: 0.47vw; height: 0.47vw; border-radius: 50%; background: #333;
1921
+ transition: all 0.3s ease;
1922
+ }
1923
+ .ps-tryon-dot.ps-done { background: #666; }
1924
+ .ps-tryon-dot.ps-active { background: #fff; width: 0.57vw; height: 0.57vw; }
1922
1925
 
1923
1926
  /* Body */
1924
1927
  .ps-tryon-body { padding: 1.25vw; min-height: 15.6vw; }
@@ -1926,31 +1929,31 @@ const STYLES = `
1926
1929
  .ps-tryon-view-enter { animation: ps-fade-up 0.35s ease both; }
1927
1930
 
1928
1931
  /* Welcome */
1929
- .ps-tryon-welcome { text-align: center; padding: clamp(8px, 0.5vw, 12px) 0; }
1930
- .ps-tryon-welcome-hero { margin-bottom: clamp(16px, 1.3vw, 24px); }
1932
+ .ps-tryon-welcome { text-align: center; padding: 0.5vw 0; }
1933
+ .ps-tryon-welcome-hero { margin-bottom: 1.3vw; }
1931
1934
  .ps-tryon-welcome-img-wrap { position: relative; display: inline-block; }
1932
- .ps-tryon-welcome-product { width: clamp(100px, 9vw, 160px); height: clamp(120px, 10.5vw, 190px); object-fit: cover; border-radius: clamp(10px, 0.9vw, 16px); border: 2px solid #333; box-shadow: 0 8px 30px rgba(0,0,0,0.4); }
1933
- .ps-tryon-welcome-sparkle { position: absolute; top: clamp(-6px, -0.5vw, -4px); right: clamp(-6px, -0.5vw, -4px); width: clamp(22px, 1.8vw, 30px); height: clamp(22px, 1.8vw, 30px); background: #bb945c; border-radius: 50%; display: flex; align-items: center; justify-content: center; animation: ps-float 3s ease-in-out infinite; }
1934
- .ps-tryon-welcome-sparkle svg { stroke: #111; width: clamp(10px, 0.9vw, 14px); height: clamp(10px, 0.9vw, 14px); }
1935
+ .ps-tryon-welcome-product { width: 9vw; height: 10.5vw; object-fit: cover; border-radius: 0.9vw; border: 2px solid #333; box-shadow: 0 8px 30px rgba(0,0,0,0.4); }
1936
+ .ps-tryon-welcome-sparkle { position: absolute; top: -0.5vw; right: -0.5vw; width: 1.8vw; height: 1.8vw; background: #bb945c; border-radius: 50%; display: flex; align-items: center; justify-content: center; animation: ps-float 3s ease-in-out infinite; }
1937
+ .ps-tryon-welcome-sparkle svg { stroke: #111; width: 0.9vw; height: 0.9vw; }
1935
1938
  @keyframes ps-float { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
1936
- .ps-tryon-welcome-title { font-size: clamp(18px, 1.4vw, 24px); font-weight: 700; color: #fff; margin: clamp(12px, 1vw, 18px) 0 clamp(4px, 0.3vw, 6px); letter-spacing: -0.01em; }
1937
- .ps-tryon-welcome-sub { font-size: clamp(13px, 0.9vw, 16px); color: #999; margin: 0; }
1938
- .ps-tryon-features { display: flex; gap: clamp(8px, 0.7vw, 12px); margin: clamp(16px, 1.3vw, 24px) 0; }
1939
- .ps-tryon-feature { flex: 1; padding: clamp(14px, 1vw, 18px) clamp(10px, 0.7vw, 14px); border: 1px solid #333; border-radius: clamp(10px, 0.8vw, 14px); text-align: center; transition: border-color 0.2s; }
1939
+ .ps-tryon-welcome-title { font-size: 1.4vw; font-weight: 700; color: #fff; margin: 1vw 0 0.3vw; letter-spacing: -0.01em; }
1940
+ .ps-tryon-welcome-sub { font-size: 0.9vw; color: #999; margin: 0; }
1941
+ .ps-tryon-features { display: flex; gap: 0.7vw; margin: 1.3vw 0; }
1942
+ .ps-tryon-feature { flex: 1; padding: 1vw 0.7vw; border: 1px solid #333; border-radius: 0.8vw; text-align: center; transition: border-color 0.2s; }
1940
1943
  .ps-tryon-feature:hover { border-color: #555; }
1941
- .ps-tryon-feature-icon { margin-bottom: clamp(6px, 0.4vw, 8px); color: #bb945c; display: flex; justify-content: center; }
1942
- .ps-tryon-feature-icon svg { stroke: currentColor; fill: none; width: clamp(18px, 1.2vw, 22px); height: clamp(18px, 1.2vw, 22px); }
1943
- .ps-tryon-feature-title { font-size: clamp(13px, 0.85vw, 15px); font-weight: 600; color: #fff; margin-bottom: 2px; }
1944
- .ps-tryon-feature-desc { font-size: clamp(11px, 0.7vw, 13px); color: #999; }
1944
+ .ps-tryon-feature-icon { margin-bottom: 0.4vw; color: #bb945c; display: flex; justify-content: center; }
1945
+ .ps-tryon-feature-icon svg { stroke: currentColor; fill: none; width: 1.2vw; height: 1.2vw; }
1946
+ .ps-tryon-feature-title { font-size: 0.85vw; font-weight: 600; color: #fff; margin-bottom: 2px; }
1947
+ .ps-tryon-feature-desc { font-size: 0.7vw; color: #999; }
1945
1948
  .ps-tryon-cta {
1946
- width: 100%; padding: clamp(14px, 1vw, 18px); background: #bb945c; color: #111; border: none;
1947
- border-radius: clamp(10px, 0.8vw, 14px); font-size: clamp(14px, 1vw, 17px); font-weight: 700; cursor: pointer;
1948
- display: flex; align-items: center; justify-content: center; gap: clamp(6px, 0.5vw, 10px); transition: all 0.2s;
1949
+ width: 100%; padding: 1vw; background: #bb945c; color: #111; border: none;
1950
+ border-radius: 0.8vw; font-size: 1vw; font-weight: 700; cursor: pointer;
1951
+ display: flex; align-items: center; justify-content: center; gap: 0.5vw; transition: all 0.2s;
1949
1952
  font-family: var(--ps-modal-font, system-ui, sans-serif);
1950
1953
  }
1951
1954
  .ps-tryon-cta:hover { background: #a07d4e; transform: translateY(-1px); }
1952
1955
  .ps-tryon-cta svg { stroke: #111; }
1953
- .ps-tryon-welcome-note { font-size: clamp(11px, 0.7vw, 13px); color: #666; margin-top: clamp(10px, 0.7vw, 14px); }
1956
+ .ps-tryon-welcome-note { font-size: 0.7vw; color: #666; margin-top: 0.7vw; }
1954
1957
 
1955
1958
  /* Upload */
1956
1959
  .ps-tryon-upload {
@@ -2004,62 +2007,62 @@ const STYLES = `
2004
2007
 
2005
2008
  /* Sizing — split layout (product image left, form right) */
2006
2009
  .ps-tryon-sizing-split {
2007
- display: grid; grid-template-columns: 1fr 1.2fr; gap: clamp(16px, 1.5vw, 28px);
2008
- min-height: clamp(300px, 22vw, 500px);
2010
+ display: grid; grid-template-columns: 1fr 1.2fr; gap: 1.5vw;
2011
+ min-height: 22vw;
2009
2012
  }
2010
2013
  .ps-tryon-sizing-img-col {
2011
2014
  display: flex; align-items: stretch; justify-content: center;
2012
- background: #0e0e0f; border-radius: clamp(10px, 0.8vw, 14px); overflow: hidden;
2015
+ background: #0e0e0f; border-radius: 0.8vw; overflow: hidden;
2013
2016
  }
2014
2017
  .ps-tryon-sizing-product-img {
2015
2018
  width: 100%; height: 100%; object-fit: cover; object-position: top;
2016
2019
  }
2017
2020
  .ps-tryon-sizing-form-col {
2018
2021
  display: flex; flex-direction: column; justify-content: center;
2019
- padding: clamp(8px, 0.5vw, 14px) 0;
2022
+ padding: 0.5vw 0;
2020
2023
  }
2021
2024
  .ps-tryon-sf-title {
2022
- font-size: clamp(18px, 1.3vw, 24px); font-weight: 700; color: #fff;
2023
- margin: 0 0 clamp(14px, 1vw, 20px); letter-spacing: -0.01em;
2025
+ font-size: 1.3vw; font-weight: 700; color: #fff;
2026
+ margin: 0 0 1vw; letter-spacing: -0.01em;
2024
2027
  }
2025
2028
  .ps-tryon-sf-unit-tabs {
2026
- display: flex; border-bottom: 1.5px solid #333; margin-bottom: clamp(14px, 1vw, 20px);
2029
+ display: flex; border-bottom: 1.5px solid #333; margin-bottom: 1vw;
2027
2030
  }
2028
2031
  .ps-tryon-sf-unit-tab {
2029
- background: none; border: none; padding: clamp(6px, 0.4vw, 10px) clamp(12px, 0.8vw, 16px);
2030
- font-size: clamp(12px, 0.8vw, 14px); font-weight: 600; color: #666; cursor: pointer;
2032
+ background: none; border: none; padding: 0.4vw 0.8vw;
2033
+ font-size: 0.8vw; font-weight: 600; color: #666; cursor: pointer;
2031
2034
  font-family: inherit; transition: all 0.2s; border-bottom: 2px solid transparent;
2032
2035
  margin-bottom: -1.5px;
2033
2036
  }
2034
2037
  .ps-tryon-sf-unit-tab:hover { color: #999; }
2035
2038
  .ps-tryon-sf-unit-tab.ps-active { color: #fff; border-bottom-color: #bb945c; }
2036
2039
 
2037
- .ps-tryon-sf-profile-bar { margin-bottom: clamp(10px, 0.7vw, 14px); }
2040
+ .ps-tryon-sf-profile-bar { margin-bottom: 0.7vw; }
2038
2041
  .ps-tryon-sf-profile-select {
2039
- width: 100%; padding: clamp(6px, 0.4vw, 8px); background: #1a1b1a; color: #ccc;
2040
- border: 1px solid #333; border-radius: clamp(6px, 0.4vw, 8px);
2041
- font-size: clamp(11px, 0.75vw, 13px); font-family: inherit; cursor: pointer;
2042
+ width: 100%; padding: 0.4vw; background: #1a1b1a; color: #ccc;
2043
+ border: 1px solid #333; border-radius: 0.4vw;
2044
+ font-size: 0.75vw; font-family: inherit; cursor: pointer;
2042
2045
  }
2043
2046
 
2044
2047
  .ps-tryon-sf-fields {
2045
- display: flex; flex-direction: column; gap: clamp(16px, 1.1vw, 22px);
2048
+ display: flex; flex-direction: column; gap: 1.1vw;
2046
2049
  flex: 1;
2047
2050
  }
2048
2051
  .ps-tryon-sf-row {
2049
2052
  display: flex; align-items: center; justify-content: space-between;
2050
- border-bottom: 1px solid #2a2a2a; padding-bottom: clamp(10px, 0.7vw, 14px);
2053
+ border-bottom: 1px solid #2a2a2a; padding-bottom: 0.7vw;
2051
2054
  }
2052
2055
  .ps-tryon-sf-label {
2053
- font-size: clamp(12px, 0.85vw, 15px); font-weight: 600; color: #ccc;
2056
+ font-size: 0.85vw; font-weight: 600; color: #ccc;
2054
2057
  letter-spacing: 0.04em; flex-shrink: 0;
2055
2058
  }
2056
2059
  .ps-tryon-sf-input-wrap { flex: 1; display: flex; justify-content: flex-end; }
2057
- .ps-tryon-sf-inline { display: flex; align-items: center; gap: clamp(6px, 0.4vw, 10px); }
2058
- .ps-tryon-sf-ft-group { display: flex; align-items: center; gap: clamp(4px, 0.3vw, 8px); }
2060
+ .ps-tryon-sf-inline { display: flex; align-items: center; gap: 0.4vw; }
2061
+ .ps-tryon-sf-ft-group { display: flex; align-items: center; gap: 0.3vw; }
2059
2062
  .ps-tryon-sf-input {
2060
2063
  background: transparent; border: none; border-bottom: 1.5px solid #444;
2061
- color: #fff; font-size: clamp(14px, 1vw, 17px); font-family: inherit;
2062
- padding: clamp(4px, 0.3vw, 6px) 0; width: clamp(50px, 4vw, 80px);
2064
+ color: #fff; font-size: 1vw; font-family: inherit;
2065
+ padding: 0.3vw 0; width: 4vw;
2063
2066
  text-align: center; outline: none; transition: border-color 0.2s;
2064
2067
  }
2065
2068
  .ps-tryon-sf-input:focus { border-bottom-color: #bb945c; }
@@ -2067,33 +2070,51 @@ const STYLES = `
2067
2070
  .ps-tryon-sf-input::-webkit-outer-spin-button,
2068
2071
  .ps-tryon-sf-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
2069
2072
  .ps-tryon-sf-unit {
2070
- font-size: clamp(11px, 0.75vw, 13px); color: #666; font-weight: 500;
2073
+ font-size: 0.75vw; color: #666; font-weight: 500;
2071
2074
  }
2072
2075
 
2073
- .ps-tryon-sf-optional { margin-top: clamp(4px, 0.3vw, 6px); }
2076
+ .ps-tryon-sf-optional { margin-top: 0.3vw; }
2077
+ .ps-tryon-sf-optional { border-top: 1px solid #282828; margin-top: 0.42vw; padding-top: 0.42vw; }
2078
+ .ps-tryon-sf-optional-fields {
2079
+ display: flex; flex-direction: column; gap: 0.52vw; padding-top: 0.52vw;
2080
+ animation: ps-fade-up 0.3s ease both;
2081
+ }
2074
2082
  .ps-tryon-sf-optional-toggle {
2075
- font-size: clamp(11px, 0.75vw, 13px); color: #666; cursor: pointer;
2083
+ font-size: 0.75vw; color: #666; cursor: pointer;
2076
2084
  font-family: inherit; list-style: none;
2077
2085
  }
2078
2086
  .ps-tryon-sf-optional-toggle:hover { color: #999; }
2079
2087
  .ps-tryon-sf-optional-toggle::-webkit-details-marker { display: none; }
2080
- .ps-tryon-sf-optional-fields { display: flex; flex-direction: column; gap: clamp(12px, 0.8vw, 16px); padding-top: clamp(10px, 0.7vw, 14px); }
2088
+ .ps-tryon-sf-optional-fields { display: flex; flex-direction: column; gap: 0.8vw; padding-top: 0.7vw; }
2081
2089
 
2082
- .ps-tryon-sf-switch { margin-top: clamp(12px, 0.8vw, 16px); text-align: center; }
2090
+ .ps-tryon-sf-switch { margin-top: 0.8vw; text-align: center; }
2083
2091
  .ps-tryon-sf-switch-btn {
2084
- background: none; border: none; color: #bb945c; font-size: clamp(12px, 0.8vw, 14px);
2092
+ background: none; border: none; color: #bb945c; font-size: 0.8vw;
2085
2093
  font-weight: 600; cursor: pointer; font-family: inherit;
2086
- display: inline-flex; align-items: center; gap: clamp(4px, 0.3vw, 6px);
2094
+ display: inline-flex; align-items: center; gap: 0.3vw;
2087
2095
  transition: color 0.2s;
2088
2096
  }
2089
2097
  .ps-tryon-sf-switch-btn:hover { color: #d6ba7d; }
2090
- .ps-tryon-sf-switch-btn svg { stroke: currentColor; width: clamp(12px, 0.8vw, 14px); height: clamp(12px, 0.8vw, 14px); }
2098
+ .ps-tryon-sf-switch-btn svg { stroke: currentColor; width: 0.8vw; height: 0.8vw; }
2099
+
2100
+ /* Save profile */
2101
+ .ps-tryon-sf-save { margin-top: 0.42vw; display: flex; flex-direction: column; gap: 0.36vw; }
2102
+ .ps-tryon-sf-save-check {
2103
+ display: flex; align-items: center; gap: 0.42vw; font-size: 0.73vw; color: #999; cursor: pointer; user-select: none;
2104
+ }
2105
+ .ps-tryon-sf-save-check input[type="checkbox"] { width: 0.83vw; height: 0.83vw; accent-color: #bb945c; cursor: pointer; }
2106
+ .ps-tryon-sf-save-name {
2107
+ padding: 0.42vw 0.63vw; border: 1.5px solid #333; border-radius: 0.42vw;
2108
+ background: #111; color: #fff; font-size: 0.73vw; font-family: inherit; outline: none;
2109
+ transition: border-color 0.2s; animation: ps-fade-up 0.2s ease both;
2110
+ }
2111
+ .ps-tryon-sf-save-name:focus { border-color: #bb945c; }
2091
2112
 
2092
2113
  .ps-tryon-sf-next {
2093
- margin-top: clamp(14px, 1vw, 20px); align-self: flex-end;
2094
- padding: clamp(10px, 0.7vw, 14px) clamp(28px, 2vw, 40px);
2114
+ margin-top: 1vw; align-self: flex-end;
2115
+ padding: 0.7vw 2vw;
2095
2116
  background: #bb945c; color: #111; border: none;
2096
- border-radius: clamp(8px, 0.6vw, 12px); font-size: clamp(14px, 0.95vw, 16px);
2117
+ border-radius: 0.6vw; font-size: 0.95vw;
2097
2118
  font-weight: 700; cursor: pointer; transition: all 0.2s; font-family: inherit;
2098
2119
  }
2099
2120
  .ps-tryon-sf-next:hover { background: #a07d4e; transform: translateY(-1px); }
@@ -2106,24 +2127,24 @@ const STYLES = `
2106
2127
  }
2107
2128
 
2108
2129
  /* Keep old class names for backwards compat */
2109
- .ps-tryon-section-title { font-size: clamp(14px, 0.95vw, 18px); font-weight: 600; color: #fff; margin: 0 0 clamp(12px, 0.8vw, 16px); }
2110
- .ps-tryon-sg-checking { display: flex; flex-direction: column; align-items: center; padding: clamp(30px, 2.5vw, 50px) clamp(15px, 1vw, 25px); text-align: center; }
2111
- .ps-tryon-sg-checking-icon { color: #bb945c; margin-bottom: clamp(12px, 0.8vw, 16px); animation: ps-pulse-ruler 1.5s ease-in-out infinite; }
2130
+ .ps-tryon-section-title { font-size: 0.95vw; font-weight: 600; color: #fff; margin: 0 0 0.8vw; }
2131
+ .ps-tryon-sg-checking { display: flex; flex-direction: column; align-items: center; padding: 2.5vw 1vw; text-align: center; }
2132
+ .ps-tryon-sg-checking-icon { color: #bb945c; margin-bottom: 0.8vw; animation: ps-pulse-ruler 1.5s ease-in-out infinite; }
2112
2133
  .ps-tryon-sg-checking-icon svg { stroke: currentColor; fill: none; }
2113
2134
  @keyframes ps-pulse-ruler { 0%, 100% { transform: scale(1); opacity: 0.7; } 50% { transform: scale(1.15); opacity: 1; } }
2114
- .ps-tryon-sg-checking-bar-wrap { width: clamp(120px, 9vw, 180px); height: 4px; background: #333; border-radius: 2px; overflow: hidden; margin-bottom: clamp(14px, 1vw, 20px); }
2135
+ .ps-tryon-sg-checking-bar-wrap { width: 9vw; height: 4px; background: #333; border-radius: 2px; overflow: hidden; margin-bottom: 1vw; }
2115
2136
  .ps-tryon-sg-checking-bar { height: 100%; width: 40%; background: linear-gradient(90deg, #bb945c, #d6ba7d); border-radius: 2px; animation: ps-sg-bar 1.5s ease-in-out infinite; }
2116
2137
  @keyframes ps-sg-bar { 0% { transform: translateX(-100%); } 100% { transform: translateX(350%); } }
2117
- .ps-tryon-sg-checking .ps-tryon-section-title { margin-bottom: clamp(4px, 0.3vw, 6px); }
2118
- .ps-tryon-sg-checking-sub { font-size: clamp(11px, 0.75vw, 13px); color: #999; margin: 0; }
2138
+ .ps-tryon-sg-checking .ps-tryon-section-title { margin-bottom: 0.3vw; }
2139
+ .ps-tryon-sg-checking-sub { font-size: 0.75vw; color: #999; margin: 0; }
2119
2140
 
2120
2141
  /* Back button */
2121
- .ps-tryon-back { display: flex; align-items: center; gap: clamp(4px, 0.3vw, 6px); background: none; border: none; color: #999; font-size: clamp(12px, 0.8vw, 14px); cursor: pointer; padding: 0; margin-bottom: clamp(10px, 0.7vw, 14px); font-family: inherit; transition: color 0.2s; }
2142
+ .ps-tryon-back { display: flex; align-items: center; gap: 0.3vw; background: none; border: none; color: #999; font-size: 0.8vw; cursor: pointer; padding: 0; margin-bottom: 0.7vw; font-family: inherit; transition: color 0.2s; }
2122
2143
  .ps-tryon-back:hover { color: #fff; }
2123
2144
  .ps-tryon-back svg { stroke: currentColor; fill: none; }
2124
2145
 
2125
2146
  /* Sizing form (legacy — redirect to split view) */
2126
- .ps-tryon-sizing-form { display: flex; flex-direction: column; gap: clamp(10px, 0.7vw, 14px); }
2147
+ .ps-tryon-sizing-form { display: flex; flex-direction: column; gap: 0.7vw; }
2127
2148
  .ps-tryon-input-row { display: flex; align-items: center; gap: 0.52vw; }
2128
2149
  .ps-tryon-input-row label { font-size: 0.68vw; font-weight: 500; color: #ccc; min-width: 4.7vw; flex-shrink: 0; }
2129
2150
  .ps-tryon-input-row input {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "4.2.2",
3
+ "version": "4.3.0",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",
@@ -55,6 +55,6 @@
55
55
  "vite": "^5.4.0"
56
56
  },
57
57
  "dependencies": {
58
- "@primestyleai/tryon": "^4.1.2"
58
+ "@primestyleai/tryon": "^4.2.2"
59
59
  }
60
60
  }