@gemboss/gem-framework 0.9.3 → 0.9.8

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.
@@ -1,4 +1,18 @@
1
1
  // ../../packages/gem-framework/src/form-set.ts
2
+ var GEM_FORM_TOKEN_KEYS = [
3
+ "radius",
4
+ "borderWidth",
5
+ "borderColor",
6
+ "fill",
7
+ "height",
8
+ "paddingInline",
9
+ "fontSize",
10
+ "focusRing",
11
+ "checkboxAccent",
12
+ "checkboxSize",
13
+ "shape",
14
+ "join"
15
+ ];
2
16
  var FORM_CSS_VAR = {
3
17
  radius: "--gem-input-radius",
4
18
  borderWidth: "--gem-input-border-width",
@@ -12,6 +26,49 @@ var FORM_CSS_VAR = {
12
26
  checkboxSize: "--gem-checkbox-size"
13
27
  };
14
28
  var GEM_FORM_CSS_VARIABLES = Object.values(FORM_CSS_VAR);
29
+ var safe = (v) => {
30
+ if (typeof v !== "string" || v.trim() === "" || v.length > 200 || /[;{}<>\\"'`]|\/\*/.test(v)) return false;
31
+ const open = [];
32
+ for (const ch of v) {
33
+ if (ch === "(" || ch === "[") open.push(ch);
34
+ else if (ch === ")" || ch === "]") {
35
+ if (open.pop() !== (ch === ")" ? "(" : "[")) return false;
36
+ }
37
+ }
38
+ return open.length === 0;
39
+ };
40
+ var hasForm = (form) => !!form && typeof form === "object" && Object.keys(form).some((k) => GEM_FORM_TOKEN_KEYS.includes(k));
41
+ var GEM_FORM_DEFAULTS = {
42
+ shape: "outline",
43
+ join: "separate",
44
+ radius: "4px",
45
+ borderWidth: "1px",
46
+ borderColor: "color-mix(in srgb, currentColor 70%, transparent)",
47
+ fill: "var(--gem-color-surface)",
48
+ height: "44px",
49
+ paddingInline: "12px",
50
+ fontSize: "16px",
51
+ checkboxAccent: "var(--gem-color-accent)",
52
+ checkboxSize: "24px"
53
+ };
54
+ var GEM_FORM_VAR_SCOPE = "[data-gem-form-set], [data-gem-form-set] :is(input, select, textarea, button, form)";
55
+ function gemFormCssBlock(form) {
56
+ const vars = gemFormCssVars(form);
57
+ return vars.length ? `${GEM_FORM_VAR_SCOPE} {
58
+ ${vars.map((d) => ` ${d}`).join("\n")}
59
+ }` : "";
60
+ }
61
+ function gemFormCssVars(form) {
62
+ if (!hasForm(form)) return [];
63
+ const out = [];
64
+ for (const [key, cssVar] of Object.entries(FORM_CSS_VAR)) {
65
+ const v = form[key];
66
+ const fallback = GEM_FORM_DEFAULTS[key];
67
+ if (safe(v)) out.push(`${cssVar}: ${v.trim()};`);
68
+ else if (fallback) out.push(`${cssVar}: ${fallback};`);
69
+ }
70
+ return out;
71
+ }
15
72
 
16
73
  // ../../packages/gem-framework/src/tokens.ts
17
74
  var GEM_FOCUS_RING_CSS_VAR = "--gem-focus-ring: 2px solid var(--gem-color-accent);";
@@ -19,6 +76,24 @@ var GEM_TAP_MIN_CSS_VAR = "--gem-tap-min: 44px;";
19
76
  var GEM_FOCUS_OFFSET_CSS_VAR = "--gem-focus-offset: 3px;";
20
77
  var GEM_DERIVED_SPACE_STEPS = { "2xs": 0.125, ms: 0.75, "4xl": 7 };
21
78
  var GEM_DERIVED_SPACE_CSS_VARIABLES = Object.keys(GEM_DERIVED_SPACE_STEPS).map((key) => `--gem-space-${slugify(key)}`);
79
+ function gemDerivedSpaceCssVars(spacing) {
80
+ const named = new Set(Object.entries(spacing ?? {}).filter(([, v]) => String(v ?? "").trim()).map(([k]) => slugify(k)));
81
+ const md = gemSpaceMdKind(spacing?.md);
82
+ return Object.entries(GEM_DERIVED_SPACE_STEPS).filter(([key]) => !named.has(slugify(key))).map(([key, factor]) => `--gem-space-${slugify(key)}: ${derivedSpaceValue(md, factor)};`);
83
+ }
84
+ function gemSpaceMdKind(raw) {
85
+ const md = stripImportant(String(raw ?? "")).trim();
86
+ if (md === "") return "absent";
87
+ if (/^[+-]?(\d+\.?\d*|\.\d+)$/.test(md)) return Number(md) === 0 ? "zero" : "invalid";
88
+ if (/^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?[a-z%]+$/i.test(md)) return "length";
89
+ if (/^(var|calc|clamp|min|max|env)\(.*\)$/i.test(md)) return "length";
90
+ return "invalid";
91
+ }
92
+ function derivedSpaceValue(md, factor) {
93
+ if (md === "zero") return "0";
94
+ if (md === "invalid") return `calc(${parseFloat(defaultGemTokens.spacing.md) * factor}px * var(--gem-style-space, 1))`;
95
+ return `calc(var(--gem-space-md) * ${factor})`;
96
+ }
22
97
  var GEM_ROW_CSS_VARIABLES = [
23
98
  "--gem-row-cols",
24
99
  "--gem-row-cols-md",
@@ -41,7 +116,134 @@ var requiredGemTokenKeys = {
41
116
  component: ["headerHeight", "cardPadding", "buttonPaddingInline", "buttonPaddingBlock", "inputHeight"],
42
117
  morphology: ["campaignDensity", "mediaRhythm", "proofIntensity", "commerceEmphasis", "policyTone"]
43
118
  };
119
+ var defaultGemTokens = {
120
+ color: {
121
+ background: "#f6f6f3",
122
+ surface: "#ffffff",
123
+ text: "#202223",
124
+ // AA on THIS background (#f6f6f3), not only on white: #6b7280 measures 4.47:1 there, under 4.5, and muted styles
125
+ // every secondary line. #656c79 measures 4.88:1 (5.28 on white). Upstreamed from gemsite app/globals.css (#212,
126
+ // found by axe) in gem-framework 0.8.0.
127
+ muted: "#656c79",
128
+ accent: "#008060",
129
+ accentText: "#ffffff",
130
+ border: "#d2d5d8",
131
+ success: "#008060",
132
+ warning: "#b7791f",
133
+ danger: "#d72c0d"
134
+ },
135
+ typography: {
136
+ body: "Inter, system-ui, sans-serif",
137
+ heading: "Inter, system-ui, sans-serif",
138
+ mono: "ui-monospace, SFMono-Regular, Menlo, monospace"
139
+ },
140
+ spacing: {
141
+ xs: "4px",
142
+ sm: "8px",
143
+ md: "16px",
144
+ lg: "24px",
145
+ xl: "32px",
146
+ "2xl": "48px",
147
+ "3xl": "64px"
148
+ },
149
+ radius: {
150
+ sm: "4px",
151
+ md: "8px",
152
+ lg: "16px",
153
+ pill: "999px"
154
+ },
155
+ border: {
156
+ subtle: "1px solid var(--gem-color-border)",
157
+ strong: "1px solid color-mix(in srgb, var(--gem-color-text) 28%, transparent)"
158
+ },
159
+ shadow: {
160
+ sm: "0 1px 2px rgb(0 0 0 / 0.08)",
161
+ md: "0 8px 24px rgb(0 0 0 / 0.10)"
162
+ },
163
+ motion: {
164
+ // Back-compat interaction motion (buttons, hovers) — emitted as --gem-motion-duration/easing.
165
+ duration: "160ms",
166
+ easing: "ease",
167
+ // Soft display easing for ambient/entrance motion — emitted as --gem-ease-soft.
168
+ easingSoft: "cubic-bezier(.45,0,.25,1)",
169
+ // Ambient duration ramp (background float/sheen/marquee) — emitted as --gem-ambient-slow|mid|fast.
170
+ ambientSlow: "9s",
171
+ ambientMid: "7s",
172
+ ambientFast: "5.5s",
173
+ // Ambient float amplitude — emitted as --gem-ambient-amp; gentled under reduce-motion.
174
+ ambientAmp: "7px"
175
+ },
176
+ layout: {
177
+ page: "1180px",
178
+ gutter: "32px",
179
+ section: "64px"
180
+ },
181
+ component: {
182
+ headerHeight: "72px",
183
+ cardPadding: "16px",
184
+ buttonPaddingInline: "18px",
185
+ buttonPaddingBlock: "12px",
186
+ inputHeight: "44px"
187
+ },
188
+ morphology: {
189
+ campaignDensity: "balanced",
190
+ mediaRhythm: "standard",
191
+ proofIntensity: "standard",
192
+ commerceEmphasis: "balanced",
193
+ policyTone: "standard"
194
+ }
195
+ };
196
+ function createGemTokenCss(tokens, selector = ":root") {
197
+ const declarations = [
198
+ ...toCssVars("color", tokens.color),
199
+ ...toCssVars("font", Object.fromEntries(Object.entries(tokens.typography ?? {}).filter(([k]) => !isRampKey(k)))),
200
+ // Space ramp is scaled by the global density knob --gem-style-space (default 1),
201
+ // so a style pack can make the WHOLE storefront airier or denser without touching
202
+ // any section — every section already consumes --gem-space-*. Knob unset → identical.
203
+ ...toScaledCssVars("space", tokens.spacing, "--gem-style-space"),
204
+ ...gemDerivedSpaceCssVars(tokens.spacing),
205
+ // Radius ramp scaled by --gem-style-radius (default 1): a 'sharp' style sets it to
206
+ // 0 (square everything), 'pill' rounds further — across every section, no edits.
207
+ ...toScaledCssVars("radius", tokens.radius, "--gem-style-radius"),
208
+ // Border widths get the --gem-style-border knob injected into their leading length,
209
+ // whatever value the plan provides (e.g. "1px solid …" → "calc(1px * var(...)) solid …").
210
+ ...toBorderCssVars("border", tokens.border, "--gem-style-border"),
211
+ ...toCssVars("shadow", tokens.shadow),
212
+ // Motion keys map to ergonomic var names (--gem-ease-soft, --gem-ambient-*) that the ambient
213
+ // and marquee primitives consume; unrecognised keys fall back to the --gem-motion-* namespace,
214
+ // so duration/easing keep emitting --gem-motion-duration/easing exactly as before (back-compat).
215
+ ...toMotionCssVars(tokens.motion),
216
+ ...toCssVars("layout", tokens.layout),
217
+ ...toCssVars("component", tokens.component),
218
+ ...toCssVars("morphology", tokens.morphology),
219
+ // THE GOVERNED TYPE RAMP — --gem-h1..h6 / --gem-body / --gem-text-sm.
220
+ // gemcapture maps every measured font-size onto these names via `font_token`
221
+ // (clone_kit._type_token), and the gem-framework contract documents them, but nothing in the
222
+ // live framework defined them: a rebuild that followed the contract styled its headings with
223
+ // variables that resolved to nothing. One modular scale, retuned by overriding --gem-type-base
224
+ // or --gem-type-scale (see gemTypeRampCssVars).
225
+ ...gemTypeRampCssVars(tokens.typography),
226
+ // Focus ring (gemfactory request #3, 28/09/2026): 11 sections wrote `outline: 2px solid
227
+ // var(--gem-color-accent)` by hand. Not a token GROUP (a group would name it --gem-border-focus-ring
228
+ // and a required key would fail every stored plan/preset without it), so it is emitted here like the
229
+ // type ramp and registered in validation.ts. Follows the accent, so presets retint it for free.
230
+ GEM_FOCUS_RING_CSS_VAR,
231
+ GEM_TAP_MIN_CSS_VAR,
232
+ GEM_FOCUS_OFFSET_CSS_VAR
233
+ ];
234
+ const formBlock = gemFormCssBlock(tokens.form);
235
+ const baseMobile = typeRampValue(tokens.typography, "baseMobile");
236
+ return [
237
+ `${selector} {`,
238
+ ...declarations.map((line) => ` ${line}`),
239
+ "}",
240
+ ...baseMobile ? [`@media (max-width: ${GEM_TYPE_MOBILE_MAX}) {`, ` ${selector} {`, ` --gem-type-base: ${baseMobile};`, " }", "}"] : [],
241
+ ...formBlock ? [formBlock] : []
242
+ ].join("\n");
243
+ }
244
+ var GEM_TYPE_RAMP_KEYS = ["base", "scale", "baseMobile"];
44
245
  var rampKey = (k) => k.toLowerCase().replace(/[^a-z0-9]/g, "");
246
+ var isRampKey = (k) => GEM_TYPE_RAMP_KEYS.some((r) => rampKey(r) === rampKey(k));
45
247
  var LENGTH = /^\d*\.?\d+(px|rem|em)$/;
46
248
  var NUMBER = /^\d*\.?\d+$/;
47
249
  var typeRampValue = (typography, key) => {
@@ -50,6 +252,7 @@ var typeRampValue = (typography, key) => {
50
252
  if (!v) return null;
51
253
  return (key === "scale" ? NUMBER.test(v) && Number(v) > 0 : LENGTH.test(v)) ? v : null;
52
254
  };
255
+ var GEM_TYPE_MOBILE_MAX = "749px";
53
256
  function gemTypeRampCssVars(typography) {
54
257
  return [
55
258
  `--gem-type-base: ${typeRampValue(typography, "base") ?? "1rem"};`,
@@ -69,6 +272,41 @@ function stripImportant(value) {
69
272
  if (!/!\s*important/i.test(s)) return s;
70
273
  return s.replace(/!\s*important/gi, " ").replace(/\s+/g, " ").replace(/\s+,/g, ",").trim();
71
274
  }
275
+ function toCssVars(namespace, values) {
276
+ if (!values) return [];
277
+ return Object.entries(values).map(([key, value]) => `--gem-${namespace}-${slugify(key)}: ${stripImportant(value)};`);
278
+ }
279
+ var motionCssVarAliases = {
280
+ easingSoft: "--gem-ease-soft",
281
+ ambientSlow: "--gem-ambient-slow",
282
+ ambientMid: "--gem-ambient-mid",
283
+ ambientFast: "--gem-ambient-fast",
284
+ ambientAmp: "--gem-ambient-amp"
285
+ };
286
+ function toMotionCssVars(values) {
287
+ return Object.entries(values).map(([key, value]) => {
288
+ const name = motionCssVarAliases[key] ?? `--gem-motion-${slugify(key)}`;
289
+ return `${name}: ${value};`;
290
+ });
291
+ }
292
+ function toScaledCssVars(namespace, values, knob) {
293
+ if (!values) return [];
294
+ return Object.entries(values).map(
295
+ // stripImportant Ở ĐÂY mới là chỗ dễ vỡ, không phải toCssVars. Một giá trị trần mang cờ ở
296
+ // CUỐI khai báo thì trình duyệt nuốt nó như importance và khai báo vẫn hợp lệ; nhưng calc()
297
+ // bọc nó vào GIỮA giá trị — `calc(16px !important * var(...))` — nên custom property lưu
298
+ // nguyên xi, rồi mọi `padding: var(--gem-space-md)` thành invalid ở computed-value và SẬP VỀ 0
299
+ // trên toàn bộ .gem-* section.
300
+ ([key, value]) => `--gem-${namespace}-${slugify(key)}: calc(${stripImportant(value)} * var(${knob}, 1));`
301
+ );
302
+ }
303
+ function toBorderCssVars(namespace, values, knob) {
304
+ if (!values) return [];
305
+ return Object.entries(values).map(([key, value]) => {
306
+ const scaled = stripImportant(value).replace(/(\d*\.?\d+)px/, `calc($1px * var(${knob}, 1))`);
307
+ return `--gem-${namespace}-${slugify(key)}: ${scaled};`;
308
+ });
309
+ }
72
310
  function slugify(value) {
73
311
  return value.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
74
312
  }
@@ -678,6 +916,2883 @@ var GEM_GRID_COLUMNS_KNOB_CSS_LINES = [
678
916
  ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-grid-columns='4'] .gem-row:is(.gem-section__grid, [class*='__grid']):not(.gem-row .gem-row) { --gem-row-cols: 4; --gem-row-cols-md: 4; --gem-row-tracks: initial; --gem-row-tracks-md: initial; }"
679
917
  ];
680
918
  var GEM_GRID_COLUMNS_ROW_KNOB_CSS = GEM_GRID_COLUMNS_KNOB_CSS_LINES.filter((line) => line.includes(" .gem-row:is(")).join("\n");
919
+ function createGemStyleKnobCss(options = {}, selector = ":root") {
920
+ const knobs = [
921
+ ["styleSpace", "--gem-style-space"],
922
+ ["styleWeight", "--gem-style-weight"],
923
+ ["styleRadius", "--gem-style-radius"],
924
+ ["styleBorder", "--gem-style-border"],
925
+ ["styleHeadingScale", "--gem-typography-heading-scale"]
926
+ ];
927
+ return knobs.flatMap(([key, property]) => {
928
+ const value = options[key];
929
+ return typeof value === "number" && value !== 1 ? [`${selector} { ${property}: ${value}; }`] : [];
930
+ });
931
+ }
932
+ function createGemThemeCss(tokens, selector = ":root", options = {}) {
933
+ const parts = createGemThemeCssParts(tokens, selector, options);
934
+ return parts.tokens + parts.primitives + parts.popupShell + parts.sections;
935
+ }
936
+ function createGemThemeCssParts(tokens, selector = ":root", options = {}) {
937
+ const base = createGemBaseCssParts(options.profile ?? "dawn-parity");
938
+ return {
939
+ tokens: [
940
+ createGemTokenCss(tokens, selector),
941
+ // Set the knobs the space / radius / border / type ramps read (only when they differ from the
942
+ // default 1, so a standard-shaped storefront emits nothing extra).
943
+ ...createGemStyleKnobCss(options, selector),
944
+ "",
945
+ ""
946
+ ].join("\n"),
947
+ primitives: base.primitives,
948
+ popupShell: [GEM_POPUP_SHELL_CSS, "", ""].join("\n"),
949
+ sections: base.sections
950
+ };
951
+ }
952
+ function createGemBaseCssParts(profile) {
953
+ const reset = [
954
+ "*, *::before, *::after {",
955
+ " box-sizing: border-box;",
956
+ "}",
957
+ "html {",
958
+ " scroll-behavior: smooth;",
959
+ " text-size-adjust: 100%;",
960
+ "}",
961
+ "body {",
962
+ " margin: 0;",
963
+ " font-family: var(--gem-font-body);",
964
+ " font-size: calc(1rem * var(--gem-typography-body-scale, 1));",
965
+ " color: var(--gem-color-text);",
966
+ " background: var(--gem-color-background);",
967
+ " line-height: 1.5;",
968
+ " -webkit-font-smoothing: antialiased;",
969
+ "}",
970
+ "main {",
971
+ " display: block;",
972
+ "}",
973
+ "img, picture, video, canvas, svg {",
974
+ " display: block;",
975
+ " max-width: 100%;",
976
+ "}",
977
+ "button, input, textarea, select {",
978
+ " font: inherit;",
979
+ "}",
980
+ "button, [type='button'], [type='submit'] {",
981
+ " cursor: pointer;",
982
+ "}",
983
+ "a {",
984
+ " color: inherit;",
985
+ "}",
986
+ // Vòng focus theo NỀN (gemsite #761, review #655; đo Chromium 03/10/2026).
987
+ // 1. --gem-focus-ring khai ở :root là "2px solid var(--gem-color-accent)" và var() bị thay MỘT LẦN ở :root: section
988
+ // đặt lại accent (bảng màu) vẫn nhận accent của trang. Khai lại trên chính section để var() tính theo section.
989
+ // 2. Núm nền accent / dark tô nền mà KHÔNG đổi accent: vòng accent trên nền accent là không thấy (1:1). Trong băng đó
990
+ // vòng HAI MÀU (WCAG C40): nét màu chữ của băng + quầng màu nền của băng bao quanh. Hai màu tương phản nhau nên
991
+ // trên nền nào cũng có một màu nổi: băng tối thì nét sáng, ô sáng lồng trong băng tối thì quầng tối. Màu chữ của
992
+ // khối chứa KHÔNG lấy được bằng CSS: currentColor giữ nguyên từ khoá tới phần tử dùng nó (kể cả biến có kiểu
993
+ // @property), nên nút / ô nhập ra vòng màu chữ của chính mặt nút (đen trên băng tối, đo).
994
+ // Đặt --gem-focus-ring ở :root không tới được trong section.
995
+ ":where(.gem-section, [data-gem-section-id]) {",
996
+ " --gem-focus-ring: 2px solid var(--gem-color-accent);",
997
+ "}",
998
+ ":focus-visible {",
999
+ " outline: var(--gem-focus-ring, 2px solid var(--gem-color-accent));",
1000
+ " outline-offset: var(--gem-focus-offset, 3px);",
1001
+ "}",
1002
+ // :focus-visible hai lần = độ ưu tiên (0,2,0): thắng `.gem-button { box-shadow: none }` của profile Dawn (0,1,0, nằm
1003
+ // sau) đã xoá quầng của nút trên ô sáng lồng trong băng (đo); luật focus riêng của section (≥ 0,3,0) vẫn thắng nó.
1004
+ ":where([data-gem-section-background='accent'], [data-gem-section-background='dark']) :focus-visible:focus-visible {",
1005
+ " box-shadow: 0 0 0 calc(var(--gem-focus-offset, 3px) + 4px) var(--gem-band-bg);",
1006
+ "}",
1007
+ ".gem-skip-to-content-link:focus {",
1008
+ " position: fixed;",
1009
+ " inset-block-start: var(--gem-space-sm);",
1010
+ " inset-inline-start: var(--gem-space-sm);",
1011
+ " z-index: 100;",
1012
+ " width: auto !important;",
1013
+ " height: auto !important;",
1014
+ " clip: auto !important;",
1015
+ " white-space: normal !important;",
1016
+ " padding: var(--gem-space-sm) var(--gem-space-md);",
1017
+ " border-radius: var(--gem-radius-md);",
1018
+ " background: var(--gem-color-accent);",
1019
+ " color: var(--gem-color-accent-text);",
1020
+ "}",
1021
+ ".gem-u-visually-hidden {",
1022
+ " position: absolute !important;",
1023
+ " width: 1px !important;",
1024
+ " height: 1px !important;",
1025
+ " overflow: hidden !important;",
1026
+ " clip: rect(0, 0, 0, 0) !important;",
1027
+ " white-space: nowrap !important;",
1028
+ "}"
1029
+ ].join("\n");
1030
+ return {
1031
+ primitives: [reset, "", createPrimitiveCss(), "", ""].join("\n"),
1032
+ sections: [createShellCss(), "", createSectionCss(), "", createThemeProfileCss(profile)].join("\n")
1033
+ };
1034
+ }
1035
+ function createThemeProfileCss(profile = "dawn-parity") {
1036
+ return profile === "dawn-parity" ? createDawnParityCss() : createMorphProfileCss();
1037
+ }
1038
+ function createMorphProfileCss() {
1039
+ return [
1040
+ "/* Gem morph profile: style packs and section presets provide visual transformation above core primitives. */",
1041
+ ":root { --gem-profile-mode: morph; }"
1042
+ ].join("\n");
1043
+ }
1044
+ function createPrimitiveCss() {
1045
+ return [
1046
+ ".gem-container {",
1047
+ " width: min(var(--gem-layout-page, 1180px), calc(100% - var(--gem-layout-gutter, 32px)));",
1048
+ " margin-inline: auto;",
1049
+ "}",
1050
+ ".gem-stack {",
1051
+ " display: grid;",
1052
+ " gap: var(--gem-space-md);",
1053
+ "}",
1054
+ ".gem-cluster {",
1055
+ " display: flex;",
1056
+ " flex-wrap: wrap;",
1057
+ " align-items: center;",
1058
+ " gap: var(--gem-space-sm);",
1059
+ "}",
1060
+ ".gem-grid {",
1061
+ " display: grid;",
1062
+ " grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));",
1063
+ " column-gap: var(--gem-grid-column-gap, var(--gem-space-md));",
1064
+ " row-gap: var(--gem-grid-row-gap, var(--gem-space-md));",
1065
+ "}",
1066
+ ...GEM_ROW_GAP_CSS_LINES,
1067
+ ".gem-button {",
1068
+ " border: 0;",
1069
+ " appearance: none;",
1070
+ " cursor: pointer;",
1071
+ " display: inline-flex;",
1072
+ " align-items: center;",
1073
+ " justify-content: center;",
1074
+ " min-height: var(--gem-component-input-height, 44px);",
1075
+ " border: var(--gem-button-border-width, 1px) solid var(--gem-color-border);",
1076
+ " border-radius: var(--gem-radius-md);",
1077
+ " padding: var(--gem-component-button-padding-block, 12px) var(--gem-component-button-padding-inline, 18px);",
1078
+ " font-weight: 700;",
1079
+ " text-decoration: none;",
1080
+ " transition: background var(--gem-motion-duration, 160ms) var(--gem-motion-easing, ease), color var(--gem-motion-duration, 160ms) var(--gem-motion-easing, ease);",
1081
+ "}",
1082
+ ".gem-button:disabled, .gem-button[aria-disabled='true'] {",
1083
+ " cursor: not-allowed;",
1084
+ " opacity: 0.55;",
1085
+ "}",
1086
+ ".gem-input:disabled, .gem-select:disabled, .gem-textarea:disabled, .gem-quantity-input__button:disabled {",
1087
+ " cursor: not-allowed;",
1088
+ " opacity: 0.6;",
1089
+ " background: color-mix(in srgb, var(--gem-color-text) 6%, var(--gem-color-surface));",
1090
+ "}",
1091
+ ".gem-button--primary {",
1092
+ " border-color: var(--gem-color-accent);",
1093
+ " background: var(--gem-color-accent);",
1094
+ " color: var(--gem-color-accent-text, var(--gem-color-surface));",
1095
+ "}",
1096
+ ".gem-button--secondary {",
1097
+ " background: var(--gem-color-surface);",
1098
+ " color: var(--gem-color-text);",
1099
+ "}",
1100
+ ".gem-button--soft {",
1101
+ " background: color-mix(in srgb, var(--gem-color-accent) 12%, var(--gem-color-surface));",
1102
+ " color: var(--gem-color-text);",
1103
+ "}",
1104
+ // `--link` is the variant the element seam has always offered and no stylesheet ever defined.
1105
+ // gemsite added a rule for it in its own hand-written globals.css; without the same rule HERE the
1106
+ // identical element tree paints a solid accent button on every surface this CSS serves (preview
1107
+ // document, headless globals) — the two-renderer drift this file exists to prevent. A cloned nav
1108
+ // or footer is made of these, so the divergence would show up on the first store that used one.
1109
+ ".gem-button--link {",
1110
+ " min-height: 0;",
1111
+ " min-width: 0;",
1112
+ " padding: 0;",
1113
+ " border: 0;",
1114
+ " background: transparent;",
1115
+ " color: inherit;",
1116
+ " text-decoration: underline;",
1117
+ " text-underline-offset: 0.2em;",
1118
+ " font-weight: inherit;",
1119
+ "}",
1120
+ // Global `button_style` follow rules. preview-document.ts sets [data-gem-button-style] on the
1121
+ // <body> from plan.global_settings.button_style, and the headless adapter emits the same pair
1122
+ // (index.ts createGlobalsCss) — but the PREVIEW CSS never shipped them, so every preview drew
1123
+ // solid primaries no matter what the plan said. `solid` stays ruleless: it IS the base style.
1124
+ //
1125
+ // The selector deliberately matches the headless adapter's — `.gem-button` MINUS the secondary,
1126
+ // not `.gem-button--primary` alone. Scoping it to the primary modifier left bare `.gem-button`
1127
+ // and `.gem-button--soft` following button_style on the published storefront but NOT in the
1128
+ // preview, which is the drift this rule exists to remove. `--primary` is named too so the
1129
+ // modifier keeps winning where both could apply.
1130
+ "[data-gem-button-style='outline'] .gem-button:not(.gem-button--secondary),",
1131
+ "[data-gem-button-style='outline'] .gem-button--primary {",
1132
+ " background: transparent;",
1133
+ " color: var(--gem-color-accent);",
1134
+ "}",
1135
+ "[data-gem-button-style='soft'] .gem-button:not(.gem-button--secondary),",
1136
+ "[data-gem-button-style='soft'] .gem-button--primary {",
1137
+ " background: color-mix(in srgb, var(--gem-color-accent) 12%, var(--gem-color-surface));",
1138
+ " border-color: transparent;",
1139
+ " color: var(--gem-color-text);",
1140
+ "}",
1141
+ ".gem-card {",
1142
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1143
+ " border-radius: var(--gem-card-radius, var(--gem-radius-md));",
1144
+ " background: var(--gem-card-background, var(--gem-color-surface));",
1145
+ " padding: var(--gem-component-card-padding, var(--gem-space-md));",
1146
+ " box-shadow: var(--gem-shadow-sm, none);",
1147
+ " text-align: var(--gem-card-text-alignment, left);",
1148
+ "}",
1149
+ ".gem-card > :first-child { margin-top: 0; }",
1150
+ ".gem-card > :last-child { margin-bottom: 0; }",
1151
+ ".gem-media {",
1152
+ " display: block;",
1153
+ // A media box must be its own CONTAINING BLOCK. The `> img` rule below fills the box with
1154
+ // `position: absolute; inset: 0`, and without this the image resolves against the nearest
1155
+ // positioned ancestor instead — which is the page. A 351x351 multicolumn tile rendered its
1156
+ // image at 1440x1000, floating full-bleed over the hero. Caught by looking at the render;
1157
+ // no test in the repo asserts anything about where an image lands.
1158
+ " position: relative;",
1159
+ " overflow: hidden;",
1160
+ " border: var(--gem-media-border-width, 0) solid color-mix(in srgb, var(--gem-color-text) 12%, transparent);",
1161
+ " border-radius: var(--gem-media-radius, var(--gem-radius-md));",
1162
+ " background: color-mix(in srgb, var(--gem-color-text) 8%, var(--gem-color-background));",
1163
+ " box-shadow: 0 8px 24px rgb(0 0 0 / var(--gem-media-shadow-opacity, 0));",
1164
+ "}",
1165
+ ".gem-media > img, .gem-media > video {",
1166
+ " display: block;",
1167
+ " width: 100%;",
1168
+ " height: 100%;",
1169
+ " object-fit: cover;",
1170
+ "}",
1171
+ ".gem-badge {",
1172
+ " display: inline-flex;",
1173
+ " align-items: center;",
1174
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1175
+ " border-radius: var(--gem-radius-pill, 999px);",
1176
+ " padding: var(--gem-space-xs) var(--gem-space-sm);",
1177
+ " font-size: 0.8125rem;",
1178
+ " font-weight: 650;",
1179
+ "}",
1180
+ ".gem-accordion {",
1181
+ " display: grid;",
1182
+ " gap: var(--gem-space-sm);",
1183
+ "}",
1184
+ ".gem-accordion details {",
1185
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1186
+ " border-radius: var(--gem-radius-md);",
1187
+ " background: var(--gem-color-surface);",
1188
+ " overflow: hidden;",
1189
+ "}",
1190
+ ".gem-accordion summary {",
1191
+ " cursor: pointer;",
1192
+ " padding: var(--gem-space-md);",
1193
+ " font-weight: 650;",
1194
+ "}",
1195
+ ".gem-divider {",
1196
+ " border: 0;",
1197
+ " border-top: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1198
+ " margin-block: var(--gem-space-lg);",
1199
+ "}",
1200
+ ".gem-form-field {",
1201
+ " display: grid;",
1202
+ " gap: var(--gem-space-xs);",
1203
+ "}",
1204
+ ".gem-input, .gem-select, .gem-textarea {",
1205
+ " width: 100%;",
1206
+ " min-height: var(--gem-component-input-height, 44px);",
1207
+ " border: var(--gem-input-border-width, 1px) solid var(--gem-color-border);",
1208
+ " border-radius: var(--gem-input-radius, var(--gem-radius-md));",
1209
+ " background: var(--gem-color-surface);",
1210
+ " color: var(--gem-color-text);",
1211
+ " padding: 0 var(--gem-space-md);",
1212
+ "}",
1213
+ // .gem-field-join (gemfactory request #8, 01/10/2026; 16 stored footers trimmed the touching corners by hand): an
1214
+ // input/select and its button as one block (newsletter, discount code). Only VISIBLE children count: Shopify forms carry hidden inputs (form_type, utf8) and a sr-only
1215
+ // label, and with plain :first-child those would square the visible outer corners and take a 44px slot. A field
1216
+ // may be wrapped in .gem-form-field. The field grows with a floor of min(10rem, 50%); the button sizes to its
1217
+ // label (dropping dawn-parity's 12rem minimum, which at 320px left the field 80px wide) and wraps a long label
1218
+ // instead of squeezing the field or overflowing. Only the corners where two children meet are squared, in logical
1219
+ // properties so it mirrors under RTL, and the seam overlaps by one border width so it is not drawn twice. A child
1220
+ // holding focus is lifted so its ring is not painted under the neighbour. Stays one row at every width.
1221
+ ".gem-field-join {",
1222
+ " display: flex;",
1223
+ " align-items: stretch;",
1224
+ " min-width: 0;",
1225
+ "}",
1226
+ '.gem-field-join > :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden) {',
1227
+ " min-height: var(--gem-component-input-height, 44px);",
1228
+ " margin: 0;",
1229
+ "}",
1230
+ ".gem-field-join > :is(.gem-input, .gem-select, .gem-form-field) {",
1231
+ " flex: 1 1 10rem;",
1232
+ " width: auto;",
1233
+ " min-width: min(10rem, 50%);",
1234
+ "}",
1235
+ // A wrapped field gets the join's height too: the dawn-parity profile sets .gem-input { min-height: 4.5rem }, and
1236
+ // only the direct-child rule above outranked it, so a wrapped input stood 72px next to a 44px one (02/10/2026).
1237
+ ".gem-field-join > .gem-form-field > :is(.gem-input, .gem-select) {",
1238
+ " width: 100%;",
1239
+ " height: 100%;",
1240
+ " min-height: var(--gem-component-input-height, 44px);",
1241
+ "}",
1242
+ '.gem-field-join > :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden):not(.gem-input, .gem-select, .gem-form-field) {',
1243
+ " flex: 0 1 auto;",
1244
+ " min-width: var(--gem-component-input-height, 44px);",
1245
+ " white-space: normal;",
1246
+ " overflow-wrap: anywhere;",
1247
+ "}",
1248
+ '.gem-field-join > :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden):not(:nth-child(1 of :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden))), .gem-field-join > .gem-form-field:not(:nth-child(1 of :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden))) > :is(.gem-input, .gem-select) {',
1249
+ " border-start-start-radius: 0;",
1250
+ " border-end-start-radius: 0;",
1251
+ "}",
1252
+ '.gem-field-join > :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden):not(:nth-child(1 of :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden))) {',
1253
+ " margin-inline-start: calc(-1 * var(--gem-input-border-width, 1px));",
1254
+ "}",
1255
+ '.gem-field-join > :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden):not(:nth-last-child(1 of :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden))), .gem-field-join > .gem-form-field:not(:nth-last-child(1 of :not([type="hidden"]):not([hidden]):not(.gem-u-visually-hidden))) > :is(.gem-input, .gem-select) {',
1256
+ " border-start-end-radius: 0;",
1257
+ " border-end-end-radius: 0;",
1258
+ "}",
1259
+ ".gem-field-join > :focus-within {",
1260
+ " position: relative;",
1261
+ " z-index: 1;",
1262
+ "}",
1263
+ ".gem-textarea {",
1264
+ " min-height: calc(var(--gem-component-input-height, 44px) * 2);",
1265
+ " padding-block: var(--gem-space-sm);",
1266
+ " resize: vertical;",
1267
+ "}",
1268
+ ".gem-checkbox {",
1269
+ " inline-size: var(--gem-space-lg);",
1270
+ " block-size: var(--gem-space-lg);",
1271
+ " accent-color: var(--gem-color-accent);",
1272
+ "}",
1273
+ ...GEM_FORM_SET_CSS_LINES,
1274
+ ".gem-submit {",
1275
+ " cursor: pointer;",
1276
+ "}",
1277
+ ".gem-newsletter-form {",
1278
+ " display: flex;",
1279
+ " flex-wrap: wrap;",
1280
+ " gap: var(--gem-space-sm);",
1281
+ " align-items: end;",
1282
+ "}",
1283
+ ".gem-newsletter-form .gem-form-field {",
1284
+ " flex: 1 1 16rem;",
1285
+ "}",
1286
+ ".gem-heading {",
1287
+ " margin: 0;",
1288
+ " font-family: var(--gem-font-heading);",
1289
+ " color: var(--gem-color-text);",
1290
+ "}",
1291
+ ".gem-text {",
1292
+ " margin: 0;",
1293
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
1294
+ " line-height: 1.6;",
1295
+ "}",
1296
+ ".gem-richtext {",
1297
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
1298
+ " line-height: 1.6;",
1299
+ "}",
1300
+ // Icon size and colour hooks (gemfactory request #11, 01/10/2026: 33 sections reset colour to inherit and wrote
1301
+ // 22/14/16/20px by hand). Additive only: with no modifier and no --gem-icon-size an icon renders exactly as before
1302
+ // (the spacing step, the accent). Changing those DEFAULTS is a design decision left open on #11.
1303
+ ".gem-icon {",
1304
+ " display: inline-flex;",
1305
+ " align-items: center;",
1306
+ " justify-content: center;",
1307
+ " inline-size: var(--gem-icon-size, var(--gem-space-lg));",
1308
+ " block-size: var(--gem-icon-size, var(--gem-space-lg));",
1309
+ " color: var(--gem-color-accent);",
1310
+ "}",
1311
+ ".gem-icon--sm { --gem-icon-size: 16px; }",
1312
+ ".gem-icon--md { --gem-icon-size: 20px; }",
1313
+ ".gem-icon--lg { --gem-icon-size: 24px; }",
1314
+ ".gem-icon--current { color: currentColor; }",
1315
+ ".gem-icon--chevron { transition: rotate var(--gem-motion-duration, 160ms) var(--gem-motion-easing, ease); }",
1316
+ // Only the TOGGLE's own state: the runtime also sets aria-expanded on containers (the open cart drawer, the
1317
+ // header drawer), and a descendant match would flip every chevron inside them (review #650).
1318
+ ":is(button, summary, [role='button'])[aria-expanded='true'] > .gem-icon--chevron, details[open] > summary > .gem-icon--chevron { rotate: 180deg; }",
1319
+ "@media (prefers-reduced-motion: reduce) { .gem-icon--chevron { transition: none; } }",
1320
+ ".gem-icon-list {",
1321
+ " display: grid;",
1322
+ " gap: var(--gem-space-sm);",
1323
+ " list-style: none;",
1324
+ " margin: 0;",
1325
+ " padding: 0;",
1326
+ "}",
1327
+ ".gem-icon-list__item {",
1328
+ " display: grid;",
1329
+ " grid-template-columns: auto minmax(0, 1fr);",
1330
+ " gap: var(--gem-space-sm);",
1331
+ " align-items: start;",
1332
+ "}",
1333
+ ".gem-video {",
1334
+ " display: block;",
1335
+ " inline-size: 100%;",
1336
+ " aspect-ratio: 16 / 9;",
1337
+ " border: 0;",
1338
+ " border-radius: var(--gem-radius-md);",
1339
+ " background: color-mix(in srgb, var(--gem-color-text) 8%, var(--gem-color-background));",
1340
+ "}",
1341
+ ".gem-marquee {",
1342
+ " overflow: hidden;",
1343
+ " border-block: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1344
+ "}",
1345
+ // Consumer contract: render the track's children TWICE (like the site's `.mq-row`) so the
1346
+ // -50% translate lands on an identical second copy and the loop is seamless with no visible jump.
1347
+ // The animation reuses the gem-marquee-scroll keyframe defined with the ambient primitive.
1348
+ ".gem-marquee__track {",
1349
+ " display: flex;",
1350
+ " gap: var(--gem-space-lg);",
1351
+ " min-width: max-content;",
1352
+ " animation: gem-marquee-scroll var(--gem-marquee-duration, 40s) linear infinite;",
1353
+ " will-change: transform;",
1354
+ "}",
1355
+ // Pause-on-hover lets a shopper read a badge/logo they want to inspect.
1356
+ ".gem-marquee:hover .gem-marquee__track {",
1357
+ " animation-play-state: paused;",
1358
+ "}",
1359
+ // Opt-in reverse direction (e.g. a second row scrolling the other way).
1360
+ ".gem-marquee[data-gem-marquee-reverse] .gem-marquee__track {",
1361
+ " animation-direction: reverse;",
1362
+ "}",
1363
+ ".gem-carousel {",
1364
+ " display: grid;",
1365
+ " gap: var(--gem-space-md);",
1366
+ "}",
1367
+ ".gem-carousel__viewport {",
1368
+ " overflow-x: auto;",
1369
+ " scroll-snap-type: x mandatory;",
1370
+ " scrollbar-width: none;",
1371
+ "}",
1372
+ ".gem-carousel__viewport::-webkit-scrollbar {",
1373
+ " display: none;",
1374
+ "}",
1375
+ ".gem-carousel__track {",
1376
+ " display: grid;",
1377
+ " grid-auto-flow: column;",
1378
+ " grid-auto-columns: minmax(min(20rem, 84vw), 1fr);",
1379
+ " gap: var(--gem-space-md);",
1380
+ "}",
1381
+ ".gem-carousel__slide {",
1382
+ " scroll-snap-align: start;",
1383
+ "}",
1384
+ ".gem-carousel__controls {",
1385
+ " display: flex;",
1386
+ " flex-wrap: wrap;",
1387
+ " gap: var(--gem-space-sm);",
1388
+ " align-items: center;",
1389
+ " justify-content: flex-end;",
1390
+ "}",
1391
+ ".gem-price {",
1392
+ " display: flex;",
1393
+ " flex-wrap: wrap;",
1394
+ " gap: var(--gem-space-xs);",
1395
+ " align-items: baseline;",
1396
+ " font-weight: 750;",
1397
+ " color: var(--gem-color-text);",
1398
+ "}",
1399
+ ".gem-price--on-sale .gem-price__regular {",
1400
+ " color: var(--gem-color-accent);",
1401
+ "}",
1402
+ ".gem-price__compare {",
1403
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 60%, transparent));",
1404
+ " font-weight: 500;",
1405
+ "}",
1406
+ ".gem-price__unit {",
1407
+ " flex-basis: 100%;",
1408
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 60%, transparent));",
1409
+ " font-size: 0.8125rem;",
1410
+ " font-weight: 500;",
1411
+ "}",
1412
+ // The commerce atoms that had NO primitive. gemcapture types every one of these on the element
1413
+ // (`part`), and half of them had a class to land on — price, compare-at, badge, sold-out — while
1414
+ // the other half had none, so a rebuild styled them ad hoc or dropped them. GEM_PART_CLASS (see
1415
+ // ./parts) is the mechanical part→class binding; these are the rules behind it.
1416
+ ".gem-review-count {",
1417
+ " font-size: var(--gem-text-sm, 0.8125rem);",
1418
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
1419
+ "}",
1420
+ ".gem-discount {",
1421
+ " font-size: var(--gem-text-sm, 0.8125rem);",
1422
+ " font-weight: 700;",
1423
+ " color: var(--gem-color-accent);",
1424
+ "}",
1425
+ ".gem-pull-quote {",
1426
+ " font-family: var(--gem-font-heading);",
1427
+ " font-size: var(--gem-h5, 1.25rem);",
1428
+ " line-height: 1.4;",
1429
+ " border-inline-start: 2px solid var(--gem-color-accent);",
1430
+ " padding-inline-start: var(--gem-space-md);",
1431
+ " margin: var(--gem-space-md) 0;",
1432
+ "}",
1433
+ ".gem-byline {",
1434
+ " font-size: var(--gem-text-sm, 0.8125rem);",
1435
+ " font-weight: 600;",
1436
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
1437
+ "}",
1438
+ ".gem-disclaimer {",
1439
+ " font-size: 0.6875rem;",
1440
+ " line-height: 1.5;",
1441
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 60%, transparent));",
1442
+ "}",
1443
+ // Bullets had no primitive either, which is why a captured benefit list rebuilt as bare lines of
1444
+ // text: gemcapture types every <li> as part "bullet", and there was nothing to bind it to.
1445
+ ".gem-list {",
1446
+ " list-style: none;",
1447
+ " margin: 0;",
1448
+ " padding: 0;",
1449
+ " display: grid;",
1450
+ " gap: var(--gem-space-xs);",
1451
+ "}",
1452
+ ".gem-list__item {",
1453
+ " position: relative;",
1454
+ " padding-inline-start: 1.4em;",
1455
+ " line-height: 1.5;",
1456
+ "}",
1457
+ ".gem-list__item::before {",
1458
+ " content: '';",
1459
+ " position: absolute;",
1460
+ " inset-inline-start: 0;",
1461
+ " top: 0.55em;",
1462
+ " width: 0.42em;",
1463
+ " height: 0.42em;",
1464
+ " border-radius: var(--gem-radius-pill, 999px);",
1465
+ " background: var(--gem-color-accent);",
1466
+ "}",
1467
+ ".gem-subhead {",
1468
+ " font-family: var(--gem-font-heading);",
1469
+ " font-size: var(--gem-h6, 1.0625rem);",
1470
+ " font-weight: 700;",
1471
+ " margin-block: var(--gem-space-sm) var(--gem-space-xs);",
1472
+ "}",
1473
+ ".gem-rating, .gem-proof {",
1474
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
1475
+ "}",
1476
+ // Star ROW primitive, driven by the two numbers gemcapture recovers (`rating: {stars, filled}`).
1477
+ // .gem-rating above is a type rule for a text label; every actual star row in the theme was a
1478
+ // hardcoded five-glyph literal, so a captured 4-of-5 (or a half star) had nowhere to land. The
1479
+ // fill is a percentage-width overlay, so fractional values render exactly instead of rounding.
1480
+ ".gem-stars {",
1481
+ " --gem-stars-total: 5;",
1482
+ " --gem-stars-value: 5;",
1483
+ " position: relative;",
1484
+ " display: inline-block;",
1485
+ " line-height: 1;",
1486
+ " font-size: var(--gem-text-sm, 0.8125rem);",
1487
+ " letter-spacing: 0.1em;",
1488
+ " color: var(--gem-color-border);",
1489
+ "}",
1490
+ ".gem-stars__base, .gem-stars__fill { display: block; white-space: nowrap; }",
1491
+ ".gem-stars__fill {",
1492
+ " position: absolute;",
1493
+ " inset: 0;",
1494
+ " width: calc(var(--gem-stars-value) / var(--gem-stars-total) * 100%);",
1495
+ " overflow: hidden;",
1496
+ " color: var(--gem-color-accent);",
1497
+ "}",
1498
+ // Marquee primitive — CSS-only and deliberately so (no JS to init, works on every render path).
1499
+ // The one requirement is a DUPLICATED track: a single track scrolls off and leaves a gap.
1500
+ ".gem-marquee { overflow: hidden; }",
1501
+ ".gem-marquee__viewport { display: flex; overflow: hidden; }",
1502
+ ".gem-marquee__track {",
1503
+ " flex: 0 0 auto;",
1504
+ " min-width: 100%;",
1505
+ " display: flex;",
1506
+ " align-items: center;",
1507
+ " justify-content: space-around;",
1508
+ " gap: var(--gem-space-lg);",
1509
+ " white-space: nowrap;",
1510
+ " animation: gem-marquee var(--gem-marquee-duration, 24s) linear infinite;",
1511
+ "}",
1512
+ ".gem-marquee__viewport:hover .gem-marquee__track { animation-play-state: paused; }",
1513
+ ".gem-marquee--reverse .gem-marquee__track { animation-direction: reverse; }",
1514
+ "@keyframes gem-marquee { from { transform: translateX(0); } to { transform: translateX(-100%); } }",
1515
+ "@media (prefers-reduced-motion: reduce) {",
1516
+ " .gem-marquee__track { animation: none; }",
1517
+ " .gem-marquee__viewport { overflow-x: auto; }",
1518
+ "}",
1519
+ ".gem-product-card {",
1520
+ " display: grid;",
1521
+ " grid-template-rows: auto minmax(0, 1fr);",
1522
+ " gap: var(--gem-space-sm);",
1523
+ " color: var(--gem-color-text);",
1524
+ "}",
1525
+ ".gem-product-card--sold-out {",
1526
+ " opacity: 0.78;",
1527
+ "}",
1528
+ // A REAL image inside the card media box. The box is a fixed-ratio frame
1529
+ // (padding-bottom: 100%; height: 0; overflow: hidden) designed around a placeholder background,
1530
+ // so an <img> child laid out in flow rendered at its natural size and broke the grid — every
1531
+ // card became one full-width picture. Captured cards always carry a real <img>.
1532
+ ".gem-product-card__media > img, .gem-media > img {",
1533
+ " position: absolute;",
1534
+ " inset: 0;",
1535
+ " display: block;",
1536
+ " width: 100%;",
1537
+ " height: 100%;",
1538
+ " object-fit: cover;",
1539
+ "}",
1540
+ ".gem-product-card__media {",
1541
+ " position: relative;",
1542
+ " aspect-ratio: 1 / 1;",
1543
+ "}",
1544
+ // The gem card media link also carries Dawn's `card__media` class, and Dawn's
1545
+ // `.card__media { position: absolute }` (same specificity, loaded later) WINS — turning the gem
1546
+ // media box absolute, so the inner `position:absolute` image lost its anchor and rendered offset
1547
+ // (a ~17px inset bleed). Re-assert relative for the both-classes case at higher specificity so
1548
+ // the gem aspect-ratio box holds and the image stays put.
1549
+ ".gem-product-card__media.card__media {",
1550
+ " position: relative;",
1551
+ " inset: auto;",
1552
+ "}",
1553
+ ".gem-product-card__media .gem-product-card__badges {",
1554
+ " position: absolute;",
1555
+ " inset-block-start: var(--gem-space-sm);",
1556
+ " inset-inline-start: var(--gem-space-sm);",
1557
+ " z-index: 1;",
1558
+ "}",
1559
+ ".gem-product-card__placeholder {",
1560
+ " display: grid;",
1561
+ " min-height: 100%;",
1562
+ " place-items: center;",
1563
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 64%, transparent));",
1564
+ "}",
1565
+ ".gem-product-card__content {",
1566
+ " display: grid;",
1567
+ " grid-template-rows: auto auto minmax(0, 1fr) auto;",
1568
+ " gap: var(--gem-space-xs);",
1569
+ "}",
1570
+ ".gem-product-card__title {",
1571
+ " margin: 0;",
1572
+ " font-family: var(--gem-font-heading);",
1573
+ " font-weight: 650;",
1574
+ "}",
1575
+ ".gem-product-card__title a {",
1576
+ " color: inherit;",
1577
+ " text-decoration: none;",
1578
+ "}",
1579
+ ".gem-product-card__title a:hover {",
1580
+ " text-decoration: underline;",
1581
+ " text-underline-offset: 0.18em;",
1582
+ "}",
1583
+ ".gem-product-card__price {",
1584
+ " display: flex;",
1585
+ " flex-wrap: wrap;",
1586
+ " gap: var(--gem-space-xs);",
1587
+ " align-items: baseline;",
1588
+ "}",
1589
+ ".gem-product-card__badges, .gem-product-card__quick-actions {",
1590
+ " display: flex;",
1591
+ " flex-wrap: wrap;",
1592
+ " gap: var(--gem-space-xs);",
1593
+ " align-items: center;",
1594
+ "}",
1595
+ ".gem-product-card__quick-actions {",
1596
+ " align-self: end;",
1597
+ "}",
1598
+ ".gem-product-card__quick-actions .gem-button {",
1599
+ " min-width: min(100%, 8rem);",
1600
+ "}",
1601
+ ".gem-product-card__secondary-image {",
1602
+ " position: absolute;",
1603
+ " inset: 0;",
1604
+ " opacity: 0;",
1605
+ " transition: opacity var(--gem-motion-duration, 160ms) var(--gem-motion-easing, ease);",
1606
+ "}",
1607
+ ".gem-product-card:hover .gem-product-card__secondary-image {",
1608
+ " opacity: 1;",
1609
+ "}",
1610
+ ".gem-product-card__vendor, .gem-product-card__rating {",
1611
+ " margin: 0;",
1612
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
1613
+ " font-size: 0.8125rem;",
1614
+ "}",
1615
+ ".gem-product-card__swatches {",
1616
+ " display: flex;",
1617
+ " flex-wrap: wrap;",
1618
+ " gap: var(--gem-space-xs);",
1619
+ "}",
1620
+ ".gem-product-media-gallery__thumb[aria-current='true'], .gem-product-media-gallery__thumb[data-gem-media-active='true'] {",
1621
+ " border-color: var(--gem-color-accent);",
1622
+ " box-shadow: 0 0 0 2px color-mix(in srgb, var(--gem-color-accent) 28%, transparent);",
1623
+ "}",
1624
+ ".gem-product-media-gallery__thumb {",
1625
+ " cursor: pointer;",
1626
+ "}",
1627
+ ".gem-product-meta {",
1628
+ " display: flex;",
1629
+ " flex-wrap: wrap;",
1630
+ " gap: var(--gem-space-xs) var(--gem-space-md);",
1631
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
1632
+ " font-size: 0.875rem;",
1633
+ "}",
1634
+ ".gem-product-meta__item {",
1635
+ " display: inline-flex;",
1636
+ " gap: var(--gem-space-xs);",
1637
+ " align-items: baseline;",
1638
+ "}",
1639
+ ".gem-product-meta__label {",
1640
+ " font-weight: 650;",
1641
+ " color: var(--gem-color-text);",
1642
+ "}",
1643
+ ".gem-product-meta__value {",
1644
+ " color: inherit;",
1645
+ "}",
1646
+ ".gem-product-main__summary {",
1647
+ " display: grid;",
1648
+ " gap: var(--gem-space-md);",
1649
+ " max-width: 48rem;",
1650
+ "}",
1651
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__inner {",
1652
+ " display: grid;",
1653
+ " grid-template-columns: minmax(0, 1fr) minmax(22rem, 0.72fr);",
1654
+ " align-items: start;",
1655
+ " gap: var(--gem-space-xl);",
1656
+ "}",
1657
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__summary {",
1658
+ " position: sticky;",
1659
+ " top: calc(var(--gem-component-header-height, 72px) + var(--gem-space-md));",
1660
+ "}",
1661
+ ".gem-product-main__media {",
1662
+ " min-width: 0;",
1663
+ "}",
1664
+ ".gem-product-main__caption {",
1665
+ " margin: 0;",
1666
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
1667
+ "}",
1668
+ ".gem-product-main__collapsible {",
1669
+ " border-block-start: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1670
+ " padding-block: var(--gem-space-md);",
1671
+ "}",
1672
+ ".gem-product-main__collapsible:last-of-type {",
1673
+ " border-block-end: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1674
+ "}",
1675
+ ".gem-product-main__collapsible summary {",
1676
+ " cursor: pointer;",
1677
+ " font-weight: 650;",
1678
+ "}",
1679
+ ".gem-product-main__price {",
1680
+ " display: flex;",
1681
+ " flex-wrap: wrap;",
1682
+ " gap: var(--gem-space-sm);",
1683
+ " align-items: baseline;",
1684
+ " font-size: 1.25rem;",
1685
+ "}",
1686
+ ".gem-product-main__price s {",
1687
+ " color: var(--gem-color-muted);",
1688
+ " font-weight: 500;",
1689
+ "}",
1690
+ ".gem-product-main__availability {",
1691
+ " margin: 0;",
1692
+ " font-weight: 650;",
1693
+ "}",
1694
+ ".gem-product-main__availability--in-stock {",
1695
+ " color: var(--gem-color-success);",
1696
+ "}",
1697
+ ".gem-product-main__availability--sold-out {",
1698
+ // --gem-color-danger, not --gem-color-error. The token pack has always emitted the former
1699
+ // (`requiredGemTokenKeys.color` lists `danger`); nothing in the fleet ever emitted the latter, so
1700
+ // every error surface fell through to this hardcoded hex. Measured on a plan carrying
1701
+ // `color.danger: #ff00aa`: the stylesheet declared `--gem-color-danger: #ff00aa` and the error
1702
+ // text still rendered rgb(180,35,24). A fallback that always wins is a token that is not governed.
1703
+ " color: var(--gem-color-danger, #b42318);",
1704
+ "}",
1705
+ ".gem-product-main__variant-fallback {",
1706
+ " max-width: 36rem;",
1707
+ " margin: 0;",
1708
+ " padding: 0;",
1709
+ " border: 0;",
1710
+ " display: flex;",
1711
+ " flex-wrap: wrap;",
1712
+ " gap: 0.8rem;",
1713
+ "}",
1714
+ ".gem-product-main__variant-fallback legend {",
1715
+ " width: 100%;",
1716
+ " padding: 0;",
1717
+ " margin: 0 0 0.3rem;",
1718
+ " font-size: 1.4rem;",
1719
+ " line-height: 1.8;",
1720
+ "}",
1721
+ ".gem-product-main__variant-pill {",
1722
+ " display: inline-flex;",
1723
+ " align-items: center;",
1724
+ " justify-content: center;",
1725
+ " min-height: 3.6rem;",
1726
+ " min-width: 9.2rem;",
1727
+ " border: 1px solid rgb(18 18 18 / 75%);",
1728
+ " border-radius: 999px;",
1729
+ " padding: 0.8rem 1.8rem;",
1730
+ " font-size: 1.3rem;",
1731
+ " line-height: 1;",
1732
+ "}",
1733
+ ".gem-product-main__variant-pill--selected {",
1734
+ " background: rgb(18 18 18);",
1735
+ " border-color: rgb(18 18 18);",
1736
+ " color: white;",
1737
+ "}",
1738
+ ".gem-product-main__variant-pill--disabled {",
1739
+ " color: rgb(18 18 18 / 55%);",
1740
+ " text-decoration: line-through;",
1741
+ "}",
1742
+ ".gem-product-main__form {",
1743
+ " display: grid;",
1744
+ " gap: var(--gem-space-md);",
1745
+ " max-width: 32rem;",
1746
+ "}",
1747
+ ".gem-buy-buttons {",
1748
+ " display: grid;",
1749
+ " gap: var(--gem-space-md);",
1750
+ " max-width: 32rem;",
1751
+ "}",
1752
+ ".gem-buy-buttons__variant, .gem-buy-buttons__quantity {",
1753
+ " display: grid;",
1754
+ " gap: var(--gem-space-xs);",
1755
+ "}",
1756
+ ".gem-buy-buttons__submit {",
1757
+ " width: 100%;",
1758
+ "}",
1759
+ ".gem-buy-buttons__variant-status {",
1760
+ " margin: 0;",
1761
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
1762
+ " font-size: 0.875rem;",
1763
+ "}",
1764
+ ".gem-buy-buttons__error { color: var(--gem-color-danger, #b42318); }",
1765
+ ".gem-product-main__assurance {",
1766
+ " display: grid;",
1767
+ " gap: var(--gem-space-xs);",
1768
+ " max-width: 32rem;",
1769
+ " padding: var(--gem-space-md);",
1770
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1771
+ " border-radius: var(--gem-radius-md);",
1772
+ " background: var(--gem-color-surface);",
1773
+ "}",
1774
+ ".gem-product-main__assurance-item {",
1775
+ " display: grid;",
1776
+ " gap: 0.125rem;",
1777
+ " margin: 0;",
1778
+ "}",
1779
+ ".gem-product-main__assurance-item strong {",
1780
+ " font-size: 0.9375rem;",
1781
+ "}",
1782
+ ".gem-product-main__assurance-item span {",
1783
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 70%, transparent));",
1784
+ " font-size: 0.875rem;",
1785
+ "}",
1786
+ ".gem-product-main__share {",
1787
+ " justify-self: start;",
1788
+ " color: var(--gem-color-text);",
1789
+ " font-weight: 650;",
1790
+ " text-underline-offset: 0.25em;",
1791
+ "}",
1792
+ ".gem-product-main__quantity {",
1793
+ " max-width: 10rem;",
1794
+ "}",
1795
+ ".gem-product-main__submit {",
1796
+ " width: 100%;",
1797
+ "}",
1798
+ ".gem-variant-picker {",
1799
+ " display: grid;",
1800
+ " gap: var(--gem-space-sm);",
1801
+ "}",
1802
+ ".gem-swatch {",
1803
+ " inline-size: 2rem;",
1804
+ " block-size: 2rem;",
1805
+ " border: var(--gem-variant-pill-border-width, 1px) solid var(--gem-color-border);",
1806
+ " border-radius: var(--gem-variant-pill-radius, var(--gem-radius-pill, 999px));",
1807
+ " background: var(--gem-color-surface);",
1808
+ "}",
1809
+ ".gem-quantity-selector {",
1810
+ " display: inline-grid;",
1811
+ " grid-template-columns: var(--gem-component-input-height, 44px) minmax(3rem, 1fr) var(--gem-component-input-height, 44px);",
1812
+ " min-height: var(--gem-component-input-height, 44px);",
1813
+ " border: var(--gem-input-border-width, 1px) solid var(--gem-color-border);",
1814
+ " border-radius: var(--gem-radius-md);",
1815
+ " overflow: hidden;",
1816
+ "}",
1817
+ ".gem-quantity-input {",
1818
+ " display: inline-grid;",
1819
+ " grid-template-columns: var(--gem-component-input-height, 44px) minmax(3rem, 1fr) var(--gem-component-input-height, 44px);",
1820
+ " width: min(100%, 10rem);",
1821
+ " min-height: var(--gem-component-input-height, 44px);",
1822
+ " border: var(--gem-input-border-width, 1px) solid var(--gem-color-border);",
1823
+ " border-radius: var(--gem-radius-md);",
1824
+ " overflow: hidden;",
1825
+ "}",
1826
+ ".gem-quantity-input__button, .gem-quantity-input__field {",
1827
+ " min-width: 0;",
1828
+ " border: 0;",
1829
+ " background: var(--gem-color-surface);",
1830
+ " color: var(--gem-color-text);",
1831
+ " text-align: center;",
1832
+ "}",
1833
+ ".gem-quantity-input__button {",
1834
+ " font-weight: 750;",
1835
+ "}",
1836
+ ".gem-cart-main__form, .gem-cart-main__items, .gem-cart-footer__inner, .gem-cart-footer__blocks {",
1837
+ " display: grid;",
1838
+ " gap: var(--gem-space-md);",
1839
+ "}",
1840
+ ".gem-cart-footer__inner {",
1841
+ " justify-items: end;",
1842
+ "}",
1843
+ ".gem-cart-footer__note, .gem-cart-footer__blocks {",
1844
+ " inline-size: min(100%, 36rem);",
1845
+ "}",
1846
+ ".gem-cart-footer__subtotal, .gem-cart-footer__buttons {",
1847
+ " display: grid;",
1848
+ " gap: var(--gem-space-sm);",
1849
+ " justify-items: stretch;",
1850
+ "}",
1851
+ ".gem-cart-footer__total-label, .gem-cart-footer__total-value {",
1852
+ " margin: 0;",
1853
+ "}",
1854
+ ".gem-cart-footer__total-value {",
1855
+ " font-size: 1.25rem;",
1856
+ " font-weight: 760;",
1857
+ "}",
1858
+ ".gem-cart-footer__tax-note {",
1859
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 64%, transparent));",
1860
+ "}",
1861
+ ".gem-cart-line-item {",
1862
+ " display: grid;",
1863
+ " grid-template-columns: minmax(5rem, 7rem) minmax(0, 1fr) auto auto;",
1864
+ " gap: var(--gem-space-md);",
1865
+ " align-items: start;",
1866
+ "}",
1867
+ ".gem-cart-line-item__title, .gem-cart-line-item__remove {",
1868
+ " color: inherit;",
1869
+ "}",
1870
+ ".gem-cart-line-item__details {",
1871
+ " display: grid;",
1872
+ " gap: var(--gem-space-xs);",
1873
+ "}",
1874
+ ".gem-cart-line-item__media {",
1875
+ " aspect-ratio: 1 / 1;",
1876
+ " min-block-size: 5rem;",
1877
+ "}",
1878
+ ".gem-cart-line-item__meta, .gem-cart-line-item__price {",
1879
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 68%, transparent));",
1880
+ "}",
1881
+ ".gem-main-login .gem-section__inner, .gem-main-register .gem-section__inner, .gem-main-activate-account .gem-section__inner, .gem-main-reset-password .gem-section__inner {",
1882
+ " max-width: min(100%, 44rem);",
1883
+ "}",
1884
+ ".gem-main-login form, .gem-main-register form, .gem-main-activate-account form, .gem-main-reset-password form {",
1885
+ " gap: var(--gem-space-md);",
1886
+ "}",
1887
+ ".gem-main-addresses form {",
1888
+ " align-self: start;",
1889
+ "}",
1890
+ ".gem-rich-text__content {",
1891
+ " display: grid;",
1892
+ " justify-items: center;",
1893
+ " gap: var(--gem-space-md);",
1894
+ " max-width: 72rem;",
1895
+ " margin-inline: auto;",
1896
+ " text-align: center;",
1897
+ "}",
1898
+ ".gem-rich-text[data-gem-rich-text-alignment='left'] .gem-rich-text__content {",
1899
+ " justify-items: start;",
1900
+ " text-align: left;",
1901
+ "}",
1902
+ ".gem-rich-text[data-gem-rich-text-alignment='right'] .gem-rich-text__content {",
1903
+ " justify-items: end;",
1904
+ " text-align: right;",
1905
+ "}",
1906
+ ".gem-rich-text__blocks {",
1907
+ " display: grid;",
1908
+ " gap: var(--gem-space-md);",
1909
+ " width: 100%;",
1910
+ "}",
1911
+ ".gem-customer-card, .gem-customer-address, .gem-customer-order-status, .gem-customer-order-address {",
1912
+ " display: grid;",
1913
+ " gap: var(--gem-space-xs);",
1914
+ "}",
1915
+ ".gem-customer-card a, .gem-customer-address a {",
1916
+ " color: inherit;",
1917
+ " text-underline-offset: 0.18em;",
1918
+ "}",
1919
+ ".gem-customer-order-history {",
1920
+ " display: grid;",
1921
+ " gap: var(--gem-space-sm);",
1922
+ "}",
1923
+ ".gem-customer-order-history h2 {",
1924
+ " margin: 0;",
1925
+ " font-family: var(--gem-font-heading);",
1926
+ " font-size: clamp(1.25rem, 2vw, 1.75rem);",
1927
+ "}",
1928
+ ".gem-customer-order-link {",
1929
+ " display: grid;",
1930
+ " grid-template-columns: minmax(0, 1fr) auto;",
1931
+ " gap: var(--gem-space-sm);",
1932
+ " align-items: center;",
1933
+ " color: inherit;",
1934
+ " text-decoration: none;",
1935
+ "}",
1936
+ ".gem-customer-order-link:hover strong {",
1937
+ " text-decoration: underline;",
1938
+ " text-underline-offset: 0.18em;",
1939
+ "}",
1940
+ ".gem-customer-order-line {",
1941
+ " grid-template-columns: minmax(0, 1fr) auto;",
1942
+ "}",
1943
+ ".gem-customer-order-total {",
1944
+ " margin: 0;",
1945
+ " justify-self: end;",
1946
+ " font-weight: 750;",
1947
+ "}",
1948
+ ".gem-pagination {",
1949
+ " display: flex;",
1950
+ " flex-wrap: wrap;",
1951
+ " gap: var(--gem-space-sm);",
1952
+ " align-items: center;",
1953
+ " justify-content: center;",
1954
+ "}",
1955
+ ".gem-pagination a, .gem-pagination span {",
1956
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1957
+ " border-radius: var(--gem-radius-md);",
1958
+ " padding: var(--gem-space-sm) var(--gem-space-md);",
1959
+ " text-decoration: none;",
1960
+ "}",
1961
+ ".gem-pagination [aria-current='page'], .gem-state-active {",
1962
+ " border-color: var(--gem-color-accent);",
1963
+ " background: var(--gem-color-accent);",
1964
+ " color: var(--gem-color-accent-text, var(--gem-color-surface));",
1965
+ "}",
1966
+ ".gem-state-empty, .gem-state-loading, .gem-state-error, .gem-state-success {",
1967
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
1968
+ " border-radius: var(--gem-radius-md);",
1969
+ " background: var(--gem-color-surface);",
1970
+ " padding: var(--gem-space-md);",
1971
+ "}",
1972
+ ".gem-state-empty, .gem-state-loading {",
1973
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 68%, transparent));",
1974
+ "}",
1975
+ ".gem-state-error {",
1976
+ " border-color: color-mix(in srgb, var(--gem-color-danger, #b42318) 42%, var(--gem-color-border));",
1977
+ " color: var(--gem-color-danger, #b42318);",
1978
+ " background: color-mix(in srgb, var(--gem-color-danger, #b42318) 7%, var(--gem-color-surface));",
1979
+ "}",
1980
+ ".gem-state-success {",
1981
+ " border-color: color-mix(in srgb, var(--gem-color-success, #027a48) 42%, var(--gem-color-border));",
1982
+ " color: var(--gem-color-success, #027a48);",
1983
+ " background: color-mix(in srgb, var(--gem-color-success, #027a48) 7%, var(--gem-color-surface));",
1984
+ "}",
1985
+ ".gem-state-loading {",
1986
+ " display: inline-flex;",
1987
+ " align-items: center;",
1988
+ " gap: var(--gem-space-sm);",
1989
+ "}",
1990
+ ".gem-state-loading::before {",
1991
+ " content: '';",
1992
+ " inline-size: 1rem;",
1993
+ " block-size: 1rem;",
1994
+ " border: 2px solid currentColor;",
1995
+ " border-right-color: transparent;",
1996
+ " border-radius: 999px;",
1997
+ " animation: gem-spin 0.8s linear infinite;",
1998
+ "}",
1999
+ "@keyframes gem-spin {",
2000
+ " to { transform: rotate(360deg); }",
2001
+ "}",
2002
+ "@media (prefers-reduced-motion: reduce) {",
2003
+ " .gem-state-loading::before { animation: none; }",
2004
+ "}",
2005
+ ".gem-sticky-atc {",
2006
+ " position: sticky;",
2007
+ " inset-block-end: 0;",
2008
+ " z-index: 30;",
2009
+ " border-top: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
2010
+ " background: var(--gem-color-surface);",
2011
+ " padding: var(--gem-space-sm) var(--gem-space-md);",
2012
+ " transition: transform 160ms ease, opacity 160ms ease;",
2013
+ "}",
2014
+ ".gem-sticky-atc[data-gem-sticky-atc-state='hidden'] {",
2015
+ " transform: translateY(100%);",
2016
+ " opacity: 0;",
2017
+ " pointer-events: none;",
2018
+ "}",
2019
+ ".gem-sticky-atc[data-gem-sticky-atc-state='visible'] {",
2020
+ " transform: translateY(0);",
2021
+ " opacity: 1;",
2022
+ "}",
2023
+ ...GEM_REVEAL_CSS_LINES,
2024
+ ...GEM_AMBIENT_CSS_LINES,
2025
+ ...GEM_DIVIDER_CSS_LINES,
2026
+ ...GEM_CARD_CSS_LINES,
2027
+ ...GEM_COUNTDOWN_ENDED_CSS_LINES,
2028
+ ".gem-promo-banner, .gem-promo-tile {",
2029
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
2030
+ " border-radius: var(--gem-radius-md);",
2031
+ " background: var(--gem-color-surface);",
2032
+ " padding: var(--gem-space-md);",
2033
+ "}",
2034
+ ".gem-promo-banner {",
2035
+ " display: flex;",
2036
+ " flex-wrap: wrap;",
2037
+ " justify-content: space-between;",
2038
+ " gap: var(--gem-space-sm);",
2039
+ "}",
2040
+ ".gem-trust-list, .gem-breadcrumbs, .gem-filter-bar {",
2041
+ " display: flex;",
2042
+ " flex-wrap: wrap;",
2043
+ " gap: var(--gem-space-sm);",
2044
+ " align-items: center;",
2045
+ "}",
2046
+ ".gem-filter-bar .gem-select {",
2047
+ " width: auto;",
2048
+ " min-width: min(18rem, 100%);",
2049
+ " margin-left: auto;",
2050
+ "}",
2051
+ ".gem-collection-filter-toolbar__form {",
2052
+ " display: flex;",
2053
+ " flex-wrap: wrap;",
2054
+ " align-items: end;",
2055
+ " gap: var(--gem-space-sm);",
2056
+ "}",
2057
+ ".gem-collection-filter-toolbar__filters, .gem-collection-filter-toolbar__sort, .gem-collection-filter-toolbar__filter {",
2058
+ " display: grid;",
2059
+ " gap: var(--gem-space-xs);",
2060
+ "}",
2061
+ ".gem-collection-filter-toolbar__filters {",
2062
+ " align-content: start;",
2063
+ "}",
2064
+ ".gem-collection-filter-toolbar__filters > summary {",
2065
+ " list-style: none;",
2066
+ "}",
2067
+ ".gem-collection-filter-toolbar__filters > summary::-webkit-details-marker {",
2068
+ " display: none;",
2069
+ "}",
2070
+ ".gem-collection-filter-toolbar__filters[open] {",
2071
+ " gap: var(--gem-space-sm);",
2072
+ "}",
2073
+ ".gem-collection-filter-toolbar__sort {",
2074
+ " margin-left: auto;",
2075
+ "}",
2076
+ ".gem-collection-filter-toolbar__select {",
2077
+ " min-height: var(--gem-component-input-height, 44px);",
2078
+ " min-width: min(16rem, 100%);",
2079
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
2080
+ " border-radius: var(--gem-radius-md);",
2081
+ " background: var(--gem-color-surface);",
2082
+ " color: var(--gem-color-text);",
2083
+ " padding-inline: var(--gem-space-md);",
2084
+ "}",
2085
+ ".gem-collection-filter-toolbar__active {",
2086
+ " display: flex;",
2087
+ " flex-wrap: wrap;",
2088
+ " align-items: center;",
2089
+ " gap: var(--gem-space-xs);",
2090
+ "}",
2091
+ ".gem-collection-filter-toolbar__active:empty {",
2092
+ " display: none;",
2093
+ "}",
2094
+ ".gem-collection-filter-toolbar__active-filter {",
2095
+ " text-decoration: none;",
2096
+ "}",
2097
+ ".gem-collection-filter-toolbar__clear {",
2098
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
2099
+ " font-size: 0.875rem;",
2100
+ "}",
2101
+ ".gem-tabs {",
2102
+ " display: grid;",
2103
+ " gap: var(--gem-space-md);",
2104
+ "}",
2105
+ ".gem-drawer, .gem-modal {",
2106
+ " background: var(--gem-color-surface);",
2107
+ " color: var(--gem-color-text);",
2108
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
2109
+ " box-shadow: var(--gem-shadow-md, none);",
2110
+ "}",
2111
+ ".gem-modal[aria-hidden='true'] {",
2112
+ " display: none;",
2113
+ "}",
2114
+ ".gem-modal[open] {",
2115
+ " display: grid;",
2116
+ " gap: var(--gem-space-sm);",
2117
+ " padding: var(--gem-space-md);",
2118
+ "}",
2119
+ ".gem-cart-drawer {",
2120
+ " position: relative;",
2121
+ " z-index: 80;",
2122
+ "}",
2123
+ ".gem-cart-drawer:not([open]) .gem-cart-drawer__overlay, .gem-cart-drawer:not([open]) .gem-cart-drawer__panel {",
2124
+ " display: none;",
2125
+ "}",
2126
+ ".gem-cart-drawer__overlay {",
2127
+ " position: fixed;",
2128
+ " inset: 0;",
2129
+ " background: rgba(0, 0, 0, 0.36);",
2130
+ "}",
2131
+ // Opening motion (gemfactory request #13, 01/10/2026): 28 stored drawers each declared their own
2132
+ // `@keyframes …-in { from { transform: translateX(24px); opacity: 0 } }`. OPT-IN on the drawer root,
2133
+ // data-gem-drawer-motion="slide", so no existing drawer changes (review #650: as a default the overlay fade
2134
+ // reached all 28): the panel slides in by --gem-drawer-offset (24px) and the overlay fades. A drawer drops its own
2135
+ // keyframes by adding the attribute. The panel sits at inline-end, so under RTL it comes from the left.
2136
+ // :dir(rtl) follows the HTML dir attribute through inheritance, so a dir="ltr" island inside an rtl page stays
2137
+ // ltr (a `[dir='rtl'] .x` descendant rule got that wrong). CSS `direction` alone is invisible to selectors. Off under prefers-reduced-motion.
2138
+ "@keyframes gem-cart-drawer-panel-in { from { translate: calc(var(--gem-drawer-offset, 24px) * var(--gem-drawer-dir, 1)) 0; opacity: 0; } }",
2139
+ "@keyframes gem-cart-drawer-overlay-in { from { opacity: 0; } }",
2140
+ ".gem-cart-drawer__panel:dir(rtl) { --gem-drawer-dir: -1; }",
2141
+ ".gem-cart-drawer[data-gem-drawer-motion='slide'] .gem-cart-drawer__overlay { animation: gem-cart-drawer-overlay-in var(--gem-motion-duration, 160ms) var(--gem-motion-easing, ease); }",
2142
+ ".gem-cart-drawer[data-gem-drawer-motion='slide'] .gem-cart-drawer__panel { animation: gem-cart-drawer-panel-in var(--gem-motion-duration, 160ms) var(--gem-motion-easing, ease); }",
2143
+ ".gem-cart-drawer__panel {",
2144
+ " position: fixed;",
2145
+ " inset-block: 0;",
2146
+ " inset-inline-end: 0;",
2147
+ " width: min(100%, 28rem);",
2148
+ " overflow: auto;",
2149
+ " background: var(--gem-color-surface);",
2150
+ " color: var(--gem-color-text);",
2151
+ " border-inline-start: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
2152
+ " box-shadow: var(--gem-shadow-md, none);",
2153
+ " padding: var(--gem-space-lg);",
2154
+ "}",
2155
+ // AFTER the opt-in rules and at THEIR specificity: measured 02/10/2026, a reduced-motion rule placed before the
2156
+ // animation rule (or weaker than it) left the panel animating.
2157
+ "@media (prefers-reduced-motion: reduce) { .gem-cart-drawer[data-gem-drawer-motion] :is(.gem-cart-drawer__panel, .gem-cart-drawer__overlay) { animation: none; } }",
2158
+ ".gem-cart-drawer__header, .gem-cart-drawer__footer {",
2159
+ " display: flex;",
2160
+ " flex-wrap: wrap;",
2161
+ " align-items: center;",
2162
+ " justify-content: space-between;",
2163
+ " gap: var(--gem-space-sm);",
2164
+ "}",
2165
+ ".gem-cart-drawer__header {",
2166
+ " margin-bottom: var(--gem-space-lg);",
2167
+ "}",
2168
+ ".gem-cart-drawer__header h2 {",
2169
+ " margin: 0;",
2170
+ " font-family: var(--gem-font-heading);",
2171
+ "}",
2172
+ ".gem-cart-drawer__form, .gem-cart-drawer__items, .gem-cart-drawer__empty {",
2173
+ " display: grid;",
2174
+ " gap: var(--gem-space-md);",
2175
+ "}",
2176
+ ".gem-cart-drawer .gem-cart-line-item {",
2177
+ " grid-template-columns: minmax(4.5rem, 5.5rem) minmax(0, 1fr);",
2178
+ " gap: var(--gem-space-sm);",
2179
+ "}",
2180
+ ".gem-cart-drawer .gem-cart-line-item__quantity, .gem-cart-drawer .gem-cart-line-item__price {",
2181
+ " grid-column: 2;",
2182
+ "}",
2183
+ ".gem-cart-drawer .gem-cart-line-item__price {",
2184
+ " justify-self: start;",
2185
+ "}",
2186
+ ".gem-cart-drawer__footer {",
2187
+ " margin-top: var(--gem-space-lg);",
2188
+ " padding-top: var(--gem-space-md);",
2189
+ " border-top: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
2190
+ "}",
2191
+ ".gem-cart-drawer__footer p {",
2192
+ " flex-basis: 100%;",
2193
+ " margin: 0;",
2194
+ " font-weight: 750;",
2195
+ "}",
2196
+ ".gem-copy-code, .gem-delivery-date, .gem-stock-indicator, .gem-popup {",
2197
+ " color: var(--gem-color-text);",
2198
+ " background: var(--gem-color-surface);",
2199
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
2200
+ " border-radius: var(--gem-radius-md);",
2201
+ "}",
2202
+ ".gem-copy-code, .gem-delivery-date, .gem-stock-indicator {",
2203
+ " display: inline-flex;",
2204
+ " align-items: center;",
2205
+ " gap: var(--gem-space-sm);",
2206
+ " padding: var(--gem-space-sm) var(--gem-space-md);",
2207
+ "}",
2208
+ ".gem-popup {",
2209
+ " box-shadow: var(--gem-shadow-md, none);",
2210
+ " padding: var(--gem-space-lg);",
2211
+ "}",
2212
+ ".gem-back-to-top {",
2213
+ " position: fixed;",
2214
+ " inset-block-end: var(--gem-space-lg);",
2215
+ " inset-inline-end: var(--gem-space-lg);",
2216
+ " z-index: 20;",
2217
+ "}",
2218
+ ".gem-content-shell {",
2219
+ " max-width: 72ch;",
2220
+ "}",
2221
+ ".gem-content-shell .gem-section__heading {",
2222
+ " max-width: 12ch;",
2223
+ "}",
2224
+ ".gem-content-header {",
2225
+ " display: grid;",
2226
+ " gap: var(--gem-space-sm);",
2227
+ "}",
2228
+ ".gem-content-body {",
2229
+ " max-width: 72ch;",
2230
+ "}",
2231
+ ".gem-content-body > * + * {",
2232
+ " margin-top: var(--gem-space-md);",
2233
+ "}",
2234
+ ".gem-content-body h2, .gem-content-body h3 {",
2235
+ " margin-bottom: 0;",
2236
+ " font-family: var(--gem-font-heading);",
2237
+ " line-height: 1.15;",
2238
+ "}",
2239
+ ".gem-content-body ul, .gem-content-body ol {",
2240
+ " padding-inline-start: var(--gem-space-lg);",
2241
+ "}",
2242
+ ".gem-content-body a {",
2243
+ " color: var(--gem-color-accent);",
2244
+ " text-underline-offset: 0.18em;",
2245
+ "}",
2246
+ ".gem-main-page .gem-content-shell {",
2247
+ " display: grid;",
2248
+ " gap: var(--gem-space-lg);",
2249
+ "}",
2250
+ ".gem-contact-form {",
2251
+ " display: grid;",
2252
+ " gap: var(--gem-space-lg);",
2253
+ "}",
2254
+ ".gem-contact-form__form {",
2255
+ " gap: var(--gem-space-md);",
2256
+ "}",
2257
+ ".gem-contact-form__form .gem-button {",
2258
+ " justify-self: start;",
2259
+ "}",
2260
+ ".gem-email-signup-banner .gem-content-shell {",
2261
+ " display: grid;",
2262
+ " justify-items: center;",
2263
+ " gap: var(--gem-space-md);",
2264
+ " margin-inline: auto;",
2265
+ " text-align: center;",
2266
+ "}",
2267
+ ".gem-email-signup-banner .gem-newsletter-form {",
2268
+ " justify-content: center;",
2269
+ " width: min(100%, 44rem);",
2270
+ "}",
2271
+ ".gem-gift-card {",
2272
+ " min-block-size: 100vh;",
2273
+ " display: grid;",
2274
+ " place-items: center;",
2275
+ " padding: var(--gem-space-lg);",
2276
+ "}",
2277
+ ".gem-gift-card__main {",
2278
+ " display: grid;",
2279
+ " justify-items: center;",
2280
+ " gap: var(--gem-space-md);",
2281
+ " text-align: center;",
2282
+ "}",
2283
+ ".gem-gift-card__code {",
2284
+ " font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;",
2285
+ " font-size: clamp(1.25rem, 4vw, 2rem);",
2286
+ " letter-spacing: 0.08em;",
2287
+ "}",
2288
+ ".gem-gift-card__actions {",
2289
+ " display: flex;",
2290
+ " flex-wrap: wrap;",
2291
+ " justify-content: center;",
2292
+ " gap: var(--gem-space-sm);",
2293
+ "}",
2294
+ ".gem-blog-grid {",
2295
+ " display: grid;",
2296
+ " grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));",
2297
+ " gap: var(--gem-space-md);",
2298
+ "}",
2299
+ ".gem-article-card {",
2300
+ " display: grid;",
2301
+ " grid-template-rows: auto minmax(0, 1fr);",
2302
+ " gap: var(--gem-space-sm);",
2303
+ " color: var(--gem-color-text);",
2304
+ "}",
2305
+ ".gem-article-card > a {",
2306
+ " color: inherit;",
2307
+ " text-decoration: none;",
2308
+ "}",
2309
+ ".gem-article-card__media {",
2310
+ " aspect-ratio: 16 / 10;",
2311
+ "}",
2312
+ ".gem-article-card__content {",
2313
+ " display: grid;",
2314
+ " gap: var(--gem-space-xs);",
2315
+ "}",
2316
+ ".gem-article-card__meta {",
2317
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
2318
+ " font-size: 0.875rem;",
2319
+ "}",
2320
+ ".gem-article-card__title {",
2321
+ " margin: 0;",
2322
+ " font-family: var(--gem-font-heading);",
2323
+ "}",
2324
+ ".gem-article-card__title a {",
2325
+ " color: inherit;",
2326
+ " text-decoration: none;",
2327
+ "}",
2328
+ ".gem-article-card__title a:hover {",
2329
+ " text-decoration: underline;",
2330
+ " text-underline-offset: 0.18em;",
2331
+ "}",
2332
+ ".gem-search-form {",
2333
+ " display: grid;",
2334
+ " grid-template-columns: minmax(0, 1fr) auto;",
2335
+ " gap: var(--gem-space-sm);",
2336
+ " align-items: end;",
2337
+ " max-width: 48rem;",
2338
+ "}",
2339
+ ".gem-search-form [data-gem-predictive-search-results] {",
2340
+ " grid-column: 1 / -1;",
2341
+ "}",
2342
+ ".gem-search-results-meta {",
2343
+ " margin: 0;",
2344
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
2345
+ "}",
2346
+ ".gem-search-result-card {",
2347
+ " display: grid;",
2348
+ " gap: var(--gem-space-xs);",
2349
+ " color: var(--gem-color-text);",
2350
+ " text-decoration: none;",
2351
+ "}",
2352
+ ".gem-search-result-card span {",
2353
+ " display: block;",
2354
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
2355
+ " font-size: 0.875rem;",
2356
+ "}",
2357
+ ".gem-search-result-card:hover strong {",
2358
+ " text-decoration: underline;",
2359
+ " text-underline-offset: 0.18em;",
2360
+ "}",
2361
+ ".gem-article-card__excerpt {",
2362
+ " margin: 0;",
2363
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
2364
+ "}",
2365
+ ".gem-not-found {",
2366
+ " max-width: 42rem;",
2367
+ "}",
2368
+ ".gem-u-hidden { display: none !important; }",
2369
+ ".gem-u-visually-hidden {",
2370
+ " position: absolute !important;",
2371
+ " width: 1px !important;",
2372
+ " height: 1px !important;",
2373
+ " overflow: hidden !important;",
2374
+ " clip: rect(0, 0, 0, 0) !important;",
2375
+ " white-space: nowrap !important;",
2376
+ "}",
2377
+ ".gem-u-center { text-align: center; }",
2378
+ ".gem-u-muted { color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent)); }",
2379
+ ".gem-u-surface { background: var(--gem-color-surface); color: var(--gem-color-text); }",
2380
+ ".gem-u-accent { color: var(--gem-color-accent); }",
2381
+ ".gem-u-stack-sm { gap: var(--gem-space-sm); }",
2382
+ ".gem-u-stack-md { gap: var(--gem-space-md); }",
2383
+ ".gem-u-stack-lg { gap: var(--gem-space-lg); }",
2384
+ "@media (max-width: 760px) {",
2385
+ " .gem-cart-line-item { grid-template-columns: minmax(4rem, 5rem) minmax(0, 1fr); }",
2386
+ " .gem-cart-line-item__quantity, .gem-cart-line-item__price { grid-column: 2; }",
2387
+ " .gem-customer-order-link, .gem-customer-order-line { grid-template-columns: minmax(0, 1fr); }",
2388
+ " .gem-customer-order-total { justify-self: start; }",
2389
+ " .gem-search-form { grid-template-columns: minmax(0, 1fr); }",
2390
+ " .gem-filter-bar, .gem-collection-filter-toolbar__form { display: grid; align-items: stretch; }",
2391
+ " .gem-filter-bar .gem-select, .gem-collection-filter-toolbar__sort, .gem-collection-filter-toolbar__select, .gem-collection-filter-toolbar__submit { width: 100%; margin-left: 0; }",
2392
+ " .gem-collection-filter-toolbar__filters { border: var(--gem-border-subtle, 1px solid var(--gem-color-border)); border-radius: var(--gem-radius-md); background: var(--gem-color-surface); padding: var(--gem-space-sm); }",
2393
+ " .gem-collection-filter-toolbar__filters > summary { width: 100%; }",
2394
+ " .gem-collection-filter-toolbar__filters[open] { padding-bottom: var(--gem-space-md); }",
2395
+ " .gem-collection-filter-toolbar__active { align-items: stretch; }",
2396
+ " .gem-collection-filter-toolbar__active-filter, .gem-collection-filter-toolbar__clear { min-height: 2.25rem; align-items: center; }",
2397
+ "}"
2398
+ ].join("\n");
2399
+ }
2400
+ function createGemSectionRuntimeContractCss(selector = "[data-gem-section-library-id]", options = {}) {
2401
+ const background = options.backgroundVar ?? "var(--gem-color-background)";
2402
+ const surface = options.surfaceVar ?? "var(--gem-color-surface)";
2403
+ const text = options.textVar ?? "var(--gem-color-text)";
2404
+ const mutedText = options.mutedTextVar ?? `color-mix(in srgb, ${text} 72%, transparent)`;
2405
+ const accent = options.accentVar ?? "var(--gem-color-accent)";
2406
+ const accentText = options.accentTextVar ?? "var(--gem-color-accent-text, #ffffff)";
2407
+ const border = options.borderVar ?? "var(--gem-color-border)";
2408
+ const page = options.pageVar ?? "var(--gem-layout-page, 1180px)";
2409
+ const gutter = options.gutterVar ?? "var(--gem-layout-gutter, 32px)";
2410
+ return [
2411
+ `${selector} {`,
2412
+ " box-sizing: border-box;",
2413
+ ` background: ${background};`,
2414
+ ` color: ${text};`,
2415
+ "}",
2416
+ `${selector} *,`,
2417
+ `${selector} *::before,`,
2418
+ `${selector} *::after {`,
2419
+ " box-sizing: border-box;",
2420
+ "}",
2421
+ `${selector} .gem-stack {`,
2422
+ " display: grid;",
2423
+ " gap: var(--gem-space-md, 16px);",
2424
+ "}",
2425
+ `${selector} .gem-cluster {`,
2426
+ " display: flex;",
2427
+ " flex-wrap: wrap;",
2428
+ " align-items: center;",
2429
+ " gap: var(--gem-space-sm, 8px);",
2430
+ "}",
2431
+ `${selector} .gem-grid,`,
2432
+ `${selector} .gem-section__grid {`,
2433
+ " display: grid;",
2434
+ " gap: var(--gem-space-lg, 24px);",
2435
+ "}",
2436
+ `${selector} .gem-card,`,
2437
+ `${selector} .gem-product-card {`,
2438
+ ` border: 1px solid ${border};`,
2439
+ " border-radius: var(--gem-radius-md, 18px);",
2440
+ ` background: ${surface};`,
2441
+ " color: inherit;",
2442
+ "}",
2443
+ `${selector} .gem-card {`,
2444
+ " padding: var(--gem-component-card-padding, 16px);",
2445
+ "}",
2446
+ `${selector} .gem-media {`,
2447
+ " display: block;",
2448
+ " overflow: hidden;",
2449
+ ` background: color-mix(in srgb, ${accent} 10%, ${surface});`,
2450
+ "}",
2451
+ `${selector} .gem-heading,`,
2452
+ `${selector} .gem-section__heading,`,
2453
+ `${selector} .gem-product-card__title {`,
2454
+ " margin: 0;",
2455
+ " color: inherit;",
2456
+ " font-family: var(--gem-font-heading, inherit);",
2457
+ "}",
2458
+ `${selector} .gem-text,`,
2459
+ `${selector} .gem-section__body {`,
2460
+ " margin: 0;",
2461
+ ` color: ${mutedText};`,
2462
+ " line-height: 1.55;",
2463
+ "}",
2464
+ `${selector} .gem-badge,`,
2465
+ `${selector} .gem-proof {`,
2466
+ " display: inline-flex;",
2467
+ " width: fit-content;",
2468
+ " align-items: center;",
2469
+ ` border: 1px solid ${border};`,
2470
+ " border-radius: var(--gem-radius-pill, 999px);",
2471
+ " padding: 6px 10px;",
2472
+ ` background: ${surface};`,
2473
+ ` color: ${text};`,
2474
+ " font-size: 0.8125rem;",
2475
+ " font-weight: 700;",
2476
+ "}",
2477
+ `${selector} .gem-icon {`,
2478
+ " display: inline-grid;",
2479
+ " width: 1.75rem;",
2480
+ " height: 1.75rem;",
2481
+ " flex: 0 0 auto;",
2482
+ " place-items: center;",
2483
+ "}",
2484
+ `${selector} .gem-u-visually-hidden {`,
2485
+ " position: absolute;",
2486
+ " width: 1px;",
2487
+ " height: 1px;",
2488
+ " overflow: hidden;",
2489
+ " clip: rect(0 0 0 0);",
2490
+ "}",
2491
+ `.gem-section${selector} {`,
2492
+ " padding-block: clamp(44px, 7vw, 92px);",
2493
+ "}",
2494
+ `.gem-section${selector} > .gem-section__inner,`,
2495
+ `.gem-section${selector} .gem-container {`,
2496
+ ` width: min(${page}, calc(100% - ${gutter}));`,
2497
+ ` max-width: ${page};`,
2498
+ " margin-inline: auto;",
2499
+ "}",
2500
+ `.gem-section${selector} .gem-section__heading,`,
2501
+ `.gem-section${selector} .gem-section__body,`,
2502
+ `.gem-section${selector} .gem-text {`,
2503
+ " overflow-wrap: anywhere;",
2504
+ "}",
2505
+ `.gem-section${selector} img {`,
2506
+ " max-width: 100%;",
2507
+ " height: auto;",
2508
+ "}",
2509
+ `.gem-section${selector} .gem-media > svg {`,
2510
+ " display: block;",
2511
+ " width: 100%;",
2512
+ " height: 100%;",
2513
+ "}",
2514
+ `${selector} .gem-button,`,
2515
+ `${selector} [class*="__button"] {`,
2516
+ " display: inline-flex;",
2517
+ " width: fit-content;",
2518
+ " min-height: 44px;",
2519
+ " align-items: center;",
2520
+ " justify-content: center;",
2521
+ ` border: 1px solid ${accent};`,
2522
+ " border-radius: var(--gem-radius-pill, 999px);",
2523
+ " padding: 10px 16px;",
2524
+ ` background: ${accent};`,
2525
+ ` color: ${accentText};`,
2526
+ " font-weight: 800;",
2527
+ " text-decoration: none;",
2528
+ "}"
2529
+ ].join("\n");
2530
+ }
2531
+ var OPT_IN_EYEBROW = ":where(.gem-section[data-gem-eyebrow='show']) .gem-section__eyebrow { display: block; letter-spacing: 0.12em; }";
2532
+ var OPT_IN_HEADING = ":where(.gem-section[data-gem-heading='section']) .gem-section__heading { margin: 0; font-family: var(--gem-font-heading); font-size: var(--gem-h2); line-height: 1.1; letter-spacing: -0.01em; text-wrap: balance; }";
2533
+ var OPT_IN_BODY = ":where(.gem-section[data-gem-body='section']) .gem-section__body { margin: 0; color: var(--gem-color-muted); font-size: var(--gem-body); line-height: var(--gem-font-body-line-height, 1.5); }";
2534
+ var OPT_IN_HEADING_MOBILE = " :where(.gem-section[data-gem-heading='section']) .gem-section__heading { font-size: min(var(--gem-h2), clamp(1.75rem, 9vw, 2.75rem)); }";
2535
+ function createSectionCss() {
2536
+ return [
2537
+ ".gem-section {",
2538
+ " color: var(--gem-color-text);",
2539
+ " background: var(--gem-color-background);",
2540
+ " padding-block: var(--gem-layout-section, var(--gem-space-3xl, 64px));",
2541
+ " overflow: clip;",
2542
+ "}",
2543
+ ".gem-section__inner {",
2544
+ " width: min(var(--gem-layout-page, 1180px), calc(100% - var(--gem-layout-gutter, 32px)));",
2545
+ " margin-inline: auto;",
2546
+ " display: grid;",
2547
+ " gap: var(--gem-space-lg);",
2548
+ "}",
2549
+ // Typography + list defaults for the SECTION layer. These live in createGemBaseCss, which styles a
2550
+ // whole storefront document — but the editor/preview renderers compose sections WITHOUT that
2551
+ // document shell, so they inherited nothing: every preview rendered in the browser's default
2552
+ // serif while only headings (which set the token themselves) came out right. Measured on a real
2553
+ // generated store: body and eyebrow computed to "Times", h1 to "system-ui".
2554
+ //
2555
+ // Setting it on `.gem-section` rather than `body` keeps it composable — a section is styled the
2556
+ // same whether it is alone in a preview or one of twenty in a document, and a section's own
2557
+ // gem.css still wins on specificity wherever it has an opinion.
2558
+ ".gem-section { font-family: var(--gem-font-body); }",
2559
+ // Eyebrow spacing lives in the .gem-section__eyebrow rule below, not here — see the note there.
2560
+ // Copy-block lists are typeset prose, not document lists: the hero shipped raw bullet discs and a
2561
+ // 40px indent that broke its centring. Scoped to `__copy` containers so FAQ/feature lists, which
2562
+ // own their markers deliberately, are untouched.
2563
+ '.gem-section [class*="__copy"] ul, .gem-section [class*="__copy"] ol { list-style: none; padding-left: 0; margin: var(--gem-space-sm, 12px) 0 0; }',
2564
+ // Content alignment knob (section LAYOUT axis) — set by apply_section_edit set_layout (gemboss
2565
+ // override key gem_content_alignment), emitted as data-gem-content-alignment on the shell (real
2566
+ // theme + published) and on the sim-preview markup. Grid items justify; text aligns. The text
2567
+ // rule also reaches hero copy + section content so heroes honor it (their absolute-positioned
2568
+ // copy box keeps its tuned position; only the text inside re-aligns).
2569
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-alignment='left'] .gem-section__inner { justify-items: start; }",
2570
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-alignment='left'] :is(.gem-section__inner, .gem-hero-banner__copy, [class*='__content']) { text-align: left; }",
2571
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-alignment='center'] .gem-section__inner { justify-items: center; }",
2572
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-alignment='center'] :is(.gem-section__inner, .gem-hero-banner__copy, [class*='__content']) { text-align: center; }",
2573
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-alignment='right'] .gem-section__inner { justify-items: end; }",
2574
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-alignment='right'] :is(.gem-section__inner, .gem-hero-banner__copy, [class*='__content']) { text-align: right; }",
2575
+ // SAFETY: justify-items above content-sizes the inner grid's items, which would COLLAPSE a
2576
+ // full-bleed grid child (a mosaic/collage/product grid that must span the row) to min-content —
2577
+ // i.e. the section visually disappears. Re-stretch any grid/media/mosaic direct child so alignment
2578
+ // only ever moves TEXT, never breaks a section's own layout (fix: collage vanished in wf_0102).
2579
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-alignment] .gem-section__inner > :is([class*='__grid'], [class*='__media'], [class*='__mosaic'], [class*='__masonry'], [class*='__frame'], [class*='__collage'], [class*='__row']) { justify-self: stretch; width: 100%; }",
2580
+ // Text-position knob (the VERTICAL sibling of content_alignment) — set by set_layout text_position
2581
+ // (gemboss override key gem_text_position), emitted as data-gem-text-position by the lean-hero
2582
+ // renderer (shopify-adapter leanHeroLayoutKeys). It had NO CSS anywhere: the agent could pick it,
2583
+ // the theme emitted it, and nothing moved — a ghost edit for every "căn giữa theo chiều dọc" /
2584
+ // "chữ dồn xuống dưới" request the tool description explicitly promises it answers.
2585
+ //
2586
+ // The full-bleed hero's copy block is ABSOLUTELY positioned (left:50%; bottom:50px), so the only
2587
+ // thing that moves it is overriding that inset — align-* on an ancestor cannot. Specificity
2588
+ // (0,3,0) beats the component's own `.gem-hero-banner--default .gem-hero-banner__copy` (0,2,0),
2589
+ // so this wins only when the operator sets the knob; unset, the tuned default position stands.
2590
+ // `bottom`/`top: auto` is required on each: leaving both insets set pins the box to BOTH edges.
2591
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-position='top'] .gem-hero-banner__copy { top: 50px; bottom: auto; }",
2592
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-position='center'] .gem-hero-banner__copy { top: 50%; bottom: auto; transform: translate(-50%, -50%); }",
2593
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-position='bottom'] .gem-hero-banner__copy { bottom: 50px; top: auto; }",
2594
+ // Non-hero sections: move the content stack within whatever spare height the section has (a
2595
+ // `section_height: tall` section, say). `align-content` is a no-op when the grid has no spare
2596
+ // space, so this never disturbs a normally-sized section — it only answers the same vertical
2597
+ // question on the sections where the question can even be asked.
2598
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-position='top'] .gem-section__inner { align-content: start; }",
2599
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-position='center'] .gem-section__inner { align-content: center; }",
2600
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-position='bottom'] .gem-section__inner { align-content: end; }",
2601
+ // Media-position knob (section LAYOUT axis) — set by set_layout media_position (gemboss override key
2602
+ // gem_media_position). On a genuine two-column section it swaps the image column to the chosen side
2603
+ // by re-ordering the media child. TWO shapes qualify: (a) `__media` is a DIRECT child of the inner
2604
+ // (inner IS the 2-col grid); (b) `__media` is a direct child of the section's OWN 2-col grid wrapper
2605
+ // (`.gem-section__inner > [class*='__grid'] > [class*='__media']`) — feature-split, image-with-text
2606
+ // and product-highlight all nest their media one level down in a `{section}__grid`, so the earlier
2607
+ // inner-DIRECT-only rule was a DEAD knob on them (advertised via the media_position setting, but the
2608
+ // swap did nothing). CARD/product grids stay untouched: their media is nested DEEPER (grid > card >
2609
+ // __media), so `grid > __media` never matches a card's image → we swap real 2-col layouts and never
2610
+ // reorder cards. A full-bleed background-image hero has its `__media` absolutely positioned, so
2611
+ // `order` is a natural no-op there — exactly right.
2612
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-media-position='left'] .gem-section__inner > [class*='__media'], :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-media-position='left'] .gem-section__inner > [class*='__grid'] > [class*='__media'] { order: -1; }",
2613
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-media-position='right'] .gem-section__inner > [class*='__media'], :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-media-position='right'] .gem-section__inner > [class*='__grid'] > [class*='__media'] { order: 1; }",
2614
+ // Spacing/density knob — set by set_layout content_spacing. Scales the inner grid gap (the gap
2615
+ // between columns + stacked rows), the direct answer to wf_0101's 'khoảng cách giữa 2 cột'.
2616
+ // Density knob — set by set_layout content_spacing. Scales the gap of the inner content stack.
2617
+ // (Per-card GRID spacing is governed by the tuned card-mode/variant rules — changed via
2618
+ // swap_variant, not this knob — so we don't fight their specificity here.)
2619
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-spacing='tight'] .gem-section__inner { gap: var(--gem-space-sm); }",
2620
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-spacing='normal'] .gem-section__inner { gap: var(--gem-space-lg); }",
2621
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-spacing='roomy'] .gem-section__inner { gap: var(--gem-space-3xl); }",
2622
+ // HERO COPY STACK — same rules as gemsite app/globals.css (gemsite #609), kept in sync by hand.
2623
+ // On a full-bleed hero the inner grid has ONE in-flow child (the media is absolutely positioned), so the
2624
+ // inner `gap` above spaces nothing and the knob was MUTE: probed on the live storefront (gemboss acceptance
2625
+ // sc-013), flipping data-gem-content-spacing on gem-hero-banner / gem-hero-video moved no property.
2626
+ // The knob drives the rhythm between the stacked copy, only when set. TWO mechanisms, chosen by the copy
2627
+ // block's measured display (every storefront HeroBanner/HeroVideo rendered and measured in Chromium):
2628
+ // - GRID copy blocks: row-gap. A margin would ADD to their existing gap (tight came out looser than
2629
+ // unset) and would override variant margins such as `.gem-hero--mobile-split .gem-hero__text
2630
+ // { margin-top: auto }`. row-gap is inert on a block container, so it is safe on every copy class.
2631
+ // - BLOCK copy blocks (default / dawn-image-banner __copy, slideshow __copy): margin between children,
2632
+ // with the children's own bottom margins zeroed — adjacent block margins collapse to the larger one.
2633
+ ":is(.gem-hero-banner, .gem-hero-video, .gem-hero)[data-gem-content-spacing='tight'] :is(.gem-hero-banner__copy, .gem-hero-banner__content, .gem-hero-slideshow__copy, .gem-hero-video__content, .gem-hero__content) { row-gap: var(--gem-space-xs); }",
2634
+ ":is(.gem-hero-banner--default, .gem-hero-banner--dawn-image-banner)[data-gem-content-spacing='tight'] .gem-hero-banner__copy > * + *, .gem-hero-banner[data-gem-content-spacing='tight'] .gem-hero-slideshow__copy > * + * { margin-top: var(--gem-space-xs); }",
2635
+ ":is(.gem-hero-banner--default, .gem-hero-banner--dawn-image-banner)[data-gem-content-spacing='tight'] .gem-hero-banner__copy > :not(:last-child), .gem-hero-banner[data-gem-content-spacing='tight'] .gem-hero-slideshow__copy > :not(:last-child) { margin-bottom: 0; }",
2636
+ ":is(.gem-hero-banner, .gem-hero-video, .gem-hero)[data-gem-content-spacing='normal'] :is(.gem-hero-banner__copy, .gem-hero-banner__content, .gem-hero-slideshow__copy, .gem-hero-video__content, .gem-hero__content) { row-gap: var(--gem-space-md); }",
2637
+ ":is(.gem-hero-banner--default, .gem-hero-banner--dawn-image-banner)[data-gem-content-spacing='normal'] .gem-hero-banner__copy > * + *, .gem-hero-banner[data-gem-content-spacing='normal'] .gem-hero-slideshow__copy > * + * { margin-top: var(--gem-space-md); }",
2638
+ ":is(.gem-hero-banner--default, .gem-hero-banner--dawn-image-banner)[data-gem-content-spacing='normal'] .gem-hero-banner__copy > :not(:last-child), .gem-hero-banner[data-gem-content-spacing='normal'] .gem-hero-slideshow__copy > :not(:last-child) { margin-bottom: 0; }",
2639
+ ":is(.gem-hero-banner, .gem-hero-video, .gem-hero)[data-gem-content-spacing='roomy'] :is(.gem-hero-banner__copy, .gem-hero-banner__content, .gem-hero-slideshow__copy, .gem-hero-video__content, .gem-hero__content) { row-gap: var(--gem-space-xl); }",
2640
+ ":is(.gem-hero-banner--default, .gem-hero-banner--dawn-image-banner)[data-gem-content-spacing='roomy'] .gem-hero-banner__copy > * + *, .gem-hero-banner[data-gem-content-spacing='roomy'] .gem-hero-slideshow__copy > * + * { margin-top: var(--gem-space-xl); }",
2641
+ ":is(.gem-hero-banner--default, .gem-hero-banner--dawn-image-banner)[data-gem-content-spacing='roomy'] .gem-hero-banner__copy > :not(:last-child), .gem-hero-banner[data-gem-content-spacing='roomy'] .gem-hero-slideshow__copy > :not(:last-child) { margin-bottom: 0; }",
2642
+ // Width knob — set by set_layout content_width. Overrides the inner container width: full-bleed
2643
+ // edge-to-edge, the default contained width, or a narrow reading measure.
2644
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-width='full'] .gem-section__inner { width: 100%; max-width: none; }",
2645
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-width='contained'] .gem-section__inner { width: min(var(--gem-layout-page, 1180px), calc(100% - var(--gem-layout-gutter, 32px))); max-width: none; }",
2646
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-content-width='narrow'] .gem-section__inner { width: min(56rem, calc(100% - var(--gem-layout-gutter, 32px))); }",
2647
+ // Height knob — set by set_layout section_height. Sets min-height on BOTH the section element
2648
+ // and its inner: the section-level rule (attr+class = (0,2,0)) beats a component's single-class
2649
+ // floor like `.gem-hero-banner--default { min-height: 720px }` (0,1,0), so "make the hero
2650
+ // shorter/taller" actually re-sizes the section (the inner-only rule alone left the section floored).
2651
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-height='short'] { min-height: 420px; }",
2652
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-height='tall'] { min-height: 760px; }",
2653
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-height='short'] .gem-section__inner { min-height: 420px; }",
2654
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-height='normal'] .gem-section__inner { min-height: auto; }",
2655
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-height='tall'] .gem-section__inner { min-height: 760px; }",
2656
+ // Columns knob — set by set_layout grid_columns. Overrides the grid container's column count. The
2657
+ // contract advertises grid_columns for any section with a `columns` setting (layoutCapabilitiesOf),
2658
+ // but MOST gem sections name their grid `{section}__grid` (gem-multicolumn__grid, gem-stats__grid,
2659
+ // gem-collage__grid…), not the universal `.gem-section__grid` — so a `.gem-section__grid`-only rule
2660
+ // was a DEAD knob on them (advertised, but set_layout grid_columns changed nothing). Match any
2661
+ // `[class*='__grid']` direct-ish child so the knob is honest everywhere it's offered. Specificity
2662
+ // (0,2,0)+attr beats a section's own single-class grid template, so it only wins when the operator
2663
+ // sets it; unset, the section's native `columns` setting still governs. (Mirrors the re-stretch rule
2664
+ // above, which already uses [class*='__grid'] safely.)
2665
+ ...GEM_GRID_COLUMNS_KNOB_CSS_LINES,
2666
+ // Per-section background knob — set by apply_section_edit set_style. Maps a THEME-TOKEN swatch to
2667
+ // a --gem-color-* background PLUS its paired text token, so contrast stays handled and the section
2668
+ // stays on-brand (no arbitrary hex). `default` = inherit the page background (the revert value).
2669
+ // block padding gives the colored band breathing room when a section's inner has none of its own.
2670
+ // Each swatch also publishes --gem-section-bg for the shape-divider to paint with. `default`
2671
+ // publishes the PAGE colour while keeping `background: transparent` on the section itself —
2672
+ // the two are separate declarations, so the section still lets whatever is behind it show
2673
+ // through, and only the divider gains something to paint. Without this, choosing `default`
2674
+ // (or leaving the knob unset) silently disabled the divider.
2675
+ // The shape-divider below paints the section's OWN
2676
+ // colour into the neighbouring section, so it needs a single name for "whatever this band is",
2677
+ // rather than re-deriving the swatch in every divider rule.
2678
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-background='default'] { --gem-section-bg: var(--gem-color-background); background: transparent; }",
2679
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-background='surface'] { --gem-section-bg: var(--gem-color-surface); background: var(--gem-section-bg); padding-block: var(--gem-space-xl); }",
2680
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-background='accent'] { --gem-section-bg: var(--gem-color-accent); background: var(--gem-section-bg); color: var(--gem-color-accent-text); --gem-band-bg: var(--gem-color-accent); --gem-focus-ring: 2px solid var(--gem-color-accent-text); padding-block: var(--gem-space-xl); }",
2681
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-background='dark'] { --gem-section-bg: var(--gem-color-text); background: var(--gem-section-bg); color: var(--gem-color-background); --gem-band-bg: var(--gem-color-text); --gem-focus-ring: 2px solid var(--gem-color-background); padding-block: var(--gem-space-xl); }",
2682
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-background='light'] { --gem-section-bg: var(--gem-color-background); background: var(--gem-section-bg); color: var(--gem-color-text); padding-block: var(--gem-space-xl); }",
2683
+ // On accent/dark bands, keep muted sub-copy + headings legible against the inverted ground.
2684
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-background='accent'] :is(.gem-section__heading, .gem-section__body, .gem-section__eyebrow), :is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-section-background='dark'] :is(.gem-section__heading, .gem-section__body, .gem-section__eyebrow) { color: inherit; }",
2685
+ // Price-colour knob (set by set_style price_color) — recolours the PRICE text on a product/collection
2686
+ // section. red/green are literal sale/savings semantics; accent uses the brand token; default inherits.
2687
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-price-color='accent'] :is(.gem-price, .gem-price__regular, [class*='__price']) { color: var(--gem-color-accent); }",
2688
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-price-color='red'] :is(.gem-price, .gem-price__regular, [class*='__price']) { color: #d61f1f; }",
2689
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-price-color='green'] :is(.gem-price, .gem-price__regular, [class*='__price']) { color: #1a7f37; }",
2690
+ // Text-weight knob (set by set_layout text_weight) — scales the section's --gem-style-weight ramp
2691
+ // (which weight-bearing type multiplies) AND sets the heading font-weight directly, so 'bold'
2692
+ // emboldens the headings on any section. default/normal inherit.
2693
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-weight='bold'] { --gem-style-weight: 1.25; }",
2694
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-weight='bold'] :is(.gem-section__heading, .gem-hero-banner__copy h1, .gem-hero-banner__copy h2) { font-weight: 800; }",
2695
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-weight='light'] { --gem-style-weight: 0.8; }",
2696
+ ":is(.gem-section, .gem-hero, .gem-hero-split, .gem-hero-collage, .gem-hero-triptych, .gem-slideshow)[data-gem-text-weight='light'] :is(.gem-section__heading, .gem-hero-banner__copy h1, .gem-hero-banner__copy h2) { font-weight: 350; }",
2697
+ // G4 — per-element colour (set by set_style element_color {target, colour}). One mechanism colours
2698
+ // the heading / eyebrow / badge in a section; swatches map to brand token or literal sale/dark.
2699
+ // (price uses data-gem-price-color above.) accent=brand, red/green=sale/savings, dark=text token.
2700
+ ".gem-section[data-gem-heading-color='accent'] :is(.gem-section__heading, .gem-hero-banner__copy h1, .gem-hero-banner__copy h2) { color: var(--gem-color-accent); }",
2701
+ ".gem-section[data-gem-heading-color='red'] :is(.gem-section__heading, .gem-hero-banner__copy h1, .gem-hero-banner__copy h2) { color: #d61f1f; }",
2702
+ ".gem-section[data-gem-heading-color='green'] :is(.gem-section__heading, .gem-hero-banner__copy h1, .gem-hero-banner__copy h2) { color: #1a7f37; }",
2703
+ ".gem-section[data-gem-heading-color='dark'] :is(.gem-section__heading, .gem-hero-banner__copy h1, .gem-hero-banner__copy h2) { color: var(--gem-color-text); }",
2704
+ ".gem-section[data-gem-eyebrow-color='accent'] .gem-section__eyebrow { color: var(--gem-color-accent); }",
2705
+ ".gem-section[data-gem-eyebrow-color='red'] .gem-section__eyebrow { color: #d61f1f; }",
2706
+ ".gem-section[data-gem-eyebrow-color='green'] .gem-section__eyebrow { color: #1a7f37; }",
2707
+ ".gem-section[data-gem-eyebrow-color='dark'] .gem-section__eyebrow { color: var(--gem-color-text); }",
2708
+ ".gem-section[data-gem-badge-color='accent'] [class*='__badge'] { color: var(--gem-color-accent); }",
2709
+ ".gem-section[data-gem-badge-color='red'] [class*='__badge'] { color: #d61f1f; }",
2710
+ ".gem-section[data-gem-badge-color='green'] [class*='__badge'] { color: #1a7f37; }",
2711
+ ".gem-section[data-gem-badge-color='dark'] [class*='__badge'] { color: var(--gem-color-text); }",
2712
+ ".gem-section__eyebrow {",
2713
+ // Bottom margin, not 0: the eyebrow sat flush against the heading (both margin:0) and the two
2714
+ // read as colliding. It belongs HERE rather than in a separate rule — an earlier standalone
2715
+ // `.gem-section__eyebrow { margin: … }` had identical specificity and simply lost to this one on
2716
+ // source order, so it shipped in the bundle and moved nothing.
2717
+ " margin: 0 0 var(--gem-space-sm, 12px);",
2718
+ " color: var(--gem-color-accent);",
2719
+ " font-size: 0.8125rem;",
2720
+ " font-weight: calc(650 * var(--gem-style-weight, 1));",
2721
+ " text-transform: uppercase;",
2722
+ "}",
2723
+ ".gem-section__heading {",
2724
+ " margin: 0;",
2725
+ " font-family: var(--gem-font-heading);",
2726
+ " font-size: clamp(calc(2rem * var(--gem-typography-heading-scale, 1)), calc(4vw * var(--gem-typography-heading-scale, 1)), calc(4rem * var(--gem-typography-heading-scale, 1)));",
2727
+ " line-height: 1.04;",
2728
+ "}",
2729
+ ".gem-section__body {",
2730
+ " margin: 0;",
2731
+ " max-width: 64ch;",
2732
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
2733
+ "}",
2734
+ ".gem-section__grid {",
2735
+ " display: grid;",
2736
+ " grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));",
2737
+ " column-gap: var(--gem-grid-column-gap, var(--gem-space-md));",
2738
+ " row-gap: var(--gem-grid-row-gap, var(--gem-space-md));",
2739
+ "}",
2740
+ ".gem-section[data-gem-composition-mode='image-with-copy'] .gem-section__inner {",
2741
+ " align-content: center;",
2742
+ "}",
2743
+ ".gem-section:is([data-gem-composition-mode='slideshow'], [data-gem-composition-mode='video-led']) .gem-section__inner {",
2744
+ " min-block-size: min(72vh, 680px);",
2745
+ " align-content: end;",
2746
+ "}",
2747
+ ".gem-section[data-gem-composition-mode='category-grid'] .gem-section__grid {",
2748
+ " grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));",
2749
+ "}",
2750
+ ".gem-section[data-gem-composition-mode='split-collage'] .gem-section__grid {",
2751
+ " grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);",
2752
+ " align-items: stretch;",
2753
+ "}",
2754
+ ".gem-section[data-gem-composition-mode='video-led'] {",
2755
+ " background: color-mix(in srgb, var(--gem-color-text) 6%, var(--gem-color-background));",
2756
+ "}",
2757
+ ".gem-section:is([data-gem-product-card-mode='gallery'], [data-gem-product-card-mode='editorial']) :is(.gem-product-card-grid__grid, .gem-section__grid) {",
2758
+ " gap: var(--gem-space-xl);",
2759
+ "}",
2760
+ ".gem-section:is([data-gem-product-card-mode='quick-buy'], [data-gem-product-card-mode='badge-heavy']) .gem-product-card {",
2761
+ " position: relative;",
2762
+ "}",
2763
+ ".gem-section[data-gem-product-card-mode='standard'] .gem-product-card-grid__grid {}",
2764
+ ".gem-section:is([data-gem-product-card-mode='utility'], [data-gem-collection-card-mode='dense-grid']) .gem-product-card-grid__grid {",
2765
+ " grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));",
2766
+ " gap: var(--gem-space-sm);",
2767
+ "}",
2768
+ ".gem-section:is([data-gem-product-card-mode='badge-heavy'], [data-gem-badge-density='high']) .gem-badge {",
2769
+ " border-color: var(--gem-color-accent);",
2770
+ " color: var(--gem-color-accent);",
2771
+ "}",
2772
+ ".gem-section:is([data-gem-collection-card-mode='image-tile'], [data-gem-collection-card-mode='editorial-tile'], [data-gem-collection-card-mode='collage']) .gem-media {",
2773
+ " min-block-size: clamp(12rem, 26vw, 24rem);",
2774
+ "}",
2775
+ ".gem-section[data-gem-collection-card-mode='editorial-tile'] .gem-section__grid {",
2776
+ " gap: var(--gem-space-xl);",
2777
+ "}",
2778
+ ".gem-section[data-gem-collection-card-mode='collage'] .gem-section__grid {",
2779
+ " grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));",
2780
+ "}",
2781
+ ".gem-section[data-gem-card-copy-mode='minimal'] :is(.gem-product-card__vendor, .gem-product-card__description) {",
2782
+ " display: none;",
2783
+ "}",
2784
+ ".gem-section:is([data-gem-image-treatment='editorial-crop'], [data-gem-image-treatment='poster']) .gem-media {",
2785
+ " aspect-ratio: 4 / 5;",
2786
+ "}",
2787
+ ".gem-section:is([data-gem-proof-mode='press'], [data-gem-proof-mode='trust-strip']) .gem-reviews-proof-strip__points {}",
2788
+ ".gem-section[data-gem-proof-mode='minimal'] .gem-reviews-proof-strip__points {",
2789
+ " gap: var(--gem-space-sm);",
2790
+ "}",
2791
+ ".gem-section[data-gem-proof-mode='compliance'] .gem-reviews-proof-strip__points {",
2792
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
2793
+ " padding: var(--gem-space-md);",
2794
+ "}",
2795
+ ".gem-section[data-gem-proof-mode='testimonial'] .gem-reviews-proof-strip__points {",
2796
+ " grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));",
2797
+ " gap: var(--gem-space-lg);",
2798
+ "}",
2799
+ ".gem-section[data-gem-editorial-band-mode='gridline-story'] .gem-section__inner {",
2800
+ " border-block: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
2801
+ " padding-block: var(--gem-space-xl);",
2802
+ "}",
2803
+ ".gem-section:is([data-gem-editorial-band-mode='rich-text'], [data-gem-editorial-band-mode='none']) .gem-section__body {}",
2804
+ ".gem-section[data-gem-editorial-band-mode='marquee'] .gem-section__heading {",
2805
+ " text-transform: uppercase;",
2806
+ "}",
2807
+ ".gem-section[data-gem-editorial-band-mode='media-story'] .gem-section__grid {",
2808
+ " grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);",
2809
+ "}",
2810
+ "@media (min-width: 990px) {",
2811
+ " #MainContent:has(.gem-product-media-gallery[data-gem-section-id='product-gallery']):has(.gem-product-main[data-gem-section-id='product-main']) {",
2812
+ " display: grid;",
2813
+ " grid-template-columns: minmax(0, 1fr) minmax(22rem, 0.72fr);",
2814
+ " gap: var(--gem-space-xl);",
2815
+ " align-items: start;",
2816
+ " width: min(var(--gem-layout-page, 1180px), calc(100% - var(--gem-layout-gutter, 32px)));",
2817
+ " margin-inline: auto;",
2818
+ " padding-block: var(--gem-space-xl);",
2819
+ " }",
2820
+ " #MainContent:has(.gem-product-media-gallery[data-gem-section-id='product-gallery']):has(.gem-product-main[data-gem-section-id='product-main']) > .gem-section {",
2821
+ " padding-block: 0;",
2822
+ " overflow: visible;",
2823
+ " }",
2824
+ " #MainContent:has(.gem-product-media-gallery[data-gem-section-id='product-gallery']):has(.gem-product-main[data-gem-section-id='product-main']) > .gem-section > .gem-section__inner {",
2825
+ " width: 100%;",
2826
+ " }",
2827
+ " #MainContent:has(.gem-product-media-gallery[data-gem-section-id='product-gallery']):has(.gem-product-main[data-gem-section-id='product-main']) > .gem-breadcrumbs {",
2828
+ " grid-column: 1 / -1;",
2829
+ " }",
2830
+ " #MainContent:has(.gem-product-media-gallery[data-gem-section-id='product-gallery']):has(.gem-product-main[data-gem-section-id='product-main']) > .gem-product-media-gallery {",
2831
+ " grid-column: 1;",
2832
+ " }",
2833
+ " #MainContent:has(.gem-product-media-gallery[data-gem-section-id='product-gallery']):has(.gem-product-main[data-gem-section-id='product-main']) > .gem-product-main {",
2834
+ " grid-column: 2;",
2835
+ " position: sticky;",
2836
+ " top: calc(var(--gem-component-header-height, 72px) + var(--gem-space-md));",
2837
+ " }",
2838
+ " #MainContent:has(.gem-product-media-gallery[data-gem-section-id='product-gallery']):has(.gem-product-main[data-gem-section-id='product-main']) > .gem-section:not(.gem-breadcrumbs):not(.gem-product-media-gallery):not(.gem-product-main) {",
2839
+ " grid-column: 1 / -1;",
2840
+ " padding-block: var(--gem-layout-section, var(--gem-space-3xl, 64px));",
2841
+ " }",
2842
+ "}",
2843
+ "@media (max-width: 760px) {",
2844
+ " .gem-section { padding-block: calc(var(--gem-layout-section, 64px) * 0.72); }",
2845
+ " .gem-section__inner, .gem-container { width: min(100% - 32px, var(--gem-layout-page, 1180px)); }",
2846
+ " .gem-section__heading { font-size: clamp(1.75rem, 9vw, 2.75rem); }",
2847
+ " .gem-section__grid { grid-template-columns: minmax(0, 1fr); }",
2848
+ " .gem-section:is([data-gem-composition-mode='split-collage'], [data-gem-editorial-band-mode='media-story']) .gem-section__grid { grid-template-columns: minmax(0, 1fr); }",
2849
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__inner { grid-template-columns: minmax(0, 1fr); }",
2850
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__summary { position: static; }",
2851
+ " .gem-section:is([data-gem-composition-mode='slideshow'], [data-gem-composition-mode='video-led']) .gem-section__inner { min-block-size: min(62vh, 560px); }",
2852
+ "}",
2853
+ OPT_IN_EYEBROW,
2854
+ OPT_IN_HEADING,
2855
+ OPT_IN_BODY,
2856
+ "@media (max-width: 760px) {",
2857
+ OPT_IN_HEADING_MOBILE,
2858
+ "}",
2859
+ // The row, LAST — see GEM_ROW_CSS_LINES. Emitted here for every profile and again after the Dawn block.
2860
+ ...GEM_ROW_CSS_LINES
2861
+ ].join("\n");
2862
+ }
2863
+ function createDawnParityCss() {
2864
+ return [
2865
+ "/* Dawn parity profile: locked default baseline; morph presets must opt out before applying Gem visual identity. */",
2866
+ ":root { --gem-profile-mode: dawn-parity; --gem-layout-page: 1100px; --gem-layout-gutter: 32px; --gem-layout-section: 52px; --gem-radius-md: 0px; --gem-card-radius: 0px; --gem-media-radius: 0px; --gem-grid-column-gap: 8px; --gem-grid-row-gap: 8px; }",
2867
+ ".utility-bar, .announcement-bar, .utility-bar__grid { min-height: 38px; }",
2868
+ ".announcement-bar__message { margin: 0; min-height: 38px; padding-block: 10px; font-size: 0.75rem; font-weight: 400; letter-spacing: 0.04em; }",
2869
+ // The pair of rules here used to blank the real message (font-size: 0) and inject a FIXED
2870
+ // string in its place, so every store — captured or not — advertised "Free shipping available
2871
+ // on all orders!" whether or not it was true. Announcement copy is data now
2872
+ // (headerPreset.announcement_text / bars[]), so render what the store actually says.
2873
+ ".announcement-bar__message span { font-size: 0.75rem; }",
2874
+ // A strip carrying several promos lays them ACROSS the bar the way stores do, rather than
2875
+ // running them together into one sentence.
2876
+ ".gem-announcement-bar__segments { display: flex; flex-wrap: wrap; justify-content: space-around; gap: 4px 24px; }",
2877
+ ".gem-shell-header .localization-wrapper { display: none !important; }",
2878
+ ".gem-shell-header { position: relative; border-bottom: 1px solid rgb(18 18 18 / 8%); background: var(--gem-color-background); }",
2879
+ ".gem-shell-header__inner, .header { width: min(1200px, 100%); max-width: 1200px; min-height: 84px; padding: 20px 50px; gap: 20px; }",
2880
+ ".gem-shell-header__inner.header--middle-center, .header.header--middle-center, .gem-shell-header__inner.header--middle-left, .header.header--middle-left { grid-template-areas: 'heading navigation icons'; grid-template-columns: 97.5px auto 1fr; }",
2881
+ // The rule above sets the DESKTOP logo-left grid for the real Dawn header (.header) but had no
2882
+ // mobile scope, so it leaked onto small screens — pushing the logo to the far left and clustering
2883
+ // the hamburger beside it (not stock Dawn mobile). Restore Dawn's own mobile header on ≤749px:
2884
+ // hamburger in the left column, logo centered (honouring header--mobile-center).
2885
+ "@media screen and (max-width: 749px) { .header.header--middle-left, .header.header--middle-center { grid-template-areas: 'left-icons heading icons'; grid-template-columns: 1fr 2fr 1fr; } .header.header--middle-left header-drawer, .header.header--middle-center header-drawer { grid-area: left-icons; justify-self: start; } .header.header--mobile-center .header__heading, .header.header--mobile-center .header__heading-link { grid-area: heading; justify-self: center; text-align: center; } }",
2886
+ // Collage placeholder cards: Shopify adds the `ratio` class (→ `.ratio::before` intrinsic height)
2887
+ // to card__inner only when featured_image is nil; the local LiquidJS mock collection doesn't hit
2888
+ // that branch, so a placeholder media in a spanned grid cell collapsed to 0 (the 3rd collage tile
2889
+ // got cut). Pin the square aspect for placeholder collage media that LACKS the `ratio` class — a
2890
+ // no-op on real Shopify (there the card__inner has `.ratio`, so `:not(.ratio)` excludes it).
2891
+ ".collage .card__inner:not(.ratio):has(.placeholder-svg) { aspect-ratio: 1 / 1; }",
2892
+ ".gem-shell-header__logo { display: inline-block; width: 105px; height: 37px; min-height: 0; padding: 7.5px; font-size: 1.125rem; line-height: 22px; font-weight: 400; letter-spacing: 0.08em; text-align: center; white-space: nowrap; overflow: hidden; }",
2893
+ ".gem-shell-header__nav a, .gem-shell-header__action { border: 0; border-radius: 0; background: transparent; font-weight: 400; text-decoration: none; }",
2894
+ ".gem-shell-header__nav { gap: 20px; }",
2895
+ ".gem-shell-header__actions { justify-self: end; gap: 0; padding-right: 8px; }",
2896
+ ".gem-shell-header .svg-wrapper { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; pointer-events: none; }",
2897
+ ".gem-shell-header .svg-wrapper > svg { display: block; width: 100%; height: 100%; }",
2898
+ ".gem-shell-header .header__icon-close { display: none; }",
2899
+ ".gem-shell-header details[open] > summary .gem-header__icon-open { display: none; }",
2900
+ ".gem-shell-header details[open] > summary .header__icon-close { display: inline-flex; }",
2901
+ ".gem-shell-header .header__icons { display: flex; align-items: center; justify-content: flex-end; }",
2902
+ ".gem-shell-header__actions .gem-shell-header__action, .gem-shell-header .header__icon { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 44px; min-width: 44px; height: 44px; min-height: 44px; padding: 0; font-size: 0; }",
2903
+ ".gem-shell-header__actions .gem-shell-header__action--cart { background: transparent; color: var(--gem-color-text); }",
2904
+ ".gem-shell-header__actions .gem-shell-header__action--search::before, .gem-shell-header__actions .gem-shell-header__action--search::after, .gem-shell-header__actions .gem-shell-header__action--account::before, .gem-shell-header__actions .gem-shell-header__action--cart::before, .gem-shell-header__actions .gem-shell-header__action--cart::after { content: none; display: none; }",
2905
+ ".gem-shell-header .cart-count-bubble, .gem-shell-header__cart-count { position: absolute; left: 2.2rem; bottom: 0.8rem; display: flex; align-items: center; justify-content: center; min-width: 1.7rem; height: 1.7rem; border-radius: 100%; background: rgb(18 18 18); color: rgb(255 255 255); font-size: 0.9rem; line-height: 1; }",
2906
+ ".gem-shell-header__drawer-toggle { border: 0; background: transparent; padding: 0; font-size: 0; }",
2907
+ ".gem-shell-header__drawer-toggle::before { content: none; display: none; }",
2908
+ ".gem-section { padding-block: var(--gem-layout-section); }",
2909
+ "main > .gem-section:first-child { padding-top: 0; }",
2910
+ ".gem-hero-banner--default { min-height: 720px; display: grid; place-items: center; text-align: center; }",
2911
+ ".gem-hero-banner--default { position: relative; overflow: hidden; padding: 0; color: white; place-items: stretch; }",
2912
+ ".gem-hero-banner--default .gem-hero-banner__inner { position: static; width: 100%; min-height: 720px; height: 100%; display: grid; align-items: end; justify-items: center; padding-bottom: 0; }",
2913
+ ".gem-hero-banner--default .gem-hero-banner__media { position: absolute; inset: 0; z-index: 0; }",
2914
+ ".gem-hero-banner--default .gem-hero-banner__media::after { content: ''; position: absolute; inset: 0; background: rgb(0 0 0 / 32%); }",
2915
+ ".gem-hero-banner--default .gem-hero-banner__image, .gem-hero-banner--default .gem-hero-banner__placeholder { width: 100%; height: 100%; object-fit: cover; display: block; }",
2916
+ ".gem-hero-banner--default .gem-hero-banner__copy { position: absolute; z-index: 1; left: 50%; bottom: 50px; transform: translateX(-50%); width: min(702px, 100%); margin: 0; padding: 40px 0; text-align: center; display: block; }",
2917
+ ".gem-hero-banner--default .gem-section__heading { margin: 0; font-size: 52px; line-height: 67.6px; color: currentColor; }",
2918
+ ".gem-hero-banner--default .gem-section__body { max-width: none; margin: 10px 0 0; color: currentColor; font-size: 16px; line-height: 28.8px; }",
2919
+ // Hero text overlays a scrimmed photo, so it MUST stay light — a palette/color-scheme
2920
+ // foreground would otherwise override it to a dark tone and make the headline unreadable
2921
+ // over the image (real-user finding 2026-07-02). Force light + a soft shadow so the copy is
2922
+ // legible on ANY background image, whatever palette the seller picks. `!important` beats the
2923
+ // scheme's `.gem-section__heading` color rule; the text-shadow covers bright/low-scrim images.
2924
+ ".gem-hero-banner--default .gem-hero-banner__copy { color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35); }",
2925
+ ".gem-hero-banner--default .gem-hero-banner__copy :is(.gem-section__heading, .gem-section__body, .gem-section__eyebrow, .gem-hero-banner__proof, .gem-hero-banner__disclaimer, p) { color: #fff !important; }",
2926
+ ".gem-hero-banner--default .gem-hero-banner__actions { margin-top: 24px; }",
2927
+ ".gem-hero-banner--default .gem-button--primary { min-width: 130px; min-height: 47px; background: transparent; border-color: currentColor; color: currentColor; padding: 0 30px; font-size: 15px; line-height: 18px; }",
2928
+ // split-proof / editorial: a real two-column split (copy beside image) — matches the
2929
+ // planner's design and the section-library gem.css the published Dawn theme uses. The
2930
+ // copy sits on the section background (legible), never overlaid on the photo.
2931
+ ".gem-hero-banner--split-proof, .gem-hero-banner--editorial { min-height: auto; display: block; padding-block: 56px; text-align: left; color: var(--gem-color-text); }",
2932
+ ".gem-hero-banner--split-proof .gem-hero-banner__inner, .gem-hero-banner--editorial .gem-hero-banner__inner { width: min(var(--gem-layout-page, 1200px), calc(100% - var(--gem-layout-gutter, 32px))); margin-inline: auto; display: grid; grid-template-columns: minmax(0, 1fr) minmax(17rem, 0.82fr); gap: 48px; align-items: center; min-height: 0; }",
2933
+ ".gem-hero-banner--split-proof .gem-hero-banner__copy, .gem-hero-banner--editorial .gem-hero-banner__copy { position: static; display: grid; gap: 14px; max-width: 40rem; margin: 0; padding: 0; text-align: left; align-content: center; }",
2934
+ ".gem-hero-banner--split-proof .gem-section__eyebrow, .gem-hero-banner--editorial .gem-section__eyebrow { display: block; margin: 0; color: var(--gem-color-muted); font-size: 13px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }",
2935
+ ".gem-hero-banner--split-proof .gem-section__heading, .gem-hero-banner--editorial .gem-section__heading { margin: 0; font-size: 46px; line-height: 1.08; color: var(--gem-color-text); }",
2936
+ ".gem-hero-banner--split-proof .gem-section__body, .gem-hero-banner--editorial .gem-section__body { margin: 0; max-width: 36rem; color: var(--gem-color-muted); font-size: 16px; line-height: 1.6; }",
2937
+ ".gem-hero-banner--split-proof .gem-hero-banner__proof, .gem-hero-banner--editorial .gem-hero-banner__proof { margin: 4px 0 0; color: var(--gem-color-muted); font-size: 14px; }",
2938
+ ".gem-hero-banner--split-proof .gem-hero-banner__actions, .gem-hero-banner--editorial .gem-hero-banner__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }",
2939
+ ".gem-hero-banner--split-proof .gem-hero-banner__media, .gem-hero-banner--editorial .gem-hero-banner__media { position: relative; inset: auto; min-height: 26rem; height: 100%; overflow: hidden; border-radius: 6px; background: rgb(244 244 244); }",
2940
+ ".gem-hero-banner--split-proof .gem-hero-banner__image, .gem-hero-banner--split-proof .gem-hero-banner__placeholder, .gem-hero-banner--editorial .gem-hero-banner__image, .gem-hero-banner--editorial .gem-hero-banner__placeholder { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }",
2941
+ ".gem-hero-banner .gem-section__content { max-width: 78rem; margin-inline: auto; }",
2942
+ ".gem-hero-banner h1, .gem-hero-banner h2, .gem-section__heading { margin: 0 0 1.5rem; font-size: clamp(calc(2.5rem * var(--gem-typography-heading-scale, 1)), calc(4vw * var(--gem-typography-heading-scale, 1)), calc(5.2rem * var(--gem-typography-heading-scale, 1))); font-weight: 400; line-height: 1.08; letter-spacing: 0; }",
2943
+ ".gem-section__eyebrow { display: none; }",
2944
+ ".gem-hero-banner--compact-collection { min-height: auto; display: block; text-align: left; padding-block: 25px; }",
2945
+ ".gem-hero-banner--compact-collection .gem-section__content, .gem-product-card-grid--quick-view-grid > .gem-section__inner { width: min(var(--gem-layout-page, 1200px), calc(100% - var(--gem-layout-gutter, 32px))); margin-inline: auto; }",
2946
+ ".gem-hero-banner--compact-collection .gem-hero-banner__inner { width: min(var(--gem-layout-page, 1200px), calc(100% - var(--gem-layout-gutter, 32px))); min-height: auto; margin-inline: auto; display: block; }",
2947
+ ".gem-hero-banner--compact-collection .gem-hero-banner__media { display: none; }",
2948
+ ".gem-hero-banner--compact-collection .gem-hero-banner__copy { max-width: none; }",
2949
+ ".gem-hero-banner--compact-collection .gem-section__heading { font-size: 40px; line-height: 52px; margin: 0; }",
2950
+ ".gem-hero-banner--compact-collection .gem-section__body { display: none; }",
2951
+ ".gem-rich-text--dawn-intro { text-align: center; padding-block: 40px 0; }",
2952
+ ".gem-rich-text--dawn-intro .gem-rich-text__content { width: min(780px, 100%); max-width: 780px; margin-inline: auto; }",
2953
+ ".gem-rich-text--dawn-intro .gem-section__heading { margin: 0; font-size: 40px; line-height: 52px; }",
2954
+ ".gem-rich-text--dawn-intro .gem-section__body { width: 100%; max-width: none; margin: 20px 0 0; font-size: 16px; line-height: 28.8px; }",
2955
+ ".gem-rich-text--dawn-intro .gem-section__body p { margin: 0; }",
2956
+ ".gem-rich-text--dawn-intro .gem-rich-text__blocks { display: block; width: 100%; }",
2957
+ ".gem-button { min-width: 12rem; border-radius: 0; font-weight: 400; box-shadow: none; }",
2958
+ ".gem-product-card-wrapper { display: block; min-width: 0; }",
2959
+ ".gem-card, .gem-product-card { border: 0; border-radius: 0; box-shadow: none; background: transparent; padding: 0; }",
2960
+ ".gem-product-card__media, .gem-media { border: 0; border-radius: 0; box-shadow: none; background: rgb(244 244 244); }",
2961
+ ".gem-product-card__media { display: block; position: relative; width: 100%; height: 0; min-block-size: 0; padding-bottom: 100%; aspect-ratio: auto; overflow: hidden; }",
2962
+ ".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; }",
2963
+ ".gem-product-card__media > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }",
2964
+ // Home product grids show generated/lifestyle imagery (not catalog product-on-white shots), so
2965
+ // `contain` letterboxes them inside the square card (looks misaligned / floating off the box).
2966
+ // Fill the card with `cover` in these grid contexts; PDP/cart cards keep `contain`.
2967
+ ".gem-featured-collection .gem-product-card__media > img, .gem-product-card-grid .gem-product-card__media > img { object-fit: cover; }",
2968
+ ".gem-product-card-grid--quick-view-grid .gem-product-card__media { display: block; min-height: 0; }",
2969
+ ".gem-product-card-grid--quick-view-grid .gem-product-card__placeholder { min-height: 0; }",
2970
+ ".gem-product-card__content { padding-top: 8px; gap: 4px; }",
2971
+ ".gem-product-card__title { font-weight: 400; font-size: 16px; line-height: 24px; }",
2972
+ ".gem-product-card__price { display: block; margin-top: 4px; font-weight: 400; line-height: 24px; }",
2973
+ ".gem-product-card__price .gem-price, .gem-product-card__price { font-size: 16px; }",
2974
+ ".gem-product-card-grid--quick-view-grid .gem-product-card__badges { display: none; }",
2975
+ ".gem-featured-collection--editorial-grid .gem-product-card__quick-actions, .gem-product-card-grid--quick-view-grid .gem-product-card__quick-actions, .gem-main-search .gem-product-card__quick-actions { display: none; }",
2976
+ ".gem-cart-recommendations--dawn-empty .gem-product-card__quick-actions { display: none; }",
2977
+ ".gem-featured-collection--editorial-grid > .gem-section__inner > .gem-section__heading, .gem-featured-collection--editorial-grid > .gem-section__inner > .gem-section__body { display: none; }",
2978
+ ".gem-featured-collection--editorial-grid { padding-block: 28px 36px; }",
2979
+ ".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; }",
2980
+ ".gem-product-card-grid--quick-view-grid { padding-top: 0; }",
2981
+ ".gem-product-card-grid--quick-view-grid .gem-section__heading:empty { display: none; }",
2982
+ // Hide a compare-at only when the price ISN'T actually on sale. The rule used to hide it
2983
+ // unconditionally — fine while every card was demo copy, wrong once real captured cards arrived:
2984
+ // longevitybox's six products each carry a genuine was-price and the grid silently dropped all
2985
+ // six. `gem-price--on-sale` is set by the binder exactly when a compare-at was captured.
2986
+ ".gem-product-card-grid--quick-view-grid .gem-price:not(.gem-price--on-sale) .gem-price__compare { display: none; }",
2987
+ ".gem-product-card-grid--quick-view-grid > .gem-section__inner { position: relative; row-gap: 0 !important; }",
2988
+ ".gem-product-card-grid__meta { position: absolute; inset-block-start: 11px; inset-inline-end: 0; float: none; display: flex; justify-content: flex-end; align-items: center; min-height: 21px; height: 21px; margin: 0; color: rgb(18 18 18 / 75%); font-size: 16px; line-height: 28.8px; }",
2989
+ ".gem-product-card-grid--quick-view-grid .gem-product-card-grid__meta { display: flex; }",
2990
+ ".gem-product-card-grid__controls { display: flex; align-items: center; gap: 20px; min-height: 32px; margin: 0 0 24px; }",
2991
+ ".gem-product-card-grid--quick-view-grid .gem-product-card-grid__controls { min-height: 51px; height: 51px; margin: 0 0 16px !important; padding-top: 10px; }",
2992
+ // Scoped to the Dawn quick-view grid it was measured on, as gemsite's copy is (app/globals.css). Unscoped,
2993
+ // it forced an 8px / 4px gap with !important on EVERY section reusing the class: GemFactory's tier-specs
2994
+ // stacked its cards 2-4px apart on mobile (library audit 2026-10-05), and this repo's own
2995
+ // product-card-grid/featured renamed its grid to __cards just to get out from under it (review #628).
2996
+ ".gem-product-card-grid--quick-view-grid .gem-product-card-grid__grid { gap: 8px !important; }",
2997
+ ".gem-product-card-grid__controls .gem-collection-filter-toolbar__filters { display: flex; align-items: center; gap: 18px; border: 0; background: transparent; padding: 0; }",
2998
+ ".gem-product-card-grid__controls .gem-collection-filter-toolbar__filters summary { min-width: auto; border: 0; background: transparent; padding: 0; pointer-events: none; }",
2999
+ ".gem-product-card-grid__controls .gem-collection-filter-toolbar__filter, .gem-product-card-grid__controls .gem-collection-filter-toolbar__sort { display: flex; align-items: center; gap: 8px; font-size: 0.75rem; font-weight: 400; }",
3000
+ ".gem-product-card-grid__controls .gem-collection-filter-toolbar__select { width: auto; min-width: 0; min-height: 0; border: 0; background: transparent; padding: 0; font-size: 0.75rem; }",
3001
+ ".gem-product-card-grid__controls .gem-collection-filter-toolbar__submit { display: none; }",
3002
+ ".gem-product-card-grid__controls::after { content: ''; display: block; clear: both; }",
3003
+ ".gem-main-search { padding-top: 36px; }",
3004
+ ".gem-main-search > .gem-section__inner { display: block; }",
3005
+ ".gem-main-search .gem-section__heading { font-size: 24px !important; line-height: 31.2px !important; margin: 16px 0 30px !important; text-align: center; }",
3006
+ ".gem-main-search .gem-search-form { width: 741px; max-width: 741px; height: 47px; grid-template-columns: minmax(0, 1fr) 44px; gap: 0; align-items: stretch; margin: 0 auto 50px; }",
3007
+ ".gem-main-search .gem-search-form .gem-form-field { display: block; height: 47px; }",
3008
+ ".gem-main-search .gem-search-form .gem-form-field span { display: none; }",
3009
+ ".gem-main-search .gem-search-form .gem-input { min-height: 47px; height: 47px; border: 1px solid rgb(18 18 18 / 75%); border-right: 0; border-radius: 0; padding: 10px 16px; }",
3010
+ ".gem-main-search .gem-search-form .gem-button { min-width: 44px; width: 44px; min-height: 47px; height: 47px; border: 1px solid rgb(18 18 18 / 75%); border-left: 0; background: transparent; color: var(--gem-color-text); font-size: 0; padding: 0; }",
3011
+ ".gem-main-search .gem-search-form .gem-button::before { content: none; display: none; }",
3012
+ ".gem-main-search .gem-search-form .gem-button .svg-wrapper, .gem-collection-filter-toolbar__filters summary .svg-wrapper { display: inline-flex; width: 18px; height: 18px; margin-right: 8px; }",
3013
+ ".gem-main-search .gem-search-form .gem-button .svg-wrapper svg, .gem-collection-filter-toolbar__filters summary .svg-wrapper svg { width: 100%; height: 100%; }",
3014
+ ".gem-main-search .gem-product-card-grid__controls { height: 51px; min-height: 51px; margin: 0 0 16px; padding-top: 10px; }",
3015
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-media-gallery__frame { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }",
3016
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-media-gallery__item { aspect-ratio: 1 / 1; }",
3017
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-media-gallery__item:first-child { grid-column: 1 / -1; }",
3018
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-media-gallery__thumbs { display: none; }",
3019
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__summary { gap: 18px; max-width: 600px; }",
3020
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__summary > .gem-section__heading { font-size: 40px; line-height: 52px; margin-bottom: 0; }",
3021
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__text--uppercase, .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__text--subtitle { display: none; }",
3022
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__availability { display: none; }",
3023
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__price, .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__price .gem-price { min-height: 30px; font-size: 16px; line-height: 24px; }",
3024
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__price .gem-price { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; font-weight: 400; }",
3025
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__price .gem-price__regular { font-weight: 400; }",
3026
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__sale-badge { min-height: 22px; border-radius: 999px; background: rgb(51 79 180); color: white; padding: 4px 12px; font-size: 12px; line-height: 12px; font-weight: 400; }",
3027
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-section__body { margin-top: 10px; font-size: 16px; line-height: 28.8px; }",
3028
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-buy-buttons__variant-status { display: none; }",
3029
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__variant-fallback { max-width: 440px; gap: 8px; }",
3030
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__variant-fallback legend { font-size: 15px; line-height: 27px; margin-bottom: 0; }",
3031
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__variant-pill { min-height: 36px; min-width: auto; padding: 0 20px; font-size: 13px; line-height: 16px; }",
3032
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__dawn-story { display: block; margin-top: 36px; }",
3033
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__dawn-story-media { aspect-ratio: 1.2 / 1; margin-bottom: 32px; overflow: hidden; background: rgb(244 244 244); }",
3034
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__dawn-story-media img { width: 100%; height: 100%; object-fit: contain; display: block; }",
3035
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__dawn-story h2 { margin: 0 0 16px; font-size: 24px; line-height: 31.2px; font-weight: 400; }",
3036
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__dawn-story p { margin: 0; color: rgb(18 18 18 / 75%); font-size: 15px; line-height: 27px; }",
3037
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__collapsible summary h2 { display: inline; margin: 0; font: inherit; }",
3038
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__collapsible summary .svg-wrapper { display: inline-flex; width: 18px; height: 18px; margin-right: 12px; color: rgb(18 18 18 / 75%); }",
3039
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__collapsible summary .gem-product-main__collapsible-caret { margin-left: auto; margin-right: 0; width: 10px; height: 10px; }",
3040
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__share { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 44px; color: rgb(18 18 18 / 75%); text-decoration: none; font-size: 15px; line-height: 27px; }",
3041
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__share .svg-wrapper { display: inline-flex; width: 13px; height: 12px; }",
3042
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-buy-buttons { gap: 15px; max-width: 440px; }",
3043
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-buy-buttons__quantity { width: 142px; gap: 6px; font-size: 15px; line-height: 27px; }",
3044
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-quantity-input { width: 142px; min-height: 47px; height: 47px; grid-template-columns: 44px 54px 44px; border-radius: 0; }",
3045
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-quantity-input__button, .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-quantity-input__field { min-height: 47px; height: 47px; padding-block: 0; }",
3046
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-buy-buttons__submit { background: transparent; color: rgb(18 18 18); border: 1px solid rgb(18 18 18); min-height: 47px; padding-block: 0; font-size: 15px; line-height: 18px; }",
3047
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] [class~='shopify-payment-button'] { position: relative; min-height: 47px; height: 47px; margin-top: -5px; overflow: hidden; }",
3048
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] [class~='shopify-payment-button'] > * { visibility: hidden; }",
3049
+ ".gem-product-main[data-gem-product-main-layout='dawn-main'] [class~='shopify-payment-button']::before { content: 'Buy it now'; position: absolute; inset: 0; display: grid; place-items: center; background: rgb(18 18 18); color: white; font-size: 15px; line-height: 18px; }",
3050
+ ".gem-recommended-products-product-rail .gem-recommended-products__quick-view-surface, .gem-recommended-products-product-rail [data-gem-quick-view-surface] { display: none !important; }",
3051
+ ".gem-recommended-products-product-rail .gem-recommended-products__inner:empty { min-height: 4.8rem; }",
3052
+ ".gem-cart-main--line-items .gem-section__heading { font-size: clamp(2.4rem, 3.4vw, 4rem); }",
3053
+ ".gem-cart-main--line-items .gem-section__body { color: rgb(18 18 18 / 75%); }",
3054
+ ".gem-cart-main__empty { width: 1100px !important; max-width: calc(100vw - 100px) !important; margin-inline: auto; }",
3055
+ ".gem-cart-main__login { margin-top: 4rem; }",
3056
+ ".gem-cart-main__login h2 { margin: 0 0 1.5rem; font-size: 1.8rem; font-weight: 400; }",
3057
+ ".gem-cart-main__login p { margin: 0; }",
3058
+ ".gem-cart-recommendations--dawn-empty { margin-top: -135px; padding-top: 0; }",
3059
+ ".gem-cart-recommendations--dawn-empty .gem-cart-recommendations__header { width: 1100px !important; max-width: calc(100vw - 100px) !important; margin: 0 auto 16px; }",
3060
+ ".gem-cart-recommendations--dawn-empty .gem-section__heading { font-size: 2rem; margin: 0; }",
3061
+ ".gem-cart-recommendations--dawn-empty .gem-cart-recommendations__rail { width: 1100px !important; max-width: calc(100vw - 100px) !important; margin-inline: auto; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }",
3062
+ ".gem-hero-collage--category-mosaic { min-height: 1003px; padding-block: 97px 36px; }",
3063
+ ".gem-hero-collage--category-mosaic > .gem-section__inner { min-height: 870px; padding: 0; align-content: start; }",
3064
+ ".gem-hero-collage--category-mosaic .gem-hero-collage__intro { display: none; }",
3065
+ ".gem-hero-collage--category-mosaic .gem-hero-collage__grid { display: grid; min-height: 870px; grid-template-columns: 2fr 1fr; grid-template-rows: repeat(2, minmax(0, 1fr)); gap: 8px; }",
3066
+ ".gem-hero-collage--category-mosaic .gem-hero-collage__tile { position: relative; display: block; min-height: 0; overflow: hidden; border: 0; background: rgb(244 244 244); }",
3067
+ ".gem-hero-collage--category-mosaic .gem-hero-collage__tile:first-child { grid-row: 1 / -1; }",
3068
+ ".gem-hero-collage--category-mosaic .gem-hero-collage__media, .gem-hero-collage--category-mosaic .gem-hero-collage__image, .gem-hero-collage--category-mosaic .gem-hero-collage__placeholder { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; }",
3069
+ ".gem-hero-collage--category-mosaic .gem-hero-collage__placeholder { background: rgb(244 244 244); }",
3070
+ ".gem-hero-collage--category-mosaic .gem-hero-collage__content { position: absolute; left: 24px; bottom: 24px; display: grid; gap: 6px; color: rgb(18 18 18); }",
3071
+ ".gem-hero-collage--category-mosaic .gem-hero-collage__badge, .gem-hero-collage--category-mosaic .gem-hero-collage__caption { display: none; }",
3072
+ ".gem-hero-collage--category-mosaic .gem-hero-collage__label { font-size: 20px; line-height: 26px; font-weight: 400; }",
3073
+ ".gem-hero-video--dawn-video { height: 552px; min-height: 552px; padding: 0; overflow: hidden; }",
3074
+ ".gem-hero-video--dawn-video > .gem-section__inner, .gem-hero-video--dawn-video .gem-hero-video__inner, .gem-hero-video--dawn-video .gem-hero-video__media { width: 100%; max-width: none; height: 552px; min-height: 552px; }",
3075
+ ".gem-hero-video--dawn-video .gem-hero-video__heading { text-align: center; margin: 0 0 24px; }",
3076
+ ".gem-hero-video--dawn-video .gem-hero-video__content-wrap, .gem-hero-video--dawn-video .gem-hero-video__scrim, .gem-hero-video--dawn-video .gem-hero-video__toggle { display: none; }",
3077
+ ".gem-hero-video--dawn-video .gem-hero-video__placeholder, .gem-hero-video--dawn-video .gem-hero-video__poster, .gem-hero-video--dawn-video .gem-hero-video__video { display: block; width: 100%; height: 100%; object-fit: cover; background: rgb(244 244 244); }",
3078
+ ".gem-advanced-list--feature-grid { height: 243px; min-height: 243px; overflow: hidden; padding-block: 36px; }",
3079
+ ".gem-advanced-list--feature-grid > .gem-section__inner > .gem-section__heading, .gem-advanced-list--feature-grid > .gem-section__inner > .gem-section__body { display: none; }",
3080
+ ".gem-advanced-list--feature-grid .gem-section__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }",
3081
+ ".gem-advanced-list--feature-grid .gem-advanced-list__item { min-height: 0; text-align: center; font-size: 14px; line-height: 25.2px; }",
3082
+ ".gem-advanced-list--feature-grid .gem-advanced-list__item h3 { display: none; }",
3083
+ ".gem-advanced-list--feature-grid .gem-advanced-list__item .gem-richtext, .gem-advanced-list--feature-grid .gem-advanced-list__item p { margin: 0; color: rgb(18 18 18 / 75%); }",
3084
+ ".gem-shell-footer { margin-top: 0; border-top: 1px solid rgb(18 18 18 / 8%); padding-block: 36px; background: rgb(255 255 255); color: rgb(18 18 18); }",
3085
+ ".gem-shell-footer__inner { max-width: var(--gem-layout-page, 1200px); }",
3086
+ ".gem-shell-footer__newsletter { display: flex; align-items: flex-start; justify-content: space-between; gap: 32px; width: 100%; max-width: 1100px; min-height: 90px; margin: 10px auto 0; padding: 0 0 20px; background: transparent; border: 0; }",
3087
+ ".gem-shell-footer__newsletter-heading { margin: 0 0 18px; font-size: 18px; line-height: 23.4px; font-weight: 400; }",
3088
+ ".gem-shell-footer__newsletter form { display: flex; align-items: stretch; flex-wrap: nowrap; gap: 0; width: min(100%, 480px); max-width: 480px; }",
3089
+ ".gem-shell-footer__newsletter .gem-input { width: 100%; min-height: 45px; border: 1px solid rgb(18 18 18 / 55%); border-radius: 0; background: transparent; padding: 10px 14px; font-size: 16px; line-height: 24px; }",
3090
+ ".gem-shell-footer__newsletter .gem-button { min-width: 45px; min-height: 45px; border-radius: 0; border: 1px solid rgb(18 18 18); background: rgb(18 18 18); color: white; font-size: 0; padding: 0; }",
3091
+ ".gem-shell-footer__newsletter .gem-button::before { content: '\\2192'; font-size: 20px; line-height: 1; }",
3092
+ ".gem-shell-footer__support, .gem-shell-footer__markets, .gem-shell-footer__community, .gem-shell-footer__trust, .gem-shell-footer__offer { display: none; }",
3093
+ ".gem-shell-footer__grid { display: flex; width: 100%; max-width: 1100px; gap: 8px; margin: 40px auto 0; padding-bottom: 0; }",
3094
+ ".gem-shell-footer__grid > div, .gem-shell-footer__column, .gem-shell-footer__block { flex: 1 1 0; border: 0; background: transparent; padding: 0; box-shadow: none; }",
3095
+ ".gem-shell-footer .footer-block__heading { margin: 0 0 20px; font-size: 18px; line-height: 23.4px; font-weight: 400; }",
3096
+ ".gem-shell-footer .footer-block__details-content { display: grid; gap: 10px; margin: 0; padding: 0; color: rgb(18 18 18 / 75%); font-size: 14px; line-height: 25.2px; }",
3097
+ ".gem-shell-footer .footer-block__details-content a { color: rgb(18 18 18 / 75%); text-decoration: none; }",
3098
+ ".gem-shell-footer .footer-block__details-content p { margin: 0; max-width: 320px; }",
3099
+ ".gem-shell-footer__bottom { display: flex; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; gap: 18px; width: 100vw; min-height: 186px; margin: 50px 0 0 calc(50% - 50vw); border-top: 1px solid rgb(18 18 18 / 8%); padding: 30px calc((100vw - 1100px) / 2) 0; }",
3100
+ ".gem-shell-footer__social, .gem-shell-footer__payments { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin: 0; padding: 0; list-style: none; }",
3101
+ ".gem-shell-footer__social a { min-height: 24px; border: 0; padding: 0; color: rgb(18 18 18 / 75%); font-size: 13px; line-height: 18px; }",
3102
+ ".gem-shell-footer__payments { margin-left: auto; gap: 6px; }",
3103
+ ".gem-shell-footer__payment-icon { width: 38px; height: auto; }",
3104
+ ".gem-shell-footer__payment-fallback { display: inline-grid; place-items: center; min-width: 38px; height: 24px; border: 1px solid rgb(18 18 18 / 12%); border-radius: 3px; background: white; color: rgb(18 18 18 / 72%); font-size: 8px; line-height: 1; }",
3105
+ ".gem-shell-footer__localization { order: -1; flex: 0 0 100%; width: 100%; }",
3106
+ ".gem-shell-footer__localization .gem-select, .gem-shell-footer__localization > .gem-select { display: inline-flex; align-items: center; min-width: 210px; min-height: 45px; border: 1px solid rgb(18 18 18 / 55%); border-radius: 0; background: transparent; padding: 10px 36px 10px 12px; color: rgb(18 18 18); font-size: 13px; line-height: 18px; }",
3107
+ // Opt-ins again, AFTER the Dawn rules above (see OPT_IN_EYEBROW).
3108
+ OPT_IN_EYEBROW,
3109
+ OPT_IN_HEADING,
3110
+ OPT_IN_BODY,
3111
+ createDawnParityMobileCss(),
3112
+ // The row again, after every Dawn rule including its phone block (see GEM_ROW_CSS_LINES).
3113
+ ...GEM_ROW_CSS_LINES
3114
+ ].join("\n");
3115
+ }
3116
+ function createDawnParityMobileCss() {
3117
+ return [
3118
+ "@media (max-width: 760px) {",
3119
+ " :root { --gem-layout-gutter: 24px; --gem-layout-section: 36px; }",
3120
+ " .gem-shell-header, .gem-shell-header__inner, .header { min-height: 64px; }",
3121
+ " .gem-shell-header { --gem-component-header-height: 64px; }",
3122
+ " .gem-shell-header__inner, .gem-shell-header__inner.header--middle-left, .gem-shell-header__inner.header--middle-center { display: grid; width: 100%; max-width: none; height: 64px; margin-inline: 0; grid-template-columns: 82px minmax(0, 1fr) 84px; grid-template-areas: 'drawer heading icons'; column-gap: 0; padding: 10px 30px; }",
3123
+ " .gem-shell-header__drawer { grid-area: drawer; order: 0; justify-self: start; }",
3124
+ " .gem-shell-header__logo { grid-area: heading; justify-self: center; }",
3125
+ " .gem-shell-header__actions { grid-area: icons; display: inline-flex; justify-self: start; gap: 0; }",
3126
+ " .gem-shell-header__actions .gem-shell-header__action.gem-shell-header__action--search, .gem-shell-header__actions .gem-shell-header__action.gem-shell-header__action--cart { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 44px; min-width: 44px; height: 44px; min-height: 44px; padding: 0; border: 0; border-radius: 0; background: transparent; color: rgb(18 18 18); font-size: 0; box-shadow: none; }",
3127
+ " .gem-shell-header__actions .gem-shell-header__action--account { display: none; }",
3128
+ " .gem-shell-header__action--search::before, .gem-shell-header__action--search::after, .gem-shell-header__action--cart::before, .gem-shell-header__action--cart::after { content: none; display: none; }",
3129
+ " .gem-shell-header .cart-count-bubble, .gem-shell-header__cart-count { display: none; }",
3130
+ " .gem-hero-banner--editorial, .gem-hero-banner--split-proof { min-height: auto; padding-block: 36px; }",
3131
+ " .gem-hero-banner--split-proof .gem-hero-banner__inner, .gem-hero-banner--editorial .gem-hero-banner__inner { grid-template-columns: 1fr; gap: 24px; }",
3132
+ " .gem-hero-banner--split-proof .gem-section__heading, .gem-hero-banner--editorial .gem-section__heading { font-size: 34px; }",
3133
+ " .gem-hero-banner--split-proof .gem-hero-banner__media, .gem-hero-banner--editorial .gem-hero-banner__media { min-height: 18rem; }",
3134
+ " .gem-hero-banner--default { min-height: 390px; }",
3135
+ " .gem-hero-banner--default .gem-hero-banner__inner { min-height: 390px; height: auto; align-items: center; justify-items: center; padding-bottom: 0; }",
3136
+ " .gem-hero-banner--default .gem-hero-banner__copy { position: relative; left: auto; bottom: auto; transform: none; align-self: auto; justify-self: auto; margin: 0 auto; padding-inline: 15px; }",
3137
+ " .gem-hero-banner--default .gem-section__heading { font-size: 40px; line-height: 52px; margin: 0; }",
3138
+ " .gem-hero-banner--default .gem-section__body { font-size: 15px; line-height: 27px; }",
3139
+ " .gem-hero-banner--default .gem-button--primary { min-width: 130px; min-height: 47px; box-sizing: border-box; font-size: 15px; line-height: 18px; }",
3140
+ " .gem-rich-text--dawn-intro { padding-block: 30px 0; }",
3141
+ " .gem-rich-text--dawn-intro .gem-rich-text__content { max-width: 320px; }",
3142
+ " .gem-rich-text--dawn-intro .gem-section__heading { font-size: 30px; line-height: 39px; }",
3143
+ " .gem-rich-text--dawn-intro .gem-section__body { font-size: 15px; line-height: 27px; }",
3144
+ " .gem-rich-text--dawn-intro .gem-rich-text__blocks { display: block; }",
3145
+ " .gem-featured-collection--editorial-grid { padding-block: 21px 27px; }",
3146
+ " .gem-hero-banner--compact-collection { padding-block: 25px; }",
3147
+ " .gem-hero-banner--compact-collection .gem-section__heading { font-size: 30px; line-height: 39px; }",
3148
+ " .gem-product-card-grid--quick-view-grid > .gem-section__inner, .gem-main-search > .gem-section__inner { width: calc(100% - 30px); }",
3149
+ " .gem-product-card-grid--quick-view-grid .gem-product-card-grid__grid { gap: 4px !important; }",
3150
+ " .gem-product-card__content { padding-top: 8px; gap: 4px; }",
3151
+ " .gem-product-card__title { font-size: 15px; line-height: 24px; }",
3152
+ " .gem-product-card__price, .gem-product-card__price .gem-price { font-size: 16px; line-height: 24px; }",
3153
+ " .gem-hero-banner h1, .gem-hero-banner h2, .gem-section__heading { font-size: clamp(2rem, 11vw, 3.6rem); }",
3154
+ " .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)); }",
3155
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] > .gem-section__inner { width: calc(100% - 30px); }",
3156
+ " .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; }",
3157
+ " .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; }",
3158
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__summary { gap: 15px; margin-top: 20px; }",
3159
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__summary > .gem-section__heading { font-size: 30px; line-height: 39px; margin-bottom: 0; }",
3160
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__price, .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__price .gem-price { min-height: 30px; font-size: 16px; line-height: 24px; }",
3161
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__sale-badge { min-height: 22px; padding: 4px 12px; font-size: 12px; line-height: 12px; font-weight: 400; }",
3162
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__variant-fallback { max-width: none; min-height: 112px; gap: 8px; }",
3163
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__variant-fallback legend { font-size: 15px; line-height: 27px; margin-bottom: 0; }",
3164
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__variant-pill { min-height: 36px; min-width: auto; padding: 0 20px; font-size: 13px; line-height: 16px; }",
3165
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-buy-buttons { gap: 15px; max-width: none; }",
3166
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-buy-buttons__quantity { width: 142px; gap: 0; font-size: 15px; line-height: 27px; }",
3167
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-quantity-input { width: 142px; min-height: 47px; height: 47px; grid-template-columns: 44px 54px 44px; }",
3168
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-quantity-input__button, .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-quantity-input__field { min-height: 47px; height: 47px; padding-block: 0; }",
3169
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-buy-buttons__submit { min-height: 47px; margin-top: 9px; padding-block: 0; font-size: 15px; line-height: 18px; }",
3170
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] [class~='shopify-payment-button'] { min-height: 47px; height: 47px; margin-top: -5px; }",
3171
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] [class~='shopify-payment-button']::before { min-height: 47px; font-size: 15px; line-height: 18px; }",
3172
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-section__body { min-height: 312px; margin-top: 10px; font-size: 15px; line-height: 27px; }",
3173
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-section__body + .gem-product-main__collapsible { margin-top: 9px; }",
3174
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__collapsible { min-height: 51px; padding: 0; }",
3175
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__collapsible + .gem-product-main__collapsible { margin-top: -15px; }",
3176
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__collapsible + .gem-product-main__share { margin-top: -4px; }",
3177
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__collapsible summary { min-height: 51px; padding-block: 12px; font-size: 15px; line-height: 27px; }",
3178
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__collapsible .gem-richtext { display: none; }",
3179
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__dawn-story { margin-top: 65px; }",
3180
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__dawn-story-media { width: 100%; height: 296px; margin-bottom: 32px; }",
3181
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__dawn-story h2 { font-size: 20px; line-height: 26px; margin-bottom: 12px; }",
3182
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__dawn-story p { font-size: 15px; line-height: 27px; }",
3183
+ " .gem-product-main[data-gem-product-main-layout='dawn-main'] .gem-product-main__share { min-height: 44px; width: 100%; font-size: 15px; line-height: 27px; }",
3184
+ " .gem-main-search { padding-top: 41px; }",
3185
+ " .gem-main-search .gem-section__heading { font-size: 20px; line-height: 26px; text-align: center; margin-bottom: 43px; }",
3186
+ " .gem-main-search .gem-search-form { max-width: none; width: 100%; margin-bottom: 22px; }",
3187
+ " .gem-main-search .gem-search-form .gem-input, .gem-main-search .gem-search-form .gem-button { min-height: 47px; }",
3188
+ " .gem-product-card-grid--quick-view-grid > .gem-section__inner, .gem-main-search > .gem-section__inner { position: relative; row-gap: 0; }",
3189
+ " .gem-product-card-grid--quick-view-grid .gem-product-card-grid__meta { position: absolute; inset-block-start: 0; inset-inline-end: 0; display: flex; float: none; justify-content: flex-end; align-items: center; min-height: 40px; height: 40px; margin: 0; font-size: 1.2rem; }",
3190
+ " .gem-product-card-grid__controls, .gem-main-search .gem-product-card-grid__controls { display: flex; justify-content: space-between; align-items: center; min-height: 40px; height: 40px; margin: 0 0 16px; padding-top: 0; }",
3191
+ " .gem-product-card-grid__controls .gem-collection-filter-toolbar__form, .gem-main-search .gem-product-card-grid__controls .gem-collection-filter-toolbar__form { display: contents; }",
3192
+ " .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters, .gem-main-search .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters { display: block; min-height: 40px; height: 40px; border: 0; background: transparent; padding: 0; overflow: hidden; }",
3193
+ " .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters summary, .gem-main-search .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters summary { display: inline-flex; align-items: center; min-height: 40px; height: 40px; border: 0; background: transparent; padding: 0; font-size: 0; pointer-events: auto; }",
3194
+ " .gem-collection-filter-toolbar__filters summary::before { content: none; display: none; }",
3195
+ " .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters summary span:not(.svg-wrapper), .gem-main-search .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters summary span:not(.svg-wrapper) { display: inline; font-size: 1.4rem; letter-spacing: 0; }",
3196
+ " .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters summary .svg-wrapper, .gem-main-search .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters summary .svg-wrapper { width: 1.6rem; height: 1.6rem; margin-right: 0.8rem; }",
3197
+ " .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters .gem-collection-filter-toolbar__filter, .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters label, .gem-product-card-grid__controls .gem-collection-filter-toolbar__filters select, .gem-product-card-grid__controls .gem-collection-filter-toolbar__sort, .gem-main-search .gem-product-card-grid__controls .gem-collection-filter-toolbar__sort { display: none; }",
3198
+ " .gem-main-search .gem-search-results-meta { margin-left: auto; font-size: 1.2rem; }",
3199
+ " .gem-cart-main--line-items { padding-top: 52px; padding-bottom: 38px; }",
3200
+ " .gem-cart-main--line-items .gem-section__heading { font-size: 30px; line-height: 39px; text-align: center; margin-bottom: 20px; }",
3201
+ " .gem-cart-main__empty { width: 360px !important; max-width: calc(100vw - 30px) !important; text-align: center; }",
3202
+ " .gem-cart-main__empty .gem-button { min-height: 47px; padding-block: 0; font-size: 15px; line-height: 18px; }",
3203
+ " .gem-cart-main__login { text-align: left; margin-top: 55px; }",
3204
+ " .gem-cart-main__login h2 { font-size: 20px; line-height: 26px; margin-bottom: 5px; }",
3205
+ " .gem-cart-main__login p { font-size: 15px; line-height: 27px; margin-top: 8px; }",
3206
+ " .gem-cart-recommendations--dawn-empty { margin-top: -46px; padding-bottom: 148px; }",
3207
+ " .gem-cart-recommendations--dawn-empty .gem-cart-recommendations__header { width: 360px !important; max-width: calc(100vw - 30px) !important; margin: 0 auto 15px; }",
3208
+ " .gem-cart-recommendations--dawn-empty .gem-section__heading { font-size: 18px; line-height: 24px; }",
3209
+ " .gem-cart-recommendations--dawn-empty .gem-cart-recommendations__rail { width: 360px !important; max-width: calc(100vw - 30px) !important; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-flow: row; grid-auto-columns: auto; overflow: visible; gap: 4px; padding-bottom: 0; }",
3210
+ " .gem-cart-recommendations--dawn-empty .gem-product-card-wrapper { width: auto; min-width: 0; }",
3211
+ " .gem-cart-recommendations--dawn-empty .gem-product-card__content { padding-top: 8px; gap: 5px; }",
3212
+ " .gem-cart-recommendations--dawn-empty .gem-product-card__title, .gem-cart-recommendations--dawn-empty .gem-product-card__price, .gem-cart-recommendations--dawn-empty .gem-product-card__price .gem-price { font-size: 15px; line-height: 24px; }",
3213
+ " .gem-shell-footer { margin-top: 0; padding-block: 27px; }",
3214
+ " .gem-shell-footer__inner { width: 100%; max-width: none; padding: 0; }",
3215
+ " .gem-shell-footer__grid { display: block; width: calc(100% - 80px); max-width: 310px; margin: 40px auto 0; padding-bottom: 0; }",
3216
+ " .gem-shell-footer__grid > div, .gem-shell-footer__column, .gem-shell-footer__block { width: 100%; margin: 0 0 40px; }",
3217
+ " .gem-shell-footer__grid > .gem-shell-footer__block:nth-child(1) { min-height: 176px; }",
3218
+ " .gem-shell-footer__grid > .gem-shell-footer__block:nth-child(2) { min-height: 222px; }",
3219
+ " .gem-shell-footer__grid > .gem-shell-footer__block:nth-child(3) { min-height: 95px; margin-bottom: 20px; }",
3220
+ " .gem-shell-footer .footer-block__heading { margin-bottom: 20px; font-size: 18px; line-height: 23.4px; }",
3221
+ " .gem-shell-footer .footer-block__details-content { gap: 10px; font-size: 14px; line-height: 25.2px; }",
3222
+ " .gem-shell-footer__newsletter { display: block; width: calc(100% - 80px); max-width: 310px; min-height: 162px; margin: 0 auto 0; padding-bottom: 0; }",
3223
+ " .gem-shell-footer__newsletter form { width: 100%; max-width: none; }",
3224
+ " .gem-shell-footer__bottom { display: flex; width: 100vw; max-width: none; min-height: 200px; margin: 9px 0 0; padding: 27px 40px 0; gap: 18px; }",
3225
+ " .gem-shell-footer__localization { order: 0; }",
3226
+ " .gem-shell-footer__payments { margin-left: 0; }",
3227
+ " .gem-hero-collage--category-mosaic { min-height: 709px; padding-block: 36px; }",
3228
+ " .gem-hero-collage--category-mosaic > .gem-section__inner { min-height: 637px; }",
3229
+ " .gem-hero-collage--category-mosaic .gem-hero-collage__grid { min-height: 637px; grid-template-columns: 1fr; grid-template-rows: 2fr 1fr 1fr; }",
3230
+ " .gem-hero-video--dawn-video { height: 212px; min-height: 212px; }",
3231
+ " .gem-hero-video--dawn-video > .gem-section__inner, .gem-hero-video--dawn-video .gem-hero-video__inner, .gem-hero-video--dawn-video .gem-hero-video__media { height: 212px; min-height: 212px; }",
3232
+ " .gem-advanced-list--feature-grid { height: 420px; min-height: 420px; padding-block: 36px; }",
3233
+ " .gem-advanced-list--feature-grid .gem-section__grid { grid-template-columns: 1fr; }",
3234
+ OPT_IN_HEADING_MOBILE,
3235
+ "}"
3236
+ ].join("\n");
3237
+ }
3238
+ function createShellCss() {
3239
+ return [
3240
+ ".page-width {",
3241
+ " max-width: var(--page-width, var(--gem-layout-page, 1200px));",
3242
+ " margin: 0 auto;",
3243
+ " padding: 0 1.5rem;",
3244
+ "}",
3245
+ "@media screen and (min-width: 750px) {",
3246
+ " .page-width { padding: 0 5rem; }",
3247
+ "}",
3248
+ ".list-unstyled {",
3249
+ " margin: 0;",
3250
+ " padding: 0;",
3251
+ " list-style: none;",
3252
+ "}",
3253
+ ".link, .link--text {",
3254
+ " color: inherit;",
3255
+ " text-decoration: none;",
3256
+ "}",
3257
+ ".focus-inset:focus-visible {",
3258
+ " outline: 0.2rem solid rgba(var(--color-foreground, 18 18 18), 0.5);",
3259
+ " outline-offset: 0.3rem;",
3260
+ "}",
3261
+ ".h2, .h5, .inline-richtext {",
3262
+ " font-family: var(--gem-font-heading);",
3263
+ "}",
3264
+ ".h2 { font-size: 2rem; line-height: 1.15; }",
3265
+ ".h5 { font-size: 1.2rem; line-height: 1.3; }",
3266
+ ".utility-bar {",
3267
+ " border-bottom: 0.1rem solid rgba(var(--color-foreground, 18 18 18), 0.08);",
3268
+ " background: var(--gem-color-surface);",
3269
+ "}",
3270
+ ".utility-bar__grid {",
3271
+ " display: grid;",
3272
+ " grid-template-columns: 1fr;",
3273
+ " align-items: center;",
3274
+ " min-height: 3.8rem;",
3275
+ "}",
3276
+ ".utility-bar__grid--2-col, .utility-bar__grid--3-col {",
3277
+ " grid-template-columns: 1fr auto;",
3278
+ "}",
3279
+ ".announcement-bar {",
3280
+ " color: var(--gem-color-text);",
3281
+ " text-align: center;",
3282
+ "}",
3283
+ ".announcement-bar__message {",
3284
+ " margin: 0;",
3285
+ " padding: 1rem 0;",
3286
+ " min-height: 3.8rem;",
3287
+ " display: flex;",
3288
+ " align-items: center;",
3289
+ " justify-content: center;",
3290
+ " letter-spacing: 0;",
3291
+ "}",
3292
+ ".announcement-bar__link {",
3293
+ " display: block;",
3294
+ " width: 100%;",
3295
+ "}",
3296
+ ".gem-shell-header .localization-wrapper {",
3297
+ " display: none !important;",
3298
+ "}",
3299
+ ".header-wrapper {",
3300
+ " display: block;",
3301
+ " position: relative;",
3302
+ " background: var(--gem-color-background);",
3303
+ " z-index: 3;",
3304
+ "}",
3305
+ ".header-wrapper--border-bottom {",
3306
+ " border-bottom: 0.1rem solid rgba(var(--color-foreground, 18 18 18), 0.08);",
3307
+ "}",
3308
+ "sticky-header.header-wrapper {",
3309
+ " position: sticky;",
3310
+ " top: 0;",
3311
+ "}",
3312
+ ".header {",
3313
+ " display: grid;",
3314
+ " grid-template-areas: 'heading navigation icons';",
3315
+ " grid-template-columns: auto 1fr auto;",
3316
+ " align-items: center;",
3317
+ " column-gap: 2rem;",
3318
+ " padding-top: 20px;",
3319
+ " padding-bottom: 20px;",
3320
+ "}",
3321
+ ".header--middle-left { grid-template-areas: 'heading navigation icons'; }",
3322
+ ".header--middle-center { grid-template-areas: 'navigation heading icons'; grid-template-columns: 1fr auto 1fr; }",
3323
+ ".header__heading-link, .gem-shell-header__logo {",
3324
+ " grid-area: heading;",
3325
+ " justify-self: start;",
3326
+ " line-height: 1;",
3327
+ "}",
3328
+ ".header__heading-logo-wrapper {",
3329
+ " display: inline-block;",
3330
+ " max-width: 100%;",
3331
+ "}",
3332
+ ".header__heading-logo {",
3333
+ " height: auto;",
3334
+ " max-width: 100%;",
3335
+ "}",
3336
+ ".header .gem-shell-header__nav {",
3337
+ " grid-area: navigation;",
3338
+ " justify-content: flex-start;",
3339
+ "}",
3340
+ ".header .gem-shell-header__actions {",
3341
+ " grid-area: icons;",
3342
+ " justify-content: flex-end;",
3343
+ "}",
3344
+ ".header__icon, .gem-shell-header__action {",
3345
+ " color: inherit;",
3346
+ " display: inline-flex;",
3347
+ " align-items: center;",
3348
+ " justify-content: center;",
3349
+ " min-width: 4.4rem;",
3350
+ " min-height: 4.4rem;",
3351
+ " padding: 0 0.8rem;",
3352
+ " text-decoration: none;",
3353
+ "}",
3354
+ ".cart-count-bubble, .gem-shell-header__cart-count {",
3355
+ " display: inline-flex;",
3356
+ " align-items: center;",
3357
+ " justify-content: center;",
3358
+ " min-width: 1.7rem;",
3359
+ " height: 1.7rem;",
3360
+ " border-radius: 50%;",
3361
+ " background: rgb(var(--color-button, 18 18 18));",
3362
+ " color: rgb(var(--color-button-text, 255 255 255));",
3363
+ " font-size: 0.9rem;",
3364
+ "}",
3365
+ ".menu-drawer-container, .gem-shell-header__drawer {",
3366
+ " display: flex;",
3367
+ "}",
3368
+ ".drawer-menu .gem-shell-header__nav { display: none; }",
3369
+ ".footer {",
3370
+ " border-top: 0.1rem solid rgba(var(--color-foreground, 18 18 18), 0.08);",
3371
+ " background: var(--gem-color-background);",
3372
+ "}",
3373
+ ".footer__content-top, .gem-shell-footer__inner {",
3374
+ " padding-bottom: 5rem;",
3375
+ "}",
3376
+ ".footer__blocks-wrapper {",
3377
+ " display: grid;",
3378
+ " gap: 3rem;",
3379
+ "}",
3380
+ "@media screen and (min-width: 750px) {",
3381
+ " .footer__blocks-wrapper.grid--4-col-tablet { grid-template-columns: repeat(4, minmax(0, 1fr)); }",
3382
+ "}",
3383
+ ".footer-block__heading {",
3384
+ " margin: 0 0 2rem;",
3385
+ " font-size: 1.6rem;",
3386
+ "}",
3387
+ ".footer-block__details-content {",
3388
+ " display: grid;",
3389
+ " gap: 1rem;",
3390
+ " color: rgba(var(--color-foreground, 18 18 18), 0.75);",
3391
+ "}",
3392
+ ".footer-block__details-content .list-menu__item--link {",
3393
+ " padding: 0;",
3394
+ "}",
3395
+ ".footer-block--newsletter {",
3396
+ " display: flex;",
3397
+ " flex-wrap: wrap;",
3398
+ " justify-content: space-between;",
3399
+ " gap: 3rem;",
3400
+ " margin-top: 3rem;",
3401
+ "}",
3402
+ ".newsletter-form__field-wrapper, .field {",
3403
+ " position: relative;",
3404
+ "}",
3405
+ ".field__input, .field input, .gem-input {",
3406
+ " min-height: 4.5rem;",
3407
+ " border-radius: var(--inputs-radius, 0);",
3408
+ "}",
3409
+ ".footer__content-bottom {",
3410
+ " border-top: 0.1rem solid rgba(var(--color-foreground, 18 18 18), 0.08);",
3411
+ " padding-top: 3rem;",
3412
+ "}",
3413
+ ".footer__content-bottom-wrapper {",
3414
+ " display: flex;",
3415
+ " width: 100%;",
3416
+ " justify-content: space-between;",
3417
+ " gap: 1.5rem;",
3418
+ "}",
3419
+ ".footer__copyright, .copyright__content, .policies {",
3420
+ " font-size: 1.1rem;",
3421
+ "}",
3422
+ ".policies {",
3423
+ " display: inline-flex;",
3424
+ " gap: 1.5rem;",
3425
+ " margin: 0;",
3426
+ " padding: 0;",
3427
+ " list-style: none;",
3428
+ "}",
3429
+ ".gem-shell-header, .gem-shell-footer {",
3430
+ " color: var(--gem-color-text);",
3431
+ " background: var(--gem-color-surface);",
3432
+ " border-color: var(--gem-color-border);",
3433
+ "}",
3434
+ ".gem-shell-header {",
3435
+ " border-bottom: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3436
+ " min-height: var(--gem-component-header-height, 72px);",
3437
+ " z-index: 20;",
3438
+ "}",
3439
+ ".gem-shell-header--sticky {",
3440
+ " position: sticky;",
3441
+ " top: 0;",
3442
+ "}",
3443
+ ".gem-shell-header--editorial {",
3444
+ " background: color-mix(in srgb, var(--gem-color-surface) 88%, transparent);",
3445
+ " backdrop-filter: blur(14px);",
3446
+ "}",
3447
+ ".gem-shell-header--overlay.gem-shell-header--transparent-start {",
3448
+ " background: color-mix(in srgb, var(--gem-color-text) 18%, transparent);",
3449
+ " color: var(--gem-color-surface);",
3450
+ " border-bottom-color: color-mix(in srgb, var(--gem-color-surface) 24%, transparent);",
3451
+ " backdrop-filter: blur(10px);",
3452
+ "}",
3453
+ ".gem-shell-header--overlay .gem-shell-header__actions .gem-shell-header__action--cart {",
3454
+ " color: var(--gem-color-surface);",
3455
+ "}",
3456
+ ".gem-shell-header--scroll-background[data-gem-header-contrast-state='solid'] {",
3457
+ " background: var(--gem-color-surface);",
3458
+ " color: var(--gem-color-text);",
3459
+ "}",
3460
+ ".gem-shell-header--search-led, .gem-shell-header--mega-menu {",
3461
+ " box-shadow: var(--gem-shadow-sm, none);",
3462
+ "}",
3463
+ ".gem-shell-header--split-nav .gem-shell-header__inner {",
3464
+ " grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);",
3465
+ "}",
3466
+ ".gem-shell-header--split-nav .gem-shell-header__logo {",
3467
+ " grid-column: 2;",
3468
+ "}",
3469
+ ".gem-shell-header--split-nav .gem-shell-header__nav {",
3470
+ " grid-column: 1;",
3471
+ " grid-row: 1;",
3472
+ " justify-content: flex-start;",
3473
+ "}",
3474
+ ".gem-shell-header--split-nav .gem-shell-header__actions {",
3475
+ " grid-column: 3;",
3476
+ " grid-row: 1;",
3477
+ " justify-content: flex-end;",
3478
+ "}",
3479
+ ".gem-shell-header--marketplace {",
3480
+ " --gem-component-header-height: 80px;",
3481
+ "}",
3482
+ ".gem-shell-header--promo-stack .gem-shell-header__announcement, .gem-shell-header__utility {",
3483
+ " font-size: 0.8125rem;",
3484
+ "}",
3485
+ ".gem-shell-header__announcement {",
3486
+ " background: var(--gem-color-accent);",
3487
+ " color: var(--gem-color-accent-text, var(--gem-color-surface));",
3488
+ " padding: var(--gem-space-sm) var(--gem-space-md);",
3489
+ " text-align: center;",
3490
+ " font-size: 0.875rem;",
3491
+ " font-weight: 650;",
3492
+ "}",
3493
+ ".gem-shell-header__utility {",
3494
+ " display: flex;",
3495
+ " justify-content: space-between;",
3496
+ " align-items: center;",
3497
+ " gap: var(--gem-space-md);",
3498
+ " width: min(var(--gem-layout-page, 1180px), calc(100% - var(--gem-layout-gutter, 32px)));",
3499
+ " margin-inline: auto;",
3500
+ " padding-block: var(--gem-space-xs);",
3501
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
3502
+ "}",
3503
+ ".gem-shell-header__utility nav {",
3504
+ " display: flex;",
3505
+ " gap: var(--gem-space-md);",
3506
+ "}",
3507
+ ".gem-shell-header__inner, .gem-shell-footer__inner {",
3508
+ " width: min(var(--gem-layout-page, 1180px), calc(100% - var(--gem-layout-gutter, 32px)));",
3509
+ " margin-inline: auto;",
3510
+ "}",
3511
+ ".gem-shell-header__inner {",
3512
+ " min-height: var(--gem-component-header-height, 72px);",
3513
+ " display: grid;",
3514
+ " grid-template-columns: auto minmax(0, 1fr) auto;",
3515
+ " align-items: center;",
3516
+ " gap: var(--gem-space-md);",
3517
+ "}",
3518
+ ".gem-shell-header__logo {",
3519
+ " color: inherit;",
3520
+ " font-family: var(--gem-font-heading);",
3521
+ " font-weight: 750;",
3522
+ " text-decoration: none;",
3523
+ "}",
3524
+ ".gem-shell-header__drawer {",
3525
+ " display: none;",
3526
+ "}",
3527
+ ".gem-shell-header__drawer-toggle {",
3528
+ " list-style: none;",
3529
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3530
+ " border-radius: var(--gem-radius-md);",
3531
+ " padding: var(--gem-space-sm) var(--gem-space-md);",
3532
+ " font-weight: 700;",
3533
+ " cursor: pointer;",
3534
+ "}",
3535
+ ".gem-shell-header__drawer-toggle::-webkit-details-marker {",
3536
+ " display: none;",
3537
+ "}",
3538
+ ".gem-shell-header__drawer-panel {",
3539
+ " position: absolute;",
3540
+ " inset-inline: 0;",
3541
+ " top: 100%;",
3542
+ " border-top: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3543
+ " border-bottom: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3544
+ " background: var(--gem-color-surface);",
3545
+ " padding: var(--gem-space-md);",
3546
+ " box-shadow: var(--gem-shadow-md, none);",
3547
+ "}",
3548
+ ".gem-shell-header__drawer-nav, .gem-shell-header__drawer-actions {",
3549
+ " display: grid;",
3550
+ " gap: var(--gem-space-sm);",
3551
+ "}",
3552
+ ".gem-shell-header__drawer-actions {",
3553
+ " margin-top: var(--gem-space-md);",
3554
+ " padding-top: var(--gem-space-md);",
3555
+ " border-top: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3556
+ "}",
3557
+ ".gem-shell-header__nav, .gem-shell-header__actions {",
3558
+ " display: flex;",
3559
+ " align-items: center;",
3560
+ " gap: var(--gem-space-md);",
3561
+ "}",
3562
+ ".gem-shell-header__nav--editorial {",
3563
+ " justify-content: center;",
3564
+ " font-family: var(--gem-font-heading);",
3565
+ "}",
3566
+ ".gem-shell-header__nav--mega {",
3567
+ " font-weight: 650;",
3568
+ "}",
3569
+ ".gem-shell-header__nav a, .gem-shell-header__actions a, .gem-shell-footer a {",
3570
+ " color: inherit;",
3571
+ " text-decoration: none;",
3572
+ "}",
3573
+ ".gem-shell-header__action--search, .gem-shell-header__action--cart {",
3574
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3575
+ " border-radius: var(--gem-radius-md);",
3576
+ " padding: var(--gem-space-sm) var(--gem-space-md);",
3577
+ "}",
3578
+ ".gem-shell-header__actions .gem-shell-header__action--cart {",
3579
+ " background: var(--gem-color-accent);",
3580
+ " color: var(--gem-color-accent-text, var(--gem-color-surface));",
3581
+ " white-space: nowrap;",
3582
+ "}",
3583
+ ".gem-shell-header__actions .gem-shell-header__action--cart * {",
3584
+ " color: inherit;",
3585
+ "}",
3586
+ ".gem-shell-header__cart-count {",
3587
+ " display: inline-flex;",
3588
+ " align-items: center;",
3589
+ " justify-content: center;",
3590
+ " min-inline-size: 1.5em;",
3591
+ " min-block-size: 1.5em;",
3592
+ " border-radius: var(--gem-radius-pill, 999px);",
3593
+ " background: color-mix(in srgb, currentColor 14%, transparent);",
3594
+ " font-size: 0.8125rem;",
3595
+ "}",
3596
+ ".gem-shell-header__mega, .gem-shell-header__departments, .gem-shell-header__promo-stack, .gem-shell-header__quicklinks, .gem-shell-header__trust-signal, .gem-shell-header__editorial-note, .gem-shell-header__search {",
3597
+ " width: min(var(--gem-layout-page, 1180px), calc(100% - var(--gem-layout-gutter, 32px)));",
3598
+ " margin-inline: auto;",
3599
+ " border-top: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3600
+ "}",
3601
+ ".gem-shell-header__mega, .gem-shell-header__departments, .gem-shell-header__promo-stack, .gem-shell-header__quicklinks {",
3602
+ " display: grid;",
3603
+ " grid-template-columns: repeat(3, minmax(0, 1fr));",
3604
+ " gap: var(--gem-space-md);",
3605
+ " padding-block: var(--gem-space-md);",
3606
+ "}",
3607
+ ".gem-shell-header__departments {",
3608
+ " grid-template-columns: repeat(4, minmax(0, 1fr));",
3609
+ "}",
3610
+ ".gem-shell-header__promo-stack {",
3611
+ " grid-template-columns: 2fr repeat(2, minmax(0, 1fr));",
3612
+ "}",
3613
+ ".gem-shell-header__quicklinks {",
3614
+ " grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));",
3615
+ "}",
3616
+ ".gem-shell-header__trust-signal {",
3617
+ " padding-block: var(--gem-space-sm);",
3618
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
3619
+ " font-size: 0.875rem;",
3620
+ "}",
3621
+ ".gem-shell-header__mega a, .gem-shell-header__mega span, .gem-shell-header__departments a, .gem-shell-header__departments span, .gem-shell-header__promo-stack a, .gem-shell-header__promo-stack span, .gem-shell-header__quicklinks a {",
3622
+ " border-radius: var(--gem-radius-md);",
3623
+ " background: var(--gem-color-background);",
3624
+ " padding: var(--gem-space-md);",
3625
+ "}",
3626
+ ".gem-shell-header__search {",
3627
+ " display: flex;",
3628
+ " gap: var(--gem-space-sm);",
3629
+ " padding-block: var(--gem-space-sm);",
3630
+ "}",
3631
+ ".gem-shell-header__search input {",
3632
+ " flex: 1;",
3633
+ " min-width: 0;",
3634
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3635
+ " border-radius: var(--gem-radius-md);",
3636
+ " padding: var(--gem-space-md);",
3637
+ "}",
3638
+ ".gem-shell-header__search button {",
3639
+ " border: 0;",
3640
+ " border-radius: var(--gem-radius-md);",
3641
+ " background: var(--gem-color-accent);",
3642
+ " color: var(--gem-color-accent-text, var(--gem-color-surface));",
3643
+ " padding-inline: var(--gem-space-lg);",
3644
+ " font-weight: 700;",
3645
+ "}",
3646
+ ".gem-shell-header__search--sticky {",
3647
+ " position: sticky;",
3648
+ " top: var(--gem-component-header-height, 72px);",
3649
+ " z-index: 19;",
3650
+ " background: var(--gem-color-surface);",
3651
+ "}",
3652
+ ".gem-shell-header__editorial-note {",
3653
+ " padding-block: var(--gem-space-sm);",
3654
+ " text-align: center;",
3655
+ " font-family: var(--gem-font-heading);",
3656
+ " color: var(--gem-color-muted, color-mix(in srgb, var(--gem-color-text) 72%, transparent));",
3657
+ "}",
3658
+ ".gem-shell-footer {",
3659
+ " border-top: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3660
+ " padding-block: var(--gem-layout-section, 64px);",
3661
+ "}",
3662
+ ".gem-shell-footer__newsletter {",
3663
+ " display: grid;",
3664
+ " gap: var(--gem-space-md);",
3665
+ " margin-bottom: var(--gem-space-xl);",
3666
+ "}",
3667
+ ".gem-shell-footer__newsletter form {",
3668
+ " display: flex;",
3669
+ " gap: var(--gem-space-sm);",
3670
+ " flex-wrap: wrap;",
3671
+ "}",
3672
+ ".gem-shell-footer__newsletter input, .gem-shell-footer__newsletter button {",
3673
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3674
+ " border-radius: var(--gem-radius-md);",
3675
+ " padding: var(--gem-space-md);",
3676
+ " background: var(--gem-color-surface);",
3677
+ " color: var(--gem-color-text);",
3678
+ "}",
3679
+ ".gem-shell-footer__newsletter button {",
3680
+ " background: var(--gem-color-accent);",
3681
+ " color: var(--gem-color-accent-text, var(--gem-color-surface));",
3682
+ " font-weight: 700;",
3683
+ "}",
3684
+ ".gem-shell-footer__grid {",
3685
+ " display: grid;",
3686
+ " grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));",
3687
+ " gap: var(--gem-space-lg);",
3688
+ "}",
3689
+ ".gem-shell-footer__grid > div, .gem-shell-footer__column {",
3690
+ " display: grid;",
3691
+ " gap: var(--gem-space-sm);",
3692
+ "}",
3693
+ ".gem-shell-footer__column {",
3694
+ " align-content: start;",
3695
+ "}",
3696
+ ".gem-shell-footer__column summary {",
3697
+ " min-height: 2.75rem;",
3698
+ " display: flex;",
3699
+ " align-items: center;",
3700
+ " cursor: pointer;",
3701
+ " font-weight: 700;",
3702
+ "}",
3703
+ ".gem-shell-footer__column [data-gem-footer-accordion-panel] {",
3704
+ " display: grid;",
3705
+ " gap: var(--gem-space-sm);",
3706
+ "}",
3707
+ ".gem-shell-footer__story, .gem-shell-footer__compliance, .gem-shell-footer__offer, .gem-shell-footer__support, .gem-shell-footer__community, .gem-shell-footer__markets {",
3708
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3709
+ " border-radius: var(--gem-radius-md);",
3710
+ " background: var(--gem-color-background);",
3711
+ " padding: var(--gem-space-lg);",
3712
+ " margin-bottom: var(--gem-space-xl);",
3713
+ "}",
3714
+ ".gem-shell-footer__story h2 {",
3715
+ " margin: 0;",
3716
+ " font-family: var(--gem-font-heading);",
3717
+ "}",
3718
+ ".gem-shell-footer__compliance strong {",
3719
+ " display: block;",
3720
+ " margin-bottom: var(--gem-space-sm);",
3721
+ "}",
3722
+ ".gem-shell-footer__offer {",
3723
+ " background: var(--gem-color-accent);",
3724
+ " color: var(--gem-color-accent-text, var(--gem-color-surface));",
3725
+ " font-weight: 700;",
3726
+ "}",
3727
+ ".gem-shell-footer--sitemap .gem-shell-footer__grid {",
3728
+ " grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));",
3729
+ "}",
3730
+ ".gem-shell-footer--community .gem-shell-footer__community h2 {",
3731
+ " margin: 0;",
3732
+ " font-family: var(--gem-font-heading);",
3733
+ "}",
3734
+ ".gem-shell-footer__trust {",
3735
+ " display: flex;",
3736
+ " flex-wrap: wrap;",
3737
+ " gap: var(--gem-space-sm);",
3738
+ " margin-top: var(--gem-space-xl);",
3739
+ "}",
3740
+ ".gem-shell-footer__trust span {",
3741
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3742
+ " border-radius: var(--gem-radius-md);",
3743
+ " padding: var(--gem-space-sm) var(--gem-space-md);",
3744
+ "}",
3745
+ ".gem-shell-footer__bottom {",
3746
+ " display: flex;",
3747
+ " flex-wrap: wrap;",
3748
+ " align-items: center;",
3749
+ " justify-content: space-between;",
3750
+ " gap: var(--gem-space-md);",
3751
+ " margin-top: var(--gem-space-xl);",
3752
+ " padding-top: var(--gem-space-lg);",
3753
+ " border-top: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3754
+ "}",
3755
+ ".gem-shell-footer__social, .gem-shell-footer__payments {",
3756
+ " display: flex;",
3757
+ " flex-wrap: wrap;",
3758
+ " align-items: center;",
3759
+ " gap: var(--gem-space-xs);",
3760
+ " margin: 0;",
3761
+ " padding: 0;",
3762
+ " list-style: none;",
3763
+ "}",
3764
+ ".gem-shell-footer__payment-icon {",
3765
+ " width: 2.375rem;",
3766
+ " height: auto;",
3767
+ "}",
3768
+ ".gem-shell-footer__social a {",
3769
+ " display: inline-flex;",
3770
+ " min-height: 2.25rem;",
3771
+ " align-items: center;",
3772
+ " border: var(--gem-border-subtle, 1px solid var(--gem-color-border));",
3773
+ " border-radius: var(--gem-radius-md);",
3774
+ " padding: var(--gem-space-xs) var(--gem-space-sm);",
3775
+ "}",
3776
+ ".gem-shell-footer__localization {",
3777
+ " min-width: min(18rem, 100%);",
3778
+ "}",
3779
+ ".gem-shell-footer__localization .gem-select {",
3780
+ " width: 100%;",
3781
+ "}",
3782
+ "@media (max-width: 760px) {",
3783
+ " .gem-shell-header { position: sticky; top: 0; }",
3784
+ " .gem-shell-header__inner { grid-template-columns: auto minmax(0, 1fr) auto; }",
3785
+ " .gem-shell-header--split-nav .gem-shell-header__inner { grid-template-columns: auto 1fr auto; }",
3786
+ " .gem-shell-header--split-nav .gem-shell-header__logo, .gem-shell-header--split-nav .gem-shell-header__nav, .gem-shell-header--split-nav .gem-shell-header__actions { grid-column: auto; grid-row: auto; }",
3787
+ " .gem-shell-header__drawer { display: block; }",
3788
+ " .gem-shell-header__drawer { order: -1; }",
3789
+ " .gem-shell-header__nav { display: none; }",
3790
+ " .gem-shell-header__actions { gap: var(--gem-space-xs); }",
3791
+ " .gem-shell-header__actions .gem-shell-header__action:not(.gem-shell-header__action--cart) { display: none; }",
3792
+ " .gem-shell-header__utility, .gem-shell-header__departments, .gem-shell-header__promo-stack, .gem-shell-header__quicklinks, .gem-shell-header__mega { grid-template-columns: 1fr; }",
3793
+ "}"
3794
+ ].join("\n");
3795
+ }
681
3796
 
