@gemboss/gem-framework 0.16.1 → 0.18.13

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.
@@ -321,6 +321,30 @@ a {
321
321
  block-size: var(--gem-checkbox-size);
322
322
  accent-color: var(--gem-checkbox-accent);
323
323
  }
324
+ [data-gem-form-set] :is(.gem-quantity-input) {
325
+ min-height: var(--gem-input-height);
326
+ border: var(--gem-input-border-width) solid var(--gem-input-border-color);
327
+ border-radius: min(var(--gem-input-radius), 22px);
328
+ }
329
+ [data-gem-form-set] :is(.gem-quantity-input__button, .gem-quantity-input__field) {
330
+ background: var(--gem-input-bg);
331
+ font-size: var(--gem-input-font-size);
332
+ }
333
+ [data-gem-form-set][data-gem-field-shape="underline"] :is(.gem-quantity-input__button, .gem-quantity-input__field) {
334
+ background: transparent;
335
+ }
336
+ @media (hover: hover) {
337
+ :is(.gem-input, .gem-select, .gem-textarea, .gem-shell-footer__newsletter .gem-input):where(:not(.gem-search-form .gem-input)):hover:not(:disabled):not([aria-invalid="true"]):not(:focus-visible) {
338
+ border-color: currentColor;
339
+ box-shadow: 0 0 0 1px currentColor;
340
+ }
341
+ [data-gem-form-set]:is([data-gem-field-shape="underline"], [data-gem-field-shape="filled"]) :is(.gem-input, .gem-select, .gem-textarea, .gem-shell-footer__newsletter .gem-input):where(:not(.gem-search-form .gem-input)):hover:not(:disabled):not([aria-invalid="true"]):not(:focus-visible) {
342
+ box-shadow: 0 1px 0 0 currentColor;
343
+ }
344
+ }
345
+ :is(.gem-input, .gem-select, .gem-textarea, .gem-shell-footer__newsletter .gem-input):where(:not(.gem-search-form .gem-input))[aria-invalid="true"] {
346
+ border-color: color-mix(in srgb, var(--gem-color-danger, #b42318) 70%, currentColor);
347
+ }
324
348
  .gem-submit {
325
349
  cursor: pointer;
326
350
  }
@@ -495,12 +519,14 @@ a {
495
519
  --gem-stars-value: 5;
496
520
  position: relative;
497
521
  display: inline-block;
522
+ width: max-content;
498
523
  line-height: 1;
499
524
  font-size: var(--gem-text-sm, 0.8125rem);
500
525
  letter-spacing: 0.1em;
501
526
  color: var(--gem-color-border);
502
527
  }
503
528
  .gem-stars__base, .gem-stars__fill { display: block; white-space: nowrap; }
529
+ .gem-stars :is(svg, img) { max-width: none; flex: none; }
504
530
  .gem-stars__fill {
505
531
  position: absolute;
506
532
  inset: 0;
@@ -831,6 +857,10 @@ a {
831
857
  color: var(--gem-color-text);
832
858
  text-align: center;
833
859
  }
860
+ .gem-quantity-input__field {
861
+ display: grid;
862
+ place-items: center;
863
+ }
834
864
  .gem-quantity-input__button {
835
865
  font-weight: 750;
836
866
  }
@@ -1051,7 +1081,7 @@ a {
1051
1081
  [data-gem-ambient] { --gem-ambient-amp: 2px; animation-duration: 12s; }
1052
1082
  [data-gem-reveal] { transition: none; opacity: 1; transform: none; }
1053
1083
  }
1054
- :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top], :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom] { position: relative; overflow: clip; overflow-clip-margin: var(--gem-divider-height, 48px); }
1084
+ :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top]:where([data-gem-divider-top='wave'], [data-gem-divider-top='slope'], [data-gem-divider-top='spikes'], [data-gem-divider-top='arch'], [data-gem-divider-top='blob']), :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom]:where([data-gem-divider-bottom='wave'], [data-gem-divider-bottom='slope'], [data-gem-divider-bottom='spikes'], [data-gem-divider-bottom='arch'], [data-gem-divider-bottom='blob']) { position: relative; overflow: clip; overflow-clip-margin: var(--gem-divider-height, 48px); }
1055
1085
  :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom='wave']::after, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom='slope']::after, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom='spikes']::after, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom='arch']::after, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom='blob']::after, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top='wave']::before, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top='slope']::before, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top='spikes']::before, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top='arch']::before, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top='blob']::before { content: ''; position: absolute; left: 0; right: 0; z-index: 1; pointer-events: none; height: var(--gem-divider-height, 48px); background: var(--gem-section-bg, var(--gem-color-background)); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: 100% 100%; mask-size: 100% 100%; }
1056
1086
  :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom]::after { top: 100%; }
1057
1087
  :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top]::before { bottom: 100%; transform: scaleY(-1); }
@@ -1065,7 +1095,7 @@ a {
1065
1095
  :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top='arch']::before { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0 0 H100 V2 Q50 12 0 2 Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0 0 H100 V2 Q50 12 0 2 Z'/%3E%3C/svg%3E"); }
1066
1096
  :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom='blob']::after { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0 0 H100 V4 C85 11 72 0 58 5 C44 10 30 2 16 6 C10 8 5 5 0 6 Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0 0 H100 V4 C85 11 72 0 58 5 C44 10 30 2 16 6 C10 8 5 5 0 6 Z'/%3E%3C/svg%3E"); }
1067
1097
  :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top='blob']::before { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0 0 H100 V4 C85 11 72 0 58 5 C44 10 30 2 16 6 C10 8 5 5 0 6 Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0 0 H100 V4 C85 11 72 0 58 5 C44 10 30 2 16 6 C10 8 5 5 0 6 Z'/%3E%3C/svg%3E"); }
1068
- :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-card] :is(.gem-section__inner, [class*='__inner']) { border-radius: var(--gem-radius-md); padding: var(--gem-space-xl); }
1098
+ :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-card]:where([data-gem-card='outline'], [data-gem-card='shadow'], [data-gem-card='filled']) :is(.gem-section__inner, [class*='__inner']) { border-radius: var(--gem-radius-md); padding: var(--gem-space-xl); }
1069
1099
  :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-card='outline'] :is(.gem-section__inner, [class*='__inner']) { border: 1px solid var(--gem-color-border); }
