@primestyleai/tryon 5.6.16 → 5.6.18

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.
@@ -3080,32 +3080,26 @@ const STYLES = `
3080
3080
  to { opacity: 1; }
3081
3081
  }
3082
3082
 
3083
- /* Active profile loaded banner shows on basics step when a profile is selected */
3084
- .ps-bp-profile-loaded {
3085
- display: flex; align-items: center; justify-content: space-between;
3086
- gap: 12px;
3087
- padding: 10px 14px;
3088
- background: var(--ps-bg-secondary);
3089
- border: 1px solid var(--ps-border-subtle);
3090
- border-radius: 10px;
3091
- margin-bottom: 4px;
3092
- }
3093
- .ps-bp-profile-loaded-label {
3094
- font-size: 12px; color: var(--ps-text-secondary);
3095
- letter-spacing: 0.02em;
3083
+ /* Minimal "Using <profile> · start fresh" hint above the first input */
3084
+ .ps-bp-profile-hint {
3085
+ margin: 0; padding: 0;
3086
+ text-align: center;
3087
+ font-size: 11px; font-weight: 400;
3088
+ color: var(--ps-text-muted);
3089
+ letter-spacing: 0.01em;
3090
+ line-height: 1.4;
3096
3091
  }
3097
- .ps-bp-profile-loaded-label strong {
3098
- color: var(--ps-text-primary); font-weight: 700;
3092
+ .ps-bp-profile-hint strong {
3093
+ color: var(--ps-text-secondary); font-weight: 600;
3099
3094
  }
3100
- .ps-bp-profile-loaded-link {
3095
+ .ps-bp-profile-hint-link {
3101
3096
  background: none; border: none;
3102
- color: var(--ps-accent);
3103
- font-family: inherit; font-size: 12px; font-weight: 700;
3097
+ color: var(--ps-text-muted);
3098
+ font-family: inherit; font-size: inherit; font-weight: 400;
3104
3099
  text-decoration: underline; text-underline-offset: 2px;
3105
3100
  cursor: pointer; padding: 0;
3106
- white-space: nowrap;
3107
3101
  }
3108
- .ps-bp-profile-loaded-link:hover { opacity: 0.85; }
3102
+ .ps-bp-profile-hint-link:hover { color: var(--ps-text-secondary); }
3109
3103
 
3110
3104
  /* Typography */
3111
3105
  .ps-bp-title {
@@ -3467,10 +3461,10 @@ const STYLES = `
3467
3461
  flex: 1; min-height: 0;
3468
3462
  }
3469
3463
 
3470
- /* The dark viewfinder containing the photo + overlays */
3464
+ /* Photo container transparent, no scanner, no chrome */
3471
3465
  .ps-msc-viewfinder {
3472
3466
  position: relative; flex-shrink: 0;
3473
- background: #0E0F11; border-radius: 12px; overflow: hidden;
3467
+ background: transparent; border-radius: 12px; overflow: hidden;
3474
3468
  height: 64vh; max-height: 540px; min-height: 360px;
3475
3469
  display: flex; align-items: center; justify-content: center;
3476
3470
  }
@@ -3478,7 +3472,6 @@ const STYLES = `
3478
3472
  max-width: 100%; max-height: 100%;
3479
3473
  width: auto; height: 100%;
3480
3474
  object-fit: contain; display: block;
3481
- filter: brightness(0.9) contrast(1.05);
3482
3475
  }
3483
3476
 
3484
3477
  /* Live feed badge top-left */
@@ -3654,13 +3647,10 @@ const STYLES = `
3654
3647
  background: var(--ps-bg-secondary);
3655
3648
  display: flex; align-items: center; justify-content: center;
3656
3649
  }
3657
- /* When showing the try-on result, give it a touch more presence */
3658
- .ps-msr-product-img-wrap.ps-tryon {
3659
- background: #0F0F10;
3660
- }
3650
+ /* Try-on result keeps the same neutral background as the product hero
3651
+ * no dark backdrop on mobile. */
3661
3652
  .ps-msr-product-img {
3662
- max-width: 100%; max-height: 100%;
3663
- width: auto; height: 100%;
3653
+ width: 100%; height: 100%;
3664
3654
  object-fit: contain; display: block;
3665
3655
  }
3666
3656
  /* Show-Fit / mediapipe overlay toggle pill — bottom-left of try-on hero */
