@syntrologie/adapt-product 2.49.1 → 2.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn.js +1 -1
- package/dist/{chunk-LFYTHTQS.js → chunk-F6ZXHGAT.js} +176 -17
- package/dist/chunk-F6ZXHGAT.js.map +7 -0
- package/dist/runtime.js +1 -1
- package/dist/widgets/PdpOtherProductsCarouselLit.d.ts +3 -0
- package/dist/widgets/PdpOtherProductsCarouselLit.d.ts.map +1 -1
- package/dist/widgets/PdpOtherProductsGridLit.d.ts +3 -0
- package/dist/widgets/PdpOtherProductsGridLit.d.ts.map +1 -1
- package/dist/widgets/ProductCardLit.d.ts.map +1 -1
- package/dist/widgets/SyntroPdpLit.d.ts +3 -0
- package/dist/widgets/SyntroPdpLit.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-LFYTHTQS.js.map +0 -7
package/dist/cdn.js
CHANGED
|
@@ -342,6 +342,110 @@ var NotifyZ = z.object({
|
|
|
342
342
|
icon: z.string().optional().describe("Notification icon (emoji or URL)")
|
|
343
343
|
}).describe("Optional toast notification shown when this action triggers.").nullable().optional();
|
|
344
344
|
|
|
345
|
+
// ../../sdk-contracts/dist/viewport.js
|
|
346
|
+
var VIEWPORT_CLASS_ATTR = "data-viewport";
|
|
347
|
+
var DESKTOP_MIN_WIDTH_PX = 720;
|
|
348
|
+
function isCoarsePointer() {
|
|
349
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function")
|
|
350
|
+
return true;
|
|
351
|
+
return window.matchMedia("(pointer: coarse)").matches;
|
|
352
|
+
}
|
|
353
|
+
function classifyPointer() {
|
|
354
|
+
return isCoarsePointer() ? "coarse" : "fine";
|
|
355
|
+
}
|
|
356
|
+
function hasAnyFinePointer() {
|
|
357
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function")
|
|
358
|
+
return true;
|
|
359
|
+
return window.matchMedia("(any-pointer: fine)").matches;
|
|
360
|
+
}
|
|
361
|
+
function observePointer(cb) {
|
|
362
|
+
const read = () => ({ primary: classifyPointer(), anyFine: hasAnyFinePointer() });
|
|
363
|
+
let current = read();
|
|
364
|
+
cb(current);
|
|
365
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function")
|
|
366
|
+
return () => {
|
|
367
|
+
};
|
|
368
|
+
const coarse = window.matchMedia("(pointer: coarse)");
|
|
369
|
+
const anyFine = window.matchMedia("(any-pointer: fine)");
|
|
370
|
+
const onChange = () => {
|
|
371
|
+
const next = read();
|
|
372
|
+
if (next.primary !== current.primary || next.anyFine !== current.anyFine) {
|
|
373
|
+
current = next;
|
|
374
|
+
cb(next);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
const sub = (mq) => {
|
|
378
|
+
if (mq.addEventListener)
|
|
379
|
+
mq.addEventListener("change", onChange);
|
|
380
|
+
else
|
|
381
|
+
mq.addListener?.(onChange);
|
|
382
|
+
};
|
|
383
|
+
const unsub = (mq) => {
|
|
384
|
+
if (mq.removeEventListener)
|
|
385
|
+
mq.removeEventListener("change", onChange);
|
|
386
|
+
else
|
|
387
|
+
mq.removeListener?.(onChange);
|
|
388
|
+
};
|
|
389
|
+
sub(coarse);
|
|
390
|
+
sub(anyFine);
|
|
391
|
+
return () => {
|
|
392
|
+
unsub(coarse);
|
|
393
|
+
unsub(anyFine);
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
var POINTER_CLASS_ATTR = "data-pointer";
|
|
397
|
+
function classifyViewport() {
|
|
398
|
+
if (typeof window === "undefined")
|
|
399
|
+
return "mobile";
|
|
400
|
+
return window.innerWidth >= DESKTOP_MIN_WIDTH_PX ? "desktop" : "mobile";
|
|
401
|
+
}
|
|
402
|
+
function observeViewportClass(cb) {
|
|
403
|
+
let current = classifyViewport();
|
|
404
|
+
cb(current);
|
|
405
|
+
if (typeof window === "undefined")
|
|
406
|
+
return () => {
|
|
407
|
+
};
|
|
408
|
+
const onResize = () => {
|
|
409
|
+
const next = classifyViewport();
|
|
410
|
+
if (next !== current) {
|
|
411
|
+
current = next;
|
|
412
|
+
cb(next);
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
window.addEventListener("resize", onResize, { passive: true });
|
|
416
|
+
return () => window.removeEventListener("resize", onResize);
|
|
417
|
+
}
|
|
418
|
+
var ViewportClassController = class {
|
|
419
|
+
constructor(host) {
|
|
420
|
+
this.value = classifyViewport();
|
|
421
|
+
this.pointer = classifyPointer();
|
|
422
|
+
this.anyFinePointer = hasAnyFinePointer();
|
|
423
|
+
this._unsubscribes = [];
|
|
424
|
+
this._host = host;
|
|
425
|
+
host.addController(this);
|
|
426
|
+
}
|
|
427
|
+
hostConnected() {
|
|
428
|
+
this._unsubscribes = [
|
|
429
|
+
observeViewportClass((c2) => {
|
|
430
|
+
this.value = c2;
|
|
431
|
+
this._host.setAttribute(VIEWPORT_CLASS_ATTR, c2);
|
|
432
|
+
this._host.requestUpdate();
|
|
433
|
+
}),
|
|
434
|
+
observePointer(({ primary, anyFine }) => {
|
|
435
|
+
this.pointer = primary;
|
|
436
|
+
this.anyFinePointer = anyFine;
|
|
437
|
+
this._host.setAttribute(POINTER_CLASS_ATTR, primary);
|
|
438
|
+
this._host.requestUpdate();
|
|
439
|
+
})
|
|
440
|
+
];
|
|
441
|
+
}
|
|
442
|
+
hostDisconnected() {
|
|
443
|
+
for (const off of this._unsubscribes)
|
|
444
|
+
off();
|
|
445
|
+
this._unsubscribes = [];
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
|
|
345
449
|
// src/presets-store.ts
|
|
346
450
|
function presetsWindow() {
|
|
347
451
|
if (typeof window === "undefined") return void 0;
|
|
@@ -1903,16 +2007,22 @@ syntro-pdp-other-products-carousel {
|
|
|
1903
2007
|
box-sizing: border-box;
|
|
1904
2008
|
}
|
|
1905
2009
|
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
2010
|
+
/* viewport-scoped (was a width media query): classification is central
|
|
2011
|
+
(sdk-contracts classifyViewport()); the host tag carries data-viewport. */
|
|
2012
|
+
syntro-pdp-other-products-carousel[data-viewport="mobile"] .opc-item {
|
|
2013
|
+
flex: 0 0 80%;
|
|
1910
2014
|
}
|
|
1911
2015
|
`;
|
|
1912
2016
|
var PdpOtherProductsCarouselLit = class extends LitElement4 {
|
|
1913
2017
|
constructor() {
|
|
1914
2018
|
super(...arguments);
|
|
1915
2019
|
this.data = null;
|
|
2020
|
+
/** Stamps data-viewport on this tag (central classification,
|
|
2021
|
+
* sdk-contracts) — the viewport-scoped CSS keys off it. */
|
|
2022
|
+
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: the
|
|
2023
|
+
// constructor registers the controller (stamps data-viewport); the
|
|
2024
|
+
// field exists to own its lifetime, not to be read.
|
|
2025
|
+
this._viewport = new ViewportClassController(this);
|
|
1916
2026
|
}
|
|
1917
2027
|
createRenderRoot() {
|
|
1918
2028
|
return this;
|
|
@@ -1969,16 +2079,22 @@ syntro-pdp-other-products-grid {
|
|
|
1969
2079
|
gap: 0.75rem;
|
|
1970
2080
|
}
|
|
1971
2081
|
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
2082
|
+
/* viewport-scoped (was a width media query): classification is central
|
|
2083
|
+
(sdk-contracts classifyViewport()); the host tag carries data-viewport. */
|
|
2084
|
+
syntro-pdp-other-products-grid[data-viewport="mobile"] .grid {
|
|
2085
|
+
grid-template-columns: 1fr;
|
|
1976
2086
|
}
|
|
1977
2087
|
`;
|
|
1978
2088
|
var PdpOtherProductsGridLit = class extends LitElement5 {
|
|
1979
2089
|
constructor() {
|
|
1980
2090
|
super(...arguments);
|
|
1981
2091
|
this.data = null;
|
|
2092
|
+
/** Stamps data-viewport on this tag (central classification,
|
|
2093
|
+
* sdk-contracts) — the viewport-scoped CSS keys off it. */
|
|
2094
|
+
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: the
|
|
2095
|
+
// constructor registers the controller (stamps data-viewport); the
|
|
2096
|
+
// field exists to own its lifetime, not to be read.
|
|
2097
|
+
this._viewport = new ViewportClassController(this);
|
|
1982
2098
|
}
|
|
1983
2099
|
createRenderRoot() {
|
|
1984
2100
|
return this;
|
|
@@ -2443,8 +2559,10 @@ var SECTION_LAYOUT_CSS = `
|
|
|
2443
2559
|
the full-bleed band (a grid can't be both full-width AND content-centered)
|
|
2444
2560
|
for the side-by-side reading rhythm; the section reads as a deliberate
|
|
2445
2561
|
magazine block on the base background. Mobile keeps the stacked layout. */
|
|
2446
|
-
|
|
2447
|
-
|
|
2562
|
+
/* viewport-scoped (was a width media query): classification is central
|
|
2563
|
+
(sdk-contracts classifyViewport()); the syntro-pdp tag carries
|
|
2564
|
+
data-viewport, stamped by ViewportClassController. */
|
|
2565
|
+
syntro-pdp[data-viewport="desktop"] [data-syntro-pdp-section][data-slot='pdp-slot-trending-news'] {
|
|
2448
2566
|
background: transparent;
|
|
2449
2567
|
display: grid;
|
|
2450
2568
|
grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.6fr);
|
|
@@ -2456,26 +2574,26 @@ var SECTION_LAYOUT_CSS = `
|
|
|
2456
2574
|
}
|
|
2457
2575
|
/* Title column: header left-aligned (not the full-band centered eyebrow),
|
|
2458
2576
|
and gently sticky so it holds while the stories scroll past. */
|
|
2459
|
-
[data-syntro-pdp-section][data-slot='pdp-slot-trending-news'] > syntro-pdp-section-header {
|
|
2577
|
+
syntro-pdp[data-viewport="desktop"] [data-syntro-pdp-section][data-slot='pdp-slot-trending-news'] > syntro-pdp-section-header {
|
|
2460
2578
|
position: sticky;
|
|
2461
2579
|
top: clamp(24px, 8vh, 72px);
|
|
2462
2580
|
}
|
|
2463
|
-
[data-syntro-pdp-section][data-slot='pdp-slot-trending-news'] .syntro-pdp-section-eyebrow {
|
|
2581
|
+
syntro-pdp[data-viewport="desktop"] [data-syntro-pdp-section][data-slot='pdp-slot-trending-news'] .syntro-pdp-section-eyebrow {
|
|
2464
2582
|
justify-content: flex-start;
|
|
2465
2583
|
}
|
|
2466
|
-
[data-syntro-pdp-section][data-slot='pdp-slot-trending-news'] .syntro-pdp-section-headline {
|
|
2584
|
+
syntro-pdp[data-viewport="desktop"] [data-syntro-pdp-section][data-slot='pdp-slot-trending-news'] .syntro-pdp-section-headline {
|
|
2467
2585
|
max-width: none;
|
|
2468
2586
|
margin-inline: 0;
|
|
2469
2587
|
padding-inline: 0;
|
|
2470
2588
|
}
|
|
2471
2589
|
/* Stories column: the body fills the wider right column (drop the centered
|
|
2472
2590
|
inner constraint + the header-gap top margin \u2014 the grid gap spaces it). */
|
|
2473
|
-
[data-syntro-pdp-section][data-slot='pdp-slot-trending-news'] > [data-syntro-pdp-section-inner] {
|
|
2591
|
+
syntro-pdp[data-viewport="desktop"] [data-syntro-pdp-section][data-slot='pdp-slot-trending-news'] > [data-syntro-pdp-section-inner] {
|
|
2474
2592
|
max-width: none;
|
|
2475
2593
|
margin: 0;
|
|
2476
2594
|
padding: 0;
|
|
2477
2595
|
}
|
|
2478
|
-
|
|
2596
|
+
|
|
2479
2597
|
`;
|
|
2480
2598
|
var CHAT_EXCERPT_KEY = "syntro.chat.lastExcerpt";
|
|
2481
2599
|
var CHAT_EXCERPT_MAX = 7500;
|
|
@@ -2662,6 +2780,12 @@ var _SyntroPdpLit = class _SyntroPdpLit extends LitElement6 {
|
|
|
2662
2780
|
const open = e2.target.open;
|
|
2663
2781
|
this._dispatchDecision({ type: "dossier-toggled", open });
|
|
2664
2782
|
};
|
|
2783
|
+
/** Stamps data-viewport on this tag (central classification,
|
|
2784
|
+
* sdk-contracts) — the viewport-scoped CSS keys off it. */
|
|
2785
|
+
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: the
|
|
2786
|
+
// constructor registers the controller (stamps data-viewport); the
|
|
2787
|
+
// field exists to own its lifetime, not to be read.
|
|
2788
|
+
this._viewport = new ViewportClassController(this);
|
|
2665
2789
|
}
|
|
2666
2790
|
/**
|
|
2667
2791
|
* Widget props (the `adaptive-product:pdp` mountable sets `el.props` before
|
|
@@ -5855,6 +5979,26 @@ function _readDevice() {
|
|
|
5855
5979
|
}
|
|
5856
5980
|
var SPEC_CHIP_FADE_MASK = "linear-gradient(90deg, black 0, black calc(100% - 18px), transparent 100%)";
|
|
5857
5981
|
var CARD_FLIP_CSS = `
|
|
5982
|
+
/* \u2500\u2500 Height-bounded container opt-in (velvet deck band) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
5983
|
+
The canvas that owns a DEFINITE-height mount opts the card into filling
|
|
5984
|
+
it by setting --sc-card-host-height: 100% (velvet: .deck-card tokens).
|
|
5985
|
+
The chain below then hands that definite height to the front-face grid,
|
|
5986
|
+
whose 1fr/auto rows resolve inside it and whose image box (max-height:
|
|
5987
|
+
100% on .sc-product-card__media) crops to what remains. Everywhere the
|
|
5988
|
+
token is unset the host is auto-height and every percentage in the
|
|
5989
|
+
chain is inert \u2014 chat/PDP stacked cards are untouched.
|
|
5990
|
+
Regression this exists for: #3591 shaved the solo-deck band 24px and
|
|
5991
|
+
the fixed 132\xD7176 image box pushed the CTA/link row past the card
|
|
5992
|
+
bottom (live on iglowmedspa.com 2026-09-03; pinned by
|
|
5993
|
+
test-server/tests/velvet-deck-product-card-fit.spec.ts). */
|
|
5994
|
+
syntro-product-card {
|
|
5995
|
+
height: var(--sc-card-host-height, auto);
|
|
5996
|
+
min-height: 0;
|
|
5997
|
+
}
|
|
5998
|
+
.sc-product-card { height: 100%; min-height: 0; }
|
|
5999
|
+
.sc-product-card > [data-face] { height: 100%; min-height: 0; }
|
|
6000
|
+
.sc-product-card [data-product-card-grid] { height: 100%; min-height: 0; }
|
|
6001
|
+
|
|
5858
6002
|
/* Hide the scrollbar chrome on the declared, scrollable spec-chip tracks
|
|
5859
6003
|
(data-clip-ok scroll containers) while keeping them scrollable. The inline
|
|
5860
6004
|
styles set scrollbar-width:none (Firefox); WebKit needs this pseudo. */
|
|
@@ -6365,6 +6509,16 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
|
|
|
6365
6509
|
height: "var(--sc-card-image-h, auto)",
|
|
6366
6510
|
// 132 × (4/3) = 176 → the spec's 132×176 portrait. Velvet's token wins.
|
|
6367
6511
|
aspectRatio: "var(--sc-card-image-aspect, 3 / 4)",
|
|
6512
|
+
// The aspect box is a PREFERENCE, never a floor: in a definite-height
|
|
6513
|
+
// container (velvet's deck band) the box caps at the area's height and
|
|
6514
|
+
// the photo object-fit:covers into whatever remains, so the card always
|
|
6515
|
+
// fits the band. In auto-height contexts (chat/PDP stacked layout)
|
|
6516
|
+
// 100% resolves against auto → no-op, the 3/4 box stands unchanged.
|
|
6517
|
+
// Regression this guards: #3591 shaved the solo-deck band 24px and the
|
|
6518
|
+
// fixed 176px box pushed the CTA/link row past the card bottom
|
|
6519
|
+
// (velvet-deck-product-card-fit.spec.ts).
|
|
6520
|
+
maxHeight: "100%",
|
|
6521
|
+
overflow: "hidden",
|
|
6368
6522
|
alignSelf: "var(--sc-card-image-align, start)",
|
|
6369
6523
|
minWidth: "0",
|
|
6370
6524
|
minHeight: "0"
|
|
@@ -6534,7 +6688,12 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
|
|
|
6534
6688
|
justifyContent: "space-between",
|
|
6535
6689
|
gap: "var(--sc-card-cta-gap, 0.5rem)",
|
|
6536
6690
|
marginTop: "0",
|
|
6537
|
-
minWidth: "0"
|
|
6691
|
+
minWidth: "0",
|
|
6692
|
+
// Lift the CTA pair off the card's bottom edge where a canvas overlays
|
|
6693
|
+
// chrome there (velvet's deck pager circles half-lap that edge — the
|
|
6694
|
+
// "Product Page" link sat right under them on crushed cards). The
|
|
6695
|
+
// canvas sets the token; default 0 keeps every other surface as-is.
|
|
6696
|
+
paddingBottom: "var(--sc-card-cta-padding-bottom, 0)"
|
|
6538
6697
|
};
|
|
6539
6698
|
const primaryCtaStyles = {
|
|
6540
6699
|
display: "inline-flex",
|
|
@@ -11977,4 +12136,4 @@ export {
|
|
|
11977
12136
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
11978
12137
|
*)
|
|
11979
12138
|
*/
|
|
11980
|
-
//# sourceMappingURL=chunk-
|
|
12139
|
+
//# sourceMappingURL=chunk-F6ZXHGAT.js.map
|