@snowcone-app/ui 0.1.43 → 0.2.1

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.
Files changed (196) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +18 -4
  3. package/dist/index.cjs +5 -2
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js +5 -2
  6. package/dist/index.js.map +1 -1
  7. package/package.json +9 -5
  8. package/src/components/CanvasIsolationBoundary.tsx +202 -0
  9. package/src/components/LoadingOverlayPrism.tsx +251 -0
  10. package/src/composed/AddToCart.tsx +229 -0
  11. package/src/composed/ArtAlignment.tsx +703 -0
  12. package/src/composed/ArtSelector.tsx +290 -0
  13. package/src/composed/ArtworkCustomizer.tsx +212 -0
  14. package/src/composed/CanvasEditor.tsx +79 -0
  15. package/src/composed/ColorPicker.tsx +111 -0
  16. package/src/composed/CurrentSelectionDisplay.tsx +86 -0
  17. package/src/composed/HeroProductImage.tsx +1079 -0
  18. package/src/composed/Lightbox.index.ts +2 -0
  19. package/src/composed/Lightbox.tsx +230 -0
  20. package/src/composed/PlacementClipShapeSelector.tsx +88 -0
  21. package/src/composed/PlacementTabs.tsx +179 -0
  22. package/src/composed/ProductCard.tsx +298 -0
  23. package/src/composed/ProductGallery.tsx +54 -0
  24. package/src/composed/ProductImage.tsx +129 -0
  25. package/src/composed/ProductList.tsx +147 -0
  26. package/src/composed/ProductOptions.tsx +305 -0
  27. package/src/composed/RealtimeMockup.tsx +121 -0
  28. package/src/composed/TileCount.tsx +348 -0
  29. package/src/composed/carousels/HeroCarousel.tsx +240 -0
  30. package/src/composed/carousels/MobileProductCarousel.tsx +1002 -0
  31. package/src/composed/carousels/index.ts +11 -0
  32. package/src/composed/carousels/types.ts +58 -0
  33. package/src/composed/grids/MasonryGrid.tsx +238 -0
  34. package/src/composed/grids/index.ts +9 -0
  35. package/src/composed/search/CurrentRefinements.tsx +80 -0
  36. package/src/composed/search/Filters.tsx +49 -0
  37. package/src/composed/search/FiltersButton.tsx +57 -0
  38. package/src/composed/search/FiltersDrawer.tsx +375 -0
  39. package/src/composed/search/ProductGrid.tsx +118 -0
  40. package/src/composed/search/ProductHit.tsx +56 -0
  41. package/src/composed/search/SearchBox.tsx +109 -0
  42. package/src/composed/search/SearchProvider.tsx +136 -0
  43. package/src/composed/search/facetConfig.ts +16 -0
  44. package/src/composed/search/index.ts +22 -0
  45. package/src/composed/search/meilisearchAdapter.ts +20 -0
  46. package/src/composed/search/types.ts +22 -0
  47. package/src/composed/zoom/EnhancedImageViewer.tsx +505 -0
  48. package/src/composed/zoom/ResponsiveZoom.tsx +134 -0
  49. package/src/composed/zoom/ZoomOverlay.tsx +194 -0
  50. package/src/composed/zoom/index.ts +12 -0
  51. package/src/composed/zoom/types.ts +12 -0
  52. package/src/design-system/ColorPalette.tsx +126 -0
  53. package/src/design-system/ColorSwatch.tsx +49 -0
  54. package/src/design-system/DesignSystemPage.tsx +130 -0
  55. package/src/design-system/ThemeSwitcher.tsx +181 -0
  56. package/src/design-system/TypographyScale.tsx +106 -0
  57. package/src/design-system/index.ts +5 -0
  58. package/src/ecommerce/stories/HeroProductImage.stories.tsx +66 -0
  59. package/src/ecommerce/stories/PDPHeroGallery.stories.tsx +105 -0
  60. package/src/ecommerce/stories/PDPInfoPanel.stories.tsx +472 -0
  61. package/src/ecommerce/stories/PDPLayout.stories.tsx +365 -0
  62. package/src/hooks/useBrand.ts +41 -0
  63. package/src/hooks/useCanvasContext.ts +127 -0
  64. package/src/hooks/useDeviceDetection.ts +64 -0
  65. package/src/hooks/useFocusTrap.ts +70 -0
  66. package/src/hooks/useImagePreloader.ts +268 -0
  67. package/src/hooks/useImageTransition.ts +608 -0
  68. package/src/hooks/usePlacementsProcessor.ts +74 -0
  69. package/src/hooks/useProductGallery.ts +193 -0
  70. package/src/hooks/useProductPage.ts +467 -0
  71. package/src/hooks/useRenderGuard.ts +96 -0
  72. package/src/hooks/useScrollDirection.ts +196 -0
  73. package/src/hooks/viewport/index.ts +25 -0
  74. package/src/hooks/viewport/useContainerWidth.ts +59 -0
  75. package/src/hooks/viewport/useMediaQuery.ts +52 -0
  76. package/src/hooks/viewport/useResponsiveImageCap.ts +149 -0
  77. package/src/hooks/viewport/useViewportDimensions.ts +135 -0
  78. package/src/hooks/viewport/useWideMonitorMode.ts +150 -0
  79. package/src/hooks/visibility/index.ts +15 -0
  80. package/src/hooks/visibility/observerPool.ts +150 -0
  81. package/src/index.ts +240 -0
  82. package/src/layouts/hero-zoom/HeroShrinkLayout.tsx +209 -0
  83. package/src/layouts/hero-zoom/HeroZoomLayout.tsx +351 -0
  84. package/src/layouts/hero-zoom/index.ts +30 -0
  85. package/src/layouts/hero-zoom/stories/HeroZoomLayout.stories.tsx +350 -0
  86. package/src/layouts/hero-zoom/types.ts +113 -0
  87. package/src/layouts/hero-zoom/useHeroZoomScales.ts +156 -0
  88. package/src/layouts/index.ts +9 -0
  89. package/src/layouts/pdp/EdgeBlurBox.tsx +210 -0
  90. package/src/layouts/pdp/ImageBlurExtension.tsx +215 -0
  91. package/src/layouts/pdp/ImageEdgeBlur.tsx +215 -0
  92. package/src/layouts/pdp/PDPLayout.tsx +246 -0
  93. package/src/layouts/pdp/SimpleImageBlur.tsx +140 -0
  94. package/src/layouts/pdp/index.ts +40 -0
  95. package/src/lib/env.ts +15 -0
  96. package/src/lib/locale.ts +167 -0
  97. package/src/lib/router.tsx +46 -0
  98. package/src/lib/utils.ts +6 -0
  99. package/src/lightbox/README.md +77 -0
  100. package/src/next/index.tsx +26 -0
  101. package/src/patterns/MockupPriorityProvider.tsx +1014 -0
  102. package/src/patterns/Product.tsx +850 -0
  103. package/src/patterns/ProductPageProvider.tsx +224 -0
  104. package/src/patterns/RealtimeProvider.tsx +1162 -0
  105. package/src/patterns/ShopProvider.tsx +603 -0
  106. package/src/personalization/PersonalizationBridge.tsx +235 -0
  107. package/src/personalization/PersonalizationContext.ts +29 -0
  108. package/src/personalization/PersonalizationInputs.tsx +110 -0
  109. package/src/personalization/PersonalizationProvider.tsx +407 -0
  110. package/src/personalization/canvas-stub.d.ts +22 -0
  111. package/src/personalization/index.ts +43 -0
  112. package/src/personalization/types.ts +48 -0
  113. package/src/personalization/usePersonalization.ts +32 -0
  114. package/src/personalization/usePersonalizationShimmer.ts +159 -0
  115. package/src/personalization/utils.ts +59 -0
  116. package/src/primitives/BrandLogo.tsx +65 -0
  117. package/src/primitives/BrandName.tsx +51 -0
  118. package/src/primitives/Button.tsx +123 -0
  119. package/src/primitives/ColorSwatch.tsx +221 -0
  120. package/src/primitives/DragHintAnimation.tsx +190 -0
  121. package/src/primitives/EdgeSwipeGuards.tsx +60 -0
  122. package/src/primitives/FloatingActionGroup.tsx +176 -0
  123. package/src/primitives/ProductPrice.tsx +171 -0
  124. package/src/primitives/ProgressiveBlur.tsx +295 -0
  125. package/src/primitives/ThemeToggle.tsx +125 -0
  126. package/src/primitives/__tests__/story-coverage.test.ts +98 -0
  127. package/src/primitives/accordion.tsx +280 -0
  128. package/src/primitives/badge.tsx +137 -0
  129. package/src/primitives/card.tsx +61 -0
  130. package/src/primitives/checkbox.tsx +56 -0
  131. package/src/primitives/collapsible.tsx +51 -0
  132. package/src/primitives/drawer.tsx +828 -0
  133. package/src/primitives/dropdown-menu.tsx +197 -0
  134. package/src/primitives/fieldset.tsx +73 -0
  135. package/src/primitives/index.ts +138 -0
  136. package/src/primitives/input.tsx +91 -0
  137. package/src/primitives/kbd.tsx +130 -0
  138. package/src/primitives/label.tsx +20 -0
  139. package/src/primitives/link.tsx +182 -0
  140. package/src/primitives/popover.tsx +80 -0
  141. package/src/primitives/radio-group.tsx +79 -0
  142. package/src/primitives/scroll-fade.tsx +159 -0
  143. package/src/primitives/select.tsx +170 -0
  144. package/src/primitives/separator.tsx +25 -0
  145. package/src/primitives/slider.tsx +221 -0
  146. package/src/primitives/spinner.tsx +72 -0
  147. package/src/primitives/stories/Accordion.stories.tsx +121 -0
  148. package/src/primitives/stories/Badge.stories.tsx +221 -0
  149. package/src/primitives/stories/Button.stories.tsx +185 -0
  150. package/src/primitives/stories/Card.stories.tsx +171 -0
  151. package/src/primitives/stories/Checkbox.stories.tsx +214 -0
  152. package/src/primitives/stories/Collapsible.stories.tsx +230 -0
  153. package/src/primitives/stories/Drawer.stories.tsx +378 -0
  154. package/src/primitives/stories/DropdownMenu.stories.tsx +182 -0
  155. package/src/primitives/stories/Fieldset.stories.tsx +212 -0
  156. package/src/primitives/stories/Input.stories.tsx +172 -0
  157. package/src/primitives/stories/Kbd.stories.tsx +183 -0
  158. package/src/primitives/stories/Label.stories.tsx +98 -0
  159. package/src/primitives/stories/Link.stories.tsx +260 -0
  160. package/src/primitives/stories/Popover.stories.tsx +178 -0
  161. package/src/primitives/stories/RadioGroup.stories.tsx +205 -0
  162. package/src/primitives/stories/Select.stories.tsx +222 -0
  163. package/src/primitives/stories/Separator.stories.tsx +134 -0
  164. package/src/primitives/stories/Slider.stories.tsx +203 -0
  165. package/src/primitives/stories/Spinner.stories.tsx +142 -0
  166. package/src/primitives/stories/Surface.stories.tsx +257 -0
  167. package/src/primitives/stories/Switch.stories.tsx +131 -0
  168. package/src/primitives/stories/Tabs.stories.tsx +275 -0
  169. package/src/primitives/stories/TextField.stories.tsx +139 -0
  170. package/src/primitives/stories/Textarea.stories.tsx +148 -0
  171. package/src/primitives/stories/Tooltip.stories.tsx +119 -0
  172. package/src/primitives/surface.tsx +86 -0
  173. package/src/primitives/switch.tsx +35 -0
  174. package/src/primitives/tabs.tsx +206 -0
  175. package/src/primitives/text-field.tsx +84 -0
  176. package/src/primitives/textarea.tsx +50 -0
  177. package/src/primitives/tooltip.tsx +58 -0
  178. package/src/services/CanvasExportService.ts +518 -0
  179. package/src/styles/base.css +380 -0
  180. package/src/styles/defaults.css +280 -0
  181. package/src/styles/globals.css +1242 -0
  182. package/src/styles/index.css +17 -0
  183. package/src/styles/ne-themes.css +4740 -0
  184. package/src/styles/tailwind.css +11 -0
  185. package/src/styles/tokens.css +117 -0
  186. package/src/styles/utilities.css +188 -0
  187. package/src/themes/apply-theme.ts +449 -0
  188. package/src/themes/getThemeStyles.ts +454 -0
  189. package/src/themes/index.ts +48 -0
  190. package/src/themes/oklch-theme.ts +283 -0
  191. package/src/themes/presets.ts +989 -0
  192. package/src/themes/types.ts +386 -0
  193. package/src/themes/useTheme.tsx +450 -0
  194. package/src/utils/dev-warnings.ts +161 -0
  195. package/src/utils/devWarnings.ts +153 -0
  196. package/dist/styles.css +0 -1
