@primestyleai/tryon 5.8.39 → 5.8.41

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.
@@ -3668,6 +3668,101 @@ const STYLES = `
3668
3668
  }
3669
3669
  .ps-pm-preview-remove:hover { background: #FFFFFF; }
3670
3670
 
3671
+ /* ── Mobile age-gate overlay ── */
3672
+ .ps-pm-preview-blurred {
3673
+ filter: blur(6px) saturate(0.7);
3674
+ pointer-events: none;
3675
+ user-select: none;
3676
+ }
3677
+ .ps-pm-age-gate {
3678
+ position: absolute; inset: 0;
3679
+ display: flex; align-items: center; justify-content: center;
3680
+ padding: max(16px, 4vw);
3681
+ background: rgba(255, 255, 255, 0.55);
3682
+ backdrop-filter: blur(8px);
3683
+ -webkit-backdrop-filter: blur(8px);
3684
+ z-index: 2;
3685
+ animation: ps-pm-age-gate-in 0.28s ease-out both;
3686
+ }
3687
+ @keyframes ps-pm-age-gate-in {
3688
+ 0% { opacity: 0; transform: scale(0.97); }
3689
+ 100% { opacity: 1; transform: scale(1); }
3690
+ }
3691
+ .ps-pm-age-gate-card {
3692
+ width: 100%; max-width: max(280px, 82vw);
3693
+ padding: max(18px, 4.6vw) max(16px, 4.2vw);
3694
+ background: #FFFFFF;
3695
+ border: 1px solid var(--ps-border-subtle);
3696
+ border-radius: max(12px, 3vw);
3697
+ box-shadow: 0 20px 40px -12px rgba(17, 24, 39, 0.25),
3698
+ 0 8px 16px -8px rgba(17, 24, 39, 0.15);
3699
+ display: flex; flex-direction: column;
3700
+ align-items: center; text-align: center;
3701
+ gap: max(8px, 2vw);
3702
+ }
3703
+ .ps-pm-age-gate-eyebrow {
3704
+ font-size: max(10px, 2.6vw); font-weight: 700;
3705
+ letter-spacing: 0.14em; text-transform: uppercase;
3706
+ color: var(--ps-accent);
3707
+ }
3708
+ .ps-pm-age-gate-eyebrow-blocked { color: #C02626; }
3709
+ .ps-pm-age-gate-question {
3710
+ font-size: max(14px, 3.8vw); font-weight: 600;
3711
+ line-height: 1.35; color: var(--ps-text-primary); margin: 0;
3712
+ }
3713
+ .ps-pm-age-gate-actions {
3714
+ display: flex; flex-direction: column; gap: max(8px, 2vw);
3715
+ width: 100%; margin-top: max(4px, 1vw);
3716
+ }
3717
+ .ps-pm-age-gate-btn {
3718
+ width: 100%;
3719
+ padding: max(11px, 2.9vw) max(14px, 3.6vw);
3720
+ border-radius: 999px;
3721
+ font-family: inherit;
3722
+ font-size: max(12px, 3.2vw); font-weight: 700;
3723
+ letter-spacing: 0.02em;
3724
+ cursor: pointer;
3725
+ transition: background 0.18s, border-color 0.18s, color 0.18s;
3726
+ }
3727
+ .ps-pm-age-gate-btn-primary {
3728
+ background: var(--ps-accent);
3729
+ color: #FFFFFF;
3730
+ border: 1.5px solid var(--ps-accent);
3731
+ }
3732
+ .ps-pm-age-gate-btn-secondary {
3733
+ background: transparent;
3734
+ color: var(--ps-text-primary);
3735
+ border: 1.5px solid var(--ps-border-color);
3736
+ }
3737
+ .ps-pm-age-gate-btn-secondary:active {
3738
+ background: var(--ps-bg-secondary);
3739
+ }
3740
+
3741
+ /* ── Mobile legal notice ── */
3742
+ .ps-pm-legal-notice {
3743
+ margin-top: max(10px, 2.6vw);
3744
+ background: rgba(33, 84, 239, 0.04);
3745
+ border: 1px solid rgba(33, 84, 239, 0.16);
3746
+ border-radius: max(10px, 2.6vw);
3747
+ padding: max(10px, 2.6vw) max(12px, 3.1vw);
3748
+ display: flex; flex-direction: column;
3749
+ gap: max(4px, 1vw);
3750
+ }
3751
+ .ps-pm-legal-notice-head {
3752
+ display: flex; align-items: center;
3753
+ gap: max(6px, 1.5vw);
3754
+ font-size: max(10px, 2.6vw); font-weight: 700;
3755
+ letter-spacing: 0.12em; text-transform: uppercase;
3756
+ color: var(--ps-accent);
3757
+ }
3758
+ .ps-pm-legal-notice-head svg { width: max(13px, 3.4vw); height: max(13px, 3.4vw); }
3759
+ .ps-pm-legal-notice-body {
3760
+ margin: 0;
3761
+ font-size: max(11px, 2.9vw);
3762
+ line-height: 1.5;
3763
+ color: var(--ps-text-secondary);
3764
+ }
3765
+
3671
3766
  /* Checklist for accuracy card */
3672
3767
  .ps-pm-checklist {
3673
3768
  display: flex; gap: max(12px, 3.1vw);
@@ -5529,6 +5624,127 @@ const STYLES = `
5529
5624
  transition: background 0.18s;
5530
5625
  }
5531
5626
  .ps-cpw-photo-retake:hover { background: rgba(33, 84, 239, 0.08); }