682
3797
  // ../../packages/gem-framework/src/offer-engine.ts
683
3798
  function offerEngineRuntimeScript() {
@@ -1067,8 +4182,38 @@ function isAllowedUntokenizedValue(property, value) {
1067
4182
  function hasRawVisualValue(value) {
1068
4183
  return /#[0-9a-f]{3,8}\b|rgb\(|hsl\(|\b\d+(?:\.\d+)?(?:px|rem|em)\b/i.test(value);
1069
4184
  }
4185
+ var frameworkPublicVariables;
4186
+ function gemFrameworkPublicCssVariables() {
4187
+ if (!frameworkPublicVariables) {
4188
+ const css = [
4189
+ createGemThemeCss(defaultGemTokens, ":root", { profile: "dawn-parity" }),
4190
+ createGemThemeCss(defaultGemTokens, ":root", { profile: "morph" }),
4191
+ createThemeProfileCss("dawn-parity"),
4192
+ createMorphProfileCss(),
4193
+ createPrimitiveCss(),
4194
+ String(createSectionCss()),
4195
+ String(createShellCss()),
4196
+ String(createGemSectionRuntimeContractCss())
4197
+ ].join("\n").replace(/\/\*[\s\S]*?\*\//g, " ");
4198
+ frameworkPublicVariables = gemPublicCssVariablesFrom(css);
4199
+ }
4200
+ return frameworkPublicVariables;
4201
+ }
4202
+ var ROOT_SELECTOR = /^\s*(?::root|html|:host)(?:\[[^\]]*\]|:[a-z-]+(?:\([^()]*\))?)*\s*$/;
4203
+ function gemPublicCssVariablesFrom(stylesheet) {
4204
+ const css = stylesheet.replace(/\/\*[\s\S]*?\*\//g, " ");
4205
+ const declaredOnRoot = /* @__PURE__ */ new Set();
4206
+ const declaredElsewhere = /* @__PURE__ */ new Set();
4207
+ for (const [, selector, body] of css.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
4208
+ const onRoot = selector.split(",").every((part) => ROOT_SELECTOR.test(part));
4209
+ for (const [, name] of body.matchAll(/(--gem-[a-z0-9-]+)\s*:/g)) (onRoot ? declaredOnRoot : declaredElsewhere).add(name);
4210
+ }
4211
+ const mentioned = new Set([...css.matchAll(/--gem-[a-z0-9-]+/g)].map((match) => match[0]));
4212
+ return new Set([...mentioned].filter((name) => declaredOnRoot.has(name) || !declaredElsewhere.has(name)));
4213
+ }
1070
4214
  function isKnownGemCssVariable(variableName, options) {
1071
4215
  if (canonicalCssVariableNames.has(variableName)) return true;
4216
+ if (gemFrameworkPublicCssVariables().has(variableName)) return true;
1072
4217
  const allowedPrefixes = [
1073
4218
  "--gem-seasonal-",
1074
4219
  // Global style-variant knobs (--gem-style-space/radius/text/weight/stroke): the