@@ -3821,6 +3811,12 @@ const STYLES = `
3821
3811
  letter-spacing: -0.01em;
3822
3812
  margin: 0 0 6px;
3823
3813
  }
3814
+ /* Wrapper that vertically centers the cards in whatever space is left
3815
+ * between the title at the top and the bottom navigation. */
3816
+ .ps-bsm-options-center {
3817
+ flex: 1 1 auto; min-height: 0;
3818
+ display: flex; flex-direction: column; justify-content: center;
3819
+ }
3824
3820
  .ps-bsm-options {
3825
3821
  display: flex; flex-direction: column; gap: 12px;
3826
3822
  }
@@ -4867,8 +4863,7 @@ const STYLES = `
4867
4863
  flex-shrink: 0;
4868
4864
  }
4869
4865
  .ps-msd-image-img {
4870
- max-width: 100%; max-height: 100%;
4871
- width: auto; height: 100%;
4866
+ width: 100%; height: 100%;
4872
4867
  object-fit: contain; display: block;
4873
4868
  }
4874
4869
 
@@ -6109,8 +6104,8 @@ function MobileSkeleton({ landmarks, w, h }) {
6109
6104
  y1: pa.y * h,
6110
6105
  x2: pb.x * w,
6111
6106
  y2: pb.y * h,
6112
- stroke: "rgba(255,255,255,0.85)",
6113
- strokeWidth: "3",
6107
+ stroke: "rgba(100,210,255,0.9)",
6108
+ strokeWidth: "4",
6114
6109
  strokeLinecap: "round",
6115
6110
  opacity: 0,
6116
6111
  style: { animation: `ps-msc-fade 0.4s ease ${i * 0.05}s forwards` }
@@ -6124,8 +6119,8 @@ function MobileSkeleton({ landmarks, w, h }) {
6124
6119
  {
6125
6120
  cx: v.x * w,
6126
6121
  cy: v.y * h,
6127
- r: 9,
6128
- fill: "rgba(255,255,255,0.18)",
6122
+ r: 10,
6123
+ fill: "rgba(100,210,255,0.25)",
6129
6124
  opacity: 0,
6130
6125
  style: { animation: `ps-msc-fade 0.3s ease ${i * 0.04}s forwards` }
6131
6126
  }
@@ -6135,8 +6130,8 @@ function MobileSkeleton({ landmarks, w, h }) {
6135
6130
  {
6136
6131
  cx: v.x * w,
6137
6132
  cy: v.y * h,
6138
- r: 5,
6139
- fill: "#FFFFFF",
6133
+ r: 6,
6134
+ fill: "rgba(100,210,255,0.95)",
6140
6135
  opacity: 0,
6141
6136
  style: { animation: `ps-msc-fade 0.3s ease ${i * 0.04}s forwards` }
6142
6137
  }
@@ -6175,30 +6170,19 @@ function MobileScanningView({
6175
6170
  };
6176
6171
  const [stageIdx, setStageIdx] = useState(0);
6177
6172
  useEffect(() => {
6178
- if (sizingDone) return;
6173
+ const id = setInterval(() => {
6174
+ setStageIdx((i) => (i + 1) % stages.length);
6175
+ }, 1500);
6176
+ return () => clearInterval(id);
6177
+ }, [stages.length]);
6178
+ useEffect(() => {
6179
6179
  if (isPhotoMode && bodyLandmarks && stageIdx === 0) {
6180
6180
  setStageIdx(1);
6181
- return;
6182
6181
  }
6183
- const id = setInterval(() => {
6184
- setStageIdx((i) => Math.min(i + 1, stages.length - 1));
6185
- }, 1600);
6186
- return () => clearInterval(id);
6187
- }, [bodyLandmarks, sizingDone, stageIdx, stages.length, isPhotoMode]);
6182
+ }, [bodyLandmarks]);
6188
6183
  const current = stages[stageIdx] ?? stages[0];
6189
- const [feedTick, setFeedTick] = useState(1);
6190
- useEffect(() => {
6191
- if (sizingDone) return;
6192
- const id = setInterval(() => setFeedTick((n) => n + 1), 850);
6193
- return () => clearInterval(id);
6194
- }, [sizingDone]);
6195
6184
  return /* @__PURE__ */ jsxs("div", { className: "ps-msc-root", children: [
6196
6185
  /* @__PURE__ */ jsxs("div", { className: "ps-msc-viewfinder", children: [
6197
- /* @__PURE__ */ jsxs("div", { className: "ps-msc-feed-badge", children: [
6198
- /* @__PURE__ */ jsx("span", { className: "ps-msc-feed-dot" }),
6199
- "LIVE_FEED:",
6200
- String(feedTick).padStart(2, "0")
6201
- ] }),
6202
6186
  displayImage && /* @__PURE__ */ jsx(
6203
6187
  "img",
6204
6188
  {
@@ -6208,22 +6192,7 @@ function MobileScanningView({
6208
6192
  onLoad: handleImgLoad
6209
6193
  }
6210
6194
  ),
6211
- /* @__PURE__ */ jsxs("div", { className: "ps-msc-corners", children: [
6212
- /* @__PURE__ */ jsx("span", { className: "ps-msc-corner ps-tl" }),
6213
- /* @__PURE__ */ jsx("span", { className: "ps-msc-corner ps-tr" }),
6214
- /* @__PURE__ */ jsx("span", { className: "ps-msc-corner ps-bl" }),
6215
- /* @__PURE__ */ jsx("span", { className: "ps-msc-corner ps-br" })
6216
- ] }),
6217
- /* @__PURE__ */ jsx("div", { className: "ps-msc-scanline" }),
6218
- isPhotoMode && bodyLandmarks && /* @__PURE__ */ jsx("div", { className: "ps-msc-pose-wrap", children: /* @__PURE__ */ jsx(MobileSkeleton, { landmarks: bodyLandmarks, w: dims.w, h: dims.h }) }),
6219
- /* @__PURE__ */ jsxs("div", { className: "ps-msc-vf-bottom", children: [
6220
- /* @__PURE__ */ jsxs("div", { className: "ps-msc-vf-text", children: [
6221
- current.viewfinderText,
6222
- "..."
6223
- ] }),
6224
- /* @__PURE__ */ jsx("div", { className: "ps-msc-vf-bar", children: /* @__PURE__ */ jsx("div", { className: "ps-msc-vf-bar-fill" }) }),
6225
- /* @__PURE__ */ jsx("div", { className: "ps-msc-vf-sub", children: t("PLEASE STAND STILL") })
6226
- ] })
6195
+ isPhotoMode && bodyLandmarks && /* @__PURE__ */ jsx("div", { className: "ps-msc-pose-wrap", children: /* @__PURE__ */ jsx(MobileSkeleton, { landmarks: bodyLandmarks, w: dims.w, h: dims.h }) })
6227
6196
  ] }),
6228
6197
  /* @__PURE__ */ jsx("div", { className: "ps-msc-stage", children: /* @__PURE__ */ jsxs("div", { className: "ps-msc-stage-slot", children: [
6229
6198
  /* @__PURE__ */ jsx("div", { className: "ps-msc-stage-title", children: current.title }),
@@ -6511,6 +6480,15 @@ function MeasurementOverlay({ lines, fitRows, show, imgWidth, imgHeight }) {
6511
6480
  const delay = i * 0.35;
6512
6481
  const curvePath = `M ${x1} ${cy} Q ${midX} ${cy + curveDepth} ${x2} ${cy}`;
6513
6482
  const lineLen = width * 1.05;
6483
+ const labelText = fitRow ? fitRow.fit === "good" ? "✓ Fit" : fitRow.fit.includes("tight") ? "Tight" : "Loose" : label;
6484
+ const labelFont = Math.round(14 * scale);
6485
+ const labelWidthEst = labelText.length * labelFont * 0.62;
6486
+ const rightSpace = W - x2 - 12 * scale;
6487
+ const flipLeft = rightSpace < labelWidthEst;
6488
+ const labelX = flipLeft ? x1 - 10 * scale : x2 + 10 * scale;
6489
+ const labelAnchor = flipLeft ? "end" : "start";
6490
+ const tickX1 = flipLeft ? x1 : x2;
6491
+ const tickX2 = flipLeft ? x1 - 6 * scale : x2 + 6 * scale;
6514
6492
  return /* @__PURE__ */ jsxs("g", { children: [
6515
6493
  /* @__PURE__ */ jsx(
6516
6494
  "path",
@@ -6551,9 +6529,9 @@ function MeasurementOverlay({ lines, fitRows, show, imgWidth, imgHeight }) {
6551
6529
  /* @__PURE__ */ jsx(
6552
6530
  "line",
6553
6531
  {
6554
- x1: x2,
6532
+ x1: tickX1,
6555
6533
  y1: cy,
6556
- x2: x2 + 6 * scale,
6534
+ x2: tickX2,
6557
6535
  y2: cy,
6558
6536
  stroke: color,
6559
6537
  strokeWidth: 2 * scale
@@ -6562,14 +6540,15 @@ function MeasurementOverlay({ lines, fitRows, show, imgWidth, imgHeight }) {
6562
6540
  /* @__PURE__ */ jsx(
6563
6541
  "text",
6564
6542
  {
6565
- x: x2 + 10 * scale,
6543
+ x: labelX,
6566
6544
  y: cy + 1 * scale,
6567
6545
  fill: color,
6568
- fontSize: Math.round(14 * scale),
6546
+ fontSize: labelFont,
6569
6547
  fontWeight: "700",
6570
6548
  fontFamily: "system-ui, -apple-system, sans-serif",
6571
6549
  dominantBaseline: "middle",
6572
- children: fitRow ? fitRow.fit === "good" ? "✓ Fit" : fitRow.fit.includes("tight") ? "Tight" : "Loose" : label
6550
+ textAnchor: labelAnchor,
6551
+ children: labelText
6573
6552
  }
6574
6553
  )
6575
6554
  ] })
@@ -7366,7 +7345,7 @@ function SizeResultView({
7366
7345
  {
7367
7346
  src: previewUrl || productImage,
7368
7347
  alt: productTitle,
7369
- className: `ps-tryon-sr-product-img${bodyLandmarks ? "" : " ps-tryon-blur"}`,
7348
+ className: "ps-tryon-sr-product-img",
7370
7349
  onLoad: handleImgLoad
7371
7350
  }
7372
7351
  ),
@@ -7520,12 +7499,8 @@ function SizeResultView({
7520
7499
  /* ── Desktop section picker: split layout — image left, image cards right ── */
7521
7500
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-v2", children: [
7522
7501
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-v2-bg", style: { position: "relative" }, children: [
7523
- /* @__PURE__ */ jsx("img", { src: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage, alt: productTitle, className: `ps-tryon-v2-bg-img${tryOnProcessing && !bodyLandmarks ? " ps-tryon-blur" : ""}`, onLoad: handleImgLoad }),
7502
+ /* @__PURE__ */ jsx("img", { src: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage, alt: productTitle, className: "ps-tryon-v2-bg-img", onLoad: handleImgLoad }),
7524
7503
  tryOnProcessing && bodyLandmarks && /* @__PURE__ */ jsx(SkeletonOverlay, { landmarks: bodyLandmarks, imgWidth: imgDims.w, imgHeight: imgDims.h }),
7525
- tryOnProcessing && !bodyLandmarks && /* @__PURE__ */ jsxs(Fragment, { children: [
7526
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-scan-overlay" }),
7527
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-scan-line" })
7528
- ] }),
7529
7504
  tryOnProcessing && /* @__PURE__ */ jsx("div", { className: "ps-tryon-v2-processing-label", children: t("Generating try-on...") }),
7530
7505
  resultImageUrl && !tryOnProcessing && poseReady && poseLines && /* @__PURE__ */ jsx(MeasurementOverlay, { lines: poseLines, fitRows: (() => {
7531
7506
  const all = [...sizingResult?.matchDetails || []];
@@ -8968,18 +8943,19 @@ function BasicsStepMobile({
8968
8943
  const incAge = () => setAge(String(Math.min(ageMax, ageNum + 1)));
8969
8944
  const decAge = () => setAge(String(Math.max(ageMin, ageNum - 1)));
8970
8945
  return /* @__PURE__ */ jsxs("div", { className: "ps-bpm-root", children: [
8971
- activeProfileName && /* @__PURE__ */ jsxs("div", { className: "ps-bp-profile-loaded", children: [
8972
- /* @__PURE__ */ jsxs("span", { className: "ps-bp-profile-loaded-label", children: [
8973
- t("Profile loaded"),
8974
- ": ",
8975
- /* @__PURE__ */ jsx("strong", { children: activeProfileName })
8976
- ] }),
8977
- onStartFresh && /* @__PURE__ */ jsx("button", { type: "button", className: "ps-bp-profile-loaded-link", onClick: onStartFresh, children: t("Start fresh AI sizing") })
8978
- ] }),
8979
8946
  /* @__PURE__ */ jsxs("div", { className: "ps-bpm-header", children: [
8980
8947
  /* @__PURE__ */ jsx("h2", { className: "ps-bpm-title", children: t("Let's find your best fit") }),
8981
8948
  /* @__PURE__ */ jsx("p", { className: "ps-bpm-subtitle", children: t("Enter your details for a bespoke size recommendation") })
8982
8949
  ] }),
8950
+ activeProfileName && /* @__PURE__ */ jsxs("p", { className: "ps-bp-profile-hint", children: [
8951
+ t("Using"),
8952
+ " ",
8953
+ /* @__PURE__ */ jsx("strong", { children: activeProfileName }),
8954
+ onStartFresh && /* @__PURE__ */ jsxs(Fragment, { children: [
8955
+ " · ",
8956
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-bp-profile-hint-link", onClick: onStartFresh, children: t("start fresh") })
8957
+ ] })
8958
+ ] }),
8983
8959
  /* @__PURE__ */ jsxs("div", { className: "ps-bpm-toggle", children: [
8984
8960
  /* @__PURE__ */ jsx(
8985
8961
  "button",
@@ -9262,7 +9238,7 @@ function BodyShapeStepMobile({
9262
9238
  String(totalSteps).padStart(2, "0")
9263
9239
  ] }),
9264
9240
  /* @__PURE__ */ jsx("h2", { className: "ps-bsm-question", children: title }),
9265
- /* @__PURE__ */ jsx("div", { className: "ps-bsm-options", children: options.map((opt, idx) => {
9241
+ /* @__PURE__ */ jsx("div", { className: "ps-bsm-options-center", children: /* @__PURE__ */ jsx("div", { className: "ps-bsm-options", children: options.map((opt, idx) => {
9266
9242
  const isActive = selected === opt.value;
9267
9243
  const profileLetter = String.fromCharCode(65 + idx);
9268
9244
  return /* @__PURE__ */ jsxs(
@@ -9285,7 +9261,7 @@ function BodyShapeStepMobile({
9285
9261
  },
9286
9262
  opt.value
9287
9263
  );
9288
- }) })
9264
+ }) }) })
9289
9265
  ] });
9290
9266
  }
9291
9267
  function CameraUploadIcon() {
@@ -9813,15 +9789,16 @@ function BodyProfileView({
9813
9789
  );
9814
9790
  }
9815
9791
  return /* @__PURE__ */ jsxs("div", { className: "ps-bp-step ps-bp-step-enter", children: [
9816
- hasActiveProfileWithMeasurements && activeProfileName && /* @__PURE__ */ jsxs("div", { className: "ps-bp-profile-loaded", children: [
9817
- /* @__PURE__ */ jsxs("span", { className: "ps-bp-profile-loaded-label", children: [
9818
- t("Profile loaded"),
9819
- ": ",
9820
- /* @__PURE__ */ jsx("strong", { children: activeProfileName })
9821
- ] }),
9822
- onStartFresh && /* @__PURE__ */ jsx("button", { type: "button", className: "ps-bp-profile-loaded-link", onClick: onStartFresh, children: t("Start fresh AI sizing") })
9823
- ] }),
9824
9792
  /* @__PURE__ */ jsx("h2", { className: "ps-bp-title", children: t("Let's find your best fit") }),
9793
+ hasActiveProfileWithMeasurements && activeProfileName && /* @__PURE__ */ jsxs("p", { className: "ps-bp-profile-hint", children: [
9794
+ t("Using"),
9795
+ " ",
9796
+ /* @__PURE__ */ jsx("strong", { children: activeProfileName }),
9797
+ onStartFresh && /* @__PURE__ */ jsxs(Fragment, { children: [
9798
+ " · ",
9799
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-bp-profile-hint-link", onClick: onStartFresh, children: t("start fresh") })
9800
+ ] })
9801
+ ] }),
9825
9802
  /* @__PURE__ */ jsxs("div", { className: "ps-bp-system-toggle", children: [
9826
9803
  /* @__PURE__ */ jsx("button", { className: `ps-bp-system-btn${!isImperialMode ? " ps-bp-system-active" : ""}`, onClick: switchToMetric, type: "button", children: t("Metric") }),
9827
9804
  /* @__PURE__ */ jsx("button", { className: `ps-bp-system-btn${isImperialMode ? " ps-bp-system-active" : ""}`, onClick: switchToImperial, type: "button", children: t("Imperial") })