5627
+
5628
+ /* ── Age-gate overlay on the dropzone ──
5629
+ Dropzone stays visible but blurred; overlay shows a premium card
5630
+ with the 18+ confirmation question and two pill buttons. */
5631
+ .ps-cpw-dropzone-wrap {
5632
+ position: relative;
5633
+ flex: 1; min-height: 0;
5634
+ width: 100%; box-sizing: border-box;
5635
+ display: flex; flex-direction: column;
5636
+ }
5637
+ .ps-cpw-dropzone-blurred {
5638
+ filter: blur(6px) saturate(0.7);
5639
+ pointer-events: none;
5640
+ user-select: none;
5641
+ }
5642
+ .ps-cpw-age-gate {
5643
+ position: absolute; inset: 0;
5644
+ display: flex; align-items: center; justify-content: center;
5645
+ padding: clamp(12px, 1vw, 24px);
5646
+ border-radius: clamp(10px, 0.75vw, 16px);
5647
+ background: rgba(255, 255, 255, 0.55);
5648
+ backdrop-filter: blur(8px);
5649
+ -webkit-backdrop-filter: blur(8px);
5650
+ z-index: 2;
5651
+ animation: ps-cpw-age-gate-in 0.28s ease-out both;
5652
+ }
5653
+ @keyframes ps-cpw-age-gate-in {
5654
+ 0% { opacity: 0; transform: scale(0.97); }
5655
+ 100% { opacity: 1; transform: scale(1); }
5656
+ }
5657
+ .ps-cpw-age-gate-card {
5658
+ width: 100%; max-width: clamp(240px, 24vw, 420px);
5659
+ padding: clamp(16px, 1.4vw, 28px) clamp(18px, 1.6vw, 32px);
5660
+ background: #FFFFFF;
5661
+ border: 1px solid var(--ps-border-subtle);
5662
+ border-radius: clamp(10px, 0.9vw, 18px);
5663
+ box-shadow: 0 20px 40px -12px rgba(17, 24, 39, 0.25),
5664
+ 0 8px 16px -8px rgba(17, 24, 39, 0.15);
5665
+ display: flex; flex-direction: column;
5666
+ align-items: center; text-align: center;
5667
+ gap: clamp(8px, 0.7vw, 14px);
5668
+ }
5669
+ .ps-cpw-age-gate-eyebrow {
5670
+ font-size: clamp(9px, 0.62vw, 11px);
5671
+ font-weight: 700;
5672
+ letter-spacing: 0.18em;
5673
+ text-transform: uppercase;
5674
+ color: var(--ps-accent);
5675
+ }
5676
+ .ps-cpw-age-gate-eyebrow-blocked { color: #C02626; }
5677
+ .ps-cpw-age-gate-question {
5678
+ font-size: clamp(13px, 0.95vw, 18px);
5679
+ font-weight: 600;
5680
+ line-height: 1.35;
5681
+ color: var(--ps-text-primary);
5682
+ margin: 0;
5683
+ }
5684
+ .ps-cpw-age-gate-actions {
5685
+ display: flex; gap: clamp(8px, 0.65vw, 14px);
5686
+ width: 100%;
5687
+ margin-top: clamp(4px, 0.35vw, 8px);
5688
+ }
5689
+ .ps-cpw-age-gate-btn {
5690
+ flex: 1;
5691
+ padding: clamp(9px, 0.75vw, 14px) clamp(12px, 1vw, 18px);
5692
+ border-radius: 999px;
5693
+ font-family: inherit;
5694
+ font-size: clamp(11px, 0.78vw, 14px);
5695
+ font-weight: 700;
5696
+ letter-spacing: 0.02em;
5697
+ cursor: pointer;
5698
+ transition: transform 0.18s, background 0.18s, border-color 0.18s, color 0.18s;
5699
+ }
5700
+ .ps-cpw-age-gate-btn:hover { transform: translateY(-1px); }
5701
+ .ps-cpw-age-gate-btn-primary {
5702
+ background: var(--ps-accent);
5703
+ color: #FFFFFF;
5704
+ border: 1.5px solid var(--ps-accent);
5705
+ }
5706
+ .ps-cpw-age-gate-btn-primary:hover { background: color-mix(in srgb, var(--ps-accent) 88%, #000); }
5707
+ .ps-cpw-age-gate-btn-secondary {
5708
+ background: transparent;
5709
+ color: var(--ps-text-primary);
5710
+ border: 1.5px solid var(--ps-border-color);
5711
+ }
5712
+ .ps-cpw-age-gate-btn-secondary:hover {
5713
+ background: var(--ps-bg-secondary);
5714
+ border-color: var(--ps-text-muted);
5715
+ }
5716
+ .ps-cpw-age-gate-card-blocked { border-color: rgba(192, 38, 38, 0.35); }
5717
+
5718
+ /* ── Legal notice card on the right column ──
5719
+ Soft neutral card with a small shield icon; matches photo-guide width. */
5720
+ .ps-cpw-legal-notice {
5721
+ background: rgba(33, 84, 239, 0.04);
5722
+ border: 1px solid rgba(33, 84, 239, 0.16);
5723
+ border-radius: clamp(10px, 0.75vw, 16px);
5724
+ padding: clamp(10px, 0.9vw, 18px) clamp(12px, 1vw, 20px);
5725
+ display: flex; flex-direction: column;
5726
+ gap: clamp(5px, 0.45vw, 10px);
5727
+ }
5728
+ .ps-cpw-legal-notice-head {
5729
+ display: flex; align-items: center;
5730
+ gap: clamp(6px, 0.5vw, 10px);
5731
+ font-size: clamp(9px, 0.62vw, 11px);
5732
+ font-weight: 700;
5733
+ letter-spacing: 0.14em;
5734
+ text-transform: uppercase;
5735
+ color: var(--ps-accent);
5736
+ }
5737
+ .ps-cpw-legal-notice-head svg {
5738
+ width: clamp(12px, 0.85vw, 15px);
5739
+ height: clamp(12px, 0.85vw, 15px);
5740
+ }
5741
+ .ps-cpw-legal-notice-body {
5742
+ margin: 0;
5743
+ font-size: clamp(10px, 0.7vw, 12.5px);
5744
+ line-height: 1.5;
5745
+ color: var(--ps-text-secondary);
5746
+ }
5747
+
5532
5748
  .ps-cpw-hint {
5533
5749
  font-size: clamp(10px, 0.72vw, 13px);
5534
5750
  line-height: 1.6;
@@ -7446,6 +7662,102 @@ const SKELETON_CONNECTIONS = [
7446
7662
  ["rightHip", "rightKnee"],
7447
7663
  ["rightKnee", "rightAnkle"]
7448
7664
  ];
7665
+ function FaceOverlay({
7666
+ landmarks,
7667
+ imgWidth,
7668
+ imgHeight
7669
+ }) {
7670
+ const W = imgWidth;
7671
+ const H = imgHeight;
7672
+ const pts = [
7673
+ { key: "forehead", p: landmarks.forehead },
7674
+ { key: "chin", p: landmarks.chin },
7675
+ { key: "noseTip", p: landmarks.noseTip },
7676
+ { key: "noseBridge", p: landmarks.noseBridge },
7677
+ { key: "leftInnerEye", p: landmarks.leftInnerEye },
7678
+ { key: "rightInnerEye", p: landmarks.rightInnerEye },
7679
+ { key: "leftOuterEye", p: landmarks.leftOuterEye },
7680
+ { key: "rightOuterEye", p: landmarks.rightOuterEye },
7681
+ { key: "leftTragus", p: landmarks.leftTragus },
7682
+ { key: "rightTragus", p: landmarks.rightTragus },
7683
+ { key: "leftMouth", p: landmarks.leftMouth },
7684
+ { key: "rightMouth", p: landmarks.rightMouth }
7685
+ ];
7686
+ const connections = [
7687
+ // Face axis
7688
+ [landmarks.forehead, landmarks.noseBridge],
7689
+ [landmarks.noseBridge, landmarks.noseTip],
7690
+ [landmarks.noseTip, landmarks.chin],
7691
+ // Horizontal eye line
7692
+ [landmarks.leftOuterEye, landmarks.leftInnerEye],
7693
+ [landmarks.leftInnerEye, landmarks.rightInnerEye],
7694
+ [landmarks.rightInnerEye, landmarks.rightOuterEye],
7695
+ // Ears
7696
+ [landmarks.leftTragus, landmarks.leftOuterEye],
7697
+ [landmarks.rightOuterEye, landmarks.rightTragus],
7698
+ // Mouth line
7699
+ [landmarks.leftMouth, landmarks.rightMouth]
7700
+ ];
7701
+ return /* @__PURE__ */ jsxs("svg", { className: "ps-tryon-pose-overlay", viewBox: `0 0 ${W} ${H}`, preserveAspectRatio: "xMidYMid meet", children: [
7702
+ connections.map(([a, b], i) => /* @__PURE__ */ jsx(
7703
+ "line",
7704
+ {
7705
+ x1: a.x * W,
7706
+ y1: a.y * H,
7707
+ x2: b.x * W,
7708
+ y2: b.y * H,
7709
+ stroke: "rgba(100,210,255,0.55)",
7710
+ strokeWidth: "3",
7711
+ strokeLinecap: "round",
7712
+ opacity: "0",
7713
+ style: { animation: `ps-pose-fade 0.4s ease ${i * 0.05}s forwards` }
7714
+ },
7715
+ `fl-${i}`
7716
+ )),
7717
+ [landmarks.leftIrisCenter, landmarks.rightIrisCenter].map((c, i) => {
7718
+ const ring = i === 0 ? landmarks.leftIrisRing : landmarks.rightIrisRing;
7719
+ const rx = ring?.length ? Math.abs((ring[0]?.x ?? c.x) - (ring[2]?.x ?? c.x)) * W / 2 : 6;
7720
+ return /* @__PURE__ */ jsx(
7721
+ "circle",
7722
+ {
7723
+ cx: c.x * W,
7724
+ cy: c.y * H,
7725
+ r: Math.max(6, rx),
7726
+ fill: "none",
7727
+ stroke: "rgba(255,230,120,0.95)",
7728
+ strokeWidth: "2.5",
7729
+ opacity: "0",
7730
+ style: { animation: `ps-pose-fade 0.3s ease ${0.3 + i * 0.1}s forwards` }
7731
+ },
7732
+ `iris-${i}`
7733
+ );
7734
+ }),
7735
+ pts.map(({ key, p }, i) => /* @__PURE__ */ jsxs("g", { children: [
7736
+ /* @__PURE__ */ jsx(
7737
+ "circle",
7738
+ {
7739
+ cx: p.x * W,
7740
+ cy: p.y * H,
7741
+ r: "11",
7742
+ fill: "rgba(100,210,255,0.22)",
7743
+ opacity: "0",
7744
+ style: { animation: `ps-pose-fade 0.3s ease ${i * 0.04}s forwards` }
7745
+ }
7746
+ ),
7747
+ /* @__PURE__ */ jsx(
7748
+ "circle",
7749
+ {
7750
+ cx: p.x * W,
7751
+ cy: p.y * H,
7752
+ r: "6",
7753
+ fill: "rgba(100,210,255,0.95)",
7754
+ opacity: "0",
7755
+ style: { animation: `ps-pose-fade 0.3s ease ${i * 0.04}s forwards, ps-dot-pulse 1.5s ease-in-out ${0.5 + i * 0.04}s infinite` }
7756
+ }
7757
+ )
7758
+ ] }, key))
7759
+ ] });
7760
+ }
7449
7761
  function SkeletonOverlay({ landmarks, imgWidth, imgHeight }) {
7450
7762
  const W = imgWidth;
7451
7763
  const H = imgHeight;
@@ -8310,6 +8622,8 @@ function SizeResultView({
8310
8622
  handleTryOnSubmit,
8311
8623
  tryOnProcessing,
8312
8624
  bodyLandmarks,
8625
+ faceLandmarks = null,
8626
+ measurementType = "body",
8313
8627
  estimationDone = false,
8314
8628
  activeSection,
8315
8629
  setActiveSection,
@@ -8596,28 +8910,33 @@ function SizeResultView({
8596
8910
  onLoad: handleImgLoad
8597
8911
  }
8598
8912
  ),
8599
- bodyLandmarks && /* @__PURE__ */ jsx(SkeletonOverlay, { landmarks: bodyLandmarks, imgWidth: imgDims.w, imgHeight: imgDims.h })
8913
+ measurementType === "face" || measurementType === "head" ? faceLandmarks && /* @__PURE__ */ jsx(FaceOverlay, { landmarks: faceLandmarks, imgWidth: imgDims.w, imgHeight: imgDims.h }) : bodyLandmarks && /* @__PURE__ */ jsx(SkeletonOverlay, { landmarks: bodyLandmarks, imgWidth: imgDims.w, imgHeight: imgDims.h })
8600
8914
  ] }),
8601
- /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-right-col ps-tryon-snap-steps", children: [
8602
- /* @__PURE__ */ jsxs("div", { className: `ps-tryon-snap-step${bodyLandmarks ? " ps-done" : " ps-active"}`, children: [
8603
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-snap-step-icon", children: bodyLandmarks ? /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-check", children: "✓" }) : /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner", style: { width: "1vw", height: "1vw", borderWidth: "1.5px" } }) }),
8604
- /* @__PURE__ */ jsx("span", { children: t("Detecting body pose") })
8605
- ] }),
8606
- !sizingDone && /* @__PURE__ */ jsxs(Fragment, { children: [
8607
- /* @__PURE__ */ jsxs("div", { className: `ps-tryon-snap-step${analyzingDone ? " ps-done" : bodyLandmarks ? " ps-active" : ""}`, children: [
8608
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-snap-step-icon", children: !bodyLandmarks ? /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-num", children: "2" }) : !analyzingDone ? /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner", style: { width: "1vw", height: "1vw", borderWidth: "1.5px" } }) : /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-check", children: "✓" }) }),
8609
- /* @__PURE__ */ jsx("span", { children: t("Analyzing your size") })
8915
+ (() => {
8916
+ const isFaceCategory = measurementType === "face" || measurementType === "head";
8917
+ const detectionDone = isFaceCategory ? !!faceLandmarks : !!bodyLandmarks;
8918
+ const detectLabel = isFaceCategory ? measurementType === "head" ? t("Detecting head") : t("Detecting face") : t("Detecting body pose");
8919
+ return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-right-col ps-tryon-snap-steps", children: [
8920
+ /* @__PURE__ */ jsxs("div", { className: `ps-tryon-snap-step${detectionDone ? " ps-done" : " ps-active"}`, children: [
8921
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-snap-step-icon", children: detectionDone ? /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-check", children: "✓" }) : /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner", style: { width: "1vw", height: "1vw", borderWidth: "1.5px" } }) }),
8922
+ /* @__PURE__ */ jsx("span", { children: detectLabel })
8923
+ ] }),
8924
+ !sizingDone && /* @__PURE__ */ jsxs(Fragment, { children: [
8925
+ /* @__PURE__ */ jsxs("div", { className: `ps-tryon-snap-step${analyzingDone ? " ps-done" : detectionDone ? " ps-active" : ""}`, children: [
8926
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-snap-step-icon", children: !detectionDone ? /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-num", children: "2" }) : !analyzingDone ? /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner", style: { width: "1vw", height: "1vw", borderWidth: "1.5px" } }) : /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-check", children: "✓" }) }),
8927
+ /* @__PURE__ */ jsx("span", { children: t("Analyzing your size") })
8928
+ ] }),
8929
+ /* @__PURE__ */ jsxs("div", { className: `ps-tryon-snap-step${analyzingDone ? " ps-active" : ""}`, children: [
8930
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-snap-step-icon", children: !analyzingDone ? /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-num", children: "3" }) : /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner", style: { width: "1vw", height: "1vw", borderWidth: "1.5px" } }) }),
8931
+ /* @__PURE__ */ jsx("span", { children: t("Finding best fit for you") })
8932
+ ] })
8610
8933
  ] }),
