@primestyleai/tryon 5.6.4 → 5.6.5

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.
@@ -549,7 +549,8 @@ const STYLES = `
549
549
  scrollbar-width: thin; scrollbar-color: var(--ps-border-color) transparent;
550
550
  flex-shrink: 0;
551
551
  }
552
- .ps-tryon-modal-wide { max-width: 55vw; width: 55vw; height: 70vh; max-height: 70vh; display: flex; flex-direction: column; overflow: visible; }
552
+ .ps-tryon-modal-wide { max-width: 55vw; width: 55vw; height: 70vh; max-height: 70vh; display: flex; flex-direction: column; overflow: visible; transition: height 0.45s cubic-bezier(0.32, 0.72, 0, 1), max-height 0.45s cubic-bezier(0.32, 0.72, 0, 1); }
553
+ .ps-tryon-modal-tall.ps-tryon-modal-wide { height: 88vh; max-height: 88vh; }
553
554
  .ps-tryon-modal:has(.ps-tryon-drawer-open) { overflow: hidden; }
554
555
  @keyframes ps-slide-up { from { transform: translateY(1.04vw) scale(0.97); opacity: 0; filter: blur(4px); } to { transform: none; opacity: 1; filter: none; } }
555
556
 
@@ -3846,6 +3847,10 @@ const STYLES = `
3846
3847
  display: flex; align-items: center; justify-content: center;
3847
3848
  margin-bottom: 12px;
3848
3849
  color: var(--ps-text-secondary);
3850
+ overflow: hidden;
3851
+ }
3852
+ .ps-msp-card-photo {
3853
+ width: 100%; height: 100%; object-fit: cover; display: block;
3849
3854
  }
3850
3855
  .ps-msp-avatar {
3851
3856
  position: relative;
@@ -4110,7 +4115,7 @@ const STYLES = `
4110
4115
  outline: none;
4111
4116
  transition: border-color 0.15s;
4112
4117
  }
4113
- .ps-cpw-input::placeholder { color: var(--ps-border-color); font-weight: 400; }
4118
+ .ps-cpw-input::placeholder { color: var(--ps-text-muted); font-weight: 500; opacity: 0.7; }
4114
4119
  .ps-cpw-input:focus { border-bottom-color: var(--ps-accent); }
4115
4120
  .ps-cpw-input::-webkit-outer-spin-button,
4116
4121
  .ps-cpw-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
@@ -4149,6 +4154,55 @@ const STYLES = `
4149
4154
  margin-top: -6px;
4150
4155
  }
4151
4156
 
4157
+ /* Optional photo upload (step 1) */
4158
+ .ps-cpw-photo {
4159
+ display: flex; flex-direction: column; gap: 8px;
4160
+ margin-top: 4px;
4161
+ }
4162
+ .ps-cpw-photo-upload {
4163
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
4164
+ gap: 6px; padding: 22px;
4165
+ background: var(--ps-bg-secondary);
4166
+ border: 2px dashed var(--ps-border-color);
4167
+ border-radius: 12px;
4168
+ color: var(--ps-text-secondary); cursor: pointer;
4169
+ font-family: inherit;
4170
+ transition: border-color 0.15s, background 0.15s;
4171
+ }
4172
+ .ps-cpw-photo-upload:hover {
4173
+ border-color: var(--ps-accent);
4174
+ background: rgba(33, 84, 239, 0.04);
4175
+ }
4176
+ .ps-cpw-photo-upload:disabled { opacity: 0.5; cursor: wait; }
4177
+ .ps-cpw-photo-upload svg { color: var(--ps-accent); }
4178
+ .ps-cpw-photo-upload-title {
4179
+ font-size: 13px; font-weight: 600;
4180
+ color: var(--ps-text-primary);
4181
+ }
4182
+ .ps-cpw-photo-upload-hint {
4183
+ font-size: 11px; font-weight: 400;
4184
+ color: var(--ps-text-muted);
4185
+ }
4186
+ .ps-cpw-photo-preview {
4187
+ position: relative;
4188
+ width: 100%; max-width: 220px;
4189
+ border-radius: 12px; overflow: hidden;
4190
+ background: var(--ps-bg-secondary);
4191
+ border: 1px solid var(--ps-border-subtle);
4192
+ aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
4193
+ }
4194
+ .ps-cpw-photo-preview img {
4195
+ width: 100%; height: 100%; object-fit: cover;
4196
+ }
4197
+ .ps-cpw-photo-remove {
4198
+ position: absolute; top: 8px; right: 8px;
4199
+ width: 28px; height: 28px; border-radius: 50%;
4200
+ background: rgba(0, 0, 0, 0.65); color: #FFFFFF;
4201
+ border: none; cursor: pointer;
4202
+ font-size: 18px; line-height: 1;
4203
+ display: flex; align-items: center; justify-content: center;
4204
+ }
4205
+
4152
4206
  /* Step 2 — Silhouette */