1070
1100
  :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-card='shadow'] :is(.gem-section__inner, [class*='__inner']) { background: var(--gem-color-surface); box-shadow: var(--gem-shadow-md); }
1071
1101
  :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-card='filled'] :is(.gem-section__inner, [class*='__inner']) { background: color-mix(in srgb, currentColor 6%, transparent); }
@@ -1435,5 +1465,12 @@ a {
1435
1465
  .gem-collection-filter-toolbar__active-filter, .gem-collection-filter-toolbar__clear { min-height: 2.25rem; align-items: center; }
1436
1466
  }
1437
1467
 
1438
- :where([data-gem-edition='2']) { --gem-section-heading-size: calc(var(--gem-h2) * var(--gem-typography-heading-scale, 1)); --gem-hero-heading-size: calc(var(--gem-h1) * var(--gem-typography-heading-scale, 1)); }
1468
+ :where([data-gem-edition='3']) .gem-product-card-grid--quick-view-grid .gem-product-card-grid__card { border: 0; border-radius: 0; box-shadow: none; background: transparent; padding: 0; }
1469
+ :where([data-gem-edition='3']) .gem-product-card-grid--quick-view-grid .gem-product-card__media > .gem-product-card__badges { display: flex; }
1470
+ @media (max-width: 989px) { :where([data-gem-edition='3']) .gem-product-card-grid--quick-view-grid .gem-product-card-grid__grid[data-gem-product-grid] { grid-template-columns: repeat(var(--gem-product-card-grid-mobile-columns, 2), minmax(0, 1fr)); } }
1471
+ :where([data-gem-edition='3']) .gem-hero.gem-hero-banner--compact-collection .gem-hero__overlay:not(.has-media) { position: relative; inset: auto; z-index: auto; opacity: 1; width: min(var(--gem-layout-page, 1200px), calc(100% - var(--gem-layout-gutter, 32px))); margin: clamp(24px, 5vw, 48px) auto 0; background: none; color: var(--gem-color-text); border-radius: 0; }
1472
+ :where([data-gem-edition='3']) .gem-hero.gem-hero-banner--compact-collection .gem-hero__overlay:not(.has-media) .gem-hero__heading { color: var(--gem-color-text); }
1473
+ :where([data-gem-edition='3']) .gem-section.gem-hero.gem-hero-banner--compact-collection:not(:has(> .gem-hero__bg)) { padding-block-end: 0; }
1474
+
1475
+ :where([data-gem-edition='2'], [data-gem-edition='3']) { --gem-section-heading-size: calc(var(--gem-h2) * var(--gem-typography-heading-scale, 1)); --gem-hero-heading-size: calc(var(--gem-h1) * var(--gem-typography-heading-scale, 1)); }
1439
1476
 
@@ -1,3 +1,38 @@
1
+ // ../../packages/gem-framework/src/section-dividers.ts
2
+ var spikes = (() => {
3
+ const teeth = [];
4
+ for (let x = 95; x > 0; x -= 5) teeth.push(`L${x} ${teeth.length % 2 === 0 ? 10 : 3}`);
5
+ return `M0 0 H100 V3 ${teeth.join(" ")} L0 ${teeth.length % 2 === 0 ? 10 : 3} Z`;
6
+ })();
7
+ var GEM_SECTION_DIVIDER_PATHS = Object.freeze({
8
+ wave: "M0 0 H100 V3 C80 9 70 -1 50 4 C30 9 20 1 0 4 Z",
9
+ slope: "M0 0 H100 V10 Z",
10
+ spikes,
11
+ arch: "M0 0 H100 V2 Q50 12 0 2 Z",
12
+ blob: "M0 0 H100 V4 C85 11 72 0 58 5 C44 10 30 2 16 6 C10 8 5 5 0 6 Z"
13
+ });
14
+ var NUMBER = "[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:e[+-]?\\d+)?";
15
+ var CHANNEL = new RegExp(`^${NUMBER}%?$`, "i");
16
+ var PERCENT = new RegExp(`^${NUMBER}%$`, "i");
17
+ var ANGLE = new RegExp(`^${NUMBER}(?:deg|grad|rad|turn)?$`, "i");
18
+ var GEM_ELEMENT_SECTION_DIVIDER_CSS = [
19
+ ".gem-el-section[data-gem-element-dividers] { position: relative; }",
20
+ // A configured edge must escape the band's parallax clip. The media keeps its own clipped
21
+ // wrapper so releasing the root cannot expose the deliberately oversized moving background.
22
+ ".gem-el-section[data-gem-parallax][data-gem-element-dividers] { overflow: visible; isolation: auto; }",
23
+ ".gem-el-section[data-gem-element-dividers] > .gem-el-section__parallax-clip { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; pointer-events: none; z-index: 0; }",
24
+ // Edge paint may extend into a neighbour with little padding. Only content, never its background,
25
+ // stacks above it. Guard on the current document's opted-in markup: a retained CSS resource after
26
+ // navigation must not change a page with no native dividers.
27
+ // An ordinary neighbouring parallax band also isolates its content by default. Release that
28
+ // stacking context on divider documents, retaining its existing media clip and direct markup.
29
+ "body:has(.gem-el-section[data-gem-element-dividers]) .gem-el-section[data-gem-parallax] { isolation: auto; }",
30
+ "body:has(.gem-el-section[data-gem-element-dividers]) .gem-el-section > .gem-el-section__inner { position: relative; z-index: 2; }",
31
+ ".gem-el-section > .gem-el-section__divider { position: absolute; display: block; inset-inline: 0; width: 100%; max-width: none; height: var(--gem-element-divider-height, 48px); color: var(--gem-element-divider-color, var(--gem-color-background)); overflow: hidden; pointer-events: none; z-index: 1; transform: scaleX(var(--gem-element-divider-scale-x, 1)); }",
32
+ ".gem-el-section > .gem-el-section__divider--bottom { top: 100%; }",
33
+ ".gem-el-section > .gem-el-section__divider--top { bottom: 100%; transform: scaleX(var(--gem-element-divider-scale-x, 1)) scaleY(-1); }"
34
+ ].join("\n");
35
+
1
36
  // ../../packages/gem-framework/src/form-set.ts