@@ -0,0 +1,380 @@
1
+ /* =============================================================================
2
+ * base.css — Shared Base Styles for Snowcone Apps
3
+ *
4
+ * This file contains the semantic font system, link styles, code formatting,
5
+ * list styles, and utility classes shared across all apps. Import it from
6
+ * your app's globals.css:
7
+ *
8
+ * @import "@merch/ui/styles/base.css";
9
+ * (or relative path: ../../../packages/ui/src/styles/base.css)
10
+ *
11
+ * CASCADE STRATEGY:
12
+ * All rules live inside @layer base. In Tailwind v4, the cascade order is:
13
+ * @layer theme < @layer base < @layer components < @layer utilities
14
+ *
15
+ * This means Tailwind utility classes (text-white, font-normal, etc.) will
16
+ * always override these defaults. This is the correct behavior — base.css
17
+ * provides sensible defaults, utilities provide explicit overrides.
18
+ *
19
+ * Rules that use !important (code fonts, fixed radius) still win because
20
+ * !important in @layer base beats normal declarations in @layer utilities.
21
+ * ============================================================================= */
22
+
23
+ @layer base {
24
+
25
+ /* =============================================================================
26
+ * Body Defaults
27
+ * ============================================================================= */
28
+
29
+ body {
30
+ margin: 0;
31
+ background-color: var(--color-background);
32
+ color: var(--color-foreground);
33
+ font-family: var(--font-body, ui-sans-serif, system-ui, sans-serif);
34
+ font-weight: var(--font-weight-body, 400);
35
+ -webkit-font-smoothing: antialiased;
36
+ -moz-osx-font-smoothing: grayscale;
37
+ }
38
+
39
+ /* =============================================================================
40
+ * Semantic Font System
41
+ *
42
+ * Font roles and their CSS variables:
43
+ * - --font-heading: h1-h6, card titles, section headers
44
+ * - --font-body: paragraphs, default text
45
+ * - --font-label: form labels, field names
46
+ * - --font-button: button text, CTAs
47
+ * - --font-caption: small text, descriptions, helper text
48
+ * - --font-display: hero text, prices, prominent numbers
49
+ * - --font-accent: emphasis, blockquotes, pullquotes
50
+ *
51
+ * Weight variables:
52
+ * - --font-weight-body (400)
53
+ * - --font-weight-heading (600)
54
+ * - --font-weight-button (500)
55
+ * - --font-weight-label (500)
56
+ * - --font-weight-caption (400)
57
+ * - --font-weight-display (700)
58
+ * ============================================================================= */
59
+
60
+ /* Apply body font to all elements except code */
61
+ *:not(code):not(pre) {
62
+ font-family: var(--font-body, inherit);
63
+ }
64
+
65
+ /* Headings use --font-heading */
66
+ h1,
67
+ h2,
68
+ h3,
69
+ h4,
70
+ h5,
71
+ h6 {
72
+ font-family: var(--font-heading, var(--font-body));
73
+ font-weight: var(--font-weight-heading, 600);
74
+ color: var(--color-heading, var(--color-foreground));
75
+ }
76
+
77
+ /* Large text sizes also use heading font */
78
+ .text-xl,
79
+ .text-2xl,
80
+ .text-3xl,
81
+ .text-4xl,
82
+ .font-bold,
83
+ .font-extrabold {
84
+ font-family: var(--font-heading, var(--font-body));
85
+ font-weight: var(--font-weight-heading, 600);
86
+ }
87
+
88
+ .font-semibold {
89
+ font-family: var(--font-heading, var(--font-body));
90
+ font-weight: var(--font-weight-heading, 600);
91
+ }
92
+
93
+ /* Buttons use --font-button + pointer cursor
94
+ * Tailwind v4 preflight resets cursor to 'default' on buttons.
95
+ * Restore pointer for all interactive button-like elements. */
96
+ button:not(code):not(pre),
97
+ .btn:not(code):not(pre),
98
+ .button:not(code):not(pre),
99
+ [role="button"]:not(code):not(pre),
100
+ .font-button {
101
+ font-family: var(--font-button);
102
+ font-weight: var(--font-weight-button, 500);
103
+ cursor: pointer;
104
+ }
105
+
106
+ /* Option buttons should maintain body font for options */
107
+ button[role="radio"],
108
+ .floating-action-button {
109
+ font-family: var(--font-body, inherit);
110
+ }
111
+
112
+ /* Labels use --font-label */
113
+ label,
114
+ .label,
115
+ .font-label {
116
+ font-family: var(--font-label, var(--font-body));
117
+ font-weight: var(--font-weight-label, 500);
118
+ }
119
+
120
+ /* Legend (fieldset captions) use heading font for hierarchy */
121
+ legend {
122
+ font-family: var(--font-heading, var(--font-body));
123
+ font-weight: var(--font-weight-heading, 600);
124
+ }
125
+
126
+ /* Icons use theme stroke width — !important needed to override inline SVG attributes */
127
+ svg,
128
+ .icon,
129
+ [data-lucide] {
130
+ stroke-width: var(--theme-icon-stroke-width, 1.5) !important;
131
+ }
132
+
133
+ /* =============================================================================
134
+ * Semantic Font Utility Classes
135
+ *
136
+ * Use these classes to apply specific font roles to elements:
137
+ * - .font-heading: Apply heading font
138
+ * - .font-body: Apply body font
139
+ * - .font-label: Apply label font (defined above with label selector)
140
+ * - .font-button: Apply button font (defined above with button selector)
141
+ * - .font-caption: Apply caption font
142
+ * - .font-display: Apply display font
143
+ * - .font-accent: Apply accent font
144
+ * ============================================================================= */
145
+
146
+ .font-body {
147
+ font-family: var(--font-body, ui-sans-serif, system-ui, sans-serif);
148
+ font-weight: var(--font-weight-body, 400);
149
+ }
150
+
151
+ .font-heading {
152
+ font-family: var(--font-heading, var(--font-body));
153
+ font-weight: var(--font-weight-heading, 600);
154
+ }
155
+
156
+ .font-caption {
157
+ font-family: var(--font-caption, var(--font-body));
158
+ font-weight: var(--font-weight-caption, 400);
159
+ }
160
+
161
+ .font-display {
162
+ font-family: var(--font-display, var(--font-heading));
163
+ font-weight: var(--font-weight-display, 700);
164
+ }
165
+
166
+ .font-accent {
167
+ font-family: var(--font-accent, var(--font-heading));
168
+ }
169
+
170
+ /* =============================================================================
171
+ * Link Styles — only in content areas (bare <a> tags without classes)
172
+ * ============================================================================= */
173
+
174
+ main a:not([class]),
175
+ article a:not([class]),
176
+ section a:not([class]),
177
+ .prose a {
178
+ color: var(--color-primary);
179
+ font-weight: 500;
180
+ text-decoration: underline;
181
+ text-decoration-color: color-mix(
182
+ in srgb,
183
+ var(--color-primary) 40%,
184
+ transparent
185
+ );
186
+ text-underline-offset: 4px;
187
+ transition: text-decoration-color 0.2s ease;
188
+ }
189
+
190
+ main a:not([class]):hover,
191
+ article a:not([class]):hover,
192
+ section a:not([class]):hover,
193
+ .prose a:hover {
194
+ text-decoration-color: var(--color-primary);
195
+ }
196
+
197
+ /* Code blocks and navigation shouldn't have link styling */
198
+ code a,
199
+ pre a,
200
+ nav a,
201
+ aside a,
202
+ header a {
203
+ text-decoration: none;
204
+ font-weight: inherit;
205
+ }
206
+
207
+ /* =============================================================================
208
+ * Code Styling
209
+ * ============================================================================= */
210
+
211
+ /* Inline code badges (not in pre blocks) */
212
+ :not(pre) > code {
213
+ font-family:
214
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
215
+ "Courier New", monospace !important;
216
+ font-size: 0.875em;
217
+ border-radius: 0.25rem;
218
+ line-height: 1;
219
+ white-space: nowrap;
220
+ }
221
+
222
+ /* Default styling for inline code */
223
+ :not(pre) > code:not(.prop-name):not(.type-badge):not(.required-badge) {
224
+ padding: 0.2em 0.4em;
225
+ background-color: var(--color-code-bg) !important;
226
+ color: var(--color-code-fg) !important;
227
+ font-weight: 400 !important;
228
+ }
229
+
230
+ /* Long code paths that need horizontal scrolling */
231
+ p > code,
232
+ div > code {
233
+ overflow-x: auto;
234
+ max-width: 100%;
235
+ display: inline-block;
236
+ vertical-align: middle;
237
+ }
238
+
239
+ /* Ensure code blocks use monospace font — !important needed to override theme fonts */
240
+ pre,
241
+ pre *,
242
+ pre code,
243
+ pre span,
244
+ pre .line,
245
+ .install-block,
246
+ .install-block * {
247
+ font-family:
248
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
249
+ "Courier New", monospace !important;
250
+ }
251
+
252
+ /* Code block line numbers */
253
+ .line {
254
+ display: inline-block;
255
+ }
256
+
257
+ .line::before {
258
+ content: attr(data-line);
259
+ display: inline-block;
260
+ width: 2rem;
261
+ margin-right: 1rem;
262
+ padding-left: 0.5rem;
263
+ text-align: right;
264
+ color: var(--color-muted-foreground);
265
+ opacity: 0.5;
266
+ user-select: none;
267
+ font-family:
268
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
269
+ "Courier New", monospace !important;
270
+ }
271
+
272
+ /* Prevent code blocks from overflowing on mobile */
273
+ pre.shiki {
274
+ max-width: 100%;
275
+ box-sizing: border-box;
276
+ }
277
+
278
+ /* =============================================================================
279
+ * Code Badge Styles
280
+ * !important needed to override inherited inline code styling
281
+ * ============================================================================= */
282
+
283
+ /* Prop name badges - bold monospace text, no background, accent color */
284
+ code.prop-name {
285
+ font-weight: 600 !important;
286
+ padding: 0 !important;
287
+ background: none !important;
288
+ vertical-align: baseline !important;
289
+ color: var(--color-primary) !important;
290
+ }
291
+
292
+ /* Type badges - compact padding matching reference */
293
+ code.type-badge {
294
+ padding: 0.125rem 0.375rem !important;
295
+ background-color: var(--color-code-bg) !important;
296
+ color: var(--color-code-fg) !important;
297
+ font-weight: 400 !important;
298
+ vertical-align: baseline !important;
299
+ position: relative;
300
+ top: -3px;
301
+ }
302
+
303
+ /* Required badges - compact padding matching reference, red color from Shiki theme */
304
+ code.required-badge {
305
+ padding: 0.125rem 0.375rem !important;
306
+ background-color: var(--color-code-bg) !important;
307
+ color: var(--color-code-error) !important;
308
+ font-weight: 400 !important;
309
+ vertical-align: baseline !important;
310
+ position: relative;
311
+ top: -3px;
312
+ }
313
+
314
+ /* =============================================================================
315
+ * Ordered List Styles
316
+ * ============================================================================= */
317
+
318
+ ol:not(.grid) {
319
+ list-style-position: outside;
320
+ padding-left: 1.5rem;
321
+ margin-top: 0.75rem;
322
+ margin-bottom: 0.75rem;
323
+ }
324
+
325
+ ol:not(.grid) li {
326
+ padding-left: 0.5rem;
327
+ margin-bottom: 0.75rem;
328
+ }
329
+
330
+ ol:not(.grid) li:last-child {
331
+ margin-bottom: 0;
332
+ }
333
+
334
+ /* =============================================================================
335
+ * text-on-primary Utility
336
+ *
337
+ * Dynamically calculated contrast color set by useTheme hook.
338
+ * Use for text on primary-colored backgrounds (buttons, badges, etc.)
339
+ * Example: <button className="bg-primary text-on-primary">Click me</button>
340
+ *
341
+ * !important needed to override any inherited color on primary backgrounds.
342
+ * ============================================================================= */
343
+ .text-on-primary {
344
+ color: var(--color-primary-foreground) !important;
345
+ }
346
+
347
+ /* =============================================================================
348
+ * View Transitions API (for MagicUI theme toggler animation)
349
+ * ============================================================================= */
350
+
351
+ ::view-transition-old(root),
352
+ ::view-transition-new(root) {
353
+ animation: none;
354
+ mix-blend-mode: normal;
355
+ }
356
+
357
+ /* =============================================================================
358
+ * Fixed Radius Utilities
359
+ *
360
+ * Use when an element MUST maintain a specific radius regardless of theme:
361
+ * - Heart/favorite buttons that should always be circular
362
+ * - Avatar placeholders that must stay round in brutalist themes
363
+ * - Any element where the shape is functional, not aesthetic
364
+ *
365
+ * !important is intentional — these explicitly override theme radius.
366
+ * ============================================================================= */
367
+ .rounded-fixed-full {
368
+ border-radius: 9999px !important;
369
+ }
370
+
371
+ .rounded-fixed-none {
372
+ border-radius: 0 !important;
373
+ }
374
+
375
+ .rounded-fixed-t-2xl {
376
+ border-top-left-radius: 1rem !important;
377
+ border-top-right-radius: 1rem !important;
378
+ }
379
+
380
+ } /* end @layer base */
@@ -0,0 +1,280 @@
1
+ /* =============================================================================
2
+ * defaults.css — Sensible Defaults for @snowcone-app/ui Components
3
+ *
4
+ * This file is the single source of truth for default design tokens used by
5
+ * any app consuming @snowcone-app/ui components. It provides a complete light theme
6
+ * on :root and a dark theme on .dark, using direct hex/pixel values with no
7
+ * external var() dependencies.
8
+ *
9
+ * HOW TO USE:
10
+ * Import this file early in your app's CSS, before component styles:
11
+ *
12
+ * @import "@merch/ui/styles/defaults.css";
13
+ *
14
+ * HOW TO OVERRIDE:
15
+ * Declare your own values on :root (or .dark) in a stylesheet that loads
16
+ * after this one. Any variable you set will take precedence:
17
+ *
18
+ * :root {
19
+ * --color-primary: #6366f1;
20
+ * --font-heading: "Custom Font", sans-serif;
21
+ * }
22
+ *
23
+ * You can also override per-component or per-section with a scoped class.
24
+ *
25
+ * DESIGN:
26
+ * - All color values are direct hex codes — no var() chains.
27
+ * - Typography and radius values are direct px/rem — no var() chains.
28
+ * - Legacy canvas aliases (--primary, --accent, etc.) reference the
29
+ * --color-* versions via var(), which is safe because both live in the
30
+ * same :root scope.
31
+ * ============================================================================= */
32
+
33
+ /* =============================================================================
34
+ * LIGHT THEME (default)
35
+ * ============================================================================= */
36
+
37
+ :root {
38
+ /* ---------------------------------------------------------------------------
39
+ * Colors — Core Palette
40
+ * ------------------------------------------------------------------------- */
41
+ --color-background: #f5f5f5;
42
+ --color-foreground: #0a0a0a;
43
+
44
+ --color-card: #ffffff;
45
+ --color-card-foreground: #0a0a0a;
46
+
47
+ --color-surface: #ffffff;
48
+ --color-surface-foreground: #0a0a0a;
49
+
50
+ --color-popover: #ffffff;
51
+ --color-popover-foreground: #0a0a0a;
52
+
53
+ --color-muted: #f4f4f5;
54
+ /* Darkened from zinc-500 (#71717a) so muted text clears WCAG AA 4.5:1 on the
55
+ * #f5f5f5 page background — #71717a only reached 4.43:1 (axe color-contrast). */
56
+ --color-muted-foreground: #6b6b73;
57
+
58
+ --color-primary: #000000;
59
+ --color-primary-foreground: #ffffff;
60
+
61
+ --color-secondary: #f4f4f5;
62
+ --color-secondary-foreground: #18181b;
63
+
64
+ --color-accent: #f4f4f5;
65
+ --color-accent-foreground: #18181b;
66
+
67
+ --color-destructive: #ef4444;
68
+ --color-destructive-foreground: #ffffff;
69
+
70
+ --color-border: #e4e4e7;
71
+ --color-input: #e4e4e7;
72
+ --color-ring: #000000;
73
+ --color-focus: #000000;
74
+
75
+ --color-field: #ffffff;
76
+ /* On-surface variants — fields and raised elements inside a Surface/Card.
77
+ * Components reference these via bg-[var(--color-field-on-surface)] etc.
78
+ * (input, textarea, select, checkbox, radio, button hover states). They
79
+ * MUST be defined here: an undefined var() in an arbitrary utility
80
+ * resolves to transparent, which renders form fields invisible inside
81
+ * drawers and cards. Values match oklch-theme.ts. */
82
+ --color-field-on-surface: #f4f4f5;
83
+ --color-default-on-surface: #e4e4e7;
84
+
85
+ --color-default: #f0f0f1;
86
+ --color-default-foreground: #18181b;
87
+
88
+ --color-code-bg: #f5f5f5;
89
+ --color-code-fg: #0a0a0a;
90
+ /* Opaque code-block surface + border. White lifts the block off the #f5f5f5
91
+ * page so snippets read as a distinct surface instead of blending in. */
92
+ --color-code-bg-solid: #ffffff;
93
+ --color-code-border: #e4e4e7;
94
+
95
+ --color-accent-text-overlay: #fbbf24;
96
+
97
+ /* ---------------------------------------------------------------------------
98
+ * Colors — Status
99
+ * ------------------------------------------------------------------------- */
100
+ --success: #22c55e;
101
+ --success-foreground: #ffffff;
102
+ --warning: #f59e0b;
103
+ --warning-foreground: #000000;
104
+ --danger: #ef4444;
105
+ --danger-foreground: #ffffff;
106
+
107
+ /* ---------------------------------------------------------------------------
108
+ * Typography — Font Families
109
+ * ------------------------------------------------------------------------- */
110
+ --font-heading: ui-sans-serif, system-ui, sans-serif;
111
+ --font-body: ui-sans-serif, system-ui, sans-serif;
112
+
113
+ /* Semantic roles — cascade from core fonts */
114
+ --font-label: var(--font-body);
115
+ --font-button: var(--font-body);
116
+ --font-caption: var(--font-body);
117
+ --font-display: var(--font-heading);
118
+ --font-accent: var(--font-heading);
119
+
120
+ /* ---------------------------------------------------------------------------
121
+ * Typography — Font Weights
122
+ * ------------------------------------------------------------------------- */
123
+ --font-weight-body: 400;
124
+ --font-weight-heading: 600;
125
+ --font-weight-button: 500;
126
+ --font-weight-label: 500;
127
+ --font-weight-caption: 400;
128
+ --font-weight-display: 700;
129
+
130
+ /* ---------------------------------------------------------------------------
131
+ * Radius
132
+ * ------------------------------------------------------------------------- */
133
+ --radius-sm: 2px;
134
+ --radius-md: 4px;
135
+ --radius-lg: 6px;
136
+ --radius-xl: 8px;
137
+ --radius-2xl: 12px;
138
+ --radius-3xl: 20px;
139
+ --radius-4xl: 24px;
140
+ --radius-full: 9999px;
141
+
142
+ /* Semantic radius roles */
143
+ --radius-button: 4px;
144
+ --radius-input: 4px;
145
+ --radius-card: 6px;
146
+ --radius-modal: 8px;
147
+ --radius-badge: 9999px;
148
+ --radius-avatar: 9999px;
149
+ --radius-tooltip: 6px;
150
+ --radius-image: 4px;
151
+
152
+ /* ---------------------------------------------------------------------------
153
+ * Shadows
154
+ * ------------------------------------------------------------------------- */
155
+ --shadow-card: 0 2px 4px rgba(0,0,0,0.04), 0 1px 2px rgba(0,0,0,0.06), 0 0 1px rgba(0,0,0,0.06);
156
+
157
+ /* ---------------------------------------------------------------------------
158
+ * Spacing
159
+ * ------------------------------------------------------------------------- */
160
+ --spacing-option-groups: 1rem;
161
+ --spacing-option-items: 0.5rem;
162
+
163
+ /* ---------------------------------------------------------------------------
164
+ * Legacy Canvas Aliases
165
+ *
166
+ * These use var() to reference the --color-* versions above, which is safe
167
+ * because both are declared in the same :root scope.
168
+ * ------------------------------------------------------------------------- */
169
+ --primary: var(--color-primary);
170
+ --primary-foreground: var(--color-primary-foreground);
171
+ --accent: var(--color-primary);
172
+ --accent-foreground: var(--color-primary-foreground);
173
+ --background: var(--color-background);
174
+ --foreground: var(--color-foreground);
175
+ --border: var(--color-border);
176
+ --muted-foreground: var(--color-muted-foreground);
177
+ --surface: var(--color-surface);
178
+ --surface-foreground: var(--color-surface-foreground);
179
+ --field: var(--color-field);
180
+ --focus: var(--color-focus);
181
+ --overlay: var(--color-popover);
182
+ --overlay-foreground: var(--color-popover-foreground);
183
+ --divider: var(--color-border);
184
+ --field-background: var(--color-field);
185
+ --field-foreground: var(--color-foreground);
186
+ --field-placeholder: var(--color-muted-foreground);
187
+ --default: var(--color-default);
188
+ --default-foreground: var(--color-default-foreground);
189
+
190
+ /* ---------------------------------------------------------------------------
191
+ * Canvas-Specific
192
+ * ------------------------------------------------------------------------- */
193
+ --color-canvas-bg: #f8f8f8;
194
+ --color-text-selection: color-mix(in srgb, var(--color-primary) 45%, transparent);
195
+ --color-spacing-indicator: #ff0000;
196
+ --color-accent-hover: var(--color-primary);
197
+ --color-accent-hover-border: var(--color-primary);
198
+ }
199
+
200
+ /* =============================================================================
201
+ * DARK THEME
202
+ * ============================================================================= */
203
+
204
+ .dark {
205
+ /* ---------------------------------------------------------------------------
206
+ * Colors — Core Palette
207
+ * ------------------------------------------------------------------------- */
208
+ --color-background: #0a0a0a;
209
+ --color-foreground: #fafafa;
210
+
211
+ /* Card / Surface / Popover bumped from #18181b (≈oklch 0.22) to lifted
212
+ * values so surfaces read as clearly raised against the page (#0a0a0a)
213
+ * in dark mode. Old values sat too close to the page once backdrop-blur
214
+ * smeared bright underlying pixels into the surface edge, which made
215
+ * drawers, popovers, and dropdowns look flush with the page.
216
+ *
217
+ * #2c2c2e ≈ oklch 0.30 — surface / card (iOS-native sheet)
218
+ * #353538 ≈ oklch 0.35 — popover (overlays clearly elevated)
219
+ */
220
+ --color-card: #2c2c2e;
221
+ --color-card-foreground: #fafafa;
222
+
223
+ --color-surface: #2c2c2e;
224
+ --color-surface-foreground: #fafafa;
225
+
226
+ --color-popover: #353538;
227
+ --color-popover-foreground: #fafafa;
228
+
229
+ --color-muted: #27272a;
230
+ --color-muted-foreground: #a1a1aa;
231
+
232
+ --color-primary: #ffffff;
233
+ --color-primary-foreground: #000000;
234
+
235
+ --color-secondary: #27272a;
236
+ --color-secondary-foreground: #fafafa;
237
+
238
+ --color-accent: #27272a;
239
+ --color-accent-foreground: #fafafa;
240
+
241
+ --color-destructive: #ef4444;
242
+ --color-destructive-foreground: #ffffff;
243
+
244
+ /* Border bumped from #3f3f46 (≈oklch 0.37) to #52525a (≈oklch 0.42)
245
+ * so it stays visible on the lifted --color-surface (oklch 0.30). At
246
+ * the old value, borders on cards and drawers were almost invisible
247
+ * (only ~0.07 lightness above the lifted surface). */
248
+ --color-border: #52525a;
249
+ --color-input: #27272a;
250
+ --color-ring: #ffffff;
251
+ --color-focus: #ffffff;
252
+
253
+ --color-field: #18181b;
254
+ /* On-surface variants (see light theme note). Field reads as an inset
255
+ * well against the lifted #2c2c2e surface; default-on-surface sits one
256
+ * step above it for ghost/outline hover visibility. */
257
+ --color-field-on-surface: #18181b;
258
+ --color-default-on-surface: #3f3f46;
259
+
260
+ --color-default: #27272a;
261
+ --color-default-foreground: #fafafa;
262
+
263
+ --color-code-bg: #1a1a1a;
264
+ --color-code-fg: #ededed;
265
+ /* Opaque code-block surface + border. #1a1a1a sits one step above the
266
+ * #0a0a0a page so snippets read as a raised surface in dark mode. */
267
+ --color-code-bg-solid: #1a1a1a;
268
+ --color-code-border: #27272a;
269
+
270
+ --color-accent-text-overlay: #fcd34d;
271
+
272
+ --shadow-card: none;
273
+
274
+ /* ---------------------------------------------------------------------------
275
+ * Canvas-Specific (dark)
276
+ * ------------------------------------------------------------------------- */
277
+ --color-canvas-bg: #1a1a1a;
278
+ --color-text-selection: color-mix(in srgb, var(--color-primary) 50%, transparent);
279
+ --field-background: var(--color-surface);
280
+ }