4153
4207
  .ps-cpw-silhouette {
4154
4208
  display: flex; flex-direction: column; gap: 28px;
@@ -4256,6 +4310,212 @@ const STYLES = `
4256
4310
  .ps-cpw-back-btn { text-align: center; }
4257
4311
  }
4258
4312
 
4313
+ /* ════════════════════════════════════════════════════════════════
4314
+ ProfileMeasurementsView (.ps-pmv-*) — full profile detail with
4315
+ all body measurements, basics, saved sizes history, and actions.
4316
+ ════════════════════════════════════════════════════════════════ */
4317
+ .ps-pmv-root {
4318
+ display: flex; flex-direction: column; gap: 24px;
4319
+ padding: 4px 4px 24px;
4320
+ }
4321
+ .ps-pmv-hero {
4322
+ display: flex; align-items: center; gap: 18px;
4323
+ padding-bottom: 18px;
4324
+ border-bottom: 1px solid var(--ps-border-subtle);
4325
+ }
4326
+ .ps-pmv-hero-avatar {
4327
+ width: 76px; height: 76px;
4328
+ border-radius: 50%;
4329
+ background: var(--ps-bg-secondary);
4330
+ border: 2px solid var(--ps-accent);
4331
+ color: var(--ps-accent);
4332
+ display: flex; align-items: center; justify-content: center;
4333
+ overflow: hidden; flex-shrink: 0;
4334
+ }
4335
+ .ps-pmv-hero-avatar img {
4336
+ width: 100%; height: 100%; object-fit: cover;
4337
+ }
4338
+ .ps-pmv-hero-info { flex: 1; min-width: 0; }
4339
+ .ps-pmv-hero-eyebrow {
4340
+ font-size: 10px; font-weight: 700;
4341
+ letter-spacing: 0.16em; text-transform: uppercase;
4342
+ color: var(--ps-accent);
4343
+ margin-bottom: 6px;
4344
+ }
4345
+ .ps-pmv-hero-name {
4346
+ font-size: 28px; font-weight: 700;
4347
+ color: var(--ps-text-primary);
4348
+ margin: 0;
4349
+ letter-spacing: -0.01em;
4350
+ }
4351
+
4352
+ /* Basics row — height / weight / age stats */
4353
+ .ps-pmv-basics {
4354
+ display: grid;
4355
+ grid-template-columns: repeat(3, 1fr);
4356
+ gap: 14px;
4357
+ }
4358
+ .ps-pmv-basic {
4359
+ background: var(--ps-bg-secondary);
4360
+ border: 1px solid var(--ps-border-subtle);
4361
+ border-radius: 10px;
4362
+ padding: 16px 18px;
4363
+ display: flex; flex-direction: column; gap: 4px;
4364
+ }
4365
+ .ps-pmv-basic-label {
4366
+ font-size: 10px; font-weight: 700;
4367
+ letter-spacing: 0.14em; text-transform: uppercase;
4368
+ color: var(--ps-text-muted);
4369
+ }
4370
+ .ps-pmv-basic-value {
4371
+ font-size: 22px; font-weight: 700;
4372
+ color: var(--ps-text-primary);
4373
+ font-feature-settings: "tnum" 1;
4374
+ }
4375
+
4376
+ /* Section blocks */
4377
+ .ps-pmv-section {
4378
+ display: flex; flex-direction: column; gap: 14px;
4379
+ }
4380
+ .ps-pmv-section-head {
4381
+ display: flex; flex-direction: column; gap: 4px;
4382
+ }
4383
+ .ps-pmv-section-title {
4384
+ font-size: 12px; font-weight: 700;
4385
+ letter-spacing: 0.14em; text-transform: uppercase;
4386
+ color: var(--ps-text-primary);
4387
+ }
4388
+ .ps-pmv-section-sub {
4389
+ font-size: 12px; font-weight: 400;
4390
+ color: var(--ps-text-muted);
4391
+ }
4392
+
4393
+ /* Body measurements grid */
4394
+ .ps-pmv-measure-grid {
4395
+ display: grid;
4396
+ grid-template-columns: repeat(4, 1fr);
4397
+ gap: 10px;
4398
+ }
4399
+ .ps-pmv-measure {
4400
+ background: var(--ps-bg-primary);
4401
+ border: 1px solid var(--ps-border-subtle);
4402
+ border-radius: 10px;
4403
+ padding: 12px 14px;
4404
+ display: flex; flex-direction: column; gap: 4px;
4405
+ }
4406
+ .ps-pmv-measure-label {
4407
+ font-size: 9px; font-weight: 700;
4408
+ letter-spacing: 0.12em; text-transform: uppercase;
4409
+ color: var(--ps-text-muted);
4410
+ }
4411
+ .ps-pmv-measure-value {
4412
+ font-size: 18px; font-weight: 700;
4413
+ color: var(--ps-text-primary);
4414
+ font-feature-settings: "tnum" 1;
4415
+ }
4416
+ .ps-pmv-measure-value.ps-loading {
4417
+ color: var(--ps-border-color);
4418
+ animation: ps-pmv-shimmer 1.4s ease-in-out infinite;
4419
+ }
4420
+ @keyframes ps-pmv-shimmer {
4421
+ 0%, 100% { opacity: 0.5; }
4422
+ 50% { opacity: 1; }
4423
+ }
4424
+
4425
+ /* Saved sizes history (per-product cache) */
4426
+ .ps-pmv-history {
4427
+ display: flex; flex-direction: column; gap: 8px;
4428
+ }
4429
+ .ps-pmv-history-card {
4430
+ display: flex; align-items: center; gap: 12px;
4431
+ padding: 12px;
4432
+ background: var(--ps-bg-primary);
4433
+ border: 1px solid var(--ps-border-subtle);
4434
+ border-radius: 10px;
4435
+ }
4436
+ .ps-pmv-history-thumb {
4437
+ width: 44px; height: 44px;
4438
+ border-radius: 6px; overflow: hidden;
4439
+ background: var(--ps-bg-secondary);
4440
+ flex-shrink: 0;
4441
+ display: flex; align-items: center; justify-content: center;
4442
+ }
4443
+ .ps-pmv-history-thumb img {
4444
+ max-width: 100%; max-height: 100%; object-fit: contain;
4445
+ }
4446
+ .ps-pmv-history-info {
4447
+ flex: 1; min-width: 0;
4448
+ display: flex; flex-direction: column; gap: 2px;
4449
+ }
4450
+ .ps-pmv-history-name {
4451
+ font-size: 13px; font-weight: 600;
4452
+ color: var(--ps-text-primary);
4453
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
4454
+ }
4455
+ .ps-pmv-history-meta {
4456
+ font-size: 10px;
4457
+ color: var(--ps-text-muted);
4458
+ }
4459
+ .ps-pmv-history-size {
4460
+ font-size: 22px; font-weight: 700;
4461
+ color: var(--ps-accent);
4462
+ font-feature-settings: "tnum" 1;
4463
+ }
4464
+
4465
+ /* Actions */
4466
+ .ps-pmv-actions {
4467
+ display: flex; align-items: center; justify-content: space-between;
4468
+ gap: 12px;
4469
+ padding-top: 18px;
4470
+ border-top: 1px solid var(--ps-border-subtle);
4471
+ margin-top: 4px;
4472
+ }
4473
+ .ps-pmv-actions-right {
4474
+ display: flex; align-items: center; gap: 8px;
4475
+ }
4476
+ .ps-pmv-btn-secondary,
4477
+ .ps-pmv-btn-edit,
4478
+ .ps-pmv-btn-delete {
4479
+ background: none; border: 1px solid var(--ps-border-color);
4480
+ border-radius: 6px;
4481
+ padding: 10px 16px;
4482
+ font-family: inherit; font-size: 11px; font-weight: 600;
4483
+ letter-spacing: 0.06em;
4484
+ color: var(--ps-text-secondary);
4485
+ cursor: pointer;
4486
+ transition: border-color 0.15s, color 0.15s;
4487
+ }
4488
+ .ps-pmv-btn-secondary:hover,
4489
+ .ps-pmv-btn-edit:hover {
4490
+ border-color: var(--ps-accent);
4491
+ color: var(--ps-accent);
4492
+ }
4493
+ .ps-pmv-btn-delete:hover {
4494
+ border-color: var(--ps-error-color);
4495
+ color: var(--ps-error-color);
4496
+ }
4497
+ .ps-pmv-btn-primary {
4498
+ background: var(--ps-accent); color: #FFFFFF;
4499
+ border: none; border-radius: 6px;
4500
+ padding: 11px 18px;
4501
+ font-family: inherit; font-size: 11px; font-weight: 700;
4502
+ letter-spacing: 0.12em; text-transform: uppercase;
4503
+ cursor: pointer;
4504
+ transition: opacity 0.15s, transform 0.15s;
4505
+ box-shadow: 0 4px 14px rgba(33, 84, 239, 0.18);
4506
+ }
4507
+ .ps-pmv-btn-primary:hover { opacity: 0.92; }
4508
+ .ps-pmv-btn-primary:active { transform: scale(0.98); }
4509
+
4510
+ @media (max-width: 768px) {
4511
+ .ps-pmv-hero { flex-direction: column; align-items: flex-start; gap: 12px; }
4512
+ .ps-pmv-hero-name { font-size: 22px; }
4513
+ .ps-pmv-basics { grid-template-columns: 1fr; }
4514
+ .ps-pmv-measure-grid { grid-template-columns: repeat(2, 1fr); }
4515
+ .ps-pmv-actions { flex-direction: column; align-items: stretch; gap: 10px; }
4516
+ .ps-pmv-actions-right { flex-wrap: wrap; }
4517
+ }
4518
+
4259
4519
  /* Big product image */
4260
4520
  .ps-msd-image {
4261
4521
  width: 100%; height: 240px;
@@ -7361,6 +7621,35 @@ function CreateProfileWizard({ onSave, onCancel, t }) {
7361
7621
  const [weightVal, setWeightVal] = useState("");
7362
7622
  const [ageVal, setAgeVal] = useState("");
7363
7623
  const [error, setError] = useState("");
7624
+ const [photoBase64, setPhotoBase64] = useState(null);
7625
+ const [photoUploading, setPhotoUploading] = useState(false);
7626
+ const photoInputRef = useRef(null);
7627
+ const handlePhotoSelect = async (e) => {
7628
+ const file = e.target.files?.[0];
7629
+ if (!file) return;
7630
+ if (!file.type.startsWith("image/")) {
7631
+ setError(t("Please upload an image file"));
7632
+ return;
7633
+ }
7634
+ if (file.size > 10 * 1024 * 1024) {
7635
+ setError(t("Image must be under 10MB"));
7636
+ return;
7637
+ }
7638
+ setPhotoUploading(true);
7639
+ try {
7640
+ const base64 = await compressImage(file);
7641
+ setPhotoBase64(base64);
7642
+ setError("");
7643
+ } catch {
7644
+ setError(t("Failed to process image"));
7645
+ } finally {
7646
+ setPhotoUploading(false);
7647
+ }
7648
+ };
7649
+ const handleRemovePhoto = () => {
7650
+ setPhotoBase64(null);
7651
+ if (photoInputRef.current) photoInputRef.current.value = "";
7652
+ };
7364
7653
  const [chestProfile, setChestProfile] = useState(null);
7365
7654
  const [midsectionProfile, setMidsectionProfile] = useState(null);
7366
7655
  const [seatProfile, setSeatProfile] = useState(null);
@@ -7411,7 +7700,8 @@ function CreateProfileWizard({ onSave, onCancel, t }) {
7411
7700
  age: parseFloat(ageVal),
7412
7701
  chestProfile: chestProfile || void 0,
7413
7702
  midsectionProfile: midsectionProfile || void 0,
7414
- hipProfile: isWomen ? hipProfile || void 0 : seatProfile || void 0
7703
+ hipProfile: isWomen ? hipProfile || void 0 : seatProfile || void 0,
7704
+ photoBase64: photoBase64 || void 0
7415
7705
  };
7416
7706
  onSave(data);
7417
7707
  };
@@ -7483,7 +7773,7 @@ function CreateProfileWizard({ onSave, onCancel, t }) {
7483
7773
  inputMode: "numeric",
7484
7774
  className: "ps-cpw-input",
7485
7775
  value: heightVal,
7486
- placeholder: unit === "cm" ? "173" : "68",
7776
+ placeholder: unit === "cm" ? t("e.g. 173") : t("e.g. 68 in"),
7487
7777
  onChange: (e) => {
7488
7778
  setHeightVal(e.target.value);
7489
7779
  setError("");
@@ -7505,7 +7795,7 @@ function CreateProfileWizard({ onSave, onCancel, t }) {
7505
7795
  inputMode: "numeric",
7506
7796
  className: "ps-cpw-input",
7507
7797
  value: weightVal,
7508
- placeholder: unit === "in" ? "154" : "70",
7798
+ placeholder: unit === "in" ? t("e.g. 154") : t("e.g. 70"),
7509
7799
  onChange: (e) => {
7510
7800
  setWeightVal(e.target.value);
7511
7801
  setError("");
@@ -7527,7 +7817,7 @@ function CreateProfileWizard({ onSave, onCancel, t }) {
7527
7817
  inputMode: "numeric",
7528
7818
  className: "ps-cpw-input",
7529
7819
  value: ageVal,
7530
- placeholder: "30",
7820
+ placeholder: t("e.g. 30"),
7531
7821
  onChange: (e) => {
7532
7822
  setAgeVal(e.target.value);
7533
7823
  setError("");
@@ -7536,6 +7826,49 @@ function CreateProfileWizard({ onSave, onCancel, t }) {
7536
7826
  )
7537
7827
  ] })
7538
7828
  ] }),
7829
+ /* @__PURE__ */ jsxs("div", { className: "ps-cpw-photo", children: [
7830
+ /* @__PURE__ */ jsx("div", { className: "ps-cpw-field-label", children: t("PROFILE PHOTO (OPTIONAL)") }),
7831
+ /* @__PURE__ */ jsx(
7832
+ "input",
7833
+ {
7834
+ ref: photoInputRef,
7835
+ type: "file",
7836
+ accept: "image/*",
7837
+ onChange: handlePhotoSelect,
7838
+ style: { display: "none" }
7839
+ }
7840
+ ),
7841
+ photoBase64 ? /* @__PURE__ */ jsxs("div", { className: "ps-cpw-photo-preview", children: [
7842
+ /* @__PURE__ */ jsx("img", { src: photoBase64, alt: t("Profile photo") }),
7843
+ /* @__PURE__ */ jsx(
7844
+ "button",
7845
+ {
7846
+ type: "button",
7847
+ className: "ps-cpw-photo-remove",
7848
+ onClick: handleRemovePhoto,
7849
+ "aria-label": t("Remove photo"),
7850
+ children: "×"
7851
+ }
7852
+ )
7853
+ ] }) : /* @__PURE__ */ jsxs(
7854
+ "button",
7855
+ {
7856
+ type: "button",
7857
+ className: "ps-cpw-photo-upload",
7858
+ onClick: () => photoInputRef.current?.click(),
7859
+ disabled: photoUploading,
7860
+ children: [
7861
+ /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", width: "22", height: "22", children: [
7862
+ /* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
7863
+ /* @__PURE__ */ jsx("polyline", { points: "17 8 12 3 7 8" }),
7864
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
7865
+ ] }),
7866
+ /* @__PURE__ */ jsx("span", { className: "ps-cpw-photo-upload-title", children: photoUploading ? t("Uploading...") : t("Upload a photo") }),
7867
+ /* @__PURE__ */ jsx("span", { className: "ps-cpw-photo-upload-hint", children: t("Helps refine your AI sizing — JPEG, PNG up to 10MB") })
7868
+ ]
7869
+ }
7870
+ )
7871
+ ] }),
7539
7872
  error && /* @__PURE__ */ jsx("div", { className: "ps-cpw-error", children: error })
7540
7873
  ] }) : /* @__PURE__ */ jsxs("div", { className: "ps-cpw-silhouette", children: [
7541
7874
  !isWomen && /* @__PURE__ */ jsxs(
@@ -7593,6 +7926,117 @@ function CreateProfileWizard({ onSave, onCancel, t }) {
7593
7926
  ] })
7594
7927
  ] });
7595
7928
  }
7929
+ const FIELDS_MEN = [
7930
+ { key: "chest", label: "CHEST" },
7931
+ { key: "waist", label: "WAIST" },
7932
+ { key: "hips", label: "HIPS" },
7933
+ { key: "shoulderWidth", label: "SHOULDER" },
7934
+ { key: "sleeveLength", label: "SLEEVE" },
7935
+ { key: "neckCircumference", label: "NECK" },
7936
+ { key: "inseam", label: "INSEAM" },
7937
+ { key: "thighCircumference", label: "THIGH" }
7938
+ ];
7939
+ const FIELDS_WOMEN = [
7940
+ { key: "bust", label: "BUST" },
7941
+ { key: "waist", label: "WAIST" },
7942
+ { key: "hips", label: "HIPS" },
7943
+ { key: "shoulderWidth", label: "SHOULDER" },
7944
+ { key: "sleeveLength", label: "SLEEVE" },
7945
+ { key: "neckCircumference", label: "NECK" },
7946
+ { key: "inseam", label: "INSEAM" },
7947
+ { key: "thighCircumference", label: "THIGH" }
7948
+ ];
7949
+ function ProfileMeasurementsView({
7950
+ profile,
7951
+ isActive,
7952
+ onSelect,
7953
+ onEdit,
7954
+ onDelete,
7955
+ onBack,
7956
+ t
7957
+ }) {
7958
+ const fields = profile.gender === "female" ? FIELDS_WOMEN : FIELDS_MEN;
7959
+ const measurements = profile.measurements || {};
7960
+ const unit = profile.measurementsUnit || "cm";
7961
+ const hasMeasurements = Object.keys(measurements).some((k) => measurements[k] != null);
7962
+ const heightDisplay = (() => {
7963
+ const h = profile.height ?? profile.heightCm;
7964
+ if (!h) return "—";
7965
+ if (profile.heightUnit === "in" || profile.heightUnit === "ft") {
7966
+ const ft = Math.floor(h / 12);
7967
+ const inches = Math.round(h % 12);
7968
+ return `${ft}'${inches}"`;
7969
+ }
7970
+ return `${Math.round(h)} cm`;
7971
+ })();
7972
+ const weightDisplay = (() => {
7973
+ const w = profile.weight ?? profile.weightKg;
7974
+ if (!w) return "—";
7975
+ return `${Math.round(w)} ${profile.weightUnit || "kg"}`;
7976
+ })();
7977
+ const ageDisplay = profile.age ? `${profile.age}` : "—";
7978
+ return /* @__PURE__ */ jsxs("div", { className: "ps-pmv-root", children: [
7979
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-hero", children: [
7980
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-hero-avatar", children: profile.photoBase64 ? /* @__PURE__ */ jsx("img", { src: profile.photoBase64, alt: profile.name }) : /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", width: "32", height: "32", children: [
7981
+ /* @__PURE__ */ jsx("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }),
7982
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "7", r: "4" })
7983
+ ] }) }),
7984
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-hero-info", children: [
7985
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-hero-eyebrow", children: isActive ? t("ACTIVE PROFILE") : profile.gender === "female" ? t("WOMEN'S FIT") : t("MEN'S FIT") }),
7986
+ /* @__PURE__ */ jsx("h2", { className: "ps-pmv-hero-name", children: profile.name })
7987
+ ] })
7988
+ ] }),
7989
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-basics", children: [
7990
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-basic", children: [
7991
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-basic-label", children: t("HEIGHT") }),
7992
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-basic-value", children: heightDisplay })
7993
+ ] }),
7994
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-basic", children: [
7995
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-basic-label", children: t("WEIGHT") }),
7996
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-basic-value", children: weightDisplay })
7997
+ ] }),
7998
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-basic", children: [
7999
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-basic-label", children: t("AGE") }),
8000
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-basic-value", children: ageDisplay })
8001
+ ] })
8002
+ ] }),
8003
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-section", children: [
8004
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-section-head", children: [
8005
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-section-title", children: t("BODY MEASUREMENTS") }),
8006
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-section-sub", children: hasMeasurements ? t("Calculated from your basics. Used to recommend the perfect size for any product.") : t("Calculating your full body measurements...") })
8007
+ ] }),
8008
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-measure-grid", children: fields.map((f) => {
8009
+ const v = measurements[f.key];
8010
+ return /* @__PURE__ */ jsxs("div", { className: "ps-pmv-measure", children: [
8011
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-measure-label", children: t(f.label) }),
8012
+ /* @__PURE__ */ jsx("div", { className: `ps-pmv-measure-value${v == null ? " ps-loading" : ""}`, children: v != null ? `${Math.round(v * 10) / 10} ${unit}` : "—" })
8013
+ ] }, f.key);
8014
+ }) })
8015
+ ] }),
8016
+ profile.sizeHistory && profile.sizeHistory.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-pmv-section", children: [
8017
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-section-head", children: [
8018
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-section-title", children: t("SAVED SIZES") }),
8019
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-section-sub", children: t("Recommendations from this profile across products") })
8020
+ ] }),
8021
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-history", children: profile.sizeHistory.slice(0, 6).map((entry) => /* @__PURE__ */ jsxs("div", { className: "ps-pmv-history-card", children: [
8022
+ entry.productImage && /* @__PURE__ */ jsx("div", { className: "ps-pmv-history-thumb", children: /* @__PURE__ */ jsx("img", { src: entry.productImage, alt: entry.productTitle }) }),
8023
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-history-info", children: [
8024
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-history-name", children: entry.productTitle }),
8025
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-history-meta", children: new Date(entry.savedAt).toLocaleDateString(void 0, { month: "short", day: "numeric" }) })
8026
+ ] }),
8027
+ /* @__PURE__ */ jsx("div", { className: "ps-pmv-history-size", children: entry.recommendedSize })
8028
+ ] }, `${entry.productId}-${entry.savedAt}`)) })
8029
+ ] }),
8030
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-actions", children: [
8031
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-pmv-btn-secondary", onClick: onBack, children: t("Back") }),
8032
+ /* @__PURE__ */ jsxs("div", { className: "ps-pmv-actions-right", children: [
8033
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-pmv-btn-edit", onClick: onEdit, children: t("Edit") }),
8034
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-pmv-btn-delete", onClick: onDelete, children: t("Delete") }),
8035
+ !isActive && /* @__PURE__ */ jsx("button", { type: "button", className: "ps-pmv-btn-primary", onClick: onSelect, children: t("USE THIS PROFILE") })
8036
+ ] })
8037
+ ] })
8038
+ ] });
8039
+ }
7596
8040
  function ProfileAvatar({ gender }) {
7597
8041
  return /* @__PURE__ */ jsxs("div", { className: "ps-msp-avatar", children: [
7598
8042
  /* @__PURE__ */ jsx(UserIcon, { size: 28 }),
@@ -7604,6 +8048,7 @@ function ProfileCard({
7604
8048
  isActive,
7605
8049
  onSelect,
7606
8050
  onEdit,
8051
+ onOpenDetail,
7607
8052
  t
7608
8053
  }) {
7609
8054
  const heightDisplay = (() => {
@@ -7626,40 +8071,49 @@ function ProfileCard({
7626
8071
  if (!ts) return null;
7627
8072
  return new Date(ts).toLocaleDateString(void 0, { month: "short", day: "numeric" });
7628
8073
  })();
7629
- return /* @__PURE__ */ jsxs("div", { className: `ps-msp-card${isActive ? " ps-active" : ""}`, children: [
7630
- /* @__PURE__ */ jsx("div", { className: "ps-msp-card-header", children: /* @__PURE__ */ jsx("span", { className: "ps-msp-card-tag", children: isActive ? t("DEFAULT PROFILE") : profile.gender === "female" ? t("WOMEN'S FIT") : t("MEN'S FIT") }) }),
7631
- /* @__PURE__ */ jsx("div", { className: "ps-msp-card-thumb", children: /* @__PURE__ */ jsx(ProfileAvatar, { gender: profile.gender }) }),
7632
- /* @__PURE__ */ jsx("div", { className: "ps-msp-card-name", children: profile.name }),
7633
- /* @__PURE__ */ jsxs("div", { className: "ps-msp-card-meta", children: [
7634
- heightDisplay && /* @__PURE__ */ jsxs("div", { className: "ps-msp-meta-row", children: [
7635
- /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-label", children: t("HEIGHT") }),
7636
- /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-value", children: heightDisplay })
7637
- ] }),
7638
- weightDisplay && /* @__PURE__ */ jsxs("div", { className: "ps-msp-meta-row", children: [
7639
- /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-label", children: t("WEIGHT") }),
7640
- /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-value", children: weightDisplay })
7641
- ] }),
7642
- updatedDisplay && /* @__PURE__ */ jsxs("div", { className: "ps-msp-meta-row", children: [
7643
- /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-label", children: t("LAST UPDATE") }),
7644
- /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-value", children: updatedDisplay })
7645
- ] })
7646
- ] }),
7647
- /* @__PURE__ */ jsxs("div", { className: "ps-msp-card-actions", children: [
7648
- /* @__PURE__ */ jsx(
7649
- "button",
7650
- {
7651
- type: "button",
7652
- className: `ps-msp-card-select${isActive ? " ps-active" : ""}`,
7653
- onClick: onSelect,
7654
- children: isActive ? t("SELECTED") : t("SELECT")
7655
- }
7656
- ),
7657
- /* @__PURE__ */ jsx("button", { type: "button", className: "ps-msp-card-edit", onClick: onEdit, "aria-label": t("Edit"), children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", width: "14", height: "14", children: [
7658
- /* @__PURE__ */ jsx("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
7659
- /* @__PURE__ */ jsx("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
7660
- ] }) })
7661
- ] })
7662
- ] });
8074
+ return /* @__PURE__ */ jsxs(
8075
+ "div",
8076
+ {
8077
+ className: `ps-msp-card${isActive ? " ps-active" : ""}`,
8078
+ onClick: onOpenDetail,
8079
+ role: "button",
8080
+ tabIndex: 0,
8081
+ children: [
8082
+ /* @__PURE__ */ jsx("div", { className: "ps-msp-card-header", children: /* @__PURE__ */ jsx("span", { className: "ps-msp-card-tag", children: isActive ? t("DEFAULT PROFILE") : profile.gender === "female" ? t("WOMEN'S FIT") : t("MEN'S FIT") }) }),
8083
+ /* @__PURE__ */ jsx("div", { className: "ps-msp-card-thumb", children: profile.photoBase64 ? /* @__PURE__ */ jsx("img", { src: profile.photoBase64, alt: profile.name, className: "ps-msp-card-photo" }) : /* @__PURE__ */ jsx(ProfileAvatar, { gender: profile.gender }) }),
8084
+ /* @__PURE__ */ jsx("div", { className: "ps-msp-card-name", children: profile.name }),
8085
+ /* @__PURE__ */ jsxs("div", { className: "ps-msp-card-meta", children: [
8086
+ heightDisplay && /* @__PURE__ */ jsxs("div", { className: "ps-msp-meta-row", children: [
8087
+ /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-label", children: t("HEIGHT") }),
8088
+ /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-value", children: heightDisplay })
8089
+ ] }),
8090
+ weightDisplay && /* @__PURE__ */ jsxs("div", { className: "ps-msp-meta-row", children: [
8091
+ /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-label", children: t("WEIGHT") }),
8092
+ /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-value", children: weightDisplay })
8093
+ ] }),
8094
+ updatedDisplay && /* @__PURE__ */ jsxs("div", { className: "ps-msp-meta-row", children: [
8095
+ /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-label", children: t("LAST UPDATE") }),
8096
+ /* @__PURE__ */ jsx("span", { className: "ps-msp-meta-value", children: updatedDisplay })
8097
+ ] })
8098
+ ] }),
8099
+ /* @__PURE__ */ jsxs("div", { className: "ps-msp-card-actions", onClick: (e) => e.stopPropagation(), children: [
8100
+ /* @__PURE__ */ jsx(
8101
+ "button",
8102
+ {
8103
+ type: "button",
8104
+ className: `ps-msp-card-select${isActive ? " ps-active" : ""}`,
8105
+ onClick: onSelect,
8106
+ children: isActive ? t("SELECTED") : t("SELECT")
8107
+ }
8108
+ ),
8109
+ /* @__PURE__ */ jsx("button", { type: "button", className: "ps-msp-card-edit", onClick: onEdit, "aria-label": t("Edit"), children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", width: "14", height: "14", children: [
8110
+ /* @__PURE__ */ jsx("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
8111
+ /* @__PURE__ */ jsx("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
8112
+ ] }) })
8113
+ ] })
8114
+ ]
8115
+ }
8116
+ );
7663
8117
  }
7664
8118
  function CreateProfileCard({ onClick, t }) {
7665
8119
  return /* @__PURE__ */ jsxs("button", { type: "button", className: "ps-msp-card ps-msp-card-create", onClick, children: [
@@ -7701,6 +8155,8 @@ function MySizingProfilesView({
7701
8155
  t
7702
8156
  }) {
7703
8157
  const [creating, setCreating] = useState(false);
8158
+ const [viewingId, setViewingId] = useState(null);
8159
+ const viewingProfile = viewingId ? profiles.find((p) => p.id === viewingId) || null : null;
7704
8160
  const allHistory = useMemo(() => {
7705
8161
  const items = [];
7706
8162
  for (const p of profiles) {
@@ -7714,12 +8170,50 @@ function MySizingProfilesView({
7714
8170
  onSaveNewProfile(data);
7715
8171
  setCreating(false);
7716
8172
  };
7717
- return /* @__PURE__ */ jsx("div", { className: "ps-msp-root", children: /* @__PURE__ */ jsx("div", { className: "ps-msp-scroll", children: creating ? (
8173
+ return /* @__PURE__ */ jsx("div", { className: "ps-msp-root", children: /* @__PURE__ */ jsx("div", { className: "ps-msp-scroll", children: viewingProfile ? (
8174
+ /* ── Profile detail view (full body measurements) ── */
8175
+ /* @__PURE__ */ jsx(
8176
+ ProfileMeasurementsView,
8177
+ {
8178
+ profile: viewingProfile,
8179
+ isActive: viewingProfile.id === activeProfileId,
8180
+ onSelect: () => {
8181
+ onSelectProfile(viewingProfile.id);
8182
+ setViewingId(null);
8183
+ },
8184
+ onEdit: () => {
8185
+ onEditProfile(viewingProfile);
8186
+ },
8187
+ onDelete: () => {
8188
+ onDeleteProfile(viewingProfile.id);
8189
+ setViewingId(null);
8190
+ },
8191
+ onBack: () => setViewingId(null),
8192
+ t
8193
+ }
8194
+ )
8195
+ ) : creating ? (
7718
8196
  /* ── Multi-step create wizard (Identity → Silhouette) ── */
7719
8197
  /* @__PURE__ */ jsx(
7720
8198
  CreateProfileWizard,
7721
8199
  {
7722
- onSave: handleSaveNewProfile,
8200
+ onSave: (data) => {
8201
+ handleSaveNewProfile(data);
8202
+ setTimeout(() => {
8203
+ const latest = typeof window !== "undefined" ? (() => {
8204
+ try {
8205
+ const raw = localStorage.getItem("primestyle_profiles");
8206
+ if (raw) {
8207
+ const list = JSON.parse(raw);
8208
+ if (list.length > 0) return list[0].id;
8209
+ }
8210
+ } catch {
8211
+ }
8212
+ return null;
8213
+ })() : null;
8214
+ if (latest) setViewingId(latest);
8215
+ }, 50);
8216
+ },
7723
8217
  onCancel: () => setCreating(false),
7724
8218
  t
7725
8219
  }
@@ -7738,6 +8232,7 @@ function MySizingProfilesView({
7738
8232
  isActive: p.id === activeProfileId,
7739
8233
  onSelect: () => onSelectProfile(p.id),
7740
8234
  onEdit: () => onEditProfile(p),
8235
+ onOpenDetail: () => setViewingId(p.id),
7741
8236
  t
7742
8237
  },
7743
8238
  p.id
@@ -10031,7 +10526,9 @@ function PrimeStyleTryonInner({
10031
10526
  createdAt: Date.now(),
10032
10527
  lastUsedAt: Date.now()
10033
10528
  };
10034
- setProfiles((prev) => [newProfile, ...prev]);
10529
+ const nextProfiles = [newProfile, ...profiles];
10530
+ lsSet("profiles", nextProfiles);
10531
+ setProfiles(nextProfiles);
10035
10532
  setActiveProfileId$1(newProfile.id);
10036
10533
  const heightVal = newProfile.heightCm || newProfile.height || 0;
10037
10534
  const weightVal = newProfile.weightKg || newProfile.weight || 0;
@@ -10045,7 +10542,11 @@ function PrimeStyleTryonInner({
10045
10542
  heightUnit: heightUnitVal,
10046
10543
  weightUnit: weightUnitVal,
10047
10544
  gender: newProfile.gender,
10048
- age: newProfile.age
10545
+ age: newProfile.age,
10546
+ chestProfile: newProfile.chestProfile,
10547
+ midsectionProfile: newProfile.midsectionProfile,
10548
+ hipProfile: newProfile.hipProfile,
10549
+ bodyImage: newProfile.photoBase64
10049
10550
  }).then((est) => {
10050
10551
  if (est) {
10051
10552
  updateProfileMeasurements(newProfile.id, est.estimates, est.unit);
@@ -10080,7 +10581,7 @@ function PrimeStyleTryonInner({
10080
10581
  /* @__PURE__ */ jsx("span", { children: resolvedButtonText })
10081
10582
  ] }),
10082
10583
  view !== "idle" && typeof document !== "undefined" && createPortal(
10083
- /* @__PURE__ */ jsx("div", { className: cx("ps-tryon-overlay", cn.overlay), style: cssVars, "data-ps-tryon-portal": true, children: /* @__PURE__ */ jsxs("div", { className: cx(`ps-tryon-modal${view === "result" && resultImageUrl && sizingResult || view === "size-result" || view === "estimation-review" || view === "body-profile" || view === "profiles" ? " ps-tryon-modal-wide" : ""}`, cn.modal), onClick: (e) => e.stopPropagation(), children: [
10584
+ /* @__PURE__ */ jsx("div", { className: cx("ps-tryon-overlay", cn.overlay), style: cssVars, "data-ps-tryon-portal": true, children: /* @__PURE__ */ jsxs("div", { className: cx(`ps-tryon-modal${view === "result" && resultImageUrl && sizingResult || view === "size-result" || view === "estimation-review" || view === "body-profile" || view === "profiles" ? " ps-tryon-modal-wide" : ""}${view === "profiles" ? " ps-tryon-modal-tall" : ""}`, cn.modal), onClick: (e) => e.stopPropagation(), children: [
10084
10585
  /* @__PURE__ */ jsxs("div", { className: cx("ps-tryon-header ps-tryon-header-minimal", cn.header), children: [
10085
10586
  /* @__PURE__ */ jsx(LangSwitcher, { activeLocale, onSelect: setActiveLocale }),
10086
10587
  /* @__PURE__ */ jsx("button", { className: "ps-tryon-header-icon", title: t("Profiles"), onClick: () => setView(view === "profiles" ? "body-profile" : "profiles"), children: /* @__PURE__ */ jsx(UserIcon, {}) }),