8611
- /* @__PURE__ */ jsxs("div", { className: `ps-tryon-snap-step${analyzingDone ? " ps-active" : ""}`, children: [
8612
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-snap-step-icon", children: !analyzingDone ? /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-num", children: "3" }) : /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner", style: { width: "1vw", height: "1vw", borderWidth: "1.5px" } }) }),
8613
- /* @__PURE__ */ jsx("span", { children: t("Finding best fit for you") })
8934
+ tryOnProcessing && /* @__PURE__ */ jsxs("div", { className: `ps-tryon-snap-step${tryOnDone ? " ps-done" : " ps-active"}`, children: [
8935
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-snap-step-icon", children: tryOnDone ? /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-check", children: "" }) : /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner", style: { width: "1vw", height: "1vw", borderWidth: "1.5px" } }) }),
8936
+ /* @__PURE__ */ jsx("span", { children: t("Generating virtual try-on") })
8614
8937
  ] })
8615
- ] }),
8616
- tryOnProcessing && /* @__PURE__ */ jsxs("div", { className: `ps-tryon-snap-step${tryOnDone ? " ps-done" : " ps-active"}`, children: [
8617
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-snap-step-icon", children: tryOnDone ? /* @__PURE__ */ jsx("span", { className: "ps-tryon-snap-check", children: "✓" }) : /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner", style: { width: "1vw", height: "1vw", borderWidth: "1.5px" } }) }),
8618
- /* @__PURE__ */ jsx("span", { children: t("Generating virtual try-on") })
8619
- ] })
8620
- ] })
8938
+ ] });
8939
+ })()
8621
8940
  ] }),