2
37
  var GEM_FORM_TOKEN_KEYS = [
3
38
  "radius",
@@ -51,7 +86,7 @@ var GEM_FORM_DEFAULTS = {
51
86
  checkboxAccent: "var(--gem-color-accent)",
52
87
  checkboxSize: "24px"
53
88
  };
54
- var GEM_FORM_VAR_SCOPE = "[data-gem-form-set], [data-gem-form-set] :is(input, select, textarea, button, form)";
89
+ var GEM_FORM_VAR_SCOPE = "[data-gem-form-set], [data-gem-form-set] :is(input, select, textarea, button, form, output)";
55
90
  function gemFormCssBlock(form) {
56
91
  const vars = gemFormCssVars(form);
57
92
  return vars.length ? `${GEM_FORM_VAR_SCOPE} {
@@ -573,12 +608,12 @@ function gemMobileTokenCssVars(tokens, phone = readPhoneTokens(tokens)) {
573
608
  var rampKey = (k) => k.toLowerCase().replace(/[^a-z0-9]/g, "");
574
609
  var isRampKey = (k) => GEM_TYPE_RAMP_KEYS.some((r) => rampKey(r) === rampKey(k));
575
610
  var LENGTH = /^\d*\.?\d+(px|rem|em)$/;
576
- var NUMBER = /^\d*\.?\d+$/;
611
+ var NUMBER2 = /^\d*\.?\d+$/;
577
612
  var typeRampValue = (typography, key) => {
578
613
  const hit = Object.entries(typography ?? {}).find(([k]) => rampKey(k) === rampKey(key));
579
614
  const v = hit == null || hit[1] == null ? "" : stripImportant(hit[1]).trim();
580
615
  if (!v) return null;
581
- return (key === "scale" ? NUMBER.test(v) && Number(v) > 0 : LENGTH.test(v)) ? v : null;
616
+ return (key === "scale" ? NUMBER2.test(v) && Number(v) > 0 : LENGTH.test(v)) ? v : null;
582
617
  };
583
618
  var GEM_TYPE_MOBILE_MAX = "749px";
584
619
  function gemTypeRampCssVars(typography) {
@@ -653,6 +688,14 @@ function slugify(value) {
653
688
  var EDITION_2_CSS = [
654
689
  `:where(&) { ${GEM_HEADING_SIZE_CSS_VARS.filter((decl) => !decl.startsWith("--gem-section-heading-size-mobile") && !decl.startsWith("--gem-hero-heading-size-mobile")).join(" ")} }`
655
690
  ];
691
+ var EDITION_3_ELEMENTS = [
692
+ `:where(&) .gem-product-card-grid--quick-view-grid .gem-product-card-grid__card { border: 0; border-radius: 0; box-shadow: none; background: transparent; padding: 0; }`,
693
+ `:where(&) .gem-product-card-grid--quick-view-grid .gem-product-card__media > .gem-product-card__badges { display: flex; }`,
694
+ `@media (max-width: 989px) { :where(&) .gem-product-card-grid--quick-view-grid .gem-product-card-grid__grid[data-gem-product-grid] { grid-template-columns: repeat(var(--gem-product-card-grid-mobile-columns, 2), minmax(0, 1fr)); } }`,
695
+ `:where(&) .gem-hero.gem-hero-banner--compact-collection .gem-hero__overlay:not(.has-media) { position: relative; inset: auto; z-index: auto; opacity: 1; width: min(var(--gem-layout-page, 1200px), calc(100% - var(--gem-layout-gutter, 32px))); margin: clamp(24px, 5vw, 48px) auto 0; background: none; color: var(--gem-color-text); border-radius: 0; }`,
696
+ `:where(&) .gem-hero.gem-hero-banner--compact-collection .gem-hero__overlay:not(.has-media) .gem-hero__heading { color: var(--gem-color-text); }`,
697
+ `:where(&) .gem-section.gem-hero.gem-hero-banner--compact-collection:not(:has(> .gem-hero__bg)) { padding-block-end: 0; }`
698
+ ];
656
699
  var GEM_FRAMEWORK_EDITIONS = [
657
700
  { edition: 1, since: "0.1.0", released: "2026-07-04", changes: [], css: [] },
658
701
  {
@@ -661,12 +704,27 @@ var GEM_FRAMEWORK_EDITIONS = [
661
704
  released: "2026-10-10",
662
705
  changes: ["Section headings and hero titles follow your type scale on tablets and computers. Phones keep their current size."],
663
706
  css: EDITION_2_CSS
707
+ },
708
+ {
709
+ // Edition 3. Collection pages at Dawn's tiers (12/10/2026, measured on a "Start from scratch" theme): EDITION_3_ELEMENTS.
710
+ edition: 3,
711
+ since: "0.17.0",
712
+ released: "2026-10-12",
713
+ changes: [
714
+ "Collection grids: each product photo fills its column, phones and tablets show your mobile column count, and Sale and Sold out badges appear.",
715
+ "The collection title sits on the page, lined up with the products, in your text colour."
716
+ ],
717
+ css: [],
718
+ elements: EDITION_3_ELEMENTS
664
719
  }
665
720
  ];
666
721
  var LATEST_GEM_FRAMEWORK_EDITION = GEM_FRAMEWORK_EDITIONS[GEM_FRAMEWORK_EDITIONS.length - 1].edition;
667
722
  function gemFrameworkEditionScope(edition) {
668
723
  return GEM_FRAMEWORK_EDITIONS.filter((e) => e.edition >= edition).map((e) => `[data-gem-edition='${e.edition}']`).join(", ");
669
724
  }
725
+ function gemFrameworkEditionElementCss() {
726
+ return GEM_FRAMEWORK_EDITIONS.flatMap((e) => (e.elements ?? []).map((rule) => rule.replaceAll("&", gemFrameworkEditionScope(e.edition)))).join("\n");
727
+ }
670
728
  function gemFrameworkEditionCss() {
671
729
  return GEM_FRAMEWORK_EDITIONS.flatMap((e) => e.css.map((rule) => rule.replaceAll("&", gemFrameworkEditionScope(e.edition)))).join("\n");
672
730
  }
@@ -1086,18 +1144,8 @@ var GEM_POPUP_SHELL_CSS = GEM_POPUP_SHELL_CSS_LINES.join("\n");
1086
1144
 
1087
1145
  // ../../packages/gem-framework/src/primitives.ts
1088
1146
  var dividerMask = (path) => `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='${path}'/%3E%3C/svg%3E")`;
1089
- var spikePath = (() => {
1090
- const teeth = [];
1091
- for (let x = 95; x > 0; x -= 5) teeth.push(`L${x} ${teeth.length % 2 === 0 ? 10 : 3}`);
1092
- return `M0 0 H100 V3 ${teeth.join(" ")} L0 ${teeth.length % 2 === 0 ? 10 : 3} Z`;
1093
- })();
1094
- var DIVIDER_SHAPES = {
1095
- wave: "M0 0 H100 V3 C80 9 70 -1 50 4 C30 9 20 1 0 4 Z",
1096
- slope: "M0 0 H100 V10 Z",
1097
- spikes: spikePath,
1098
- arch: "M0 0 H100 V2 Q50 12 0 2 Z",
1099
- blob: "M0 0 H100 V4 C85 11 72 0 58 5 C44 10 30 2 16 6 C10 8 5 5 0 6 Z"
1100
- };
1147
+ var knownValues = (attr, values) => `:where(${values.map((v) => `[${attr}='${v}']`).join(", ")})`;
1148
+ var DIVIDER_SHAPES = Object.keys(GEM_SECTION_DIVIDER_PATHS);
1101
1149
  var GEM_DIVIDER_CSS_LINES = [
1102
1150
  // The clip is WIDENED, not removed. `.gem-section` sets `overflow: clip` and the wedge is drawn
1103
1151
  // at `top: 100%` / `bottom: 100%` — entirely outside the box — so the parent deleted every
@@ -1108,7 +1156,8 @@ var GEM_DIVIDER_CSS_LINES = [
1108
1156
  // it entirely would paint square corners over that radius. A browser without
1109
1157
  // `overflow-clip-margin` keeps plain `clip` — the divider stays hidden, which is today's
1110
1158
  // behaviour rather than a broken layout.
1111
- ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top], :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom] { position: relative; overflow: clip; overflow-clip-margin: var(--gem-divider-height, 48px); }",
1159
+ // Only for a shape that has a mask (knownValues): a "none" edge used to widen the clip by 48px for nothing.
1160
+ `:is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top]${knownValues("data-gem-divider-top", DIVIDER_SHAPES)}, :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom]${knownValues("data-gem-divider-bottom", DIVIDER_SHAPES)} { position: relative; overflow: clip; overflow-clip-margin: var(--gem-divider-height, 48px); }`,
1112
1161
  // Shared geometry. `top: 100%` / `bottom: 100%` put it outside the box; z-index 1 keeps it above the
1113
1162
  // neighbouring band's background. pointer-events: none so it never eats a click near the seam.
1114
1163
  // Qualified by SHAPE. Unqualified, any value paints a solid 48px slab — including the literal
@@ -1118,7 +1167,7 @@ var GEM_DIVIDER_CSS_LINES = [
1118
1167
  ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom]::after { top: 100%; }",
1119
1168
  // The top edge reuses the same masks, mirrored, so five shapes cover both edges.
1120
1169
  ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-top]::before { bottom: 100%; transform: scaleY(-1); }",
1121
- ...Object.entries(DIVIDER_SHAPES).flatMap(([name, path]) => {
1170
+ ...Object.entries(GEM_SECTION_DIVIDER_PATHS).flatMap(([name, path]) => {
1122
1171
  const mask = dividerMask(path);
1123
1172
  return [
1124
1173
  `:is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-divider-bottom='${name}']::after { -webkit-mask-image: ${mask}; mask-image: ${mask}; }`,
@@ -1127,8 +1176,10 @@ var GEM_DIVIDER_CSS_LINES = [
1127
1176
  })
1128
1177
  ];
1129
1178
  var GEM_DIVIDER_CSS = GEM_DIVIDER_CSS_LINES.join("\n");
1179
+ var GEM_CARD_STYLES = ["outline", "shadow", "filled"];
1130
1180
  var GEM_CARD_CSS_LINES = [
1131
- ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-card] :is(.gem-section__inner, [class*='__inner']) { border-radius: var(--gem-radius-md); padding: var(--gem-space-xl); }",
1181
+ // Only for a style that draws (knownValues): "none", the knob's revert value, arrives here as an attribute too.
1182
+ `:is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-card]${knownValues("data-gem-card", GEM_CARD_STYLES)} :is(.gem-section__inner, [class*='__inner']) { border-radius: var(--gem-radius-md); padding: var(--gem-space-xl); }`,
1132
1183
  ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-card='outline'] :is(.gem-section__inner, [class*='__inner']) { border: 1px solid var(--gem-color-border); }",
1133
1184
  ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-card='shadow'] :is(.gem-section__inner, [class*='__inner']) { background: var(--gem-color-surface); box-shadow: var(--gem-shadow-md); }",
1134
1185
  // `filled` tints the section's own ground rather than reaching for a fixed colour, so it stays
@@ -1211,6 +1262,23 @@ var GEM_FORM_SET_CSS_LINES = [
1211
1262
  " inline-size: var(--gem-checkbox-size);",
1212
1263
  " block-size: var(--gem-checkbox-size);",
1213
1264
  " accent-color: var(--gem-checkbox-accent);",
1265
+ "}",
1266
+ // THE QUANTITY STEPPER IS A FIELD OF THE SET (20/10/2026): its box takes the set's height, edge and corner (capped at
1267
+ // 22px, so a pill set draws a round stepper, not a 999px lozenge), its -/+ and number the set's fill and text size, and
1268
+ // the underline shape paints no cell, as it paints no field. The storefront carried these (gemsite #1001/#1007, with its
1269
+ // own element stepper in the :is() lists); the package did not, so every section the kho previewed drew a square 44px
1270
+ // stepper beside 48px pill fields (GemFactory Framework › Controls, measured 20/10/2026).
1271
+ "[data-gem-form-set] :is(.gem-quantity-input) {",
1272
+ " min-height: var(--gem-input-height);",
1273
+ " border: var(--gem-input-border-width) solid var(--gem-input-border-color);",
1274
+ " border-radius: min(var(--gem-input-radius), 22px);",
1275
+ "}",
1276
+ "[data-gem-form-set] :is(.gem-quantity-input__button, .gem-quantity-input__field) {",
1277
+ " background: var(--gem-input-bg);",
1278
+ " font-size: var(--gem-input-font-size);",
1279
+ "}",
1280
+ '[data-gem-form-set][data-gem-field-shape="underline"] :is(.gem-quantity-input__button, .gem-quantity-input__field) {',
1281
+ " background: transparent;",
1214
1282
  "}"
1215
1283
  ];
1216
1284
  var GEM_FORM_SET_CSS = GEM_FORM_SET_CSS_LINES.join("\n");
@@ -1415,7 +1483,7 @@ function createGemBaseCssParts(profile) {
1415
1483
  ].join("\n");
1416
1484
  return {
1417
1485
  // Edition rules close the primitives (editions.ts): custom properties on <html>, scoped :where([data-gem-edition]).
1418
- primitives: [reset, "", createPrimitiveCss(), "", gemFrameworkEditionCss(), "", ""].join("\n"),
1486
+ primitives: [reset, "", createPrimitiveCss(), "", gemFrameworkEditionElementCss(), "", gemFrameworkEditionCss(), "", ""].join("\n"),
1419
1487
  sections: [createShellCss(), "", createSectionCss(), "", createThemeProfileCss(profile)].join("\n")
1420
1488
  };
1421
1489
  }
@@ -1425,7 +1493,11 @@ function createThemeProfileCss(profile = "dawn-parity") {
1425
1493
  function createMorphProfileCss() {
1426
1494
  return [
1427
1495
  "/* Gem morph profile: style packs and section presets provide visual transformation above core primitives. */",
1428
- ":root { --gem-profile-mode: morph; }"
1496
+ ":root { --gem-profile-mode: morph; }",
1497
+ // A morph theme's quick-view card is a box drawn from its card tokens (the .gem-card primitive). Edition 3 unboxes this
1498
+ // card for Dawn's collection page; restated here one class higher, so a morph theme keeps its box and its card knobs on
1499
+ // every edition (review of #764). The same values as .gem-card: nothing changes for a morph store on edition 1 or 2.
1500
+ ".gem-product-card-grid--quick-view-grid .gem-card.gem-product-card-grid__card { border: var(--gem-border-subtle, 1px solid var(--gem-color-border)); border-radius: var(--gem-card-radius, var(--gem-radius-md)); background: var(--gem-card-background, var(--gem-color-surface)); padding: var(--gem-component-card-padding, var(--gem-space-md)); box-shadow: var(--gem-shadow-sm, none); }"
1429
1501
  ].join("\n");
1430
1502
  }
1431
1503
  function createPrimitiveCss() {
@@ -1648,8 +1720,9 @@ function createPrimitiveCss() {
1648
1720
  " width: auto;",
1649
1721
  " min-width: min(10rem, 50%);",
1650
1722
  "}",
1651
- // A wrapped field gets the join's height too: the dawn-parity profile sets .gem-input { min-height: 4.5rem }, and
1652
- // only the direct-child rule above outranked it, so a wrapped input stood 72px next to a 44px one (02/10/2026).
1723
+ // A wrapped field gets the join's height too: the dawn-parity profile's 4.5rem floor named .gem-input until 0.18.12, and
1724
+ // only the direct-child rule above outranked it, so a wrapped input stood 72px next to a 44px one (02/10/2026). The
1725
+ // floor no longer names it; this keeps a wrapped field at the join's height whatever a profile floors it at.
1653
1726
  ".gem-field-join > .gem-form-field > :is(.gem-input, .gem-select) {",
1654
1727
  " width: 100%;",
1655
1728
  " height: 100%;",
@@ -1687,6 +1760,32 @@ function createPrimitiveCss() {
1687
1760
  " accent-color: var(--gem-color-accent);",
1688
1761
  "}",
1689
1762
  ...GEM_FORM_SET_CSS_LINES,
1763
+ // HOVER AND ERROR (§9.2 state matrix, 20/10/2026): GemFactory Framework › Controls measured both INERT, so a field a
1764
+ // shopper points at, or one a form marked invalid, looked like any other. Written once for every field, with or
1765
+ // without a form set.
1766
+ // HOVER thickens the edge by 1px in the field's own ink, as Dawn does (`box-shadow: 0 0 0 calc(border + .1rem)`): a
1767
+ // colour change alone was invisible under every form set, whose edge is already the ink (measured #1f2224 → #202223).
1768
+ // The ring follows the box and its corner; an underline or filled field has only a bottom rule, so only that thickens.
1769
+ // ERROR (`aria-invalid="true"`, set by the form) takes the danger colour mixed 70/30 with that ink, which keeps the
1770
+ // edge at 3:1 or more on a white field (9.7:1), an underline field on a dark band (4.2:1) and on an accent band
1771
+ // (3.0:1); plain #b42318 there was 2.4:1 and 1.8:1. Only the edge colour changes, so every shape keeps its edges.
1772
+ // Hover skips a disabled or invalid field (an error must not lose its colour under the pointer), a focused one (the
1773
+ // focus halo on a dark or accent band is a box-shadow, and a click focuses a text field as :focus-visible, so the
1774
+ // pointer still on it would wipe the halo: review) and touch screens, where a tap would leave it stuck.
1775
+ // Specificity: hover (0,6,0; 0,8,0 per shape) outranks the set's field rule (0,3,0); error (0,3,0) ties it and wins by
1776
+ // coming later in the sheet.
1777
+ "@media (hover: hover) {",
1778
+ ' :is(.gem-input, .gem-select, .gem-textarea, .gem-shell-footer__newsletter .gem-input):where(:not(.gem-search-form .gem-input)):hover:not(:disabled):not([aria-invalid="true"]):not(:focus-visible) {',
1779
+ " border-color: currentColor;",
1780
+ " box-shadow: 0 0 0 1px currentColor;",
1781
+ " }",
1782
+ ' [data-gem-form-set]:is([data-gem-field-shape="underline"], [data-gem-field-shape="filled"]) :is(.gem-input, .gem-select, .gem-textarea, .gem-shell-footer__newsletter .gem-input):where(:not(.gem-search-form .gem-input)):hover:not(:disabled):not([aria-invalid="true"]):not(:focus-visible) {',
1783
+ " box-shadow: 0 1px 0 0 currentColor;",
1784
+ " }",
1785
+ "}",
1786
+ ':is(.gem-input, .gem-select, .gem-textarea, .gem-shell-footer__newsletter .gem-input):where(:not(.gem-search-form .gem-input))[aria-invalid="true"] {',
1787
+ " border-color: color-mix(in srgb, var(--gem-color-danger, #b42318) 70%, currentColor);",
1788
+ "}",
1690
1789
  ".gem-submit {",
1691
1790
  " cursor: pointer;",
1692
1791
  "}",
@@ -1871,17 +1970,25 @@ function createPrimitiveCss() {
1871
1970
  // .gem-rating above is a type rule for a text label; every actual star row in the theme was a
1872
1971
  // hardcoded five-glyph literal, so a captured 4-of-5 (or a half star) had nowhere to land. The
1873
1972
  // fill is a percentage-width overlay, so fractional values render exactly instead of rounding.
1973
+ // SVG stars (GemFactory gap #45, 0.18.11): real review widgets draw each star as an SVG (solid + outline), and the
1974
+ // eight product-reviews sections rebuilt in GemFactory put those SVGs in __base / __fill. Two things broke the fill
1975
+ // (measured 12/10/2026): the base `svg { max-width: 100% }` shrank the SVGs in the clipped __fill to the fill's
1976
+ // width (4.2 drew as five squeezed stars), and a .gem-stars that is a stretched grid / flex item computed its
1977
+ // percentage against the stretched width (3 of 5 drew as 5). The row is as wide as its stars, always, and a star
1978
+ // keeps its own size inside the clip.
1874
1979
  ".gem-stars {",
1875
1980
  " --gem-stars-total: 5;",
1876
1981
  " --gem-stars-value: 5;",
1877
1982
  " position: relative;",
1878
1983
  " display: inline-block;",
1984
+ " width: max-content;",
1879
1985
  " line-height: 1;",
1880
1986
  " font-size: var(--gem-text-sm, 0.8125rem);",
1881
1987
  " letter-spacing: 0.1em;",
1882
1988
  " color: var(--gem-color-border);",
1883
1989
  "}",
1884
1990
  ".gem-stars__base, .gem-stars__fill { display: block; white-space: nowrap; }",
1991
+ ".gem-stars :is(svg, img) { max-width: none; flex: none; }",
1885
1992
  ".gem-stars__fill {",
1886
1993
  " position: absolute;",
1887
1994
  " inset: 0;",
@@ -2238,6 +2345,12 @@ function createPrimitiveCss() {
2238
2345
  " color: var(--gem-color-text);",
2239
2346
  " text-align: center;",
2240
2347
  "}",
2348
+ // The number in the middle of its cell, as the -/+ beside it (a <button> centres its label; an <output> is inline and
2349
+ // put the digit 8-9px above the middle; Framework › Controls, 20/10/2026).
2350
+ ".gem-quantity-input__field {",
2351
+ " display: grid;",
2352
+ " place-items: center;",
2353
+ "}",
2241
2354
  ".gem-quantity-input__button {",
2242
2355
  " font-weight: 750;",
2243
2356
  "}",
@@ -3387,7 +3500,7 @@ function createDawnParityCss() {
3387
3500
  ".gem-card, .gem-product-card { border: 0; border-radius: 0; box-shadow: none; background: transparent; padding: 0; }",
3388
3501
  ".gem-product-card__media, .gem-media { border: 0; border-radius: 0; box-shadow: none; background: rgb(244 244 244); }",
3389
3502
  ".gem-product-card__media { display: block; position: relative; width: 100%; height: 0; min-block-size: 0; padding-bottom: 100%; aspect-ratio: auto; overflow: hidden; }",
3390
- ".gem-featured-collection--editorial-grid .gem-product-card__media, .gem-product-card-grid--quick-view-grid .gem-product-card__media, .gem-main-search .gem-product-card__media, .gem-cart-recommendations--dawn-empty .gem-product-card__media { min-block-size: 0 !important; }",
3503
+ ".gem-featured-collection--editorial-grid .gem-product-card__media, .gem-product-card-grid--quick-view-grid .gem-product-card__media, .gem-main-search .gem-product-card__media, .gem-cart-recommendations--dawn-empty .gem-product-card__media, .gem-recommended-products--product-rail .gem-product-card__media, .gem-cart-recommendations--product-rail .gem-product-card__media { min-block-size: 0 !important; }",
3391
3504
  ".gem-product-card__media > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }",
3392
3505
  // Home product grids show generated/lifestyle imagery (not catalog product-on-white shots), so
3393
3506
  // `contain` letterboxes them inside the square card (looks misaligned / floating off the box).
@@ -3404,7 +3517,7 @@ function createDawnParityCss() {
3404
3517
  ".gem-cart-recommendations--dawn-empty .gem-product-card__quick-actions { display: none; }",
3405
3518
  ".gem-featured-collection--editorial-grid > .gem-section__inner > .gem-section__heading, .gem-featured-collection--editorial-grid > .gem-section__inner > .gem-section__body { display: none; }",
3406
3519
  ".gem-featured-collection--editorial-grid { padding-block: 28px 36px; }",
3407
- ".gem-featured-collection--editorial-grid .gem-section__grid, .gem-product-card-grid--quick-view-grid .gem-section__grid, .gem-main-search .gem-section__grid { grid-template-columns: repeat(var(--gem-product-card-grid-columns, 4), minmax(0, 1fr)); gap: 8px; }",
3520
+ ".gem-featured-collection--editorial-grid .gem-section__grid, .gem-product-card-grid--quick-view-grid .gem-section__grid, .gem-main-search .gem-section__grid, .gem-recommended-products--product-rail .gem-section__grid, .gem-cart-recommendations--product-rail .gem-section__grid { grid-template-columns: repeat(var(--gem-product-card-grid-columns, 4), minmax(0, 1fr)); gap: 8px; }",
3408
3521
  ".gem-product-card-grid--quick-view-grid { padding-top: 0; }",
3409
3522
  ".gem-product-card-grid--quick-view-grid .gem-section__heading:empty { display: none; }",
3410
3523
  // Hide a compare-at only when the price ISN'T actually on sale. The rule used to hide it
@@ -3574,14 +3687,16 @@ function createDawnParityMobileCss() {
3574
3687
  " .gem-hero-banner--compact-collection { padding-block: 25px; }",
3575
3688
  " .gem-hero-banner--compact-collection .gem-section__heading { font-size: 30px; line-height: 39px; }",
3576
3689
  " .gem-product-card-grid--quick-view-grid > .gem-section__inner, .gem-main-search > .gem-section__inner { width: calc(100% - 30px); }",
3577
- " .gem-product-card-grid--quick-view-grid .gem-product-card-grid__grid { gap: 4px !important; }",
3690
+ // 8px on a phone too, as the featured collection and the two product rails: the cards are Dawn's flat cards, and with
3691
+ // no padding of their own a 4px gap left two columns of titles 4px apart at 320 (review of gemsite #951).
3692
+ " .gem-product-card-grid--quick-view-grid .gem-product-card-grid__grid { gap: 8px !important; }",
3578
3693
  " .gem-product-card__content { padding-top: 8px; gap: 4px; }",
3579
3694
  " .gem-product-card__title { font-size: 15px; line-height: 24px; }",
3580
3695
  " .gem-product-card__price, .gem-product-card__price .gem-price { font-size: 16px; line-height: 24px; }",
3581
3696
  // Fallback = the profile's own phone heading, declared once as --gem-heading-phone-cap on the :root above.
3582
3697
  " .gem-section__heading { font-size: var(--gem-section-heading-size-mobile, var(--gem-heading-phone-cap)); }",
3583
3698
  " .gem-hero-banner h1, .gem-hero-banner h2 { font-size: var(--gem-hero-heading-size-mobile, var(--gem-heading-phone-cap)); }",
3584
- " .gem-featured-collection--editorial-grid .gem-section__grid, .gem-product-card-grid--quick-view-grid .gem-section__grid, .gem-main-search .gem-section__grid { grid-template-columns: repeat(var(--gem-product-card-grid-mobile-columns, 2), minmax(0, 1fr)); }",
3699
+ " .gem-featured-collection--editorial-grid .gem-section__grid, .gem-product-card-grid--quick-view-grid .gem-section__grid, .gem-main-search .gem-section__grid, .gem-recommended-products--product-rail .gem-section__grid, .gem-cart-recommendations--product-rail .gem-section__grid { grid-template-columns: repeat(var(--gem-product-card-grid-mobile-columns, 2), minmax(0, 1fr)); }",
3585
3700
  " .gem-product-main[data-gem-product-main-layout='dawn-main'] > .gem-section__inner { width: calc(100% - 30px); }",
3586
3701
  " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-media-gallery__frame { display: flex; gap: 0; overflow-x: auto; scroll-snap-type: x mandatory; }",
3587
3702
  " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-media-gallery__item { flex: 0 0 100%; scroll-snap-align: start; aspect-ratio: 1 / 1; }",
@@ -3832,7 +3947,10 @@ function createShellCss() {
3832
3947
  ".newsletter-form__field-wrapper, .field {",
3833
3948
  " position: relative;",
3834
3949
  "}",
3835
- ".field__input, .field input, .gem-input {",
3950
+ // Dawn's field floor, for Dawn's own field classes. It named .gem-input too, and 4.5rem is Dawn's 45px only on Dawn's
3951
+ // 10px root: on this 16px root a .gem-input stood 72px beside a 44px select and stepper whenever no form set ruled it
3952
+ // (GemFactory Framework › Controls, 20/10/2026). A .gem-input takes the primitive's floor, as every field does.
3953
+ ".field__input, .field input {",
3836
3954
  " min-height: 4.5rem;",
3837
3955
  " border-radius: var(--inputs-radius, 0);",
3838
3956
  "}",
@@ -5061,6 +5179,11 @@ var claimNamed = (key) => CLAIM_KEY.test(key) && !DISPLAY_QUANTITY.test(key);
5061
5179
  function stringLiteralsIn(line) {
5062
5180
  return [...line.matchAll(/(["'`])((?:\\.|(?!\1)[^\\])*)\1/g)].map((m) => m[2]);
5063
5181
  }
5182
+ var VERIFIED_FLAG = String.raw`\b(?:is_?)?verified(?:_?(?:buyer|purchase|purchaser|customer|review))?\b`;
5183
+ var VERIFIED_BY_DEFAULT = new RegExp(
5184
+ `(?:${VERIFIED_FLAG}\\s*(?:!==?\\s*false\\b|(?:\\?\\?|\\|\\|)=?\\s*(?:true|!0)\\b|===?\\s*false\\s*\\?\\s*(?:null|undefined|false|""|'')\\s*:)|(?<=[{[,(]\\s*)${VERIFIED_FLAG}\\s*=(?![=>])\\s*(?:true|!0)\\b)`,
5185
+ "i"
5186
+ );
5064
5187
  function fabricatedProofInSource(raw) {
5065
5188
  const src = blankComments(raw);
5066
5189
  const out = [];
@@ -5108,6 +5231,11 @@ function fabricatedProofInSource(raw) {
5108
5231
  out.push({ line: at, why: `${kind} ${JSON.stringify(text)}`, text: line.trim() });
5109
5232
  }
5110
5233
  });
5234
+ const code = src.replace(/(["'])((?:\\.|(?!\1)[^\\\n])*)\1/g, (_m, q, body) => q + body.replace(/[^\n]/g, " ") + q);
5235
+ for (const m of code.matchAll(new RegExp(VERIFIED_BY_DEFAULT.source, "gi"))) {
5236
+ const at = code.slice(0, m.index).split("\n").length;
5237
+ out.push({ line: at, why: `verified by default (${m[0].replace(/\s+/g, " ").trim()}); badge only on verified === true`, text: (lines[at - 1] ?? "").trim() });
5238
+ }
5111
5239
  for (const r of demoReads) {
5112
5240
  const onDemoLine = caught.has(`${r.entry.line}\0key\0${r.key}`) || stringLiteralsIn(r.entry.value).some((text) => caught.has(`${r.entry.line}\0str\0${text}`));
5113
5241
  if (!onDemoLine) out.push({ line: r.at, why: r.why, text: r.text });
@@ -5272,6 +5400,7 @@ export {
5272
5400
  SHARED_FRAMEWORK_PREFIXES,
5273
5401
  TESTIMONY_NAME,
5274
5402
  TESTIMONY_PROPERTY,
5403
+ VERIFIED_BY_DEFAULT,
5275
5404
  claimIn,
5276
5405
  classesStyledBy,
5277
5406
  cssPairingOrphans,
package/dist/sections.css CHANGED
@@ -163,7 +163,7 @@ sticky-header.header-wrapper {
163
163
  .newsletter-form__field-wrapper, .field {
164
164
  position: relative;
165
165
  }
166
- .field__input, .field input, .gem-input {
166
+ .field__input, .field input {
167
167
  min-height: 4.5rem;
168
168
  border-radius: var(--inputs-radius, 0);
169
169
  }
@@ -859,7 +859,7 @@ main > .gem-section:first-child { padding-top: 0; }
859
859
  .gem-card, .gem-product-card { border: 0; border-radius: 0; box-shadow: none; background: transparent; padding: 0; }
860
860
  .gem-product-card__media, .gem-media { border: 0; border-radius: 0; box-shadow: none; background: rgb(244 244 244); }
861
861
  .gem-product-card__media { display: block; position: relative; width: 100%; height: 0; min-block-size: 0; padding-bottom: 100%; aspect-ratio: auto; overflow: hidden; }
862
- .gem-featured-collection--editorial-grid .gem-product-card__media, .gem-product-card-grid--quick-view-grid .gem-product-card__media, .gem-main-search .gem-product-card__media, .gem-cart-recommendations--dawn-empty .gem-product-card__media { min-block-size: 0 !important; }
862
+ .gem-featured-collection--editorial-grid .gem-product-card__media, .gem-product-card-grid--quick-view-grid .gem-product-card__media, .gem-main-search .gem-product-card__media, .gem-cart-recommendations--dawn-empty .gem-product-card__media, .gem-recommended-products--product-rail .gem-product-card__media, .gem-cart-recommendations--product-rail .gem-product-card__media { min-block-size: 0 !important; }
863
863
  .gem-product-card__media > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
864
864
  .gem-featured-collection .gem-product-card__media > img, .gem-product-card-grid .gem-product-card__media > img { object-fit: cover; }
865
865
  .gem-product-card-grid--quick-view-grid .gem-product-card__media { display: block; min-height: 0; }
@@ -873,7 +873,7 @@ main > .gem-section:first-child { padding-top: 0; }
873
873
  .gem-cart-recommendations--dawn-empty .gem-product-card__quick-actions { display: none; }
874
874
  .gem-featured-collection--editorial-grid > .gem-section__inner > .gem-section__heading, .gem-featured-collection--editorial-grid > .gem-section__inner > .gem-section__body { display: none; }
875
875
  .gem-featured-collection--editorial-grid { padding-block: 28px 36px; }
876
- .gem-featured-collection--editorial-grid .gem-section__grid, .gem-product-card-grid--quick-view-grid .gem-section__grid, .gem-main-search .gem-section__grid { grid-template-columns: repeat(var(--gem-product-card-grid-columns, 4), minmax(0, 1fr)); gap: 8px; }
876
+ .gem-featured-collection--editorial-grid .gem-section__grid, .gem-product-card-grid--quick-view-grid .gem-section__grid, .gem-main-search .gem-section__grid, .gem-recommended-products--product-rail .gem-section__grid, .gem-cart-recommendations--product-rail .gem-section__grid { grid-template-columns: repeat(var(--gem-product-card-grid-columns, 4), minmax(0, 1fr)); gap: 8px; }
877
877
  .gem-product-card-grid--quick-view-grid { padding-top: 0; }
878
878
  .gem-product-card-grid--quick-view-grid .gem-section__heading:empty { display: none; }
879
879
  .gem-product-card-grid--quick-view-grid .gem-price:not(.gem-price--on-sale) .gem-price__compare { display: none; }
@@ -1027,13 +1027,13 @@ main > .gem-section:first-child { padding-top: 0; }
1027
1027
  .gem-hero-banner--compact-collection { padding-block: 25px; }
1028
1028
  .gem-hero-banner--compact-collection .gem-section__heading { font-size: 30px; line-height: 39px; }
1029
1029
  .gem-product-card-grid--quick-view-grid > .gem-section__inner, .gem-main-search > .gem-section__inner { width: calc(100% - 30px); }
1030
- .gem-product-card-grid--quick-view-grid .gem-product-card-grid__grid { gap: 4px !important; }
1030
+ .gem-product-card-grid--quick-view-grid .gem-product-card-grid__grid { gap: 8px !important; }
1031
1031
  .gem-product-card__content { padding-top: 8px; gap: 4px; }
1032
1032
  .gem-product-card__title { font-size: 15px; line-height: 24px; }
1033
1033
  .gem-product-card__price, .gem-product-card__price .gem-price { font-size: 16px; line-height: 24px; }
1034
1034
  .gem-section__heading { font-size: var(--gem-section-heading-size-mobile, var(--gem-heading-phone-cap)); }
1035
1035
  .gem-hero-banner h1, .gem-hero-banner h2 { font-size: var(--gem-hero-heading-size-mobile, var(--gem-heading-phone-cap)); }
1036
- .gem-featured-collection--editorial-grid .gem-section__grid, .gem-product-card-grid--quick-view-grid .gem-section__grid, .gem-main-search .gem-section__grid { grid-template-columns: repeat(var(--gem-product-card-grid-mobile-columns, 2), minmax(0, 1fr)); }
1036
+ .gem-featured-collection--editorial-grid .gem-section__grid, .gem-product-card-grid--quick-view-grid .gem-section__grid, .gem-main-search .gem-section__grid, .gem-recommended-products--product-rail .gem-section__grid, .gem-cart-recommendations--product-rail .gem-section__grid { grid-template-columns: repeat(var(--gem-product-card-grid-mobile-columns, 2), minmax(0, 1fr)); }
1037
1037
  .gem-product-main[data-gem-product-main-layout='dawn-main'] > .gem-section__inner { width: calc(100% - 30px); }
1038
1038
  .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-media-gallery__frame { display: flex; gap: 0; overflow-x: auto; scroll-snap-type: x mandatory; }
1039
1039
  .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-media-gallery__item { flex: 0 0 100%; scroll-snap-align: start; aspect-ratio: 1 / 1; }