@syntrologie/adapt-product 2.47.0 → 2.49.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.
@@ -11,7 +11,7 @@ import {
11
11
  heroSchema,
12
12
  recoSchema,
13
13
  takeoverPlanSchema
14
- } from "./chunk-Y2QAYCSK.js";
14
+ } from "./chunk-D2W6UYLT.js";
15
15
 
16
16
  // ../../../node_modules/@lit/context/lib/create-context.js
17
17
  function n(n2) {
@@ -4101,7 +4101,7 @@ function startNativeSlotWatcher() {
4101
4101
  }
4102
4102
 
4103
4103
  // src/widgets/ProductCardLit.ts
4104
- import { html as html8, LitElement as LitElement8, nothing as nothing4 } from "lit";
4104
+ import { html as html9, LitElement as LitElement8, nothing as nothing4 } from "lit";
4105
4105
  import { styleMap } from "lit/directives/style-map.js";
4106
4106
 
4107
4107
  // src/bind/dom-selector.ts
@@ -4355,7 +4355,7 @@ var BindController = class {
4355
4355
  }
4356
4356
  start() {
4357
4357
  for (const product of this.products) {
4358
- if (product.image.bind) {
4358
+ if (product.image?.bind) {
4359
4359
  __privateGet(this, _pending).push(__privateMethod(this, _BindController_instances, resolveImage_fn).call(this, product.id, product.image.bind));
4360
4360
  }
4361
4361
  if (product.price?.bind) {
@@ -4937,12 +4937,12 @@ function isDangerousUrlAttr(name, value) {
4937
4937
  const normalized = normalizeUrlAttr(value);
4938
4938
  return normalized.startsWith("javascript:") || normalized.startsWith("vbscript:") || normalized.startsWith("data:");
4939
4939
  }
4940
- function sanitizeHtml(html30) {
4940
+ function sanitizeHtml(html31) {
4941
4941
  const hasNative = typeof window.Sanitizer === "function";
4942
4942
  if (hasNative) {
4943
4943
  try {
4944
4944
  const s4 = new window.Sanitizer({});
4945
- const frag = s4.sanitizeToFragment(html30);
4945
+ const frag = s4.sanitizeToFragment(html31);
4946
4946
  const div = document.createElement("div");
4947
4947
  div.append(frag);
4948
4948
  return div.innerHTML;
@@ -4950,7 +4950,7 @@ function sanitizeHtml(html30) {
4950
4950
  }
4951
4951
  }
4952
4952
  const tpl = document.createElement("template");
4953
- tpl.innerHTML = html30;
4953
+ tpl.innerHTML = html31;
4954
4954
  const root = tpl.content;
4955
4955
  const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null);
4956
4956
  const toRemove = [];
@@ -4990,6 +4990,18 @@ function ensureStylesInRoot(el, id, css) {
4990
4990
  target.appendChild(style);
4991
4991
  }
4992
4992
 
4993
+ // src/widgets/imageStandin.ts
4994
+ import { html as html7 } from "lit";
4995
+ var IMAGE_STANDIN_BACKGROUND = "linear-gradient(135deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.02) 45%, rgba(0, 0, 0, 0.22)), var(--sc-color-primary, #3a3a3a)";
4996
+ function standinMonogram(name) {
4997
+ const initial = ([...name.trim()][0] ?? "?").toUpperCase();
4998
+ return html7`<span
4999
+ data-standin-monogram
5000
+ style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font:700 2.4rem/1 var(--sc-font-family, inherit);color:var(--sc-launcher-color, #ffffff);opacity:0.85;letter-spacing:0.02em;user-select:none;"
5001
+ >${initial}</span
5002
+ >`;
5003
+ }
5004
+
4993
5005
  // src/widgets/renderHealth.ts
4994
5006
  var BLANK_MIN_AREA = 60 * 60;
4995
5007
  function elementPath(el, stopAt) {
@@ -5178,7 +5190,7 @@ cancel_fn = function() {
5178
5190
  };
5179
5191
 
5180
5192
  // src/widgets/VariantPanelLit.ts
5181
- import { html as html7, LitElement as LitElement7, nothing as nothing3 } from "lit";
5193
+ import { html as html8, LitElement as LitElement7, nothing as nothing3 } from "lit";
5182
5194
  var PANEL_CSS = `
5183
5195
  syntro-variant-panel {
5184
5196
  display: grid;
@@ -5522,17 +5534,17 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5522
5534
  }
5523
5535
  render() {
5524
5536
  if (this.state === "error") {
5525
- return html7`
5537
+ return html8`
5526
5538
  <div class="svp-error-block" data-error-block>
5527
5539
  <div>${this.error ?? "Couldn't load options."}</div>
5528
- ${this.retryable ? html7`<button class="svp-retry-btn" data-retry-button @click=${this._onRetry}>
5540
+ ${this.retryable ? html8`<button class="svp-retry-btn" data-retry-button @click=${this._onRetry}>
5529
5541
  Try again
5530
5542
  </button>` : nothing3}
5531
5543
  </div>
5532
5544
  `;
5533
5545
  }
5534
5546
  if (this.state === "loading" || !this.payload) {
5535
- return html7`
5547
+ return html8`
5536
5548
  <div data-loading-skeleton>
5537
5549
  <div class="svp-skeleton"></div>
5538
5550
  <div class="svp-skeleton"></div>
@@ -5545,15 +5557,15 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5545
5557
  const compareAt = matching?.compare_at_price ?? null;
5546
5558
  const singleVariant = this.payload.attributes.length === 0;
5547
5559
  const heroSrc = this._heroSrc();
5548
- const backBtn = html7`<button
5560
+ const backBtn = html8`<button
5549
5561
  class="svp-back-btn"
5550
5562
  data-back-button
5551
5563
  @click=${this._onBack}
5552
5564
  aria-label="Back"
5553
5565
  >‹ Back</button>`;
5554
- return html7`
5566
+ return html8`
5555
5567
  <div class="svp-image-col" data-image-col>
5556
- ${heroSrc ? html7`<img
5568
+ ${heroSrc ? html8`<img
5557
5569
  class="svp-image"
5558
5570
  data-variant-image
5559
5571
  src=${heroSrc}
@@ -5562,9 +5574,9 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5562
5574
  />` : nothing3}
5563
5575
  </div>
5564
5576
  <div class="svp-body" data-panel-body>
5565
- ${this.productTitle ? html7`<div class="svp-product-title" data-product-title data-critical-text>${this.productTitle}</div>` : nothing3}
5577
+ ${this.productTitle ? html8`<div class="svp-product-title" data-product-title data-critical-text>${this.productTitle}</div>` : nothing3}
5566
5578
  <div class="svp-attributes-scroll" data-attributes-scroll data-clip-ok>
5567
- ${singleVariant ? html7`<div class="svp-single-variant-note" data-single-variant-note>
5579
+ ${singleVariant ? html8`<div class="svp-single-variant-note" data-single-variant-note>
5568
5580
  Just one option — ready to add.
5569
5581
  </div>` : this.payload.attributes.map((attr) => this._renderAttributeRow(attr))}
5570
5582
  </div>
@@ -5579,7 +5591,7 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5579
5591
  ${// Short label: "Add · $64" (the price commits HERE — the card's
5580
5592
  // front face carries no price; round-3 feedback shortened this
5581
5593
  // so Back fits beside it on the same row).
5582
- ctaPrice != null ? html7`Add ${compareAt ? html7`<span class="svp-compare">$${compareAt.toFixed(2)}</span>` : nothing3}· $${ctaPrice.toFixed(2)}` : html7`Add to cart`}
5594
+ ctaPrice != null ? html8`Add ${compareAt ? html8`<span class="svp-compare">$${compareAt.toFixed(2)}</span>` : nothing3}· $${ctaPrice.toFixed(2)}` : html8`Add to cart`}
5583
5595
  </button>
5584
5596
  ${backBtn}
5585
5597
  </div>
@@ -5591,11 +5603,11 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5591
5603
  }
5592
5604
  _renderAttributeRow(attr) {
5593
5605
  const oosVisible = this._hasAnyOOSForAttribute(attr);
5594
- return html7`
5606
+ return html8`
5595
5607
  <div class="svp-attribute-row" data-attribute-row data-attribute-key=${attr.key}>
5596
5608
  <div class="svp-attribute-label" data-attribute-label id=${`attrlabel-${attr.key}`}>${attr.label}</div>
5597
5609
  ${attr.values.length >= _VariantPanelLit.COLLAPSE_MIN_OPTIONS ? this._renderCollapsedAxis(attr) : attr.kind === "swatch" ? this._renderSwatchRow(attr) : this._renderPillRow(attr)}
5598
- ${oosVisible ? html7`<div class="svp-oos-microcopy" data-out-of-stock-microcopy>Out of stock for one or more options</div>` : nothing3}
5610
+ ${oosVisible ? html8`<div class="svp-oos-microcopy" data-out-of-stock-microcopy>Out of stock for one or more options</div>` : nothing3}
5599
5611
  </div>
5600
5612
  `;
5601
5613
  }
@@ -5604,12 +5616,12 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5604
5616
  }
5605
5617
  _renderPillRow(attr) {
5606
5618
  const segmented = attr.values.length <= _VariantPanelLit.SEGMENTED_MAX_OPTIONS;
5607
- return html7`
5619
+ return html8`
5608
5620
  <div class="svp-pill-row" data-segmented=${segmented ? "" : nothing3} data-scroll=${this._isScrollTier(attr) ? "" : nothing3} role="radiogroup" aria-labelledby=${`attrlabel-${attr.key}`}>
5609
5621
  ${attr.values.map((v) => {
5610
5622
  const disabled2 = this._isValueDisabled(attr.key, v.id);
5611
5623
  const checked = this._selection[attr.key] === v.id;
5612
- return html7`<button
5624
+ return html8`<button
5613
5625
  class="svp-pill"
5614
5626
  data-pill
5615
5627
  data-attribute-key=${attr.key}
@@ -5627,14 +5639,14 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5627
5639
  _renderSwatchRow(attr) {
5628
5640
  const selectedValueId = this._selection[attr.key];
5629
5641
  const selectedLabel = attr.values.find((v) => v.id === selectedValueId)?.label ?? "";
5630
- return html7`
5642
+ return html8`
5631
5643
  <div class="svp-swatch-label">${selectedLabel}</div>
5632
5644
  <div class="svp-swatch-row" data-scroll=${this._isScrollTier(attr) ? "" : nothing3} role="radiogroup" aria-labelledby=${`attrlabel-${attr.key}`}>
5633
5645
  ${attr.values.map((v) => {
5634
5646
  const disabled2 = this._isValueDisabled(attr.key, v.id);
5635
5647
  const checked = this._selection[attr.key] === v.id;
5636
5648
  const color = v.swatch?.kind === "color" ? v.swatch.value : "transparent";
5637
- return html7`<button
5649
+ return html8`<button
5638
5650
  class="svp-swatch-pill"
5639
5651
  data-pill
5640
5652
  data-swatch-dot
@@ -5688,8 +5700,8 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5688
5700
  const filter = (this._axisFilter[attr.key] ?? "").trim().toLowerCase();
5689
5701
  const filtered = filter ? attr.values.filter((v) => v.label.toLowerCase().includes(filter)) : attr.values;
5690
5702
  const showFilter = attr.values.length >= _VariantPanelLit.FILTER_MIN_OPTIONS;
5691
- const dot = (v) => v?.swatch?.kind === "color" ? html7`<span class="svp-swatch-dot" style="background-color: ${v.swatch.value}"></span>` : nothing3;
5692
- return html7`
5703
+ const dot = (v) => v?.swatch?.kind === "color" ? html8`<span class="svp-swatch-dot" style="background-color: ${v.swatch.value}"></span>` : nothing3;
5704
+ return html8`
5693
5705
  <div
5694
5706
  class="svp-collapse"
5695
5707
  data-collapsed-axis
@@ -5719,7 +5731,7 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5719
5731
  <span class="svp-collapse-value">${selected ? selected.label : `Choose ${attr.label.toLowerCase()}`}</span>
5720
5732
  <span class="svp-collapse-caret">${expanded ? "\u25B4" : "\u25BE"}</span>
5721
5733
  </button>
5722
- ${expanded ? html7`
5734
+ ${expanded ? html8`
5723
5735
  <div
5724
5736
  class="svp-collapse-list"
5725
5737
  data-clip-ok
@@ -5727,7 +5739,7 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5727
5739
  role="listbox"
5728
5740
  aria-labelledby=${`attrlabel-${attr.key}`}
5729
5741
  >
5730
- ${showFilter ? html7`<input
5742
+ ${showFilter ? html8`<input
5731
5743
  class="svp-collapse-filter"
5732
5744
  data-collapse-filter
5733
5745
  type="text"
@@ -5738,7 +5750,7 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5738
5750
  ${filtered.map((v) => {
5739
5751
  const disabled2 = this._isValueDisabled(attr.key, v.id);
5740
5752
  const isSelected = this._selection[attr.key] === v.id;
5741
- return html7`<button
5753
+ return html8`<button
5742
5754
  class="svp-collapse-option"
5743
5755
  data-collapse-option
5744
5756
  data-value-id=${v.id}
@@ -5749,7 +5761,7 @@ var _VariantPanelLit = class _VariantPanelLit extends LitElement7 {
5749
5761
  @click=${() => this._onCollapsedSelect(attr.key, v.id)}
5750
5762
  >${dot(v)}<span class="svp-collapse-value">${v.label}</span></button>`;
5751
5763
  })}
5752
- ${filtered.length === 0 ? html7`<div class="svp-collapse-empty">No matches</div>` : nothing3}
5764
+ ${filtered.length === 0 ? html8`<div class="svp-collapse-empty">No matches</div>` : nothing3}
5753
5765
  </div>` : nothing3}
5754
5766
  </div>
5755
5767
  `;
@@ -5978,9 +5990,9 @@ var ProductCardLit = class extends LitElement8 {
5978
5990
  super.disconnectedCallback();
5979
5991
  }
5980
5992
  render() {
5981
- if (this.validationError || !this.props) return html8``;
5993
+ if (this.validationError || !this.props) return html9``;
5982
5994
  const parsed = cardSchema.safeParse(this.props);
5983
- if (!parsed.success) return html8``;
5995
+ if (!parsed.success) return html9``;
5984
5996
  const density = this._device === "mobile" ? "compact" : parsed.data.density;
5985
5997
  const { product, visibleFacts } = parsed.data;
5986
5998
  const resolved = this.resolved[product.id];
@@ -6007,7 +6019,7 @@ var ProductCardLit = class extends LitElement8 {
6007
6019
  onPrimaryCtaClick,
6008
6020
  !view.primaryCta.disabled
6009
6021
  );
6010
- const backFace = html8`<syntro-variant-panel
6022
+ const backFace = html9`<syntro-variant-panel
6011
6023
  .payload=${view.panel.payload}
6012
6024
  .productTitle=${product.name ?? ""}
6013
6025
  .productImage=${product.image ? { src: product.image.src, alt: product.image.alt } : null}
@@ -6019,22 +6031,22 @@ var ProductCardLit = class extends LitElement8 {
6019
6031
  @variant-panel-retry=${this._onVariantRetry}
6020
6032
  @variant-panel-selection-change=${this._onVariantSelectionChange}
6021
6033
  ></syntro-variant-panel>
6022
- ${view.addError ? html8`<div data-add-to-cart-error>${view.addError}</div>` : nothing4}`;
6034
+ ${view.addError ? html9`<div data-add-to-cart-error>${view.addError}</div>` : nothing4}`;
6023
6035
  const backView = view.face === "back" && view.flipAnimating ? (
6024
6036
  // Mid-flip: both faces coexist inside a preserve-3d container. The
6025
6037
  // front turns away (inert + aria-hidden) while the back turns in.
6026
- html8`<div data-card-flip @animationend=${__privateGet(this, _onFlipAnimationEnd)}>
6038
+ html9`<div data-card-flip @animationend=${__privateGet(this, _onFlipAnimationEnd)}>
6027
6039
  <div data-face="front" aria-hidden="true" inert>${frontContent}</div>
6028
6040
  <div data-face="back">${backFace}</div>
6029
6041
  </div>`
6030
6042
  ) : view.face === "back" ? (
6031
6043
  // Settled back: flat, untransformed — no flip container, no perspective.
6032
- html8`<div data-face="back">${backFace}</div>`
6033
- ) : html8`<div data-face="front">
6044
+ html9`<div data-face="back">${backFace}</div>`
6045
+ ) : html9`<div data-face="front">
6034
6046
  ${frontContent}
6035
- ${view.addError ? html8`<div data-add-to-cart-error>${view.addError}</div>` : nothing4}
6047
+ ${view.addError ? html9`<div data-add-to-cart-error>${view.addError}</div>` : nothing4}
6036
6048
  </div>`;
6037
- return html8`
6049
+ return html9`
6038
6050
  <article
6039
6051
  class="sc-product-card"
6040
6052
  data-active-face=${view.face}
@@ -6261,7 +6273,7 @@ function _buildArticleStyles(density, face = "front") {
6261
6273
  };
6262
6274
  }
6263
6275
  function renderProductCardInner(product, density, resolved, visibleFacts, ctas, onPrimaryCtaClick, commerceAvailable = true) {
6264
- const imgSrc = resolved?.image ?? product.image.src;
6276
+ const imgSrc = resolved?.image ?? product.image?.src;
6265
6277
  const showFraming = density === "standard" && product.framing;
6266
6278
  const specGroups = buildSpecGroups(product);
6267
6279
  const CORE_FACTS = [
@@ -6576,7 +6588,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6576
6588
  maxWidth: "100%",
6577
6589
  flexShrink: "1"
6578
6590
  };
6579
- const ctaRow = html8`<div class="sc-product-card__ctas" style=${styleMap(ctasStyles)}>
6591
+ const ctaRow = html9`<div class="sc-product-card__ctas" style=${styleMap(ctasStyles)}>
6580
6592
  ${ctas.map((c2, i2) => {
6581
6593
  const disabled2 = c2.actionId === "add_to_cart" && !commerceAvailable;
6582
6594
  const ctaStyles = {
@@ -6584,7 +6596,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6584
6596
  ...disabled2 ? { opacity: "0.5", "pointer-events": "none", cursor: "not-allowed" } : {}
6585
6597
  };
6586
6598
  const ctaLabel = c2.label;
6587
- return html8`<a
6599
+ return html9`<a
6588
6600
  class="sc-product-card__cta"
6589
6601
  data-product-cta=${i2 === 0 ? "primary" : "secondary"}
6590
6602
  data-critical-text
@@ -6614,7 +6626,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6614
6626
  >`;
6615
6627
  })}
6616
6628
  </div>`;
6617
- const ratingOverlay = overlay && product.rating && isVisible("rating") ? html8`<div
6629
+ const ratingOverlay = overlay && product.rating && isVisible("rating") ? html9`<div
6618
6630
  class="sc-product-card__rating sc-product-card__rating--overlay"
6619
6631
  data-product-rating
6620
6632
  data-rating-value=${product.rating.value}
@@ -6630,7 +6642,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6630
6642
  >(${product.rating.count.toLocaleString()})</span
6631
6643
  >
6632
6644
  </div>` : nothing4;
6633
- const priceOverlay = overlay && isVisible("price") && (product.price || product.salePrice) ? html8`<div
6645
+ const priceOverlay = overlay && isVisible("price") && (product.price || product.salePrice) ? html9`<div
6634
6646
  class="sc-product-card__price sc-product-card__price--overlay"
6635
6647
  data-product-price
6636
6648
  style=${styleMap(overlayPriceStyles)}
@@ -6642,27 +6654,29 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6642
6654
  >${activePriceText}</span
6643
6655
  >
6644
6656
  </div>` : nothing4;
6645
- const mediaBlock = overlay ? html8`<div class="sc-product-card__media" style=${styleMap(mediaWrapperStyles)}>
6646
- <img
6657
+ const cardMedia = (styles) => imgSrc ? html9`<img
6647
6658
  class="sc-product-card__image"
6648
6659
  data-product-image
6649
6660
  src=${imgSrc}
6650
- alt=${product.image.alt}
6661
+ alt=${product.image?.alt ?? product.name}
6651
6662
  loading="lazy"
6652
6663
  @error=${onImageError}
6653
- style=${styleMap(overlayImgStyles)}
6654
- />
6655
- ${ratingOverlay}${priceOverlay}
6656
- </div>` : html8`<img
6657
- class="sc-product-card__image"
6658
- data-product-image
6659
- src=${imgSrc}
6660
- alt=${product.image.alt}
6661
- loading="lazy"
6662
- @error=${onImageError}
6663
- style=${styleMap(imageStyles)}
6664
- />`;
6665
- return html8`
6664
+ style=${styleMap(styles)}
6665
+ />` : html9`<div
6666
+ class="sc-product-card__image"
6667
+ data-product-image-standin
6668
+ aria-hidden="true"
6669
+ style=${styleMap({
6670
+ ...styles,
6671
+ objectFit: void 0,
6672
+ position: "relative",
6673
+ background: IMAGE_STANDIN_BACKGROUND
6674
+ })}
6675
+ >${standinMonogram(product.name)}</div>`;
6676
+ const mediaBlock = overlay ? html9`<div class="sc-product-card__media" style=${styleMap(mediaWrapperStyles)}>
6677
+ ${cardMedia(overlayImgStyles)} ${ratingOverlay}${priceOverlay}
6678
+ </div>` : cardMedia(imageStyles);
6679
+ return html9`
6666
6680
  <div class="sc-product-card__grid" data-product-card-grid style=${styleMap(rootGridStyles)}>
6667
6681
  ${mediaBlock}
6668
6682
  <div class="sc-product-card__content" style=${styleMap(contentColStyles)}>
@@ -6729,7 +6743,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6729
6743
  // products to their booker instead — see detail-cta.ts.
6730
6744
  (() => {
6731
6745
  const navCta = pickDetailCta(ctas);
6732
- return navCta?.href ? html8`<a
6746
+ return navCta?.href ? html9`<a
6733
6747
  data-product-name-link
6734
6748
  href=${navCta.href}
6735
6749
  target=${navCta.target ?? "_self"}
@@ -6739,7 +6753,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6739
6753
  })()}</h3>
6740
6754
  ${// On compact the rating renders as an image OVERLAY pill (item 2),
6741
6755
  // so it is omitted from the header identity row here.
6742
- !overlay && product.rating && isVisible("rating") ? html8`<div
6756
+ !overlay && product.rating && isVisible("rating") ? html9`<div
6743
6757
  class="sc-product-card__rating"
6744
6758
  data-product-rating
6745
6759
  data-rating-value=${product.rating.value}
@@ -6756,7 +6770,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6756
6770
  <span class="sc-product-card__rating-count" style=${styleMap({ opacity: "0.65", marginLeft: "0.2rem", display: "var(--sc-card-rating-count-display, inline)" })}>(${product.rating.count.toLocaleString()})</span>
6757
6771
  </div>` : nothing4}
6758
6772
  </div>
6759
- ${(product.tagline || product.framing) && isVisible("tagline") ? html8`<p
6773
+ ${(product.tagline || product.framing) && isVisible("tagline") ? html9`<p
6760
6774
  class="sc-product-card__tagline"
6761
6775
  data-product-tagline
6762
6776
  style=${styleMap({
@@ -6806,12 +6820,12 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6806
6820
  if (key === "price") {
6807
6821
  if (overlay) return nothing4;
6808
6822
  if (!isVisible("price") || !product.price && !product.salePrice) return nothing4;
6809
- return html8`<div
6823
+ return html9`<div
6810
6824
  class="sc-product-card__price"
6811
6825
  data-product-price
6812
6826
  style=${styleMap(priceBlockStyles)}
6813
6827
  >
6814
- ${hasSalePrice && product.price ? html8`<span
6828
+ ${hasSalePrice && product.price ? html9`<span
6815
6829
  class="sc-product-card__amount-original"
6816
6830
  data-product-price-original
6817
6831
  style=${styleMap(priceOriginalStyles)}
@@ -6824,7 +6838,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6824
6838
  style=${styleMap(priceSaleStyles)}
6825
6839
  >${activePriceText}</span
6826
6840
  >
6827
- ${activeCadence ? html8`<span
6841
+ ${activeCadence ? html9`<span
6828
6842
  class="sc-product-card__cadence"
6829
6843
  style=${styleMap(priceCadenceStyles)}
6830
6844
  >${activeCadence}</span
@@ -6833,7 +6847,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6833
6847
  }
6834
6848
  if (key === "availability") {
6835
6849
  if (!isVisible("availability") || !product.availability) return nothing4;
6836
- return html8`<span
6850
+ return html9`<span
6837
6851
  class="sc-product-card__availability"
6838
6852
  data-product-availability
6839
6853
  data-availability=${product.availability}
@@ -6843,7 +6857,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6843
6857
  }
6844
6858
  if (key === "badge") {
6845
6859
  if (!isVisible("badge") || !product.badge) return nothing4;
6846
- return html8`<span
6860
+ return html9`<span
6847
6861
  class="sc-product-card__badge"
6848
6862
  data-product-badge
6849
6863
  data-tone=${product.badge.tone}
@@ -6864,7 +6878,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6864
6878
  const allRows = specGroups.flatMap((g) => g.rows);
6865
6879
  const highlights = allRows.slice(0, 4);
6866
6880
  if (highlights.length === 0) return nothing4;
6867
- return html8`<div
6881
+ return html9`<div
6868
6882
  class="sc-product-card__specs"
6869
6883
  data-density="compact"
6870
6884
  data-clip-ok
@@ -6874,7 +6888,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6874
6888
  style=${styleMap(specChipRowStyles)}
6875
6889
  >
6876
6890
  ${highlights.map(
6877
- (r) => html8`<span
6891
+ (r) => html9`<span
6878
6892
  data-spec-chip
6879
6893
  style=${styleMap(specChipStyles)}
6880
6894
  ><span style="font-weight: 600;">${r.name}</span
@@ -6883,9 +6897,9 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6883
6897
  )}
6884
6898
  </div>`;
6885
6899
  }
6886
- return html8`<div class="sc-product-card__specs" style=${styleMap(specsContainerStyles)}>
6900
+ return html9`<div class="sc-product-card__specs" style=${styleMap(specsContainerStyles)}>
6887
6901
  ${specGroups.map(
6888
- (g) => html8`<section
6902
+ (g) => html9`<section
6889
6903
  class="sc-product-card__spec-section"
6890
6904
  data-spec-section=${g.section}
6891
6905
  style=${styleMap(specGroupStyles)}
@@ -6903,7 +6917,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6903
6917
  style=${styleMap(specRowsStyles)}
6904
6918
  >
6905
6919
  ${g.rows.map(
6906
- (r) => html8`<li
6920
+ (r) => html9`<li
6907
6921
  data-spec-row
6908
6922
  data-spec-chip
6909
6923
  data-attribute-emphasis=${r.emphasis ? "true" : "false"}
@@ -6928,7 +6942,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6928
6942
  style=${styleMap(specValueStyles)}
6929
6943
  >${r.value}</span
6930
6944
  >
6931
- ${r.unit ? html8`<span
6945
+ ${r.unit ? html9`<span
6932
6946
  class="sc-product-card__spec-unit"
6933
6947
  data-spec-unit
6934
6948
  style="opacity: 0.72;"
@@ -6943,7 +6957,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6943
6957
  }
6944
6958
  if (key === "framing") {
6945
6959
  if (!isVisible("framing") || !showFraming) return nothing4;
6946
- return html8`<p
6960
+ return html9`<p
6947
6961
  class="sc-product-card__framing"
6948
6962
  style=${styleMap({
6949
6963
  margin: "0",
@@ -6966,7 +6980,7 @@ function renderProductCardInner(product, density, resolved, visibleFacts, ctas,
6966
6980
  }
6967
6981
  function renderProductCard(product, density, resolved, visibleFacts) {
6968
6982
  const articleStyles = _buildArticleStyles(density);
6969
- return html8`
6983
+ return html9`
6970
6984
  <article
6971
6985
  class="sc-product-card"
6972
6986
  data-density=${density}
@@ -6984,7 +6998,7 @@ function onImageError(e2) {
6984
6998
  }
6985
6999
 
6986
7000
  // src/widgets/ProductComparisonLit.ts
6987
- import { html as html9, LitElement as LitElement9, nothing as nothing5 } from "lit";
7001
+ import { html as html10, LitElement as LitElement9, nothing as nothing5 } from "lit";
6988
7002
  var _controller2, _parsed, _ProductComparisonLit_instances, healthProbe_fn2, _scrollListenerEl, _onBodyScroll, syncScrollCue_fn, startBind_fn2, renderDiveDeeper_fn, onDiveDeeper_fn, visibleRows_fn, rowComplete_fn, maxFields_fn, synthesizeRows_fn, renderMatrix_fn;
6989
7003
  var ProductComparisonLit = class extends LitElement9 {
6990
7004
  constructor() {
@@ -7028,7 +7042,7 @@ var ProductComparisonLit = class extends LitElement9 {
7028
7042
  __privateGet(this, _controller2)?.destroy();
7029
7043
  }
7030
7044
  render() {
7031
- if (this.validationError || !__privateGet(this, _parsed)) return html9``;
7045
+ if (this.validationError || !__privateGet(this, _parsed)) return html10``;
7032
7046
  const parsed = __privateGet(this, _parsed);
7033
7047
  const bodyStyle = (
7034
7048
  // touch-action:pan-y is REQUIRED for the deck swipe-to-cycle to work over a
@@ -7042,7 +7056,7 @@ var ProductComparisonLit = class extends LitElement9 {
7042
7056
  // rows and hands horizontal drags back to the deck's swipe handler.
7043
7057
  "flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;touch-action:pan-y;scrollbar-width:none;-ms-overflow-style:none;overscroll-behavior:contain;" + (this.scrollFade ? "mask-image:linear-gradient(to bottom,#000 calc(100% - 18px),transparent);-webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 18px),transparent);" : "")
7044
7058
  );
7045
- return html9`
7059
+ return html10`
7046
7060
  <section
7047
7061
  class="sc-product-comparison"
7048
7062
  style="display:flex;flex-direction:column;flex:1 1 auto;padding:2px var(--sc-comparison-inset,12px) var(--sc-comparison-inset,12px);box-sizing:border-box;max-width:100%;min-width:0;min-height:0;max-height:100%;overflow:hidden;"
@@ -7077,7 +7091,7 @@ var ProductComparisonLit = class extends LitElement9 {
7077
7091
  }
7078
7092
  }
7079
7093
  </style>
7080
- ${parsed.heading ? html9`<h2
7094
+ ${parsed.heading ? html10`<h2
7081
7095
  class="sc-product-comparison__heading"
7082
7096
  data-comparison-heading
7083
7097
  style="flex:0 0 auto;margin:0 0 4px;font:600 14px/1.3 var(--sc-font-family,inherit);color:var(--sc-tile-title-color,inherit);min-width:0;overflow-wrap:break-word;"
@@ -7102,7 +7116,7 @@ var ProductComparisonLit = class extends LitElement9 {
7102
7116
  // it's in-theme; pointer-events:none so it never blocks scroll/taps;
7103
7117
  // gated on scrollFade (content below the current scroll) so it hides
7104
7118
  // at the end. Bounce is dropped under prefers-reduced-motion (style).
7105
- this.scrollFade ? html9`<span class="sc-product-comparison__scroll-cue" aria-hidden="true"></span>` : nothing5}
7119
+ this.scrollFade ? html10`<span class="sc-product-comparison__scroll-cue" aria-hidden="true"></span>` : nothing5}
7106
7120
  </div>
7107
7121
  ${__privateMethod(this, _ProductComparisonLit_instances, renderDiveDeeper_fn).call(this, parsed)}
7108
7122
  </section>
@@ -7189,7 +7203,7 @@ startBind_fn2 = function() {
7189
7203
  renderDiveDeeper_fn = function(parsed) {
7190
7204
  if (parsed.products.length < 2) return nothing5;
7191
7205
  const chipStyle = "flex:0 0 auto;align-self:flex-end;margin-top:6px;padding:4px 10px;border-radius:9999px;border:1px solid var(--sc-color-border,rgba(0,0,0,0.14));background:transparent;cursor:pointer;font:600 12px/1.2 var(--sc-font-family,inherit);color:var(--sc-color-primary,#3d8a5e);white-space:nowrap;";
7192
- return html9`<button
7206
+ return html10`<button
7193
7207
  type="button"
7194
7208
  class="sc-product-comparison__dive-deeper"
7195
7209
  data-dive-deeper
@@ -7268,7 +7282,7 @@ renderMatrix_fn = function(products, rows) {
7268
7282
  const colHeadStyle = "display:block;padding:6px 3px;text-align:left;font-weight:600;min-width:0;";
7269
7283
  const labelStyle = "padding:8px 4px 8px 2px;font-weight:600;font-size:0.75rem;opacity:0.75;border-top:1px solid var(--sc-tile-border-color,rgba(0,0,0,0.08));align-self:stretch;min-width:0;overflow-wrap:break-word;hyphens:auto;";
7270
7284
  const cellStyle = "padding:8px 6px;border-top:1px solid var(--sc-tile-border-color,rgba(0,0,0,0.08));align-self:stretch;min-width:0;overflow-wrap:anywhere;";
7271
- return html9`
7285
+ return html10`
7272
7286
  <div
7273
7287
  class="sc-product-comparison__matrix"
7274
7288
  data-comparison-matrix
@@ -7294,7 +7308,7 @@ renderMatrix_fn = function(products, rows) {
7294
7308
  >
7295
7309
  ${products.map((p) => {
7296
7310
  const resolved = this.resolved[p.id];
7297
- const imgSrc = resolved?.image ?? p.image.src;
7311
+ const imgSrc = resolved?.image ?? p.image?.src;
7298
7312
  const priceText = resolved?.price ?? p.price?.amount;
7299
7313
  const navCta = pickDetailCta(p.ctas);
7300
7314
  const pdpHref = navCta?.href;
@@ -7302,16 +7316,25 @@ renderMatrix_fn = function(products, rows) {
7302
7316
  const showRatingPill = !compactHeaders && p.rating;
7303
7317
  const nameOverlayStyle = compactHeaders ? "display:block;font-weight:600;font-size:0.66rem;line-height:1.2;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.55);white-space:normal;overflow-wrap:break-word;min-width:0;" : "display:block;font-weight:600;font-size:0.76rem;line-height:1.25;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.55);white-space:normal;overflow-wrap:break-word;min-width:0;";
7304
7318
  const mediaStyle = "position:relative;display:block;width:100%;aspect-ratio:var(--sc-comparison-image-aspect, 19 / 10);border-radius:10px;overflow:hidden;background:#e5e7eb;text-decoration:none;";
7305
- const cardInner = html9`
7306
- <img
7307
- class="sc-product-comparison__thumb"
7308
- src=${imgSrc}
7309
- alt=${p.image.alt}
7310
- loading="lazy"
7311
- style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;"
7312
- />
7319
+ const cardInner = html10`
7320
+ ${imgSrc ? html10`<img
7321
+ class="sc-product-comparison__thumb"
7322
+ src=${imgSrc}
7323
+ alt=${p.image?.alt ?? p.name}
7324
+ loading="lazy"
7325
+ style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;"
7326
+ />` : (
7327
+ // Imageless product → branded stand-in tile (imageStandin.ts).
7328
+ // The scrim + name overlay below stay identical, so contrast
7329
+ // is guaranteed the same way it is over an arbitrary photo.
7330
+ html10`<div
7331
+ data-product-image-standin
7332
+ aria-hidden="true"
7333
+ style="position:absolute;inset:0;background:${IMAGE_STANDIN_BACKGROUND};"
7334
+ >${standinMonogram(p.name)}</div>`
7335
+ )}
7313
7336
  <span aria-hidden="true" style="position:absolute;inset:auto 0 0 0;height:62%;background:linear-gradient(transparent,rgba(0,0,0,.62));"></span>
7314
- ${showRatingPill && p.rating ? html9`<span
7337
+ ${showRatingPill && p.rating ? html10`<span
7315
7338
  class="sc-product-comparison__rating-pill"
7316
7339
  data-product-rating
7317
7340
  data-rating-value=${p.rating.value}
@@ -7319,7 +7342,7 @@ renderMatrix_fn = function(products, rows) {
7319
7342
  style=${`${pillBase}left:4px;`}
7320
7343
  ><span style="color:#f5a623;">★</span><span style="margin-left:0.12rem;">${p.rating.value}</span></span
7321
7344
  >` : nothing5}
7322
- ${priceText ? html9`<span
7345
+ ${priceText ? html10`<span
7323
7346
  class="sc-product-comparison__price"
7324
7347
  data-critical-text
7325
7348
  style=${`${pillBase}right:4px;`}
@@ -7331,13 +7354,13 @@ renderMatrix_fn = function(products, rows) {
7331
7354
  style=${`position:absolute;left:8px;right:8px;bottom:6px;${nameOverlayStyle}`}
7332
7355
  >${p.name}</span
7333
7356
  >`;
7334
- return html9`<div
7357
+ return html10`<div
7335
7358
  class="sc-product-comparison__matrix-col"
7336
7359
  role="columnheader"
7337
7360
  data-product-id=${p.id}
7338
7361
  style=${colHeadStyle}
7339
7362
  >
7340
- ${pdpHref ? html9`<a
7363
+ ${pdpHref ? html10`<a
7341
7364
  class="sc-product-comparison__media"
7342
7365
  data-comparison-media
7343
7366
  data-product-cta="primary"
@@ -7348,19 +7371,19 @@ renderMatrix_fn = function(products, rows) {
7348
7371
  data-action-id=${navCta?.actionId ?? ""}
7349
7372
  data-variant=${navCta?.variant ?? ""}
7350
7373
  style=${mediaStyle}
7351
- >${cardInner}</a>` : html9`<div class="sc-product-comparison__media" data-comparison-media style=${mediaStyle}>${cardInner}</div>`}
7374
+ >${cardInner}</a>` : html10`<div class="sc-product-comparison__media" data-comparison-media style=${mediaStyle}>${cardInner}</div>`}
7352
7375
  </div>`;
7353
7376
  })}
7354
7377
  </div>
7355
7378
  ${rows.map((row) => {
7356
7379
  const cells = [row.valueA, row.valueB, row.valueC, row.valueD];
7357
- return html9`
7380
+ return html10`
7358
7381
  <div role="row" style="display:contents;">
7359
7382
  <span class="sc-product-comparison__matrix-label" role="rowheader" style=${labelStyle}
7360
7383
  >${row.label}</span
7361
7384
  >
7362
7385
  ${products.map(
7363
- (_p, i2) => html9`<span class="sc-product-comparison__matrix-cell" role="cell" style=${cellStyle}
7386
+ (_p, i2) => html10`<span class="sc-product-comparison__matrix-cell" role="cell" style=${cellStyle}
7364
7387
  >${cells[i2] ?? "\u2014"}</span
7365
7388
  >`
7366
7389
  )}
@@ -7378,7 +7401,7 @@ ProductComparisonLit.properties = {
7378
7401
  };
7379
7402
 
7380
7403
  // src/widgets/ProductGridLit.ts
7381
- import { html as html10, LitElement as LitElement10, nothing as nothing6 } from "lit";
7404
+ import { html as html11, LitElement as LitElement10, nothing as nothing6 } from "lit";
7382
7405
  var _controller3, _ProductGridLit_instances, startBind_fn3;
7383
7406
  var ProductGridLit = class extends LitElement10 {
7384
7407
  constructor() {
@@ -7406,20 +7429,20 @@ var ProductGridLit = class extends LitElement10 {
7406
7429
  __privateGet(this, _controller3)?.destroy();
7407
7430
  }
7408
7431
  render() {
7409
- if (this.validationError || !this.props) return html10``;
7432
+ if (this.validationError || !this.props) return html11``;
7410
7433
  const parsed = gridSchema.safeParse(this.props);
7411
- if (!parsed.success) return html10``;
7434
+ if (!parsed.success) return html11``;
7412
7435
  const { products, desktopColumns, heading } = parsed.data;
7413
- return html10`
7436
+ return html11`
7414
7437
  <section class="sc-product-grid">
7415
- ${heading ? html10`<h2 data-grid-heading class="sc-product-grid__heading">${heading}</h2>` : nothing6}
7438
+ ${heading ? html11`<h2 data-grid-heading class="sc-product-grid__heading">${heading}</h2>` : nothing6}
7416
7439
  <div
7417
7440
  data-grid-root
7418
7441
  class="sc-product-grid__cells"
7419
7442
  style=${`--sc-product-grid-cols:${desktopColumns}`}
7420
7443
  >
7421
7444
  ${products.map(
7422
- (p) => html10`<div data-grid-cell class="sc-product-grid__cell">
7445
+ (p) => html11`<div data-grid-cell class="sc-product-grid__cell">
7423
7446
  ${renderProductCard(p, "standard", this.resolved[p.id])}
7424
7447
  </div>`
7425
7448
  )}
@@ -7460,7 +7483,7 @@ ProductGridLit.properties = {
7460
7483
  };
7461
7484
 
7462
7485
  // src/widgets/ProductHeroLit.ts
7463
- import { html as html11, LitElement as LitElement11, nothing as nothing7 } from "lit";
7486
+ import { html as html12, LitElement as LitElement11, nothing as nothing7 } from "lit";
7464
7487
  var _controller4, _ProductHeroLit_instances, startBind_fn4;
7465
7488
  var ProductHeroLit = class extends LitElement11 {
7466
7489
  constructor() {
@@ -7488,40 +7511,45 @@ var ProductHeroLit = class extends LitElement11 {
7488
7511
  __privateGet(this, _controller4)?.destroy();
7489
7512
  }
7490
7513
  render() {
7491
- if (this.validationError || !this.props) return html11``;
7514
+ if (this.validationError || !this.props) return html12``;
7492
7515
  const parsed = heroSchema.safeParse(this.props);
7493
- if (!parsed.success) return html11``;
7516
+ if (!parsed.success) return html12``;
7494
7517
  const { product, layout, longCopy } = parsed.data;
7495
7518
  const resolved = this.resolved[product.id];
7496
- const imgSrc = resolved?.image ?? product.image.src;
7519
+ const imgSrc = resolved?.image ?? product.image?.src;
7497
7520
  const priceText = resolved?.price ?? product.price?.amount;
7498
7521
  const isTopLayout = layout === "image-top";
7499
7522
  const sectionStyles = isTopLayout ? "display:block;" : `display:flex;flex-direction:${layout === "image-right" ? "row-reverse" : "row"};gap:1rem;align-items:flex-start;`;
7500
7523
  const imageStyles = isTopLayout ? "width:100%;max-height:160px;object-fit:cover;border-radius:8px;display:block;margin-bottom:0.75rem;" : "width:128px;height:128px;object-fit:cover;border-radius:8px;flex-shrink:0;";
7501
7524
  const contentStyles = isTopLayout ? "" : "flex:1;min-width:0;";
7502
- return html11`
7525
+ return html12`
7503
7526
  <section class="sc-product-hero" data-hero-layout=${layout} style=${sectionStyles}>
7504
- <img
7505
- class="sc-product-hero__image"
7506
- src=${imgSrc}
7507
- alt=${product.image.alt}
7508
- loading="lazy"
7509
- style=${imageStyles}
7510
- />
7527
+ ${imgSrc ? html12`<img
7528
+ class="sc-product-hero__image"
7529
+ src=${imgSrc}
7530
+ alt=${product.image?.alt ?? product.name}
7531
+ loading="lazy"
7532
+ style=${imageStyles}
7533
+ />` : html12`<div
7534
+ class="sc-product-hero__image"
7535
+ data-product-image-standin
7536
+ aria-hidden="true"
7537
+ style="${imageStyles}background:${IMAGE_STANDIN_BACKGROUND};position:relative;"
7538
+ >${standinMonogram(product.name)}</div>`}
7511
7539
  <div class="sc-product-hero__content" style=${contentStyles}>
7512
7540
  <h2 class="sc-product-hero__name">${product.name}</h2>
7513
- ${product.tagline ? html11`<p class="sc-product-hero__tagline">${product.tagline}</p>` : nothing7}
7514
- ${product.price ? html11`<p class="sc-product-hero__price">
7515
- ${priceText}${product.price.cadence ? html11` <small>${product.price.cadence}</small>` : nothing7}
7541
+ ${product.tagline ? html12`<p class="sc-product-hero__tagline">${product.tagline}</p>` : nothing7}
7542
+ ${product.price ? html12`<p class="sc-product-hero__price">
7543
+ ${priceText}${product.price.cadence ? html12` <small>${product.price.cadence}</small>` : nothing7}
7516
7544
  </p>` : nothing7}
7517
- ${longCopy ? html11`<div
7545
+ ${longCopy ? html12`<div
7518
7546
  data-hero-longcopy
7519
7547
  class="sc-product-hero__longcopy"
7520
7548
  .innerHTML=${sanitizeHtml(longCopy)}
7521
7549
  ></div>` : nothing7}
7522
7550
  <div class="sc-product-hero__ctas">
7523
7551
  ${product.ctas.map(
7524
- (c2, i2) => html11`<a
7552
+ (c2, i2) => html12`<a
7525
7553
  class="sc-product-hero__cta"
7526
7554
  data-product-cta=${i2 === 0 ? "primary" : "secondary"}
7527
7555
  data-variant=${c2.variant}
@@ -7569,7 +7597,7 @@ ProductHeroLit.properties = {
7569
7597
  };
7570
7598
 
7571
7599
  // src/widgets/ProductRecoCarouselLit.ts
7572
- import { html as html12, LitElement as LitElement12, nothing as nothing8 } from "lit";
7600
+ import { html as html13, LitElement as LitElement12, nothing as nothing8 } from "lit";
7573
7601
  import { styleMap as styleMap2 } from "lit/directives/style-map.js";
7574
7602
  var _ProductRecoCarouselLit_instances, healthProbe_fn3;
7575
7603
  var ProductRecoCarouselLit = class extends LitElement12 {
@@ -7591,20 +7619,20 @@ var ProductRecoCarouselLit = class extends LitElement12 {
7591
7619
  }
7592
7620
  render() {
7593
7621
  const items = this._parsed?.items ?? [];
7594
- if (items.length === 0) return html12``;
7595
- return html12`
7622
+ if (items.length === 0) return html13``;
7623
+ return html13`
7596
7624
  <section class="sc-reco" style="box-sizing:border-box;display:flex;flex-direction:column;height:100%;padding:2px var(--sc-reco-inset,12px) var(--sc-reco-inset,12px);">
7597
7625
  <div class="sc-reco__carousel" role="list" style="display:flex;align-items:stretch;gap:8px;flex:1 1 auto;min-height:0;overflow-x:auto;scroll-snap-type:x mandatory;">
7598
7626
  ${items.map(
7599
- (it) => html12`
7627
+ (it) => html13`
7600
7628
  <div role="listitem" style="display:contents;">
7601
7629
  <a data-reco-item data-product-cta="primary" href=${it.pdp_href}
7602
7630
  style=${styleMap2({ position: "relative", flex: "0 0 auto", aspectRatio: "4 / 5", minHeight: "var(--sc-reco-item-min-h, 162px)", maxHeight: "var(--sc-reco-item-max-h, 340px)", borderRadius: "12px", overflow: "hidden", scrollSnapAlign: "start", textDecoration: "none", display: "block", background: "#e5e7eb" })}>
7603
- ${it.image_url ? html12`<img src=${it.image_url} alt=${it.hook ?? "Recommended product"} loading="lazy" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;">` : nothing8}
7631
+ ${it.image_url ? html13`<img src=${it.image_url} alt=${it.hook ?? "Recommended product"} loading="lazy" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;">` : nothing8}
7604
7632
  <span style="position:absolute;inset:auto 0 0 0;height:60%;background:linear-gradient(transparent,rgba(0,0,0,.62));"></span>
7605
7633
  <span style="position:absolute;left:8px;right:8px;bottom:8px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.5);">
7606
- ${it.price ? html12`<span style="display:block;font-weight:700;font-size:0.9rem;">${it.price}</span>` : nothing8}
7607
- ${it.hook ? html12`<span style="display:block;font-size:0.72rem;line-height:1.2;opacity:.95;">${it.hook}</span>` : nothing8}
7634
+ ${it.price ? html13`<span style="display:block;font-weight:700;font-size:0.9rem;">${it.price}</span>` : nothing8}
7635
+ ${it.hook ? html13`<span style="display:block;font-size:0.72rem;line-height:1.2;opacity:.95;">${it.hook}</span>` : nothing8}
7608
7636
  </span>
7609
7637
  </a>
7610
7638
  </div>`
@@ -7639,7 +7667,7 @@ if (!customElements.get("syntro-product-reco-carousel"))
7639
7667
  customElements.define("syntro-product-reco-carousel", ProductRecoCarouselLit);
7640
7668
 
7641
7669
  // src/widgets/PdpTrendingNewsLit.ts
7642
- import { html as html13, LitElement as LitElement13 } from "lit";
7670
+ import { html as html14, LitElement as LitElement13 } from "lit";
7643
7671
 
7644
7672
  // src/widgets/entrance.ts
7645
7673
  function armEntranceSettle(onSettle, container, settleMs, fastPath = false) {
@@ -8022,7 +8050,7 @@ var PdpTrendingNewsLit = class extends LitElement13 {
8022
8050
  }
8023
8051
  render() {
8024
8052
  if (!this.data) {
8025
- return html13`<div data-skeleton class="pdp-trending-news-skeleton">
8053
+ return html14`<div data-skeleton class="pdp-trending-news-skeleton">
8026
8054
  <div class="pdp-skeleton-bar" style="width:60%"></div>
8027
8055
  <div class="pdp-skeleton-bar" style="width:90%"></div>
8028
8056
  <div class="pdp-skeleton-bar" style="width:80%"></div>
@@ -8032,7 +8060,7 @@ var PdpTrendingNewsLit = class extends LitElement13 {
8032
8060
  const items = this.data.items;
8033
8061
  const featured = items[0];
8034
8062
  const rest = items.slice(1);
8035
- return html13`
8063
+ return html14`
8036
8064
  <section
8037
8065
  class="${this._entering ? "pdp-trending-news is-entering" : "pdp-trending-news"}"
8038
8066
  aria-label="Trending news"
@@ -8049,7 +8077,7 @@ var PdpTrendingNewsLit = class extends LitElement13 {
8049
8077
  <p class="pdp-tn-blurb">${featured.blurb}</p>
8050
8078
  </article>
8051
8079
  ${rest.map(
8052
- (item) => html13`
8080
+ (item) => html14`
8053
8081
  <article class="pdp-tn-card">
8054
8082
  <div class="pdp-tn-meta">
8055
8083
  <span class="pdp-tn-dot" aria-hidden="true"></span>
@@ -8071,8 +8099,8 @@ PdpTrendingNewsLit.properties = {
8071
8099
  _entering: { state: true }
8072
8100
  };
8073
8101
  function renderHeadlineLink(item) {
8074
- if (!item.url) return html13`${item.headline}`;
8075
- return html13`<a
8102
+ if (!item.url) return html14`${item.headline}`;
8103
+ return html14`<a
8076
8104
  class="pdp-tn-headline-link"
8077
8105
  href=${item.url}
8078
8106
  target="_blank"
@@ -8085,7 +8113,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-tre
8085
8113
  }
8086
8114
 
8087
8115
  // src/widgets/PdpTrendingNewsMagazineLit.ts
8088
- import { html as html14, LitElement as LitElement14 } from "lit";
8116
+ import { html as html15, LitElement as LitElement14 } from "lit";
8089
8117
  function ensureMagazineStyles() {
8090
8118
  if (typeof document === "undefined") return;
8091
8119
  if (document.getElementById("syntro-pdp-trending-news-magazine-style")) return;
@@ -8279,13 +8307,13 @@ var PdpTrendingNewsMagazineLit = class extends LitElement14 {
8279
8307
  }
8280
8308
  render() {
8281
8309
  if (!this.data) {
8282
- return html14`<div aria-busy="true" class="pdp-tn-mag" style="opacity:0.5;">…</div>`;
8310
+ return html15`<div aria-busy="true" class="pdp-tn-mag" style="opacity:0.5;">…</div>`;
8283
8311
  }
8284
8312
  const items = this.data.items;
8285
8313
  const [lead, ...rest] = items;
8286
- return html14`
8314
+ return html15`
8287
8315
  <section class="pdp-tn-mag" aria-label="Trending news">
8288
- ${lead ? html14`<article class="pdp-tn-mag__lead">
8316
+ ${lead ? html15`<article class="pdp-tn-mag__lead">
8289
8317
  <div class="pdp-tn-mag__meta">
8290
8318
  <span class="pdp-tn-mag__meta-source">${lead.source}</span>
8291
8319
  · ${lead.published_relative}
@@ -8294,7 +8322,7 @@ var PdpTrendingNewsMagazineLit = class extends LitElement14 {
8294
8322
  <p class="pdp-tn-mag__blurb">${lead.blurb}</p>
8295
8323
  </article>` : ""}
8296
8324
  ${rest.map(
8297
- (it) => html14`<article class="pdp-tn-mag__item">
8325
+ (it) => html15`<article class="pdp-tn-mag__item">
8298
8326
  <div class="pdp-tn-mag__meta">
8299
8327
  <span class="pdp-tn-mag__meta-source">${it.source}</span>
8300
8328
  · ${it.published_relative}
@@ -8311,8 +8339,8 @@ PdpTrendingNewsMagazineLit.properties = {
8311
8339
  data: { attribute: false }
8312
8340
  };
8313
8341
  function renderHeadlineLink2(item) {
8314
- if (!item.url) return html14`${item.headline}`;
8315
- return html14`<a
8342
+ if (!item.url) return html15`${item.headline}`;
8343
+ return html15`<a
8316
8344
  class="pdp-tn-mag__headline-link"
8317
8345
  href=${item.url}
8318
8346
  target="_blank"
@@ -8325,7 +8353,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-tre
8325
8353
  }
8326
8354
 
8327
8355
  // src/widgets/PdpTrendingNewsHeroLit.ts
8328
- import { html as html15, LitElement as LitElement15 } from "lit";
8356
+ import { html as html16, LitElement as LitElement15 } from "lit";
8329
8357
  function ensureHeroStyles() {
8330
8358
  if (typeof document === "undefined") return;
8331
8359
  if (document.getElementById("syntro-pdp-trending-news-hero-style")) return;
@@ -8530,11 +8558,11 @@ var PdpTrendingNewsHeroLit = class extends LitElement15 {
8530
8558
  }
8531
8559
  render() {
8532
8560
  if (!this.data) {
8533
- return html15`<div aria-busy="true" class="pdp-tn-hero" style="opacity:0.5;">…</div>`;
8561
+ return html16`<div aria-busy="true" class="pdp-tn-hero" style="opacity:0.5;">…</div>`;
8534
8562
  }
8535
8563
  const [lead, ...rest] = this.data.items;
8536
- if (!lead) return html15``;
8537
- return html15`
8564
+ if (!lead) return html16``;
8565
+ return html16`
8538
8566
  <section class="pdp-tn-hero" aria-label="Trending news">
8539
8567
  <article class="pdp-tn-hero__panel">
8540
8568
  <blockquote class="pdp-tn-hero__quote">${lead.blurb}</blockquote>
@@ -8545,9 +8573,9 @@ var PdpTrendingNewsHeroLit = class extends LitElement15 {
8545
8573
  </footer>
8546
8574
  <p class="pdp-tn-hero__headline">${renderHeadlineLink3(lead)}</p>
8547
8575
  </article>
8548
- ${rest.length ? html15`<div class="pdp-tn-hero__followon">
8576
+ ${rest.length ? html16`<div class="pdp-tn-hero__followon">
8549
8577
  ${rest.map(
8550
- (it) => html15`<div class="pdp-tn-hero__row">
8578
+ (it) => html16`<div class="pdp-tn-hero__row">
8551
8579
  <p class="pdp-tn-hero__row-headline">${renderHeadlineLink3(it)}</p>
8552
8580
  <span class="pdp-tn-hero__row-meta">${it.source}</span>
8553
8581
  </div>`
@@ -8561,8 +8589,8 @@ PdpTrendingNewsHeroLit.properties = {
8561
8589
  data: { attribute: false }
8562
8590
  };
8563
8591
  function renderHeadlineLink3(item) {
8564
- if (!item.url) return html15`${item.headline}`;
8565
- return html15`<a
8592
+ if (!item.url) return html16`${item.headline}`;
8593
+ return html16`<a
8566
8594
  class="pdp-tn-hero__headline-link"
8567
8595
  href=${item.url}
8568
8596
  target="_blank"
@@ -8575,7 +8603,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-tre
8575
8603
  }
8576
8604
 
8577
8605
  // src/widgets/PdpPeerFeedMasonryLit.ts
8578
- import { html as html16, LitElement as LitElement16 } from "lit";
8606
+ import { html as html17, LitElement as LitElement16 } from "lit";
8579
8607
  function ensureMasonryStyles() {
8580
8608
  if (typeof document === "undefined") return;
8581
8609
  if (document.getElementById("syntro-pdp-peer-feed-masonry-style")) return;
@@ -8733,13 +8761,13 @@ var PdpPeerFeedMasonryLit = class extends LitElement16 {
8733
8761
  }
8734
8762
  render() {
8735
8763
  if (!this.data) {
8736
- return html16`<div aria-busy="true" class="pdp-pf-mas" style="opacity:0.5;">…</div>`;
8764
+ return html17`<div aria-busy="true" class="pdp-pf-mas" style="opacity:0.5;">…</div>`;
8737
8765
  }
8738
- return html16`
8766
+ return html17`
8739
8767
  <section class="pdp-pf-mas" aria-label="Peer voices">
8740
8768
  <div class="pdp-pf-mas__grid">
8741
8769
  ${this.data.peers.map(
8742
- (p) => html16`<article
8770
+ (p) => html17`<article
8743
8771
  class="pdp-pf-mas__card"
8744
8772
  style=${`--pf-avatar-hue: ${personaHue(p.persona)};`}
8745
8773
  >
@@ -8767,7 +8795,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-pee
8767
8795
  }
8768
8796
 
8769
8797
  // src/widgets/PdpPeerFeedCarouselLit.ts
8770
- import { html as html17, LitElement as LitElement17, svg } from "lit";
8798
+ import { html as html18, LitElement as LitElement17, svg } from "lit";
8771
8799
  function ensureCarouselStyles2() {
8772
8800
  if (typeof document === "undefined") return;
8773
8801
  if (document.getElementById("syntro-pdp-peer-feed-carousel-style")) return;
@@ -8997,15 +9025,15 @@ var PdpPeerFeedCarouselLit = class extends LitElement17 {
8997
9025
  }
8998
9026
  render() {
8999
9027
  if (!this.data) {
9000
- return html17`<div aria-busy="true" class="pdp-pf-car" style="opacity:0.5;">…</div>`;
9028
+ return html18`<div aria-busy="true" class="pdp-pf-car" style="opacity:0.5;">…</div>`;
9001
9029
  }
9002
- return html17`
9030
+ return html18`
9003
9031
  <section class="pdp-pf-car" aria-label="Peer voices">
9004
9032
  <div class="pdp-pf-car__track">
9005
9033
  ${this.data.peers.map((p) => {
9006
9034
  const kind = glyphFor(p.persona);
9007
9035
  const hue = glyphHue(p.persona);
9008
- return html17`<article class="pdp-pf-car__card" style=${`--pf-glyph-hue: ${hue};`}>
9036
+ return html18`<article class="pdp-pf-car__card" style=${`--pf-glyph-hue: ${hue};`}>
9009
9037
  <span class="pdp-pf-car__glyph" aria-hidden="true">${renderGlyph(kind)}</span>
9010
9038
  <span class="pdp-pf-car__persona">${p.persona}</span>
9011
9039
  <blockquote class="pdp-pf-car__quote">${p.quote}</blockquote>
@@ -9030,7 +9058,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-pee
9030
9058
  }
9031
9059
 
9032
9060
  // src/widgets/PdpChartLit.ts
9033
- import { html as html18, LitElement as LitElement18, nothing as nothing9, svg as svg2 } from "lit";
9061
+ import { html as html19, LitElement as LitElement18, nothing as nothing9, svg as svg2 } from "lit";
9034
9062
  function formatNum(v) {
9035
9063
  if (v === void 0 || !Number.isFinite(v)) return "\u2014";
9036
9064
  if (Number.isInteger(v)) return v.toLocaleString("en-US");
@@ -9689,7 +9717,7 @@ var PdpChartLit = class extends LitElement18 {
9689
9717
  }
9690
9718
  render() {
9691
9719
  if (!this.data) {
9692
- return html18`<div data-skeleton class="pdp-chart-skeleton">
9720
+ return html19`<div data-skeleton class="pdp-chart-skeleton">
9693
9721
  <div class="pdp-skeleton-bar" style="width:50%"></div>
9694
9722
  <div class="pdp-skeleton-rect" style="height:200px"></div>
9695
9723
  </div>`;
@@ -9698,7 +9726,7 @@ var PdpChartLit = class extends LitElement18 {
9698
9726
  const allSeriesOnePoint = this.data.series.every((s4) => s4.points.length <= 1);
9699
9727
  const effectiveKind = isTable ? "table" : this.data.viz_kind === "line" && !allSeriesOnePoint ? "line" : "bar";
9700
9728
  const isMultiSeries = this.data.series.length > 1;
9701
- return html18`
9729
+ return html19`
9702
9730
  <section
9703
9731
  class="${this._entering ? "pdp-chart pdp-chart-frame is-entering" : "pdp-chart pdp-chart-frame"}"
9704
9732
  aria-label="${this.data.title}"
@@ -9713,7 +9741,7 @@ var PdpChartLit = class extends LitElement18 {
9713
9741
  ${effectiveKind === "bar" ? __privateMethod(this, _PdpChartLit_instances, renderBars_fn).call(this) : nothing9}
9714
9742
  ${effectiveKind === "line" ? __privateMethod(this, _PdpChartLit_instances, renderLine_fn).call(this) : nothing9}
9715
9743
  ${effectiveKind !== "table" && isMultiSeries ? __privateMethod(this, _PdpChartLit_instances, renderLegend_fn).call(this) : nothing9}
9716
- ${this.data.rationale ? html18`<p class="pdp-chart-rationale">${this.data.rationale}</p>` : nothing9}
9744
+ ${this.data.rationale ? html19`<p class="pdp-chart-rationale">${this.data.rationale}</p>` : nothing9}
9717
9745
  </section>
9718
9746
  `;
9719
9747
  }
@@ -9721,10 +9749,10 @@ var PdpChartLit = class extends LitElement18 {
9721
9749
  _PdpChartLit_instances = new WeakSet();
9722
9750
  renderLegend_fn = function() {
9723
9751
  const data = this.data;
9724
- return html18`
9752
+ return html19`
9725
9753
  <ol class="pdp-chart-legend" aria-label="Legend">
9726
9754
  ${data.series.map(
9727
- (s4, idx) => html18`
9755
+ (s4, idx) => html19`
9728
9756
  <li class="pdp-chart-legend-item">
9729
9757
  <span
9730
9758
  class="pdp-chart-legend-swatch"
@@ -9740,22 +9768,22 @@ renderLegend_fn = function() {
9740
9768
  };
9741
9769
  renderTable_fn = function() {
9742
9770
  const matrix = buildComparisonMatrix(this.data);
9743
- return html18`
9771
+ return html19`
9744
9772
  <div class="pdp-chart-table-wrap">
9745
9773
  <table class="pdp-chart-table">
9746
9774
  <thead>
9747
9775
  <tr>
9748
9776
  <th></th>
9749
- ${matrix.colLabels.map((label) => html18`<th>${label}</th>`)}
9777
+ ${matrix.colLabels.map((label) => html19`<th>${label}</th>`)}
9750
9778
  </tr>
9751
9779
  </thead>
9752
9780
  <tbody>
9753
9781
  ${matrix.rowLabels.map(
9754
- (row, rowIdx) => html18`
9782
+ (row, rowIdx) => html19`
9755
9783
  <tr class=${rowIdx === matrix.winningRow ? "is-winning" : ""}>
9756
9784
  <td>${row}</td>
9757
9785
  ${matrix.cells[rowIdx].map(
9758
- (cell) => html18`<td class="pdp-chart-numeric-cell">${formatNum(cell)}</td>`
9786
+ (cell) => html19`<td class="pdp-chart-numeric-cell">${formatNum(cell)}</td>`
9759
9787
  )}
9760
9788
  </tr>
9761
9789
  `
@@ -9770,7 +9798,7 @@ renderBars_fn = function() {
9770
9798
  const { buckets, yMax } = buildBarBuckets(data);
9771
9799
  const ticks = niceTicks(yMax);
9772
9800
  const scaleMax = Math.max(yMax, ticks[ticks.length - 1]);
9773
- return html18`
9801
+ return html19`
9774
9802
  <div
9775
9803
  class="pdp-chart-bars"
9776
9804
  role="figure"
@@ -9779,7 +9807,7 @@ renderBars_fn = function() {
9779
9807
  >
9780
9808
  <div class="pdp-chart-yaxis" aria-hidden="true">
9781
9809
  ${ticks.map(
9782
- (t2) => html18`
9810
+ (t2) => html19`
9783
9811
  <span
9784
9812
  class="pdp-chart-yaxis-tick"
9785
9813
  style="bottom:${t2 / scaleMax * 100}%"
@@ -9791,7 +9819,7 @@ renderBars_fn = function() {
9791
9819
  </div>
9792
9820
  <div class="pdp-chart-bars-area">
9793
9821
  ${ticks.map(
9794
- (t2) => html18`
9822
+ (t2) => html19`
9795
9823
  <div
9796
9824
  class="pdp-chart-bars-gridline"
9797
9825
  style="bottom:${t2 / scaleMax * 100}%"
@@ -9801,11 +9829,11 @@ renderBars_fn = function() {
9801
9829
  )}
9802
9830
  <div class="pdp-chart-bars-baseline" aria-hidden="true"></div>
9803
9831
  ${buckets.map(
9804
- (bucket, bIdx) => html18`
9832
+ (bucket, bIdx) => html19`
9805
9833
  <div class="pdp-chart-bars-bucket">
9806
9834
  <div class="pdp-chart-bars-stack">
9807
9835
  ${bucket.bars.map(
9808
- (bar, barIdxInBucket) => html18`
9836
+ (bar, barIdxInBucket) => html19`
9809
9837
  <div
9810
9838
  class="pdp-chart-bar"
9811
9839
  style="
@@ -9816,7 +9844,7 @@ renderBars_fn = function() {
9816
9844
  role="img"
9817
9845
  aria-label="${bucket.label} — ${bar.seriesName}: ${formatNum(bar.value)}"
9818
9846
  >
9819
- ${bucket.bars.length === 1 ? html18`<span class="pdp-chart-bar-value"
9847
+ ${bucket.bars.length === 1 ? html19`<span class="pdp-chart-bar-value"
9820
9848
  >${formatNum(bar.value)}</span
9821
9849
  >` : nothing9}
9822
9850
  </div>
@@ -9836,7 +9864,7 @@ renderLine_fn = function() {
9836
9864
  const { series, xLabels, yMax } = buildLinePaths(data);
9837
9865
  const ticks = niceTicks(yMax);
9838
9866
  const scaleMax = Math.max(yMax, ticks[ticks.length - 1]);
9839
- return html18`
9867
+ return html19`
9840
9868
  <div
9841
9869
  class="pdp-chart-line"
9842
9870
  role="figure"
@@ -9846,7 +9874,7 @@ renderLine_fn = function() {
9846
9874
  >
9847
9875
  <div class="pdp-chart-line-yaxis" aria-hidden="true">
9848
9876
  ${ticks.map(
9849
- (t2) => html18`
9877
+ (t2) => html19`
9850
9878
  <span
9851
9879
  class="pdp-chart-yaxis-tick"
9852
9880
  style="bottom:${t2 / scaleMax * 100}%"
@@ -9895,7 +9923,7 @@ renderLine_fn = function() {
9895
9923
  style="--col-count:${xLabels.length}"
9896
9924
  aria-hidden="true"
9897
9925
  >
9898
- ${xLabels.map((label) => html18`<span>${label}</span>`)}
9926
+ ${xLabels.map((label) => html19`<span>${label}</span>`)}
9899
9927
  </div>
9900
9928
  `;
9901
9929
  };
@@ -9908,7 +9936,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-cha
9908
9936
  }
9909
9937
 
9910
9938
  // src/widgets/PdpChartBarStackedLit.ts
9911
- import { html as html19, LitElement as LitElement19 } from "lit";
9939
+ import { html as html20, LitElement as LitElement19 } from "lit";
9912
9940
  function ensureStyles() {
9913
9941
  if (typeof document === "undefined") return;
9914
9942
  if (document.getElementById("syntro-pdp-chart-bar-style")) return;
@@ -10009,16 +10037,16 @@ var PdpChartBarStackedLit = class extends LitElement19 {
10009
10037
  ensureStyles();
10010
10038
  }
10011
10039
  render() {
10012
- if (!this.data) return html19`<div class="pdp-chart-bar" style="opacity:0.5;">…</div>`;
10040
+ if (!this.data) return html20`<div class="pdp-chart-bar" style="opacity:0.5;">…</div>`;
10013
10041
  const { title, series } = this.data;
10014
10042
  const allX = Array.from(new Set(series.flatMap((s4) => s4.points.map((p) => p.x))));
10015
10043
  const max = Math.max(...series.flatMap((s4) => s4.points.map((p) => p.y)), 1);
10016
- return html19`
10044
+ return html20`
10017
10045
  <section class="pdp-chart-bar" aria-label=${title}>
10018
10046
  <h3 class="pdp-chart-bar__title">${title}</h3>
10019
- ${series.length > 1 ? html19`<div class="pdp-chart-bar__legend">
10047
+ ${series.length > 1 ? html20`<div class="pdp-chart-bar__legend">
10020
10048
  ${series.map(
10021
- (s4, i2) => html19`<span
10049
+ (s4, i2) => html20`<span
10022
10050
  ><span
10023
10051
  class="pdp-chart-bar__legend-dot"
10024
10052
  style=${`background: ${PALETTE[i2 % PALETTE.length]};`}
@@ -10028,14 +10056,14 @@ var PdpChartBarStackedLit = class extends LitElement19 {
10028
10056
  )}
10029
10057
  </div>` : ""}
10030
10058
  ${allX.map(
10031
- (x) => html19`<div class="pdp-chart-bar__row">
10059
+ (x) => html20`<div class="pdp-chart-bar__row">
10032
10060
  <div class="pdp-chart-bar__row-label">${x}</div>
10033
10061
  <div class="pdp-chart-bar__row-bars">
10034
10062
  ${series.map((s4, i2) => {
10035
10063
  const point = s4.points.find((p) => p.x === x);
10036
10064
  if (!point) return "";
10037
10065
  const pct = point.y / max * 100;
10038
- return html19`<div class="pdp-chart-bar__bar-track">
10066
+ return html20`<div class="pdp-chart-bar__bar-track">
10039
10067
  <div
10040
10068
  class="pdp-chart-bar__bar-fill"
10041
10069
  style=${`width: ${pct.toFixed(1)}%; background: ${PALETTE[i2 % PALETTE.length]};`}
@@ -10058,7 +10086,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-cha
10058
10086
  }
10059
10087
 
10060
10088
  // src/widgets/PdpChartMetricPullLit.ts
10061
- import { html as html20, LitElement as LitElement20, svg as svg3 } from "lit";
10089
+ import { html as html21, LitElement as LitElement20, svg as svg3 } from "lit";
10062
10090
  function ensureStyles2() {
10063
10091
  if (typeof document === "undefined") return;
10064
10092
  if (document.getElementById("syntro-pdp-chart-metric-style")) return;
@@ -10183,10 +10211,10 @@ var PdpChartMetricPullLit = class extends LitElement20 {
10183
10211
  ensureStyles2();
10184
10212
  }
10185
10213
  render() {
10186
- if (!this.data) return html20`<div class="pdp-chart-met" style="opacity:0.5;">…</div>`;
10214
+ if (!this.data) return html21`<div class="pdp-chart-met" style="opacity:0.5;">…</div>`;
10187
10215
  const { title, series } = this.data;
10188
10216
  const first = series[0];
10189
- if (!first || first.points.length === 0) return html20``;
10217
+ if (!first || first.points.length === 0) return html21``;
10190
10218
  const points = first.points;
10191
10219
  const peak = points.reduce((b, p) => p.y > b.y ? p : b, points[0]);
10192
10220
  const mean = points.reduce((s4, p) => s4 + p.y, 0) / points.length;
@@ -10199,7 +10227,7 @@ var PdpChartMetricPullLit = class extends LitElement20 {
10199
10227
  const max = Math.max(...points.map((p) => p.y));
10200
10228
  const range = max - min || 1;
10201
10229
  const py = h - 4 - (peak.y - min) / range * (h - 8);
10202
- return html20`
10230
+ return html21`
10203
10231
  <section class="pdp-chart-met" aria-label=${title}>
10204
10232
  <div class="pdp-chart-met__metric">
10205
10233
  <span class="pdp-chart-met__big">${peak.y}</span>
@@ -10231,7 +10259,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-cha
10231
10259
  }
10232
10260
 
10233
10261
  // src/widgets/PdpQaAccordionLit.ts
10234
- import { html as html21, LitElement as LitElement21 } from "lit";
10262
+ import { html as html22, LitElement as LitElement21 } from "lit";
10235
10263
  function ensureStyles3() {
10236
10264
  if (typeof document === "undefined") return;
10237
10265
  if (document.getElementById("syntro-pdp-qa-accordion-style")) return;
@@ -10326,11 +10354,11 @@ var PdpQaAccordionLit = class extends LitElement21 {
10326
10354
  ensureStyles3();
10327
10355
  }
10328
10356
  render() {
10329
- if (!this.data) return html21`<div class="pdp-qa-acc" style="opacity:0.5;">…</div>`;
10330
- return html21`
10357
+ if (!this.data) return html22`<div class="pdp-qa-acc" style="opacity:0.5;">…</div>`;
10358
+ return html22`
10331
10359
  <section class="pdp-qa-acc" aria-label="Frequently asked questions">
10332
10360
  ${this.data.items.map(
10333
- (it) => html21`<details class="pdp-qa-acc__item">
10361
+ (it) => html22`<details class="pdp-qa-acc__item">
10334
10362
  <summary>
10335
10363
  <span class="pdp-qa-acc__chev" aria-hidden="true"></span>
10336
10364
  <span>${it.question}</span>
@@ -10350,7 +10378,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-qa-
10350
10378
  }
10351
10379
 
10352
10380
  // src/widgets/PdpQaSideBySideLit.ts
10353
- import { html as html22, LitElement as LitElement22 } from "lit";
10381
+ import { html as html23, LitElement as LitElement22 } from "lit";
10354
10382
  function ensureStyles4() {
10355
10383
  if (typeof document === "undefined") return;
10356
10384
  if (document.getElementById("syntro-pdp-qa-side-style")) return;
@@ -10437,11 +10465,11 @@ var PdpQaSideBySideLit = class extends LitElement22 {
10437
10465
  ensureStyles4();
10438
10466
  }
10439
10467
  render() {
10440
- if (!this.data) return html22`<div class="pdp-qa-side" style="opacity:0.5;">…</div>`;
10441
- return html22`
10468
+ if (!this.data) return html23`<div class="pdp-qa-side" style="opacity:0.5;">…</div>`;
10469
+ return html23`
10442
10470
  <section class="pdp-qa-side" aria-label="Q&A">
10443
10471
  ${this.data.items.map(
10444
- (it) => html22`<div class="pdp-qa-side__item">
10472
+ (it) => html23`<div class="pdp-qa-side__item">
10445
10473
  <h4 class="pdp-qa-side__q">${it.question}</h4>
10446
10474
  <p class="pdp-qa-side__a">${it.answer}</p>
10447
10475
  </div>`
@@ -10458,7 +10486,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-qa-
10458
10486
  }
10459
10487
 
10460
10488
  // src/widgets/PdpRegionalFullBleedLit.ts
10461
- import { html as html23, LitElement as LitElement23 } from "lit";
10489
+ import { html as html24, LitElement as LitElement23 } from "lit";
10462
10490
  function ensureStyles5() {
10463
10491
  if (typeof document === "undefined") return;
10464
10492
  if (document.getElementById("syntro-pdp-regional-fullbleed-style")) return;
@@ -10562,9 +10590,9 @@ var PdpRegionalFullBleedLit = class extends LitElement23 {
10562
10590
  ensureStyles5();
10563
10591
  }
10564
10592
  render() {
10565
- if (!this.data) return html23`<div class="pdp-reg-fb" style="opacity:0.5;">…</div>`;
10593
+ if (!this.data) return html24`<div class="pdp-reg-fb" style="opacity:0.5;">…</div>`;
10566
10594
  const d = this.data;
10567
- return html23`
10595
+ return html24`
10568
10596
  <section class="pdp-reg-fb" aria-label="Where you are">
10569
10597
  <article class="pdp-reg-fb__panel">
10570
10598
  <svg class="pdp-reg-fb__glyph" viewBox="0 0 56 56" aria-hidden="true">
@@ -10607,7 +10635,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-reg
10607
10635
  }
10608
10636
 
10609
10637
  // src/widgets/PdpRegionalInlineNoteLit.ts
10610
- import { html as html24, LitElement as LitElement24 } from "lit";
10638
+ import { html as html25, LitElement as LitElement24 } from "lit";
10611
10639
  function ensureStyles6() {
10612
10640
  if (typeof document === "undefined") return;
10613
10641
  if (document.getElementById("syntro-pdp-regional-inline-style")) return;
@@ -10681,9 +10709,9 @@ var PdpRegionalInlineNoteLit = class extends LitElement24 {
10681
10709
  ensureStyles6();
10682
10710
  }
10683
10711
  render() {
10684
- if (!this.data) return html24`<div class="pdp-reg-in" style="opacity:0.5;">…</div>`;
10712
+ if (!this.data) return html25`<div class="pdp-reg-in" style="opacity:0.5;">…</div>`;
10685
10713
  const d = this.data;
10686
- return html24`
10714
+ return html25`
10687
10715
  <aside class="pdp-reg-in" aria-label="Regional note">
10688
10716
  <svg class="pdp-reg-in__icon" viewBox="0 0 22 22" aria-hidden="true">
10689
10717
  <circle cx="11" cy="11" r="9" fill="none" stroke="currentColor" stroke-width="1.6"/>
@@ -10711,7 +10739,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-reg
10711
10739
  }
10712
10740
 
10713
10741
  // src/widgets/PdpSlotPlaceholderLit.ts
10714
- import { html as html25, LitElement as LitElement25 } from "lit";
10742
+ import { html as html26, LitElement as LitElement25 } from "lit";
10715
10743
  var PdpSlotPlaceholderLit = class extends LitElement25 {
10716
10744
  constructor() {
10717
10745
  super(...arguments);
@@ -10721,7 +10749,7 @@ var PdpSlotPlaceholderLit = class extends LitElement25 {
10721
10749
  return this;
10722
10750
  }
10723
10751
  render() {
10724
- return html25`
10752
+ return html26`
10725
10753
  <div class="pdp-slot-placeholder" data-placeholder>
10726
10754
  <p>${this.label}</p>
10727
10755
  <small>Ask in chat to explore this product further.</small>
@@ -10737,7 +10765,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-slo
10737
10765
  }
10738
10766
 
10739
10767
  // src/widgets/PdpRibbonLit.ts
10740
- import { html as html26, LitElement as LitElement26, nothing as nothing10 } from "lit";
10768
+ import { html as html27, LitElement as LitElement26, nothing as nothing10 } from "lit";
10741
10769
  function ensureRibbonStyles() {
10742
10770
  if (typeof document === "undefined") return;
10743
10771
  if (document.getElementById("syntro-pdp-ribbon-style")) return;
@@ -10904,7 +10932,7 @@ var PdpRibbonLit = class extends LitElement26 {
10904
10932
  }
10905
10933
  render() {
10906
10934
  const cls = this._entering ? "syntro-pdp-ribbon is-entering" : "syntro-pdp-ribbon";
10907
- return html26`
10935
+ return html27`
10908
10936
  <div class="${cls}" role="status" aria-live="polite">
10909
10937
  <span class="syntro-pdp-ribbon-sweep" aria-hidden="true"></span>
10910
10938
  <svg
@@ -10924,7 +10952,7 @@ var PdpRibbonLit = class extends LitElement26 {
10924
10952
  </svg>
10925
10953
  <p class="syntro-pdp-ribbon-copy">
10926
10954
  Tailored to your conversation about
10927
- ${this.topic ? html26` <span class="syntro-pdp-ribbon-topic">${this.topic}</span>.` : nothing10}
10955
+ ${this.topic ? html27` <span class="syntro-pdp-ribbon-topic">${this.topic}</span>.` : nothing10}
10928
10956
  <span class="syntro-pdp-ribbon-trail"> ${this.subtitle}</span>
10929
10957
  </p>
10930
10958
  </div>
@@ -10941,7 +10969,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-rib
10941
10969
  }
10942
10970
 
10943
10971
  // src/widgets/PdpQaLit.ts
10944
- import { html as html27, LitElement as LitElement27, nothing as nothing11 } from "lit";
10972
+ import { html as html28, LitElement as LitElement27, nothing as nothing11 } from "lit";
10945
10973
  function ensureQaStyles() {
10946
10974
  if (typeof document === "undefined") return;
10947
10975
  if (document.getElementById("syntro-pdp-qa-style")) return;
@@ -11138,19 +11166,19 @@ var PdpQaLit = class extends LitElement27 {
11138
11166
  }
11139
11167
  render() {
11140
11168
  if (!this.data) {
11141
- return html27`<div data-skeleton class="pdp-qa-skeleton">
11169
+ return html28`<div data-skeleton class="pdp-qa-skeleton">
11142
11170
  <div class="pdp-qa-skeleton-row"></div>
11143
11171
  <div class="pdp-qa-skeleton-row"></div>
11144
11172
  <div class="pdp-qa-skeleton-row"></div>
11145
11173
  </div>`;
11146
11174
  }
11147
- return html27`
11175
+ return html28`
11148
11176
  <section
11149
11177
  class="${this._entering ? "pdp-qa is-entering" : "pdp-qa"}"
11150
11178
  aria-label="Frequently asked questions"
11151
11179
  >
11152
11180
  ${this.data.items.map(
11153
- (item, idx) => html27`
11181
+ (item, idx) => html28`
11154
11182
  <details class="pdp-qa-item" ?open=${idx === 0}>
11155
11183
  <summary class="pdp-qa-question">
11156
11184
  <span>${item.question}</span>
@@ -11179,7 +11207,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-qa"
11179
11207
  }
11180
11208
 
11181
11209
  // src/widgets/PdpRegionalLit.ts
11182
- import { html as html28, LitElement as LitElement28 } from "lit";
11210
+ import { html as html29, LitElement as LitElement28 } from "lit";
11183
11211
  function ensureRegionalStyles() {
11184
11212
  if (typeof document === "undefined") return;
11185
11213
  if (document.getElementById("syntro-pdp-regional-style")) return;
@@ -11403,11 +11431,11 @@ var PdpRegionalLit = class extends LitElement28 {
11403
11431
  }
11404
11432
  render() {
11405
11433
  if (!this.data) {
11406
- return html28`<div data-skeleton class="pdp-qa-skeleton" style="height:200px;">
11434
+ return html29`<div data-skeleton class="pdp-qa-skeleton" style="height:200px;">
11407
11435
  <div class="pdp-qa-skeleton-row" style="height:200px;border-radius:24px;"></div>
11408
11436
  </div>`;
11409
11437
  }
11410
- return html28`
11438
+ return html29`
11411
11439
  <section
11412
11440
  class="${this._entering ? "pdp-regional is-entering" : "pdp-regional"}"
11413
11441
  aria-label="Regional and temporal context"
@@ -11452,7 +11480,7 @@ if (typeof customElements !== "undefined" && !customElements.get("syntro-pdp-reg
11452
11480
  }
11453
11481
 
11454
11482
  // src/widgets/PdpPeerFeedLit.ts
11455
- import { html as html29, LitElement as LitElement29 } from "lit";
11483
+ import { html as html30, LitElement as LitElement29 } from "lit";
11456
11484
  function ensurePeerFeedStyles() {
11457
11485
  if (typeof document === "undefined") return;
11458
11486
  if (document.getElementById("syntro-pdp-peer-feed-style")) return;
@@ -11699,19 +11727,19 @@ var PdpPeerFeedLit = class extends LitElement29 {
11699
11727
  }
11700
11728
  render() {
11701
11729
  if (!this.data) {
11702
- return html29`<div data-skeleton class="pdp-peer-skeleton">
11730
+ return html30`<div data-skeleton class="pdp-peer-skeleton">
11703
11731
  <div class="pdp-peer-skeleton-row"></div>
11704
11732
  <div class="pdp-peer-skeleton-row"></div>
11705
11733
  <div class="pdp-peer-skeleton-row"></div>
11706
11734
  </div>`;
11707
11735
  }
11708
- return html29`
11736
+ return html30`
11709
11737
  <section
11710
11738
  class="${this._entering ? "pdp-peer-feed is-entering" : "pdp-peer-feed"}"
11711
11739
  aria-label="Users like you"
11712
11740
  >
11713
11741
  ${this.data.peers.map(
11714
- (peer) => html29`
11742
+ (peer) => html30`
11715
11743
  <article class="pdp-peer-post">
11716
11744
  <div class="pdp-peer-avatar" aria-hidden="true">${peer.initials}</div>
11717
11745
  <div class="pdp-peer-body">
@@ -11949,4 +11977,4 @@ export {
11949
11977
  * SPDX-License-Identifier: BSD-3-Clause
11950
11978
  *)
11951
11979
  */
11952
- //# sourceMappingURL=chunk-4DLT7VV6.js.map
11980
+ //# sourceMappingURL=chunk-LFYTHTQS.js.map