@skyfall_ai/bazaar 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "@skyfall_ai/bazaar",
3
+ "version": "0.1.0",
4
+ "description": "Skyfall Bazaar — Curated eCommerce UI kit for discovery, trust, and conversion",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ }
18
+ },
19
+ "./styles": "./dist/index.css",
20
+ "./styles.css": "./dist/index.css",
21
+ "./tokens": "./src/tokens/bazaar-tokens.css",
22
+ "./package.json": "./package.json"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "src/tokens/*.css"
27
+ ],
28
+ "sideEffects": [
29
+ "**/*.css"
30
+ ],
31
+ "publishConfig": {
32
+ "access": "restricted"
33
+ },
34
+ "scripts": {
35
+ "dev": "storybook dev -p 6006",
36
+ "build": "vite build --config vite.lib.config.ts && cp dist/index.d.ts dist/index.d.mts",
37
+ "build-storybook": "storybook build",
38
+ "chromatic": "chromatic --exit-zero-on-changes",
39
+ "typecheck": "tsc --noEmit",
40
+ "clean": "rm -rf dist storybook-static",
41
+ "prepublishOnly": "npm run clean && npm run build"
42
+ },
43
+ "peerDependencies": {
44
+ "react": ">=18.0.0",
45
+ "react-dom": ">=18.0.0",
46
+ "recharts": ">=2.10.0"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "recharts": {
50
+ "optional": false
51
+ }
52
+ },
53
+ "devDependencies": {
54
+ "@storybook/addon-a11y": "^10.3.5",
55
+ "@storybook/addon-docs": "^10.3.5",
56
+ "@storybook/react": "^10.3.5",
57
+ "@storybook/react-vite": "^10.3.5",
58
+ "@types/react": "^18.3.0",
59
+ "@types/react-dom": "^18.3.0",
60
+ "@vitejs/plugin-react": "^6.0.1",
61
+ "chromatic": "^16.3.0",
62
+ "react": "^18.3.0",
63
+ "react-dom": "^18.3.0",
64
+ "recharts": "^2.15.4",
65
+ "storybook": "^10.3.5",
66
+ "tsup": "^8.3.0",
67
+ "typescript": "^5.6.0",
68
+ "vite": "^8.0.0",
69
+ "vite-plugin-dts": "^4.5.4"
70
+ },
71
+ "keywords": [
72
+ "ecommerce",
73
+ "commerce",
74
+ "storefront",
75
+ "retail",
76
+ "checkout",
77
+ "design-system",
78
+ "react",
79
+ "components",
80
+ "ui",
81
+ "skyfall"
82
+ ],
83
+ "license": "MIT",
84
+ "homepage": "https://github.com/skyfall-consulting/skyfall-bazaar#readme",
85
+ "repository": {
86
+ "type": "git",
87
+ "url": "git+https://github.com/skyfall-consulting/skyfall-bazaar.git"
88
+ }
89
+ }
@@ -0,0 +1,427 @@
1
+ /*
2
+ * Skyfall Bazaar — Design Tokens
3
+ *
4
+ * Palette: Warm neutrals. Oat, ecru, warm ink for the structural surfaces;
5
+ * terracotta for accent and promotion; sage for confirmation and eco
6
+ * signals. Optimized for considered commerce — editorial calm over
7
+ * marketplace noise.
8
+ *
9
+ * Naming convention: --bazaar-{category}-{role}-{variant}-{scale}
10
+ */
11
+
12
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&display=swap');
13
+
14
+ :root {
15
+ /* ============================================
16
+ BRAND & CORE PALETTE — Warm Ink
17
+ Commerce "primary" lives as near-black buttons and typography;
18
+ the scale supplies hover/active states and low-emphasis fills.
19
+ ============================================ */
20
+ --bazaar-color-brand-primary-50: #F5F3EE;
21
+ --bazaar-color-brand-primary-100: #E5E1D5;
22
+ --bazaar-color-brand-primary-200: #C6BFAC;
23
+ --bazaar-color-brand-primary-300: #8A816B;
24
+ --bazaar-color-brand-primary-400: #5E5749;
25
+ --bazaar-color-brand-primary-500: #433D32;
26
+ --bazaar-color-brand-primary-600: #2E2A23;
27
+ --bazaar-color-brand-primary-700: #1F1C17;
28
+ --bazaar-color-brand-primary-800: #161310;
29
+ --bazaar-color-brand-primary-900: #0E0B09;
30
+
31
+ /* ============================================
32
+ SECONDARY — TERRACOTTA / CLAY
33
+ Reserved for accent, promo strips, sale badges, progress fills.
34
+ Not the default button color — commerce prefers ink for CTAs.
35
+ ============================================ */
36
+ --bazaar-color-brand-secondary-50: #FBEEE4;
37
+ --bazaar-color-brand-secondary-100: #F6D9C5;
38
+ --bazaar-color-brand-secondary-200: #ECB690;
39
+ --bazaar-color-brand-secondary-300: #DF9662;
40
+ --bazaar-color-brand-secondary-400: #C96C3E;
41
+ --bazaar-color-brand-secondary-500: #AB5428;
42
+ --bazaar-color-brand-secondary-600: #873F1C;
43
+ --bazaar-color-brand-secondary-700: #662E13;
44
+ --bazaar-color-brand-secondary-800: #4A2110;
45
+ --bazaar-color-brand-secondary-900: #2E160A;
46
+
47
+ /* ============================================
48
+ SUPPORT ACCENT — SAGE
49
+ Success / in-stock / eco. Aliased as "teal" for API parity.
50
+ ============================================ */
51
+ --bazaar-color-accent-mint-50: #EAF1EA;
52
+ --bazaar-color-accent-mint-100: #D1DFD3;
53
+ --bazaar-color-accent-mint-200: #A8C1AC;
54
+ --bazaar-color-accent-mint-300: #7BA181;
55
+ --bazaar-color-accent-mint-400: #4A7C59;
56
+ --bazaar-color-accent-mint-500: #3A6547;
57
+ --bazaar-color-accent-mint-600: #2E5237;
58
+ --bazaar-color-accent-mint-700: #22402A;
59
+
60
+ --bazaar-color-accent-teal-50: #EAF1EA;
61
+ --bazaar-color-accent-teal-100: #D1DFD3;
62
+ --bazaar-color-accent-teal-200: #A8C1AC;
63
+ --bazaar-color-accent-teal-300: #7BA181;
64
+ --bazaar-color-accent-teal-400: #4A7C59;
65
+ --bazaar-color-accent-teal-500: #3A6547;
66
+ --bazaar-color-accent-teal-600: #2E5237;
67
+ --bazaar-color-accent-teal-700: #22402A;
68
+
69
+ /* ============================================
70
+ REWARD ACCENT — WARM AMBER
71
+ Loyalty, rewards, gold-tier highlights.
72
+ ============================================ */
73
+ --bazaar-color-accent-amber-50: #FBF2DF;
74
+ --bazaar-color-accent-amber-100: #F5E1B6;
75
+ --bazaar-color-accent-amber-200: #EAC079;
76
+ --bazaar-color-accent-amber-300: #D9A046;
77
+ --bazaar-color-accent-amber-400: #B58235;
78
+ --bazaar-color-accent-amber-500: #8C6324;
79
+ --bazaar-color-accent-amber-600: #6C4B1A;
80
+ --bazaar-color-accent-amber-700: #513712;
81
+
82
+ /* ============================================
83
+ NEUTRAL PALETTE — Oat / Ecru / Ink
84
+ Warm undertone throughout — avoids the cool blue cast of
85
+ cloud/slate neutrals that reads as "dashboard" rather than
86
+ "shop."
87
+ ============================================ */
88
+ --bazaar-color-neutral-0: #FFFFFF;
89
+ --bazaar-color-neutral-25: #FBF9F4;
90
+ --bazaar-color-neutral-50: #F4F2EC;
91
+ --bazaar-color-neutral-100: #ECE7DC;
92
+ --bazaar-color-neutral-200: #D9D2C1;
93
+ --bazaar-color-neutral-300: #B8AE97;
94
+ --bazaar-color-neutral-400: #8A816B;
95
+ --bazaar-color-neutral-500: #5E5749;
96
+ --bazaar-color-neutral-600: #433D32;
97
+ --bazaar-color-neutral-700: #2E2A23;
98
+ --bazaar-color-neutral-800: #1F1C17;
99
+ --bazaar-color-neutral-900: #131110;
100
+
101
+ /* ============================================
102
+ SEMANTIC PALETTE
103
+ Warm interpretations of each status tone so callouts don't
104
+ clash with the editorial neutrals.
105
+ ============================================ */
106
+ --bazaar-color-success-50: #EAF1EA;
107
+ --bazaar-color-success-500: #4A7C59;
108
+ --bazaar-color-success-700: #2E5237;
109
+
110
+ --bazaar-color-warning-50: #FBF2DF;
111
+ --bazaar-color-warning-500: #B58235;
112
+ --bazaar-color-warning-700: #6C4B1A;
113
+
114
+ --bazaar-color-error-50: #F9E8E4;
115
+ --bazaar-color-error-500: #B04848;
116
+ --bazaar-color-error-700: #7D2E2E;
117
+
118
+ --bazaar-color-info-50: #F4F2EC;
119
+ --bazaar-color-info-500: #433D32;
120
+ --bazaar-color-info-700: #1F1C17;
121
+
122
+ /* Status aliases — referenced by commerce components. */
123
+ --bazaar-color-status-success: #4A7C59;
124
+ --bazaar-color-status-warning: #B58235;
125
+ --bazaar-color-status-danger: #B04848;
126
+
127
+ /* ============================================
128
+ TEXT & SURFACE ALIASES
129
+ ============================================ */
130
+ --bazaar-color-text-primary: #1F1C17;
131
+ --bazaar-color-text-secondary: #433D32;
132
+ --bazaar-color-text-muted: #8A816B;
133
+ --bazaar-color-text-inverse: #FBF9F4;
134
+ --bazaar-color-text-brand: #C96C3E;
135
+
136
+ --bazaar-color-surface-canvas: #FBF9F4;
137
+ --bazaar-color-surface-default: #FFFFFF;
138
+ --bazaar-color-surface-subtle: #F4F2EC;
139
+ --bazaar-color-surface-raised: #FFFFFF;
140
+ --bazaar-color-surface-overlay: #FFFFFF;
141
+ --bazaar-color-surface-sunken: #ECE7DC;
142
+ --bazaar-color-surface-hover: #F4F2EC;
143
+ --bazaar-color-surface-active: #ECE7DC;
144
+ --bazaar-color-surface-selected: #F4F2EC;
145
+ --bazaar-color-surface-selected-hover: #ECE7DC;
146
+ --bazaar-color-surface-spotlight: #FBEEE4;
147
+
148
+ --bazaar-color-border-default: #D9D2C1;
149
+ --bazaar-color-border-strong: #B8AE97;
150
+ --bazaar-color-border-subtle: rgba(31, 28, 23, 0.08);
151
+ --bazaar-color-border-inverse: #2E2A23;
152
+ --bazaar-color-border-brand: #1F1C17;
153
+ --bazaar-color-border-success: #4A7C59;
154
+ --bazaar-color-border-warning: #B58235;
155
+ --bazaar-color-border-error: #B04848;
156
+
157
+ /* Accent alias — used across commerce components for focus
158
+ rings, progress fills, and small highlights. */
159
+ --bazaar-color-accent: #C96C3E;
160
+ --bazaar-color-accent-soft: #FBEEE4;
161
+
162
+ /* Commerce-specific aliases — sale, surface-muted. Sale renders on
163
+ warm-neutral surfaces; we use the deepest terracotta so it
164
+ registers as "urgent" without shouting. */
165
+ --bazaar-color-sale: #873F1C;
166
+ --bazaar-color-surface-muted: #D9D2C1;
167
+
168
+ --bazaar-color-focus-ring: #C96C3E;
169
+ --bazaar-color-overlay-scrim: rgba(31, 28, 23, 0.52);
170
+
171
+ /* Warm glow used behind spotlight tiles and seasonal promos. */
172
+ --bazaar-color-glow-soft: rgba(201, 108, 62, 0.12);
173
+ --bazaar-color-glow-medium: rgba(201, 108, 62, 0.22);
174
+
175
+ /* ============================================
176
+ TYPOGRAPHY
177
+ Inter for body + labels. Fraunces (variable serif) for
178
+ editorial display headlines — hero, campaign, product name.
179
+ ============================================ */
180
+ --bazaar-font-family-sans: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
181
+ --bazaar-font-family-display: "Fraunces", "Inter", system-ui, serif;
182
+ --bazaar-font-family-mono: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;
183
+
184
+ --bazaar-font-weight-regular: 400;
185
+ --bazaar-font-weight-medium: 500;
186
+ --bazaar-font-weight-semibold: 600;
187
+ --bazaar-font-weight-bold: 700;
188
+
189
+ /* Type scale — sizes */
190
+ --bazaar-font-size-display-lg: 48px;
191
+ --bazaar-font-size-display-md: 36px;
192
+ --bazaar-font-size-heading-xl: 28px;
193
+ --bazaar-font-size-heading-lg: 24px;
194
+ --bazaar-font-size-heading-md: 20px;
195
+ --bazaar-font-size-heading-sm: 18px;
196
+ --bazaar-font-size-body-lg: 16px;
197
+ --bazaar-font-size-body-md: 14px;
198
+ --bazaar-font-size-body-sm: 13px;
199
+ --bazaar-font-size-label-lg: 14px;
200
+ --bazaar-font-size-label-md: 13px;
201
+ --bazaar-font-size-caption: 12px;
202
+ --bazaar-font-size-data: 14px;
203
+ --bazaar-font-size-code: 13px;
204
+
205
+ /* Type scale — line heights (editorial is slightly airier) */
206
+ --bazaar-line-height-display-lg: 56px;
207
+ --bazaar-line-height-display-md: 44px;
208
+ --bazaar-line-height-heading-xl: 36px;
209
+ --bazaar-line-height-heading-lg: 32px;
210
+ --bazaar-line-height-heading-md: 28px;
211
+ --bazaar-line-height-heading-sm: 26px;
212
+ --bazaar-line-height-body-lg: 26px;
213
+ --bazaar-line-height-body-md: 22px;
214
+ --bazaar-line-height-body-sm: 20px;
215
+ --bazaar-line-height-label-lg: 20px;
216
+ --bazaar-line-height-label-md: 18px;
217
+ --bazaar-line-height-caption: 16px;
218
+ --bazaar-line-height-data: 20px;
219
+ --bazaar-line-height-code: 18px;
220
+
221
+ /* Letter spacing — editorial display prefers a touch tighter. */
222
+ --bazaar-tracking-tight: -0.02em;
223
+ --bazaar-tracking-normal: 0em;
224
+ --bazaar-tracking-wide: 0.08em;
225
+
226
+ /* ============================================
227
+ SPACING
228
+ ============================================ */
229
+ --bazaar-space-0: 0;
230
+ --bazaar-space-1: 4px;
231
+ --bazaar-space-2: 8px;
232
+ --bazaar-space-3: 12px;
233
+ --bazaar-space-4: 16px;
234
+ --bazaar-space-5: 20px;
235
+ --bazaar-space-6: 24px;
236
+ --bazaar-space-8: 32px;
237
+ --bazaar-space-10: 40px;
238
+ --bazaar-space-12: 48px;
239
+ --bazaar-space-16: 64px;
240
+ --bazaar-space-20: 80px;
241
+
242
+ /* ============================================
243
+ SIZING
244
+ ============================================ */
245
+ --bazaar-size-control-sm: 32px;
246
+ --bazaar-size-control-md: 40px;
247
+ --bazaar-size-control-lg: 48px;
248
+
249
+ --bazaar-size-icon-xs: 12px;
250
+ --bazaar-size-icon-sm: 16px;
251
+ --bazaar-size-icon-md: 20px;
252
+ --bazaar-size-icon-lg: 24px;
253
+
254
+ --bazaar-size-touch-min: 44px;
255
+
256
+ --bazaar-size-sidebar-default: 280px;
257
+ --bazaar-size-modal-sm: 400px;
258
+ --bazaar-size-modal-md: 560px;
259
+ --bazaar-size-modal-lg: 720px;
260
+ --bazaar-size-modal-xl: 880px;
261
+
262
+ /* ============================================
263
+ RADIUS
264
+ Commerce prefers slightly sharper corners than the Beacon
265
+ source — less "dashboard", more "magazine."
266
+ ============================================ */
267
+ --bazaar-radius-none: 0;
268
+ --bazaar-radius-sm: 4px;
269
+ --bazaar-radius-md: 8px;
270
+ --bazaar-radius-lg: 12px;
271
+ --bazaar-radius-xl: 16px;
272
+ --bazaar-radius-full: 9999px;
273
+
274
+ /* ============================================
275
+ BORDERS
276
+ ============================================ */
277
+ --bazaar-border-width-none: 0;
278
+ --bazaar-border-width-hairline: 1px;
279
+ --bazaar-border-width-medium: 2px;
280
+ --bazaar-border-width-strong: 3px;
281
+ --bazaar-border-style-default: solid;
282
+
283
+ /* ============================================
284
+ SHADOWS & ELEVATION
285
+ Shadow RGBA uses the warm-ink base so elevation reads as
286
+ natural shadow rather than cold slate.
287
+ ============================================ */
288
+ --bazaar-shadow-none: none;
289
+ --bazaar-shadow-xs: 0 1px 2px rgba(31, 28, 23, 0.04);
290
+ --bazaar-shadow-sm: 0 1px 2px rgba(31, 28, 23, 0.06), 0 2px 8px rgba(31, 28, 23, 0.04);
291
+ --bazaar-shadow-md: 0 2px 4px rgba(31, 28, 23, 0.05), 0 10px 24px rgba(31, 28, 23, 0.08);
292
+ --bazaar-shadow-lg: 0 4px 8px rgba(31, 28, 23, 0.06), 0 20px 44px rgba(31, 28, 23, 0.12);
293
+ --bazaar-shadow-xl: 0 8px 16px rgba(31, 28, 23, 0.07), 0 28px 60px rgba(31, 28, 23, 0.16);
294
+ --bazaar-shadow-glow: 0 0 0 1px rgba(201, 108, 62, 0.18), 0 8px 24px rgba(201, 108, 62, 0.18);
295
+ --bazaar-shadow-focus: 0 0 0 3px rgba(201, 108, 62, 0.28);
296
+ --bazaar-shadow-focus-error: 0 0 0 3px rgba(176, 72, 72, 0.24);
297
+ --bazaar-shadow-focus-success: 0 0 0 3px rgba(74, 124, 89, 0.22);
298
+ --bazaar-shadow-inset-xs: inset 0 1px 2px rgba(31, 28, 23, 0.06);
299
+ --bazaar-shadow-inset-sm: inset 0 2px 4px rgba(31, 28, 23, 0.08);
300
+
301
+ /* ============================================
302
+ MOTION
303
+ ============================================ */
304
+ --bazaar-motion-duration-fast: 120ms;
305
+ --bazaar-motion-duration-base: 180ms;
306
+ --bazaar-motion-duration-slow: 240ms;
307
+ --bazaar-motion-easing-standard: cubic-bezier(0.2, 0, 0, 1);
308
+ --bazaar-motion-easing-emphasized: cubic-bezier(0.2, 0, 0, 1);
309
+ --bazaar-motion-easing-exit: cubic-bezier(0.4, 0, 1, 1);
310
+
311
+ /* ============================================
312
+ OPACITY
313
+ ============================================ */
314
+ --bazaar-opacity-disabled: 0.48;
315
+ --bazaar-opacity-subtle: 0.72;
316
+ --bazaar-opacity-overlay: 0.48;
317
+ --bazaar-opacity-scrim-strong: 0.64;
318
+
319
+ /* ============================================
320
+ Z-INDEX
321
+ ============================================ */
322
+ --bazaar-z-base: 0;
323
+ --bazaar-z-dropdown: 1000;
324
+ --bazaar-z-sticky: 1100;
325
+ --bazaar-z-banner: 1200;
326
+ --bazaar-z-overlay: 1300;
327
+ --bazaar-z-modal: 1400;
328
+ --bazaar-z-toast: 1500;
329
+ --bazaar-z-tooltip: 1600;
330
+
331
+ /* ============================================
332
+ GRID & LAYOUT
333
+ ============================================ */
334
+ --bazaar-layout-container-max: 1400px;
335
+ --bazaar-layout-container-reading: 720px;
336
+ --bazaar-layout-grid-columns: 12;
337
+ --bazaar-layout-grid-gutter: 24px;
338
+ --bazaar-layout-grid-margin-desktop: 32px;
339
+ --bazaar-layout-grid-margin-tablet: 24px;
340
+ --bazaar-layout-grid-margin-mobile: 16px;
341
+
342
+ /* ============================================
343
+ FOCUS & INTERACTION
344
+ ============================================ */
345
+ --bazaar-focus-ring-width: 2px;
346
+ --bazaar-focus-ring-color: rgba(201, 108, 62, 0.32);
347
+ --bazaar-focus-ring-offset: 2px;
348
+ --bazaar-focus-outline-color: #C96C3E;
349
+
350
+ /* ============================================
351
+ ICONOGRAPHY
352
+ ============================================ */
353
+ --bazaar-icon-stroke-default: 1.5;
354
+ --bazaar-icon-size-default: 20px;
355
+
356
+ /* ============================================
357
+ INTERACTIVE STATES
358
+ ============================================ */
359
+ --bazaar-state-hover-overlay: rgba(31, 28, 23, 0.04);
360
+ --bazaar-state-active-overlay: rgba(31, 28, 23, 0.08);
361
+ --bazaar-state-selected-bg: #F4F2EC;
362
+ --bazaar-state-selected-border: #B8AE97;
363
+ --bazaar-state-drag-bg: #F4F2EC;
364
+
365
+ /* ============================================
366
+ DATA VISUALIZATION
367
+ Warm, considered palette for charts in account/admin views.
368
+ ============================================ */
369
+ --bazaar-data-vis-1: #1F1C17;
370
+ --bazaar-data-vis-2: #C96C3E;
371
+ --bazaar-data-vis-3: #4A7C59;
372
+ --bazaar-data-vis-4: #B58235;
373
+ --bazaar-data-vis-5: #8A816B;
374
+ --bazaar-data-vis-gridline: #ECE7DC;
375
+ --bazaar-data-vis-axis: #8A816B;
376
+
377
+ /* ============================================
378
+ PROGRESS & ACHIEVEMENT
379
+ ============================================ */
380
+ --bazaar-progress-track: #ECE7DC;
381
+ --bazaar-progress-fill-default: #1F1C17;
382
+ --bazaar-progress-fill-success: #4A7C59;
383
+ --bazaar-progress-fill-reward: #C96C3E;
384
+ --bazaar-progress-fill-gradient: linear-gradient(90deg, #C96C3E 0%, #1F1C17 100%);
385
+ --bazaar-achievement-glow: 0 0 0 4px rgba(201, 108, 62, 0.18);
386
+ --bazaar-milestone-marker: #C96C3E;
387
+ }
388
+
389
+ /* ============================================
390
+ REDUCED MOTION
391
+ ============================================ */
392
+ @media (prefers-reduced-motion: reduce) {
393
+ :root {
394
+ --bazaar-motion-duration-fast: 0ms;
395
+ --bazaar-motion-duration-base: 0ms;
396
+ --bazaar-motion-duration-slow: 0ms;
397
+ }
398
+ }
399
+
400
+ /* ============================================
401
+ GLOBAL RESET & BASE STYLES
402
+ ============================================ */
403
+ *,
404
+ *::before,
405
+ *::after {
406
+ box-sizing: border-box;
407
+ }
408
+
409
+ body {
410
+ margin: 0;
411
+ font-family: var(--bazaar-font-family-sans);
412
+ font-size: var(--bazaar-font-size-body-lg);
413
+ line-height: var(--bazaar-line-height-body-lg);
414
+ color: var(--bazaar-color-text-primary);
415
+ background-color: var(--bazaar-color-surface-canvas);
416
+ -webkit-font-smoothing: antialiased;
417
+ -moz-osx-font-smoothing: grayscale;
418
+ }
419
+
420
+ /* Display families are applied explicitly by components that want
421
+ the serif voice — we don't paint every heading globally. */
422
+
423
+ :focus-visible {
424
+ outline: var(--bazaar-border-width-medium) solid var(--bazaar-focus-outline-color);
425
+ outline-offset: var(--bazaar-focus-ring-offset);
426
+ box-shadow: var(--bazaar-shadow-focus);
427
+ }