8622
8941
  (allDone || sizingResult && !isSnapProcessing) && /* @__PURE__ */ jsxs(Fragment, { children: [
8623
8942
  isMultiSection ? activeSection ? (
@@ -9416,9 +9735,18 @@ function CreateProfileWizard({ onSave, onCancel, onPhotoPreview, onEstimate, t }
9416
9735
  const photoInputRef = useRef(null);
9417
9736
  const nameInputRef = useRef(null);
9418
9737
  const [nameShaking, setNameShaking] = useState(false);
9738
+ const [ageConfirmed, setAgeConfirmed] = useState(null);
9739
+ const openFilePicker = () => {
9740
+ if (ageConfirmed !== true) return;
9741
+ photoInputRef.current?.click();
9742
+ };
9419
9743
  const handlePhotoSelect = async (e) => {
9420
9744
  const file = e.target.files?.[0];
9421
9745
  if (!file) return;
9746
+ if (ageConfirmed !== true) {
9747
+ setError(t("Please confirm that the person in the photo is 18 or older before uploading."));
9748
+ return;
9749
+ }
9422
9750
  if (!file.type.startsWith("image/")) {
9423
9751
  setError(t("Please upload an image file"));
9424
9752
  return;
@@ -9999,18 +10327,71 @@ function CreateProfileWizard({ onSave, onCancel, onPhotoPreview, onEstimate, t }
9999
10327
  /* @__PURE__ */ jsx("div", { className: "ps-cpw-image-left", children: photoBase64 ? /* @__PURE__ */ jsxs("div", { className: "ps-cpw-photo-preview-frame", children: [
10000
10328
  /* @__PURE__ */ jsx("img", { src: photoBase64, alt: t("Profile photo"), className: "ps-cpw-photo-preview-img" }),
10001
10329
  /* @__PURE__ */ jsx("button", { type: "button", className: "ps-cpw-photo-remove", onClick: handleRemovePhoto, "aria-label": t("Remove photo"), children: "×" }),
10002
- /* @__PURE__ */ jsx("button", { type: "button", className: "ps-cpw-photo-retake-pill", onClick: () => photoInputRef.current?.click(), children: t("Retake") })
10003
- ] }) : /* @__PURE__ */ jsxs("button", { type: "button", className: "ps-cpw-dropzone", onClick: () => photoInputRef.current?.click(), disabled: photoUploading, children: [
10004
- /* @__PURE__ */ jsx("img", { src: photoUploadIllustrationImg, alt: "", "aria-hidden": "true", className: "ps-cpw-dropzone-silhouette" }),
10005
- /* @__PURE__ */ jsxs("div", { className: "ps-cpw-dropzone-content", children: [
10006
- /* @__PURE__ */ jsxs("svg", { className: "ps-cpw-dropzone-upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
10007
- /* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
10008
- /* @__PURE__ */ jsx("polyline", { points: "17 8 12 3 7 8" }),
10009
- /* @__PURE__ */ jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
10010
- ] }),
10011
- /* @__PURE__ */ jsx("span", { className: "ps-cpw-dropzone-title", children: photoUploading ? t("Processing...") : t("Drop a photo or click to upload") }),
10012
- /* @__PURE__ */ jsx("span", { className: "ps-cpw-dropzone-hint", children: t("JPEG · PNG · WebP · up to 10MB") })
10013
- ] })
10330
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-cpw-photo-retake-pill", onClick: openFilePicker, children: t("Retake") })
10331
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "ps-cpw-dropzone-wrap", children: [
10332
+ /* @__PURE__ */ jsxs(
10333
+ "button",
10334
+ {
10335
+ type: "button",
10336
+ className: `ps-cpw-dropzone${ageConfirmed !== true ? " ps-cpw-dropzone-blurred" : ""}`,
10337
+ onClick: openFilePicker,
10338
+ disabled: photoUploading || ageConfirmed !== true,
10339
+ "aria-hidden": ageConfirmed !== true,
10340
+ tabIndex: ageConfirmed !== true ? -1 : 0,
10341
+ children: [
10342
+ /* @__PURE__ */ jsx("img", { src: photoUploadIllustrationImg, alt: "", "aria-hidden": "true", className: "ps-cpw-dropzone-silhouette" }),
10343
+ /* @__PURE__ */ jsxs("div", { className: "ps-cpw-dropzone-content", children: [
10344
+ /* @__PURE__ */ jsxs("svg", { className: "ps-cpw-dropzone-upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
10345
+ /* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
10346
+ /* @__PURE__ */ jsx("polyline", { points: "17 8 12 3 7 8" }),
10347
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
10348
+ ] }),
10349
+ /* @__PURE__ */ jsx("span", { className: "ps-cpw-dropzone-title", children: photoUploading ? t("Processing...") : t("Drop a photo or click to upload") }),
10350
+ /* @__PURE__ */ jsx("span", { className: "ps-cpw-dropzone-hint", children: t("JPEG · PNG · WebP · up to 10MB") })
10351
+ ] })
10352
+ ]
10353
+ }
10354
+ ),
10355
+ ageConfirmed === null && /* @__PURE__ */ jsx("div", { className: "ps-cpw-age-gate", role: "dialog", "aria-labelledby": "ps-cpw-age-gate-q", children: /* @__PURE__ */ jsxs("div", { className: "ps-cpw-age-gate-card", children: [
10356
+ /* @__PURE__ */ jsx("div", { className: "ps-cpw-age-gate-eyebrow", children: t("AGE VERIFICATION") }),
10357
+ /* @__PURE__ */ jsx("div", { id: "ps-cpw-age-gate-q", className: "ps-cpw-age-gate-question", children: t("Is the person in this photo 18 years or older?") }),
10358
+ /* @__PURE__ */ jsxs("div", { className: "ps-cpw-age-gate-actions", children: [
10359
+ /* @__PURE__ */ jsx(
10360
+ "button",
10361
+ {
10362
+ type: "button",
10363
+ className: "ps-cpw-age-gate-btn ps-cpw-age-gate-btn-primary",
10364
+ onClick: () => {
10365
+ setAgeConfirmed(true);
10366
+ setError("");
10367
+ },
10368
+ children: t("Yes, 18 or older")
10369
+ }
10370
+ ),
10371
+ /* @__PURE__ */ jsx(
10372
+ "button",
10373
+ {
10374
+ type: "button",
10375
+ className: "ps-cpw-age-gate-btn ps-cpw-age-gate-btn-secondary",
10376
+ onClick: () => setAgeConfirmed(false),
10377
+ children: t("No, under 18")
10378
+ }
10379
+ )
10380
+ ] })
10381
+ ] }) }),
10382
+ ageConfirmed === false && /* @__PURE__ */ jsx("div", { className: "ps-cpw-age-gate", role: "alert", children: /* @__PURE__ */ jsxs("div", { className: "ps-cpw-age-gate-card ps-cpw-age-gate-card-blocked", children: [
10383
+ /* @__PURE__ */ jsx("div", { className: "ps-cpw-age-gate-eyebrow ps-cpw-age-gate-eyebrow-blocked", children: t("UPLOAD NOT ALLOWED") }),
10384
+ /* @__PURE__ */ jsx("div", { className: "ps-cpw-age-gate-question", children: t("For your safety, we cannot process photos of people under 18.") }),
10385
+ /* @__PURE__ */ jsx(
10386
+ "button",
10387
+ {
10388
+ type: "button",
10389
+ className: "ps-cpw-age-gate-btn ps-cpw-age-gate-btn-secondary",
10390
+ onClick: () => setAgeConfirmed(null),
10391
+ children: t("Go back")
10392
+ }
10393
+ )
10394
+ ] }) })
10014
10395
  ] }) }),
10015
10396
  /* @__PURE__ */ jsxs("div", { className: "ps-cpw-image-right", children: [
10016
10397
  /* @__PURE__ */ jsx("div", { className: "ps-bp-inline-fields ps-cpw-inline-fields", children: /* @__PURE__ */ jsxs("div", { className: "ps-bp-inline-row", children: [
@@ -10041,6 +10422,13 @@ function CreateProfileWizard({ onSave, onCancel, onPhotoPreview, onEstimate, t }
10041
10422
  ] })
10042
10423
  ] })
10043
10424
  ] }),
10425
+ /* @__PURE__ */ jsxs("div", { className: "ps-cpw-legal-notice", children: [
10426
+ /* @__PURE__ */ jsxs("div", { className: "ps-cpw-legal-notice-head", children: [
10427
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }) }),
10428
+ /* @__PURE__ */ jsx("span", { children: t("LEGAL NOTICE") })
10429
+ ] }),
10430
+ /* @__PURE__ */ jsx("p", { className: "ps-cpw-legal-notice-body", children: t("Your image will be used to generate a virtual try-on preview showing how selected items may look and fit. Images are processed securely and are not stored after generation.") })
10431
+ ] }),
10044
10432
  error && /* @__PURE__ */ jsx("div", { className: "ps-cpw-error", children: error })
10045
10433
  ] })
10046
10434
  ] }, "image-photo"),
@@ -10884,6 +11272,8 @@ function PhotoStepMobile({
10884
11272
  const isCloseUp = photoVariant === "close-up";
10885
11273
  const fileRef = useRef(null);
10886
11274
  const hasPhoto = !!photoPreview;
11275
+ const [ageConfirmed, setAgeConfirmed] = useState(null);
11276
+ const gated = !hasPhoto && ageConfirmed !== true;
10887
11277
  return /* @__PURE__ */ jsxs("div", { className: "ps-pm-root", children: [
10888
11278
  /* @__PURE__ */ jsxs("div", { className: "ps-pm-header", children: [
10889
11279
  /* @__PURE__ */ jsx("h2", { className: "ps-pm-title", children: isCloseUp ? t("Upload a face photo or selfie") : t("Review your photo") }),
@@ -10911,19 +11301,46 @@ function PhotoStepMobile({
10911
11301
  children: /* @__PURE__ */ jsx(CloseIconSm, {})
10912
11302
  }
10913
11303
  )
10914
- ] }) : /* @__PURE__ */ jsxs(
10915
- "button",
10916
- {
10917
- type: "button",
10918
- className: "ps-pm-preview-empty",
10919
- onClick: () => fileRef.current?.click(),
10920
- children: [
10921
- /* @__PURE__ */ jsx(UploadIconLg, {}),
10922
- /* @__PURE__ */ jsx("span", { className: "ps-pm-preview-empty-title", children: t("Tap to upload") }),
10923
- /* @__PURE__ */ jsx("span", { className: "ps-pm-preview-empty-hint", children: t("JPEG, PNG up to 10MB") })
10924
- ]
10925
- }
10926
- ) }),
11304
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
11305
+ /* @__PURE__ */ jsxs(
11306
+ "button",
11307
+ {
11308
+ type: "button",
11309
+ className: `ps-pm-preview-empty${gated ? " ps-pm-preview-blurred" : ""}`,
11310
+ onClick: () => {
11311
+ if (!gated) fileRef.current?.click();
11312
+ },
11313
+ disabled: gated,
11314
+ "aria-hidden": gated,
11315
+ tabIndex: gated ? -1 : 0,
11316
+ children: [
11317
+ /* @__PURE__ */ jsx(UploadIconLg, {}),
11318
+ /* @__PURE__ */ jsx("span", { className: "ps-pm-preview-empty-title", children: t("Tap to upload") }),
11319
+ /* @__PURE__ */ jsx("span", { className: "ps-pm-preview-empty-hint", children: t("JPEG, PNG up to 10MB") })
11320
+ ]
11321
+ }
11322
+ ),
11323
+ ageConfirmed === null && /* @__PURE__ */ jsx("div", { className: "ps-pm-age-gate", role: "dialog", children: /* @__PURE__ */ jsxs("div", { className: "ps-pm-age-gate-card", children: [
11324
+ /* @__PURE__ */ jsx("div", { className: "ps-pm-age-gate-eyebrow", children: t("AGE VERIFICATION") }),
11325
+ /* @__PURE__ */ jsx("div", { className: "ps-pm-age-gate-question", children: t("Is the person in this photo 18 years or older?") }),
11326
+ /* @__PURE__ */ jsxs("div", { className: "ps-pm-age-gate-actions", children: [
11327
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-pm-age-gate-btn ps-pm-age-gate-btn-primary", onClick: () => setAgeConfirmed(true), children: t("Yes, 18 or older") }),
11328
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-pm-age-gate-btn ps-pm-age-gate-btn-secondary", onClick: () => setAgeConfirmed(false), children: t("No, under 18") })
11329
+ ] })
11330
+ ] }) }),
11331
+ ageConfirmed === false && /* @__PURE__ */ jsx("div", { className: "ps-pm-age-gate", role: "alert", children: /* @__PURE__ */ jsxs("div", { className: "ps-pm-age-gate-card", children: [
11332
+ /* @__PURE__ */ jsx("div", { className: "ps-pm-age-gate-eyebrow ps-pm-age-gate-eyebrow-blocked", children: t("UPLOAD NOT ALLOWED") }),
11333
+ /* @__PURE__ */ jsx("div", { className: "ps-pm-age-gate-question", children: t("For your safety, we cannot process photos of people under 18.") }),
11334
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-pm-age-gate-btn ps-pm-age-gate-btn-secondary", onClick: () => setAgeConfirmed(null), children: t("Go back") })
11335
+ ] }) })
11336
+ ] }) }),
11337
+ /* @__PURE__ */ jsxs("div", { className: "ps-pm-legal-notice", children: [
11338
+ /* @__PURE__ */ jsxs("div", { className: "ps-pm-legal-notice-head", children: [
11339
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }) }),
11340
+ /* @__PURE__ */ jsx("span", { children: t("LEGAL NOTICE") })
11341
+ ] }),
11342
+ /* @__PURE__ */ jsx("p", { className: "ps-pm-legal-notice-body", children: t("Your image will be used to generate a virtual try-on preview showing how selected items may look and fit. Images are processed securely and are not stored after generation.") })
11343
+ ] }),
10927
11344
  /* @__PURE__ */ jsxs("div", { className: "ps-pm-checklist", children: [
10928
11345
  /* @__PURE__ */ jsx("div", { className: "ps-pm-checklist-icon", children: /* @__PURE__ */ jsx(InfoIcon, {}) }),
10929
11346
  /* @__PURE__ */ jsxs("div", { className: "ps-pm-checklist-body", children: [
@@ -11171,6 +11588,7 @@ function BodyProfileView({
11171
11588
  const [photoBase64, setPhotoBase64] = useState(null);
11172
11589
  const [photoProcessing, setPhotoProcessing] = useState(false);
11173
11590
  const fileInputRef = useRef(null);
11591
+ const [ageConfirmed, setAgeConfirmed] = useState(null);
11174
11592
  const [photoStepHeight, setPhotoStepHeight] = useState(() => {
11175
11593
  if (seedTotalIn != null) return String(Math.round(seedTotalIn * 2.54));
11176
11594
  return seedHeightCm;
@@ -11195,6 +11613,10 @@ function BodyProfileView({
11195
11613
  const handlePhotoSelect = useCallback(async (e) => {
11196
11614
  const file = e.target.files?.[0];
11197
11615
  if (!file) return;
11616
+ if (ageConfirmed !== true) {
11617
+ setError(t("Please confirm that the person in the photo is 18 or older before uploading."));
11618
+ return;
11619
+ }
11198
11620
  if (!file.type.startsWith("image/")) {
11199
11621
  setError(t("Please upload an image file"));
11200
11622
  return;
@@ -11217,7 +11639,7 @@ function BodyProfileView({
11217
11639
  } finally {
11218
11640
  setPhotoProcessing(false);
11219
11641
  }
11220
- }, [t]);
11642
+ }, [t, ageConfirmed]);
11221
11643
  const handleRemovePhoto = useCallback(() => {
11222
11644
  if (photoPreview) URL.revokeObjectURL(photoPreview);
11223
11645
  setPhotoFile(null);
@@ -11383,38 +11805,186 @@ function BodyProfileView({
11383
11805
  }
11384
11806
  return /* @__PURE__ */ jsxs("div", { className: "ps-bp-wrapper", children: [
11385
11807
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "1.2vw", padding: "1.5vw", width: "100%", height: "100%", minHeight: "20vw", alignItems: "stretch" }, children: [
11386
- /* @__PURE__ */ jsx(
11387
- "div",
11388
- {
11389
- onClick: () => !photoPreview && fileInputRef.current?.click(),
11390
- style: {
11391
- flex: 1,
11392
- display: "flex",
11393
- flexDirection: "column",
11394
- alignItems: "center",
11395
- justifyContent: "center",
11396
- border: photoPreview ? "2px solid var(--ps-accent)" : "2px dashed var(--ps-border-color)",
11397
- borderRadius: "0.5vw",
11398
- cursor: photoPreview ? "default" : "pointer",
11399
- position: "relative",
11400
- background: "var(--ps-bg-secondary)",
11401
- transition: "border-color 0.2s",
11402
- overflow: "hidden"
11403
- },
11404
- children: photoPreview ? /* @__PURE__ */ jsxs(Fragment, { children: [
11405
- /* @__PURE__ */ jsx("img", { src: photoPreview, alt: "preview", style: { width: "100%", height: "100%", objectFit: "contain" } }),
11406
- /* @__PURE__ */ jsx("button", { onClick: (e) => {
11407
- e.stopPropagation();
11408
- handleRemovePhoto();
11409
- }, style: { position: "absolute", top: "0.5vw", right: "0.5vw", width: "1.4vw", height: "1.4vw", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "none", color: "#fff", fontSize: "0.7vw", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }, children: "×" })
11410
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
11411
- /* @__PURE__ */ jsx(UploadIcon, { size: 32 }),
11412
- /* @__PURE__ */ jsx("span", { style: { fontSize: "0.85vw", fontWeight: 600, color: "var(--ps-text-primary)", marginTop: "0.5vw" }, children: t("Upload your photo") }),
11413
- /* @__PURE__ */ jsx("span", { style: { fontSize: "0.6vw", color: "var(--ps-text-muted)", marginTop: "0.2vw" }, children: t("Click or drag a full-body photo") }),
11414
- /* @__PURE__ */ jsx("span", { style: { fontSize: "0.5vw", color: "var(--ps-text-dim)", marginTop: "0.4vw" }, children: "JPEG, PNG (max 10MB)" })
11415
- ] })
11416
- }
11417
- ),
11808
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, position: "relative", display: "flex" }, children: [
11809
+ /* @__PURE__ */ jsx(
11810
+ "div",
11811
+ {
11812
+ onClick: () => {
11813
+ if (!photoPreview && ageConfirmed === true) fileInputRef.current?.click();
11814
+ },
11815
+ style: {
11816
+ flex: 1,
11817
+ display: "flex",
11818
+ flexDirection: "column",
11819
+ alignItems: "center",
11820
+ justifyContent: "center",
11821
+ border: photoPreview ? "2px solid var(--ps-accent)" : "2px dashed var(--ps-border-color)",
11822
+ borderRadius: "0.5vw",
11823
+ cursor: photoPreview ? "default" : ageConfirmed === true ? "pointer" : "not-allowed",
11824
+ position: "relative",
11825
+ background: "var(--ps-bg-secondary)",
11826
+ transition: "border-color 0.2s, filter 0.25s",
11827
+ overflow: "hidden",
11828
+ filter: !photoPreview && ageConfirmed !== true ? "blur(6px) saturate(0.7)" : void 0,
11829
+ pointerEvents: !photoPreview && ageConfirmed !== true ? "none" : void 0,
11830
+ userSelect: !photoPreview && ageConfirmed !== true ? "none" : void 0
11831
+ },
11832
+ "aria-hidden": !photoPreview && ageConfirmed !== true,
11833
+ children: photoPreview ? /* @__PURE__ */ jsxs(Fragment, { children: [
11834
+ /* @__PURE__ */ jsx("img", { src: photoPreview, alt: "preview", style: { width: "100%", height: "100%", objectFit: "contain" } }),
11835
+ /* @__PURE__ */ jsx("button", { onClick: (e) => {
11836
+ e.stopPropagation();
11837
+ handleRemovePhoto();
11838
+ }, style: { position: "absolute", top: "0.5vw", right: "0.5vw", width: "1.4vw", height: "1.4vw", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "none", color: "#fff", fontSize: "0.7vw", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }, children: "×" })
11839
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
11840
+ /* @__PURE__ */ jsx(UploadIcon, { size: 32 }),
11841
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.85vw", fontWeight: 600, color: "var(--ps-text-primary)", marginTop: "0.5vw" }, children: t("Upload your photo") }),
11842
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.6vw", color: "var(--ps-text-muted)", marginTop: "0.2vw" }, children: t("Click or drag a full-body photo") }),
11843
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.5vw", color: "var(--ps-text-dim)", marginTop: "0.4vw" }, children: "JPEG, PNG (max 10MB)" })
11844
+ ] })
11845
+ }
11846
+ ),
11847
+ !photoPreview && ageConfirmed === null && /* @__PURE__ */ jsx(
11848
+ "div",
11849
+ {
11850
+ role: "dialog",
11851
+ "aria-labelledby": "ps-bp-age-q",
11852
+ style: {
11853
+ position: "absolute",
11854
+ inset: 0,
11855
+ display: "flex",
11856
+ alignItems: "center",
11857
+ justifyContent: "center",
11858
+ padding: "1vw",
11859
+ background: "rgba(255,255,255,0.55)",
11860
+ backdropFilter: "blur(8px)",
11861
+ WebkitBackdropFilter: "blur(8px)",
11862
+ borderRadius: "0.5vw",
11863
+ zIndex: 2,
11864
+ animation: "ps-cpw-age-gate-in 0.28s ease-out both"
11865
+ },
11866
+ children: /* @__PURE__ */ jsxs("div", { style: {
11867
+ width: "100%",
11868
+ maxWidth: "min(420px, 22vw)",
11869
+ padding: "1.4vw 1.6vw",
11870
+ background: "#FFFFFF",
11871
+ border: "1px solid var(--ps-border-subtle)",
11872
+ borderRadius: "0.9vw",
11873
+ boxShadow: "0 20px 40px -12px rgba(17,24,39,0.25), 0 8px 16px -8px rgba(17,24,39,0.15)",
11874
+ display: "flex",
11875
+ flexDirection: "column",
11876
+ alignItems: "center",
11877
+ textAlign: "center",
11878
+ gap: "0.75vw"
11879
+ }, children: [
11880
+ /* @__PURE__ */ jsx("div", { style: { fontSize: "0.62vw", fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ps-accent)" }, children: t("AGE VERIFICATION") }),
11881
+ /* @__PURE__ */ jsx("div", { id: "ps-bp-age-q", style: { fontSize: "0.95vw", fontWeight: 600, lineHeight: 1.35, color: "var(--ps-text-primary)" }, children: t("Is the person in this photo 18 years or older?") }),
11882
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "0.65vw", width: "100%", marginTop: "0.4vw" }, children: [
11883
+ /* @__PURE__ */ jsx(
11884
+ "button",
11885
+ {
11886
+ type: "button",
11887
+ onClick: () => {
11888
+ setAgeConfirmed(true);
11889
+ setError("");
11890
+ },
11891
+ style: {
11892
+ flex: 1,
11893
+ padding: "0.75vw 1vw",
11894
+ borderRadius: "999px",
11895
+ background: "var(--ps-accent)",
11896
+ color: "#FFFFFF",
11897
+ border: "1.5px solid var(--ps-accent)",
11898
+ fontFamily: "inherit",
11899
+ fontSize: "0.78vw",
11900
+ fontWeight: 700,
11901
+ cursor: "pointer",
11902
+ transition: "transform 0.18s, background 0.18s"
11903
+ },
11904
+ children: t("Yes, 18 or older")
11905
+ }
11906
+ ),
11907
+ /* @__PURE__ */ jsx(
11908
+ "button",
11909
+ {
11910
+ type: "button",
11911
+ onClick: () => setAgeConfirmed(false),
11912
+ style: {
11913
+ flex: 1,
11914
+ padding: "0.75vw 1vw",
11915
+ borderRadius: "999px",
11916
+ background: "transparent",
11917
+ color: "var(--ps-text-primary)",
11918
+ border: "1.5px solid var(--ps-border-color)",
11919
+ fontFamily: "inherit",
11920
+ fontSize: "0.78vw",
11921
+ fontWeight: 700,
11922
+ cursor: "pointer",
11923
+ transition: "background 0.18s, border-color 0.18s"
11924
+ },
11925
+ children: t("No, under 18")
11926
+ }
11927
+ )
11928
+ ] })
11929
+ ] })
11930
+ }
11931
+ ),
11932
+ !photoPreview && ageConfirmed === false && /* @__PURE__ */ jsx(
11933
+ "div",
11934
+ {
11935
+ role: "alert",
11936
+ style: {
11937
+ position: "absolute",
11938
+ inset: 0,
11939
+ display: "flex",
11940
+ alignItems: "center",
11941
+ justifyContent: "center",
11942
+ padding: "1vw",
11943
+ background: "rgba(255,255,255,0.55)",
11944
+ backdropFilter: "blur(8px)",
11945
+ WebkitBackdropFilter: "blur(8px)",
11946
+ borderRadius: "0.5vw",
11947
+ zIndex: 2
11948
+ },
11949
+ children: /* @__PURE__ */ jsxs("div", { style: {
11950
+ width: "100%",
11951
+ maxWidth: "min(420px, 22vw)",
11952
+ padding: "1.4vw 1.6vw",
11953
+ background: "#FFFFFF",
11954
+ border: "1px solid rgba(192,38,38,0.35)",
11955
+ borderRadius: "0.9vw",
11956
+ boxShadow: "0 20px 40px -12px rgba(17,24,39,0.25)",
11957
+ display: "flex",
11958
+ flexDirection: "column",
11959
+ alignItems: "center",
11960
+ textAlign: "center",
11961
+ gap: "0.75vw"
11962
+ }, children: [
11963
+ /* @__PURE__ */ jsx("div", { style: { fontSize: "0.62vw", fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase", color: "#C02626" }, children: t("UPLOAD NOT ALLOWED") }),
11964
+ /* @__PURE__ */ jsx("div", { style: { fontSize: "0.95vw", fontWeight: 600, lineHeight: 1.35, color: "var(--ps-text-primary)" }, children: t("For your safety, we cannot process photos of people under 18.") }),
11965
+ /* @__PURE__ */ jsx(
11966
+ "button",
11967
+ {
11968
+ type: "button",
11969
+ onClick: () => setAgeConfirmed(null),
11970
+ style: {
11971
+ padding: "0.75vw 1.4vw",
11972
+ borderRadius: "999px",
11973
+ background: "transparent",
11974
+ color: "var(--ps-text-primary)",
11975
+ border: "1.5px solid var(--ps-border-color)",
11976
+ fontFamily: "inherit",
11977
+ fontSize: "0.78vw",
11978
+ fontWeight: 700,
11979
+ cursor: "pointer"
11980
+ },
11981
+ children: t("Go back")
11982
+ }
11983
+ )
11984
+ ] })
11985
+ }
11986
+ )
11987
+ ] }),
11418
11988
  /* @__PURE__ */ jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "0.6vw", justifyContent: "center" }, children: [
11419
11989
  /* @__PURE__ */ jsx("div", { style: { fontSize: "0.85vw", fontWeight: 700, color: "var(--ps-text-primary)", marginBottom: "0.3vw" }, children: t("How to take the best photo") }),
11420
11990
  /* @__PURE__ */ jsxs("div", { style: { background: "#ddfbe7", borderRadius: "0.5vw", padding: "0.6vw 0.8vw" }, children: [
@@ -11457,6 +12027,21 @@ function BodyProfileView({
11457
12027
  /* @__PURE__ */ jsx("span", { style: { color: "#3267c3", fontSize: "0.65vw", fontWeight: 600 }, children: t("Quick Tip") })
11458
12028
  ] }),
11459
12029
  /* @__PURE__ */ jsx("div", { style: { fontSize: "0.58vw", color: "var(--ps-text-primary)", lineHeight: 1.6 }, children: t("The simpler your photo is, the more accurate your virtual try-on results will be.") })
12030
+ ] }),
12031
+ /* @__PURE__ */ jsxs("div", { style: {
12032
+ background: "rgba(33, 84, 239, 0.04)",
12033
+ border: "1px solid rgba(33, 84, 239, 0.16)",
12034
+ borderRadius: "0.5vw",
12035
+ padding: "0.6vw 0.8vw",
12036
+ display: "flex",
12037
+ flexDirection: "column",
12038
+ gap: "0.3vw"
12039
+ }, children: [
12040
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.35vw" }, children: [
12041
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "0.75vw", height: "0.75vw", fill: "none", stroke: "#2154ef", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }) }),
12042
+ /* @__PURE__ */ jsx("span", { style: { color: "#2154ef", fontSize: "0.62vw", fontWeight: 700, letterSpacing: "0.12em", textTransform: "uppercase" }, children: t("Legal Notice") })
12043
+ ] }),
12044
+ /* @__PURE__ */ jsx("div", { style: { fontSize: "0.58vw", color: "var(--ps-text-secondary)", lineHeight: 1.55 }, children: t("Your image will be used to generate a virtual try-on preview showing how selected items may look and fit. Images are processed securely and are not stored after generation.") })
11460
12045
  ] })
11461
12046
  ] })
11462
12047
  ] }),
@@ -12445,6 +13030,7 @@ function PrimeStyleTryonInner({
12445
13030
  const bodyRef = useRef(null);
12446
13031
  const modelPoseRef = useRef(null);
12447
13032
  const [bodyLandmarks, setBodyLandmarks] = useState(null);
13033
+ const [faceLandmarks, setFaceLandmarks] = useState(null);
12448
13034
  const selectedFileRef = useRef(null);
12449
13035
  useEffect(() => {
12450
13036
  try {
@@ -13025,8 +13611,10 @@ function PrimeStyleTryonInner({
13025
13611
  setView("size-result");
13026
13612
  const measurementType = detectMeasurementType(productTitle);
13027
13613
  if (measurementType === "face" || measurementType === "head") {
13614
+ setFaceLandmarks(null);
13028
13615
  try {
13029
13616
  const faceResult = await detectFaceMeasurements(objUrl);
13617
+ if (faceResult) setFaceLandmarks(faceResult.landmarks);
13030
13618
  const facePayload = {
13031
13619
  product: { title: productTitle },
13032
13620
  sizeGuide: sizeGuide ?? { found: false },
@@ -13680,6 +14268,8 @@ function PrimeStyleTryonInner({
13680
14268
  handleTryOnSubmit,
13681
14269
  tryOnProcessing,
13682
14270
  bodyLandmarks,
14271
+ faceLandmarks,
14272
+ measurementType: detectMeasurementType(productTitle),
13683
14273
  activeSection,
13684
14274
  setActiveSection,
13685
14275
  onResetTryOn: () => {