@snowcone-app/ui 0.1.42 → 0.2.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/CHANGELOG.md +33 -0
- package/README.md +18 -4
- package/package.json +9 -5
- package/src/components/CanvasIsolationBoundary.tsx +202 -0
- package/src/components/LoadingOverlayPrism.tsx +251 -0
- package/src/composed/AddToCart.tsx +229 -0
- package/src/composed/ArtAlignment.tsx +703 -0
- package/src/composed/ArtSelector.tsx +290 -0
- package/src/composed/ArtworkCustomizer.tsx +212 -0
- package/src/composed/CanvasEditor.tsx +79 -0
- package/src/composed/ColorPicker.tsx +111 -0
- package/src/composed/CurrentSelectionDisplay.tsx +86 -0
- package/src/composed/HeroProductImage.tsx +1071 -0
- package/src/composed/Lightbox.index.ts +2 -0
- package/src/composed/Lightbox.tsx +230 -0
- package/src/composed/PlacementClipShapeSelector.tsx +88 -0
- package/src/composed/PlacementTabs.tsx +179 -0
- package/src/composed/ProductCard.tsx +298 -0
- package/src/composed/ProductGallery.tsx +54 -0
- package/src/composed/ProductImage.tsx +129 -0
- package/src/composed/ProductList.tsx +147 -0
- package/src/composed/ProductOptions.tsx +305 -0
- package/src/composed/RealtimeMockup.tsx +121 -0
- package/src/composed/TileCount.tsx +348 -0
- package/src/composed/carousels/HeroCarousel.tsx +240 -0
- package/src/composed/carousels/MobileProductCarousel.tsx +1002 -0
- package/src/composed/carousels/index.ts +11 -0
- package/src/composed/carousels/types.ts +58 -0
- package/src/composed/grids/MasonryGrid.tsx +238 -0
- package/src/composed/grids/index.ts +9 -0
- package/src/composed/search/CurrentRefinements.tsx +80 -0
- package/src/composed/search/Filters.tsx +49 -0
- package/src/composed/search/FiltersButton.tsx +57 -0
- package/src/composed/search/FiltersDrawer.tsx +375 -0
- package/src/composed/search/ProductGrid.tsx +118 -0
- package/src/composed/search/ProductHit.tsx +56 -0
- package/src/composed/search/SearchBox.tsx +109 -0
- package/src/composed/search/SearchProvider.tsx +136 -0
- package/src/composed/search/facetConfig.ts +16 -0
- package/src/composed/search/index.ts +22 -0
- package/src/composed/search/meilisearchAdapter.ts +20 -0
- package/src/composed/search/types.ts +22 -0
- package/src/composed/zoom/EnhancedImageViewer.tsx +505 -0
- package/src/composed/zoom/ResponsiveZoom.tsx +134 -0
- package/src/composed/zoom/ZoomOverlay.tsx +194 -0
- package/src/composed/zoom/index.ts +12 -0
- package/src/composed/zoom/types.ts +12 -0
- package/src/design-system/ColorPalette.tsx +126 -0
- package/src/design-system/ColorSwatch.tsx +49 -0
- package/src/design-system/DesignSystemPage.tsx +130 -0
- package/src/design-system/ThemeSwitcher.tsx +181 -0
- package/src/design-system/TypographyScale.tsx +106 -0
- package/src/design-system/index.ts +5 -0
- package/src/ecommerce/stories/HeroProductImage.stories.tsx +66 -0
- package/src/ecommerce/stories/PDPHeroGallery.stories.tsx +105 -0
- package/src/ecommerce/stories/PDPInfoPanel.stories.tsx +472 -0
- package/src/ecommerce/stories/PDPLayout.stories.tsx +365 -0
- package/src/hooks/useBrand.ts +41 -0
- package/src/hooks/useCanvasContext.ts +127 -0
- package/src/hooks/useDeviceDetection.ts +64 -0
- package/src/hooks/useFocusTrap.ts +70 -0
- package/src/hooks/useImagePreloader.ts +268 -0
- package/src/hooks/useImageTransition.ts +608 -0
- package/src/hooks/usePlacementsProcessor.ts +74 -0
- package/src/hooks/useProductGallery.ts +193 -0
- package/src/hooks/useProductPage.ts +467 -0
- package/src/hooks/useRenderGuard.ts +96 -0
- package/src/hooks/useScrollDirection.ts +196 -0
- package/src/hooks/viewport/index.ts +25 -0
- package/src/hooks/viewport/useContainerWidth.ts +59 -0
- package/src/hooks/viewport/useMediaQuery.ts +52 -0
- package/src/hooks/viewport/useResponsiveImageCap.ts +149 -0
- package/src/hooks/viewport/useViewportDimensions.ts +135 -0
- package/src/hooks/viewport/useWideMonitorMode.ts +150 -0
- package/src/hooks/visibility/index.ts +15 -0
- package/src/hooks/visibility/observerPool.ts +150 -0
- package/src/index.ts +240 -0
- package/src/layouts/hero-zoom/HeroShrinkLayout.tsx +209 -0
- package/src/layouts/hero-zoom/HeroZoomLayout.tsx +351 -0
- package/src/layouts/hero-zoom/index.ts +30 -0
- package/src/layouts/hero-zoom/stories/HeroZoomLayout.stories.tsx +350 -0
- package/src/layouts/hero-zoom/types.ts +113 -0
- package/src/layouts/hero-zoom/useHeroZoomScales.ts +156 -0
- package/src/layouts/index.ts +9 -0
- package/src/layouts/pdp/EdgeBlurBox.tsx +210 -0
- package/src/layouts/pdp/ImageBlurExtension.tsx +215 -0
- package/src/layouts/pdp/ImageEdgeBlur.tsx +215 -0
- package/src/layouts/pdp/PDPLayout.tsx +246 -0
- package/src/layouts/pdp/SimpleImageBlur.tsx +140 -0
- package/src/layouts/pdp/index.ts +40 -0
- package/src/lib/env.ts +15 -0
- package/src/lib/locale.ts +167 -0
- package/src/lib/router.tsx +46 -0
- package/src/lib/utils.ts +6 -0
- package/src/lightbox/README.md +77 -0
- package/src/next/index.tsx +26 -0
- package/src/patterns/MockupPriorityProvider.tsx +1014 -0
- package/src/patterns/Product.tsx +850 -0
- package/src/patterns/ProductPageProvider.tsx +224 -0
- package/src/patterns/RealtimeProvider.tsx +1162 -0
- package/src/patterns/ShopProvider.tsx +603 -0
- package/src/personalization/PersonalizationBridge.tsx +235 -0
- package/src/personalization/PersonalizationContext.ts +29 -0
- package/src/personalization/PersonalizationInputs.tsx +110 -0
- package/src/personalization/PersonalizationProvider.tsx +407 -0
- package/src/personalization/canvas-stub.d.ts +22 -0
- package/src/personalization/index.ts +43 -0
- package/src/personalization/types.ts +48 -0
- package/src/personalization/usePersonalization.ts +32 -0
- package/src/personalization/usePersonalizationShimmer.ts +159 -0
- package/src/personalization/utils.ts +59 -0
- package/src/primitives/BrandLogo.tsx +65 -0
- package/src/primitives/BrandName.tsx +51 -0
- package/src/primitives/Button.tsx +123 -0
- package/src/primitives/ColorSwatch.tsx +221 -0
- package/src/primitives/DragHintAnimation.tsx +190 -0
- package/src/primitives/EdgeSwipeGuards.tsx +60 -0
- package/src/primitives/FloatingActionGroup.tsx +176 -0
- package/src/primitives/ProductPrice.tsx +171 -0
- package/src/primitives/ProgressiveBlur.tsx +295 -0
- package/src/primitives/ThemeToggle.tsx +125 -0
- package/src/primitives/__tests__/story-coverage.test.ts +98 -0
- package/src/primitives/accordion.tsx +280 -0
- package/src/primitives/badge.tsx +137 -0
- package/src/primitives/card.tsx +61 -0
- package/src/primitives/checkbox.tsx +56 -0
- package/src/primitives/collapsible.tsx +51 -0
- package/src/primitives/drawer.tsx +828 -0
- package/src/primitives/dropdown-menu.tsx +197 -0
- package/src/primitives/fieldset.tsx +73 -0
- package/src/primitives/index.ts +138 -0
- package/src/primitives/input.tsx +91 -0
- package/src/primitives/kbd.tsx +130 -0
- package/src/primitives/label.tsx +20 -0
- package/src/primitives/link.tsx +182 -0
- package/src/primitives/popover.tsx +80 -0
- package/src/primitives/radio-group.tsx +79 -0
- package/src/primitives/scroll-fade.tsx +159 -0
- package/src/primitives/select.tsx +170 -0
- package/src/primitives/separator.tsx +25 -0
- package/src/primitives/slider.tsx +221 -0
- package/src/primitives/spinner.tsx +72 -0
- package/src/primitives/stories/Accordion.stories.tsx +121 -0
- package/src/primitives/stories/Badge.stories.tsx +221 -0
- package/src/primitives/stories/Button.stories.tsx +185 -0
- package/src/primitives/stories/Card.stories.tsx +171 -0
- package/src/primitives/stories/Checkbox.stories.tsx +214 -0
- package/src/primitives/stories/Collapsible.stories.tsx +230 -0
- package/src/primitives/stories/Drawer.stories.tsx +378 -0
- package/src/primitives/stories/DropdownMenu.stories.tsx +182 -0
- package/src/primitives/stories/Fieldset.stories.tsx +212 -0
- package/src/primitives/stories/Input.stories.tsx +172 -0
- package/src/primitives/stories/Kbd.stories.tsx +183 -0
- package/src/primitives/stories/Label.stories.tsx +98 -0
- package/src/primitives/stories/Link.stories.tsx +260 -0
- package/src/primitives/stories/Popover.stories.tsx +178 -0
- package/src/primitives/stories/RadioGroup.stories.tsx +205 -0
- package/src/primitives/stories/Select.stories.tsx +222 -0
- package/src/primitives/stories/Separator.stories.tsx +134 -0
- package/src/primitives/stories/Slider.stories.tsx +203 -0
- package/src/primitives/stories/Spinner.stories.tsx +142 -0
- package/src/primitives/stories/Surface.stories.tsx +257 -0
- package/src/primitives/stories/Switch.stories.tsx +131 -0
- package/src/primitives/stories/Tabs.stories.tsx +275 -0
- package/src/primitives/stories/TextField.stories.tsx +139 -0
- package/src/primitives/stories/Textarea.stories.tsx +148 -0
- package/src/primitives/stories/Tooltip.stories.tsx +119 -0
- package/src/primitives/surface.tsx +86 -0
- package/src/primitives/switch.tsx +35 -0
- package/src/primitives/tabs.tsx +206 -0
- package/src/primitives/text-field.tsx +84 -0
- package/src/primitives/textarea.tsx +50 -0
- package/src/primitives/tooltip.tsx +58 -0
- package/src/services/CanvasExportService.ts +518 -0
- package/src/styles/base.css +380 -0
- package/src/styles/defaults.css +280 -0
- package/src/styles/globals.css +1242 -0
- package/src/styles/index.css +17 -0
- package/src/styles/ne-themes.css +4740 -0
- package/src/styles/tailwind.css +11 -0
- package/src/styles/tokens.css +117 -0
- package/src/styles/utilities.css +188 -0
- package/src/themes/apply-theme.ts +449 -0
- package/src/themes/getThemeStyles.ts +454 -0
- package/src/themes/index.ts +48 -0
- package/src/themes/oklch-theme.ts +283 -0
- package/src/themes/presets.ts +989 -0
- package/src/themes/types.ts +386 -0
- package/src/themes/useTheme.tsx +450 -0
- package/src/utils/dev-warnings.ts +161 -0
- package/src/utils/devWarnings.ts +153 -0
- package/dist/styles.css +0 -1
|
@@ -0,0 +1,1242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global CSS Configuration - Tailwind v4
|
|
3
|
+
*
|
|
4
|
+
* Import order: Tailwind → Tokens → Themes
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
@import 'tailwindcss';
|
|
8
|
+
|
|
9
|
+
/* Ensure all component source files are scanned for Tailwind classes */
|
|
10
|
+
@source "../**/*.tsx";
|
|
11
|
+
|
|
12
|
+
@import './tokens.css';
|
|
13
|
+
@import './ne-themes.css'; /* Generated from @snowcone-app/ui/themes - run `npm run generate:themes` to update */
|
|
14
|
+
|
|
15
|
+
:root {
|
|
16
|
+
--font-inter: 'Inter', 'Inter Placeholder', sans-serif;
|
|
17
|
+
|
|
18
|
+
/* ==========================================================================
|
|
19
|
+
* SEMANTIC FONT ROLES
|
|
20
|
+
* ==========================================================================
|
|
21
|
+
* Theme designers can customize fonts for different UI contexts.
|
|
22
|
+
* Each role defaults to either --font-body or --font-heading, but themes
|
|
23
|
+
* can override any of them independently for fine-grained control.
|
|
24
|
+
*
|
|
25
|
+
* Example: A luxury brand might use:
|
|
26
|
+
* - Serif heading font for titles
|
|
27
|
+
* - Sans body font for paragraphs
|
|
28
|
+
* - Modern sans for buttons (different from body)
|
|
29
|
+
* - Elegant serif for display/prices
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/* Primary font families - the two core fonts */
|
|
33
|
+
--font-heading: ui-sans-serif, system-ui, sans-serif;
|
|
34
|
+
--font-body: ui-sans-serif, system-ui, sans-serif;
|
|
35
|
+
|
|
36
|
+
/* Semantic font roles - default to core fonts but can be overridden */
|
|
37
|
+
--font-label: var(--font-body); /* Form labels, field names */
|
|
38
|
+
--font-button: var(--font-body); /* Button text, CTAs */
|
|
39
|
+
--font-caption: var(--font-body); /* Small text, descriptions, helper text */
|
|
40
|
+
--font-display: var(--font-heading); /* Hero text, prices, prominent numbers */
|
|
41
|
+
--font-accent: var(--font-heading); /* Emphasis, blockquotes, pullquotes */
|
|
42
|
+
--font-code: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
|
|
43
|
+
|
|
44
|
+
/* Font weights - can be overridden per-role */
|
|
45
|
+
--font-weight-body: 400;
|
|
46
|
+
--font-weight-heading: 600;
|
|
47
|
+
--font-weight-button: 500;
|
|
48
|
+
--font-weight-label: 500;
|
|
49
|
+
--font-weight-caption: 400;
|
|
50
|
+
--font-weight-display: 700;
|
|
51
|
+
|
|
52
|
+
/* Override HeroUI's default font to use our font-body variable */
|
|
53
|
+
--default-font-family: var(--font-body);
|
|
54
|
+
|
|
55
|
+
/* ==========================================================================
|
|
56
|
+
* SEMANTIC RADIUS ROLES
|
|
57
|
+
* ==========================================================================
|
|
58
|
+
* Theme designers can customize border-radius for different component types.
|
|
59
|
+
* This gives each theme a distinct "shape personality" while using the same
|
|
60
|
+
* component library.
|
|
61
|
+
*
|
|
62
|
+
* Example personalities:
|
|
63
|
+
* - Sharp/Technical: All radii set to 0 or sm
|
|
64
|
+
* - Soft/Friendly: Buttons use full (pill), cards use 2xl
|
|
65
|
+
* - Brutalist: Everything at 0
|
|
66
|
+
* - Playful: Large radii with variation between components
|
|
67
|
+
*
|
|
68
|
+
* See docs/SEMANTIC_RADIUS.md for complete documentation.
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
/* Semantic radius roles - map to primitive radius tokens by default */
|
|
72
|
+
--radius-button: var(--radius-md); /* Buttons, chips, toggles */
|
|
73
|
+
--radius-input: var(--radius-md); /* Text inputs, selects, textareas */
|
|
74
|
+
--radius-card: var(--radius-lg); /* Cards, panels, surfaces */
|
|
75
|
+
--radius-modal: var(--radius-xl); /* Modals, dialogs, sheets */
|
|
76
|
+
--radius-badge: var(--radius-full); /* Badges, tags, status indicators */
|
|
77
|
+
--radius-avatar: var(--radius-full); /* Avatars, profile images */
|
|
78
|
+
--radius-tooltip: var(--radius-lg); /* Tooltips, popovers, dropdowns */
|
|
79
|
+
--radius-image: var(--radius-md); /* Product images, thumbnails */
|
|
80
|
+
|
|
81
|
+
/* ==========================================================================
|
|
82
|
+
* GRADIENT SYSTEM
|
|
83
|
+
* ==========================================================================
|
|
84
|
+
* Theme-aware gradients for buttons, badges, cards, and other elements.
|
|
85
|
+
* Each theme can override these to match its color palette.
|
|
86
|
+
*
|
|
87
|
+
* NOTE: --gradient-primary is intentionally NOT set in :root
|
|
88
|
+
* This means default/primary buttons use solid --primary color.
|
|
89
|
+
* Themes that want gradient buttons (Aurora, Candy) define --gradient-primary.
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
/* Accent gradient - alternative gradient for variety */
|
|
93
|
+
--gradient-accent: linear-gradient(135deg, var(--secondary, var(--primary)) 0%, var(--primary) 100%);
|
|
94
|
+
|
|
95
|
+
/* Subtle gradient - for backgrounds, cards */
|
|
96
|
+
--gradient-subtle: linear-gradient(180deg, var(--background) 0%, var(--surface) 100%);
|
|
97
|
+
|
|
98
|
+
/* Success/Warning/Danger gradients */
|
|
99
|
+
--gradient-success: linear-gradient(135deg, var(--success) 0%, color-mix(in oklch, var(--success) 80%, var(--primary)) 100%);
|
|
100
|
+
--gradient-warning: linear-gradient(135deg, var(--warning) 0%, color-mix(in oklch, var(--warning) 80%, var(--danger)) 100%);
|
|
101
|
+
--gradient-danger: linear-gradient(135deg, var(--danger) 0%, color-mix(in oklch, var(--danger) 80%, var(--primary)) 100%);
|
|
102
|
+
|
|
103
|
+
/* Gradient foreground - text color for gradient backgrounds */
|
|
104
|
+
--gradient-foreground: var(--primary-foreground);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Custom Themes following HeroUI pattern */
|
|
108
|
+
/* IMPORTANT: Must use @layer base to override HeroUI's defaults */
|
|
109
|
+
/* HeroUI declares layer order: theme, base, components, utilities */
|
|
110
|
+
/* HeroUI's theme variables are in @layer base, so we must also use @layer base */
|
|
111
|
+
/* Our @layer base comes after HeroUI's import, so we win by source order within the same layer */
|
|
112
|
+
@layer base {
|
|
113
|
+
/*
|
|
114
|
+
* ============================================================================
|
|
115
|
+
* DEFAULT THEME - HeroUI v3 exact default colors
|
|
116
|
+
* ============================================================================
|
|
117
|
+
* Blue accent matching HeroUI's out-of-the-box defaults
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
/* Default Light Theme - HeroUI v3 exact defaults */
|
|
121
|
+
:root,
|
|
122
|
+
[data-theme='light'],
|
|
123
|
+
[data-theme='default'] {
|
|
124
|
+
color-scheme: light;
|
|
125
|
+
|
|
126
|
+
/* == Primitive Colors == */
|
|
127
|
+
--white: oklch(100% 0 0);
|
|
128
|
+
--black: oklch(0% 0 0);
|
|
129
|
+
--snow: oklch(0.9911 0 0);
|
|
130
|
+
--eclipse: oklch(0.2103 0.0059 285.89);
|
|
131
|
+
|
|
132
|
+
/* == HeroUI v3 Default Blue Accent == */
|
|
133
|
+
--accent: oklch(0.6204 0.195 253.83); /* HeroUI default blue */
|
|
134
|
+
--accent-foreground: var(--snow);
|
|
135
|
+
--color-text-selection: oklch(0.6204 0.195 253.83 / 0.25);
|
|
136
|
+
|
|
137
|
+
/* ===== HeroUI v3 Semantic Colors ===== */
|
|
138
|
+
--primary: var(--accent);
|
|
139
|
+
--primary-foreground: var(--accent-foreground);
|
|
140
|
+
|
|
141
|
+
--default: oklch(94% 0.001 286.375);
|
|
142
|
+
--default-foreground: var(--eclipse);
|
|
143
|
+
|
|
144
|
+
--success: oklch(0.7329 0.1935 150.81);
|
|
145
|
+
--success-foreground: var(--eclipse);
|
|
146
|
+
|
|
147
|
+
--warning: oklch(0.7819 0.1585 72.33);
|
|
148
|
+
--warning-foreground: var(--eclipse);
|
|
149
|
+
|
|
150
|
+
--danger: oklch(0.6532 0.2328 25.74);
|
|
151
|
+
--danger-foreground: var(--snow);
|
|
152
|
+
|
|
153
|
+
/* ===== HeroUI v3 Layout Colors ===== */
|
|
154
|
+
--background: oklch(0.9607 0 0); /* #f5f5f5 - standardized light background */
|
|
155
|
+
--foreground: var(--eclipse);
|
|
156
|
+
|
|
157
|
+
--muted: oklch(0.5517 0.0138 285.94);
|
|
158
|
+
--divider: oklch(92% 0.004 286.32);
|
|
159
|
+
--focus: var(--accent);
|
|
160
|
+
|
|
161
|
+
/* Surface: cards, accordions, disclosure groups */
|
|
162
|
+
--surface: var(--white);
|
|
163
|
+
--surface-foreground: var(--foreground);
|
|
164
|
+
--surface-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06);
|
|
165
|
+
|
|
166
|
+
/* Overlay: tooltips, popovers, modals, menus */
|
|
167
|
+
--overlay: var(--white);
|
|
168
|
+
--overlay-foreground: var(--foreground);
|
|
169
|
+
--overlay-shadow: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09);
|
|
170
|
+
|
|
171
|
+
/* ===== HeroUI v3 Field/Input Colors ===== */
|
|
172
|
+
--field-background: var(--white);
|
|
173
|
+
--field-foreground: var(--eclipse);
|
|
174
|
+
--field-placeholder: var(--muted);
|
|
175
|
+
--field-border: transparent;
|
|
176
|
+
|
|
177
|
+
/* Canvas Background */
|
|
178
|
+
--color-canvas-bg: #f5f5f5;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* Default Dark Theme - HeroUI v3 exact defaults */
|
|
182
|
+
.dark,
|
|
183
|
+
[data-theme='dark'] {
|
|
184
|
+
color-scheme: dark;
|
|
185
|
+
|
|
186
|
+
/* == Primitive Colors (same in dark) == */
|
|
187
|
+
--white: oklch(100% 0 0);
|
|
188
|
+
--black: oklch(0% 0 0);
|
|
189
|
+
--snow: oklch(0.9911 0 0);
|
|
190
|
+
--eclipse: oklch(0.2103 0.0059 285.89);
|
|
191
|
+
|
|
192
|
+
/* == HeroUI v3 Default Blue Accent (same in dark) == */
|
|
193
|
+
--accent: oklch(0.6204 0.195 253.83); /* HeroUI default blue */
|
|
194
|
+
--accent-foreground: var(--snow);
|
|
195
|
+
--color-text-selection: oklch(0.6204 0.195 253.83 / 0.3);
|
|
196
|
+
|
|
197
|
+
/* ===== HeroUI v3 Semantic Colors (Dark Mode) ===== */
|
|
198
|
+
--primary: var(--accent);
|
|
199
|
+
--primary-foreground: var(--accent-foreground);
|
|
200
|
+
|
|
201
|
+
--default: oklch(27.4% 0.006 286.033);
|
|
202
|
+
--default-foreground: var(--snow);
|
|
203
|
+
|
|
204
|
+
--success: oklch(0.7329 0.1935 150.81); /* Same as light */
|
|
205
|
+
--success-foreground: var(--eclipse);
|
|
206
|
+
|
|
207
|
+
--warning: oklch(0.8203 0.1388 76.34);
|
|
208
|
+
--warning-foreground: var(--eclipse);
|
|
209
|
+
|
|
210
|
+
--danger: oklch(0.594 0.1967 24.63);
|
|
211
|
+
--danger-foreground: var(--snow);
|
|
212
|
+
|
|
213
|
+
/* ===== HeroUI v3 Layout Colors (Dark Mode) ===== */
|
|
214
|
+
--background: oklch(0.07 0.002 270); /* #080809 - standardized dark background */
|
|
215
|
+
--foreground: var(--snow);
|
|
216
|
+
|
|
217
|
+
--muted: oklch(70.5% 0.015 286.067);
|
|
218
|
+
/* --divider bumped 0.32 → 0.42 to stay visible on the lifted --surface
|
|
219
|
+
* (0.30) below. At 0.32 it sat 0.02 above surface and effectively
|
|
220
|
+
* disappeared on every bordered card, drawer, and dropdown. */
|
|
221
|
+
--divider: oklch(0.42 0.006 286);
|
|
222
|
+
--focus: var(--accent);
|
|
223
|
+
|
|
224
|
+
/* Surface: cards, accordions, disclosure groups, drawer panels.
|
|
225
|
+
*
|
|
226
|
+
* Bumped from 0.21 → 0.30 so surfaces read as clearly raised against
|
|
227
|
+
* the near-black page (--background = oklch 0.07) in dark mode. The
|
|
228
|
+
* old value sat too close to the page once backdrop-blur smeared
|
|
229
|
+
* bright underlying pixels into the surface edge. 0.30 lands in iOS
|
|
230
|
+
* native sheet territory and removes the need for per-component
|
|
231
|
+
* dark-mode background overrides on drawers / popovers / dropdowns.
|
|
232
|
+
*/
|
|
233
|
+
--surface: oklch(0.30 0.006 286);
|
|
234
|
+
--surface-foreground: var(--foreground);
|
|
235
|
+
--surface-shadow: 0 0 0 0 transparent inset;
|
|
236
|
+
|
|
237
|
+
/* Overlay: tooltips, popovers, modals, menus.
|
|
238
|
+
* Sits ~0.05 above --surface so overlays read as clearly elevated when
|
|
239
|
+
* they appear over a card/surface (e.g. a popover anchored to a card). */
|
|
240
|
+
--overlay: oklch(0.35 0.006 286);
|
|
241
|
+
--overlay-foreground: var(--foreground);
|
|
242
|
+
--overlay-shadow: 0 0 0 0 transparent inset;
|
|
243
|
+
|
|
244
|
+
/* ===== HeroUI v3 Field/Input Colors (Dark Mode) ===== */
|
|
245
|
+
--field-background: var(--default);
|
|
246
|
+
--field-foreground: var(--foreground);
|
|
247
|
+
--field-placeholder: var(--muted);
|
|
248
|
+
--field-border: transparent;
|
|
249
|
+
|
|
250
|
+
/* Canvas Background */
|
|
251
|
+
--color-canvas-bg: #080809;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/*
|
|
255
|
+
* ============================================================================
|
|
256
|
+
* ACCENT-ONLY THEMES (HeroUI Convention)
|
|
257
|
+
* ============================================================================
|
|
258
|
+
* These themes ONLY override accent colors. Layout colors (background,
|
|
259
|
+
* surface, etc.) are inherited from :root (light) or .dark (dark mode).
|
|
260
|
+
*
|
|
261
|
+
* COLOR METHODOLOGY:
|
|
262
|
+
* ------------------
|
|
263
|
+
* 1. LIGHT MODE: "Darker Accent, Light Text"
|
|
264
|
+
* - Background is white/light
|
|
265
|
+
* - Accent uses lower lightness (L ~0.6) to contrast with background
|
|
266
|
+
* - Foreground text is WHITE (oklch(100% 0 0)) to contrast with dark accent
|
|
267
|
+
*
|
|
268
|
+
* 2. DARK MODE: "Brighter Accent, Dark Text"
|
|
269
|
+
* - Background is black/dark
|
|
270
|
+
* - Accent uses higher lightness (L ~0.7) to pop against dark background
|
|
271
|
+
* - Foreground text flips to BLACK (oklch(0% 0 0)) because the accent
|
|
272
|
+
* is now too bright for white text
|
|
273
|
+
*
|
|
274
|
+
* Usage:
|
|
275
|
+
* - data-theme="axis|indigo|ocean|sunset" sets the accent color
|
|
276
|
+
* - .dark class controls light/dark mode independently
|
|
277
|
+
* - Both can be combined: <html class="dark" data-theme="ocean">
|
|
278
|
+
*/
|
|
279
|
+
|
|
280
|
+
/*
|
|
281
|
+
* AXIS THEME - Monochrome black/white accent
|
|
282
|
+
* Light mode: black accent, Dark mode: white accent
|
|
283
|
+
*/
|
|
284
|
+
[data-theme='axis'] {
|
|
285
|
+
--accent: oklch(0% 0 0); /* Black */
|
|
286
|
+
--accent-foreground: oklch(100% 0 0); /* White */
|
|
287
|
+
--color-text-selection: oklch(0% 0 0 / 0.15);
|
|
288
|
+
--primary: var(--accent);
|
|
289
|
+
--primary-foreground: var(--accent-foreground);
|
|
290
|
+
--focus: var(--accent);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.dark[data-theme='axis'] {
|
|
294
|
+
--accent: oklch(100% 0 0); /* White */
|
|
295
|
+
--accent-foreground: oklch(0% 0 0); /* Black */
|
|
296
|
+
--color-text-selection: oklch(100% 0 0 / 0.2);
|
|
297
|
+
--primary: var(--accent);
|
|
298
|
+
--primary-foreground: var(--accent-foreground);
|
|
299
|
+
--focus: var(--accent);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/*
|
|
303
|
+
* INDIGO THEME - Purple/Indigo accent
|
|
304
|
+
*/
|
|
305
|
+
[data-theme='indigo'] {
|
|
306
|
+
--accent: oklch(0.55 0.2 270);
|
|
307
|
+
--accent-foreground: oklch(100% 0 0);
|
|
308
|
+
--color-text-selection: oklch(0.55 0.2 270 / 0.25);
|
|
309
|
+
--primary: var(--accent);
|
|
310
|
+
--primary-foreground: var(--accent-foreground);
|
|
311
|
+
--focus: var(--accent);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.dark[data-theme='indigo'] {
|
|
315
|
+
--accent: oklch(0.7 0.2 270); /* Brighter in dark mode */
|
|
316
|
+
--accent-foreground: oklch(0% 0 0); /* Dark text on bright purple */
|
|
317
|
+
--color-text-selection: oklch(0.7 0.2 270 / 0.3);
|
|
318
|
+
--primary: var(--accent);
|
|
319
|
+
--primary-foreground: var(--accent-foreground);
|
|
320
|
+
--focus: var(--accent);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/*
|
|
324
|
+
* OCEAN THEME - Cyan/Teal accent
|
|
325
|
+
*/
|
|
326
|
+
[data-theme='ocean'] {
|
|
327
|
+
--accent: oklch(0.6 0.15 200);
|
|
328
|
+
--accent-foreground: oklch(100% 0 0);
|
|
329
|
+
--color-text-selection: oklch(0.6 0.15 200 / 0.25);
|
|
330
|
+
--primary: var(--accent);
|
|
331
|
+
--primary-foreground: var(--accent-foreground);
|
|
332
|
+
--focus: var(--accent);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.dark[data-theme='ocean'] {
|
|
336
|
+
--accent: oklch(0.7 0.15 200); /* Brighter in dark mode */
|
|
337
|
+
--accent-foreground: oklch(0% 0 0); /* Dark text on bright cyan */
|
|
338
|
+
--color-text-selection: oklch(0.7 0.15 200 / 0.3);
|
|
339
|
+
--primary: var(--accent);
|
|
340
|
+
--primary-foreground: var(--accent-foreground);
|
|
341
|
+
--focus: var(--accent);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/*
|
|
345
|
+
* SUNSET THEME - Orange accent
|
|
346
|
+
*/
|
|
347
|
+
[data-theme='sunset'] {
|
|
348
|
+
--accent: oklch(0.65 0.2 40);
|
|
349
|
+
--accent-foreground: oklch(100% 0 0);
|
|
350
|
+
--color-text-selection: oklch(0.65 0.2 40 / 0.25);
|
|
351
|
+
--primary: var(--accent);
|
|
352
|
+
--primary-foreground: var(--accent-foreground);
|
|
353
|
+
--focus: var(--accent);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.dark[data-theme='sunset'] {
|
|
357
|
+
--accent: oklch(0.7 0.2 40); /* Brighter in dark mode */
|
|
358
|
+
--accent-foreground: oklch(0% 0 0); /* Dark text on bright orange */
|
|
359
|
+
--color-text-selection: oklch(0.7 0.2 40 / 0.3);
|
|
360
|
+
--primary: var(--accent);
|
|
361
|
+
--primary-foreground: var(--accent-foreground);
|
|
362
|
+
--focus: var(--accent);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/*
|
|
366
|
+
* LIME THEME - Green/Lime accent
|
|
367
|
+
*/
|
|
368
|
+
[data-theme='lime'] {
|
|
369
|
+
--accent: oklch(0.85 0.23 135); /* Same bright neon as dark mode */
|
|
370
|
+
--accent-foreground: oklch(0% 0 0); /* Black text */
|
|
371
|
+
--color-text-selection: oklch(0.85 0.23 135 / 0.25);
|
|
372
|
+
--primary: var(--accent);
|
|
373
|
+
--primary-foreground: var(--accent-foreground);
|
|
374
|
+
--focus: var(--accent);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/*
|
|
378
|
+
* SCOPED COMPONENT OVERRIDES FOR LIME THEME
|
|
379
|
+
*
|
|
380
|
+
* The "Secondary" button variant maps to the 'default' (gray) color semantic.
|
|
381
|
+
* We want buttons to be Lime-themed, but we DON'T want to turn generic
|
|
382
|
+
* layout elements (like Tabs, Cards, Disabled states) green.
|
|
383
|
+
*
|
|
384
|
+
* Solution: Override '--default' ONLY for enabled buttons and chips.
|
|
385
|
+
*/
|
|
386
|
+
.light[data-theme='lime']
|
|
387
|
+
button:not([role='tab']):not([disabled]):not([data-disabled='true']):not(.button--secondary):not(.button--tertiary),
|
|
388
|
+
.light[data-theme='lime']
|
|
389
|
+
[role='button']:not([role='tab']):not([disabled]):not([data-disabled='true']):not(.button--secondary):not(
|
|
390
|
+
.button--tertiary
|
|
391
|
+
) {
|
|
392
|
+
--default: oklch(0.9 0.1 135); /* Soft Pastel Lime */
|
|
393
|
+
--default-foreground: oklch(0.4 0.15 135); /* Dark Green Text */
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/*
|
|
397
|
+
* SECONDARY BUTTON OVERRIDE FOR LIME LIGHT THEME
|
|
398
|
+
*
|
|
399
|
+
* The secondary button uses: bg-default + text-accent
|
|
400
|
+
* We want the default gray background with our lime green text.
|
|
401
|
+
* oklch(0.70 0.20 135) is the brightest lime that passes WCAG AA (4.5:1 contrast).
|
|
402
|
+
*/
|
|
403
|
+
.light[data-theme='lime'] .button--secondary:not([disabled]):not([data-disabled='true']) {
|
|
404
|
+
--accent: var(--default-foreground);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/*
|
|
408
|
+
* CHIP OVERRIDE FOR LIME LIGHT THEME
|
|
409
|
+
*
|
|
410
|
+
* Chips with color="accent" need dark text for readability.
|
|
411
|
+
* - chip--accent uses text-accent
|
|
412
|
+
* - chip--accent.chip--primary uses text-accent-foreground
|
|
413
|
+
* - chip--accent.chip--soft uses text-accent-soft-foreground
|
|
414
|
+
*/
|
|
415
|
+
.light[data-theme='lime'] .chip--accent.chip--primary {
|
|
416
|
+
--accent-foreground: var(--default-foreground);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
.light[data-theme='lime'] .chip--accent.chip--soft {
|
|
420
|
+
--accent-soft-foreground: var(--default-foreground);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.light[data-theme='lime'] .chip--accent:not(.chip--primary):not(.chip--soft) {
|
|
424
|
+
--accent: var(--default-foreground);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.dark[data-theme='lime'] {
|
|
428
|
+
--accent: oklch(0.85 0.23 135); /* Super bright electric lime */
|
|
429
|
+
--accent-foreground: oklch(0% 0 0); /* Black text on bright lime */
|
|
430
|
+
--color-text-selection: oklch(0.85 0.23 135 / 0.3);
|
|
431
|
+
--primary: var(--accent);
|
|
432
|
+
--primary-foreground: var(--accent-foreground);
|
|
433
|
+
--focus: var(--accent);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/*
|
|
437
|
+
* Legacy theme aliases for backward compatibility
|
|
438
|
+
* Map old "theme-mode" format to new accent-only format
|
|
439
|
+
*/
|
|
440
|
+
[data-theme='axis-light'] {
|
|
441
|
+
--accent: oklch(0% 0 0);
|
|
442
|
+
--accent-foreground: oklch(100% 0 0);
|
|
443
|
+
--primary: var(--accent);
|
|
444
|
+
--primary-foreground: var(--accent-foreground);
|
|
445
|
+
--focus: var(--accent);
|
|
446
|
+
}
|
|
447
|
+
[data-theme='axis-dark'] {
|
|
448
|
+
--accent: oklch(100% 0 0);
|
|
449
|
+
--accent-foreground: oklch(0% 0 0);
|
|
450
|
+
--primary: var(--accent);
|
|
451
|
+
--primary-foreground: var(--accent-foreground);
|
|
452
|
+
--focus: var(--accent);
|
|
453
|
+
}
|
|
454
|
+
[data-theme='indigo-light'] {
|
|
455
|
+
--accent: oklch(0.55 0.2 270);
|
|
456
|
+
--accent-foreground: oklch(100% 0 0);
|
|
457
|
+
--primary: var(--accent);
|
|
458
|
+
--primary-foreground: var(--accent-foreground);
|
|
459
|
+
--focus: var(--accent);
|
|
460
|
+
}
|
|
461
|
+
[data-theme='indigo-dark'] {
|
|
462
|
+
--accent: oklch(0.65 0.2 270);
|
|
463
|
+
--accent-foreground: oklch(100% 0 0);
|
|
464
|
+
--primary: var(--accent);
|
|
465
|
+
--primary-foreground: var(--accent-foreground);
|
|
466
|
+
--focus: var(--accent);
|
|
467
|
+
}
|
|
468
|
+
[data-theme='ocean-light'] {
|
|
469
|
+
--accent: oklch(0.6 0.15 200);
|
|
470
|
+
--accent-foreground: oklch(100% 0 0);
|
|
471
|
+
--primary: var(--accent);
|
|
472
|
+
--primary-foreground: var(--accent-foreground);
|
|
473
|
+
--focus: var(--accent);
|
|
474
|
+
}
|
|
475
|
+
[data-theme='ocean-dark'] {
|
|
476
|
+
--accent: oklch(0.7 0.15 200);
|
|
477
|
+
--accent-foreground: oklch(0% 0 0);
|
|
478
|
+
--primary: var(--accent);
|
|
479
|
+
--primary-foreground: var(--accent-foreground);
|
|
480
|
+
--focus: var(--accent);
|
|
481
|
+
}
|
|
482
|
+
[data-theme='sunset-light'] {
|
|
483
|
+
--accent: oklch(0.65 0.2 40);
|
|
484
|
+
--accent-foreground: oklch(100% 0 0);
|
|
485
|
+
--primary: var(--accent);
|
|
486
|
+
--primary-foreground: var(--accent-foreground);
|
|
487
|
+
--focus: var(--accent);
|
|
488
|
+
}
|
|
489
|
+
[data-theme='sunset-dark'] {
|
|
490
|
+
--accent: oklch(0.7 0.2 40);
|
|
491
|
+
--accent-foreground: oklch(0% 0 0);
|
|
492
|
+
--primary: var(--accent);
|
|
493
|
+
--primary-foreground: var(--accent-foreground);
|
|
494
|
+
--focus: var(--accent);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/*
|
|
498
|
+
* CRITICAL: Ensure dependent variables use the LOCAL accent color
|
|
499
|
+
* when a theme is applied to a specific element (scoped theming).
|
|
500
|
+
*/
|
|
501
|
+
[data-theme] {
|
|
502
|
+
/* Legacy accent aliases */
|
|
503
|
+
--color-accent-primary: var(--accent);
|
|
504
|
+
--color-accent-hover: var(--accent);
|
|
505
|
+
--color-accent-light: color-mix(in oklch, var(--accent) 20%, transparent);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/* Map to Tailwind */
|
|
510
|
+
/* NOTE: Using @theme (not inline) so CSS custom properties are output consistently */
|
|
511
|
+
/* This ensures bg-default compiles to var(--color-default) everywhere */
|
|
512
|
+
@theme {
|
|
513
|
+
/* ===== Semantic Font Families for Tailwind ===== */
|
|
514
|
+
/* Enables: font-heading, font-body, font-label, font-button, etc. */
|
|
515
|
+
--font-family-heading: var(--font-heading);
|
|
516
|
+
--font-family-body: var(--font-body);
|
|
517
|
+
--font-family-label: var(--font-label);
|
|
518
|
+
--font-family-button: var(--font-button);
|
|
519
|
+
--font-family-caption: var(--font-caption);
|
|
520
|
+
--font-family-display: var(--font-display);
|
|
521
|
+
--font-family-accent: var(--font-accent);
|
|
522
|
+
--font-family-code: var(--font-code);
|
|
523
|
+
|
|
524
|
+
/* ===== HeroUI v3 Semantic Colors for Tailwind ===== */
|
|
525
|
+
/* Enables: bg-primary, text-primary-foreground, border-danger, etc. */
|
|
526
|
+
--color-primary: var(--primary);
|
|
527
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
528
|
+
--color-secondary: var(--secondary);
|
|
529
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
530
|
+
--color-default: var(--default);
|
|
531
|
+
--color-default-foreground: var(--default-foreground);
|
|
532
|
+
--color-danger: var(--danger);
|
|
533
|
+
--color-danger-foreground: var(--danger-foreground);
|
|
534
|
+
--color-success: var(--success);
|
|
535
|
+
--color-success-foreground: var(--success-foreground);
|
|
536
|
+
--color-warning: var(--warning);
|
|
537
|
+
--color-warning-foreground: var(--warning-foreground);
|
|
538
|
+
|
|
539
|
+
/* ===== Core Layout Colors ===== */
|
|
540
|
+
--color-background: var(--background);
|
|
541
|
+
--color-foreground: var(--foreground);
|
|
542
|
+
--color-divider: var(--divider);
|
|
543
|
+
--color-focus: var(--focus);
|
|
544
|
+
|
|
545
|
+
/* ===== Semantic Field Colors (OKLCH system) ===== */
|
|
546
|
+
/*
|
|
547
|
+
* FIELD BACKGROUNDS:
|
|
548
|
+
* - --color-field: Field on page/transparent background
|
|
549
|
+
* - --color-field-on-surface: Field inside Surface/Card (set by oklch-theme.ts)
|
|
550
|
+
*
|
|
551
|
+
* Components auto-detect context via useSurface() hook
|
|
552
|
+
*/
|
|
553
|
+
--color-field: var(--field);
|
|
554
|
+
--color-field-foreground: var(--field-foreground);
|
|
555
|
+
--color-field-placeholder: var(--field-placeholder);
|
|
556
|
+
--color-field-border: var(--field-border);
|
|
557
|
+
|
|
558
|
+
/* ===== Accent (kept for backward compatibility) ===== */
|
|
559
|
+
--color-accent: var(--accent);
|
|
560
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
561
|
+
|
|
562
|
+
/* ===== Overlay and Surface ===== */
|
|
563
|
+
--color-overlay: var(--overlay);
|
|
564
|
+
--color-overlay-foreground: var(--overlay-foreground);
|
|
565
|
+
--shadow-overlay: var(--overlay-shadow);
|
|
566
|
+
|
|
567
|
+
--color-surface: var(--surface);
|
|
568
|
+
--color-surface-foreground: var(--surface-foreground);
|
|
569
|
+
--shadow-surface: var(--surface-shadow);
|
|
570
|
+
|
|
571
|
+
/* ===== Status colors (aliases for backward compatibility) ===== */
|
|
572
|
+
--color-error: var(--color-status-error);
|
|
573
|
+
--color-error-foreground: var(--color-status-error-foreground);
|
|
574
|
+
--color-info: var(--color-status-info);
|
|
575
|
+
--color-info-foreground: var(--color-status-info-foreground);
|
|
576
|
+
|
|
577
|
+
/* ===== Shadcn/Radix Compatibility Aliases ===== */
|
|
578
|
+
/* Enables Shadcn components to use standard naming conventions */
|
|
579
|
+
--color-card: var(--surface);
|
|
580
|
+
--color-card-foreground: var(--surface-foreground);
|
|
581
|
+
--color-popover: var(--overlay);
|
|
582
|
+
--color-popover-foreground: var(--overlay-foreground);
|
|
583
|
+
--color-border: var(--divider);
|
|
584
|
+
--color-muted: var(--default);
|
|
585
|
+
--color-muted-foreground: oklch(from var(--foreground) l c h / 0.6);
|
|
586
|
+
--color-destructive: var(--danger);
|
|
587
|
+
--color-destructive-foreground: var(--danger-foreground);
|
|
588
|
+
--color-ring: var(--focus);
|
|
589
|
+
--color-input: var(--field-border);
|
|
590
|
+
|
|
591
|
+
/* ===== Custom Shadows (HeroUI v3 style) ===== */
|
|
592
|
+
/* Soft shadow - visible on transparent surfaces while remaining subtle */
|
|
593
|
+
--shadow-soft: rgba(0, 0, 0, 0.04) 0px 2px 4px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px;
|
|
594
|
+
|
|
595
|
+
/* ===== Semantic Radius for Tailwind ===== */
|
|
596
|
+
/* Maps semantic radius roles to Tailwind's border-radius utilities */
|
|
597
|
+
/* Enables: rounded-button, rounded-input, rounded-card, etc. */
|
|
598
|
+
--radius-semantic-button: var(--radius-button);
|
|
599
|
+
--radius-semantic-input: var(--radius-input);
|
|
600
|
+
--radius-semantic-card: var(--radius-card);
|
|
601
|
+
--radius-semantic-modal: var(--radius-modal);
|
|
602
|
+
--radius-semantic-badge: var(--radius-badge);
|
|
603
|
+
--radius-semantic-avatar: var(--radius-avatar);
|
|
604
|
+
--radius-semantic-tooltip: var(--radius-tooltip);
|
|
605
|
+
--radius-semantic-image: var(--radius-image);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/* Configure dark mode variant */
|
|
609
|
+
@variant dark (&:where(.dark, .dark *));
|
|
610
|
+
|
|
611
|
+
/*
|
|
612
|
+
* ============================================================================
|
|
613
|
+
* DARK MODE THEME OVERRIDES - UNLAYERED (Highest Priority)
|
|
614
|
+
* ============================================================================
|
|
615
|
+
* These styles are outside of @layer to ensure they override HeroUI's defaults.
|
|
616
|
+
* Unlayered styles always have higher priority than layered styles.
|
|
617
|
+
*/
|
|
618
|
+
|
|
619
|
+
/* Dark mode accent overrides - these MUST win over HeroUI's .dark defaults */
|
|
620
|
+
.dark[data-theme='axis'],
|
|
621
|
+
[data-theme='axis'] .dark {
|
|
622
|
+
--accent: oklch(100% 0 0); /* White */
|
|
623
|
+
--accent-foreground: oklch(0% 0 0); /* Black */
|
|
624
|
+
--primary: var(--accent);
|
|
625
|
+
--primary-foreground: var(--accent-foreground);
|
|
626
|
+
--focus: var(--accent);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
.dark[data-theme='indigo'],
|
|
630
|
+
[data-theme='indigo'] .dark {
|
|
631
|
+
--accent: oklch(0.7 0.2 270); /* Brighter in dark mode */
|
|
632
|
+
--accent-foreground: oklch(0% 0 0); /* Dark text on bright purple */
|
|
633
|
+
--primary: var(--accent);
|
|
634
|
+
--primary-foreground: var(--accent-foreground);
|
|
635
|
+
--focus: var(--accent);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
.dark[data-theme='ocean'],
|
|
639
|
+
[data-theme='ocean'] .dark {
|
|
640
|
+
--accent: oklch(0.7 0.15 200); /* Brighter in dark mode */
|
|
641
|
+
--accent-foreground: oklch(0% 0 0); /* Dark text on bright cyan */
|
|
642
|
+
--primary: var(--accent);
|
|
643
|
+
--primary-foreground: var(--accent-foreground);
|
|
644
|
+
--focus: var(--accent);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
.dark[data-theme='sunset'],
|
|
648
|
+
[data-theme='sunset'] .dark {
|
|
649
|
+
--accent: oklch(0.7 0.2 40); /* Brighter in dark mode */
|
|
650
|
+
--accent-foreground: oklch(0% 0 0); /* Dark text on bright orange */
|
|
651
|
+
--primary: var(--accent);
|
|
652
|
+
--primary-foreground: var(--accent-foreground);
|
|
653
|
+
--focus: var(--accent);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
.dark[data-theme='lime'],
|
|
657
|
+
[data-theme='lime'] .dark {
|
|
658
|
+
--accent: oklch(0.85 0.23 135); /* Super bright electric lime */
|
|
659
|
+
--accent-foreground: oklch(0% 0 0); /* Black text on bright lime */
|
|
660
|
+
--primary: var(--accent);
|
|
661
|
+
--primary-foreground: var(--accent-foreground);
|
|
662
|
+
--focus: var(--accent);
|
|
663
|
+
|
|
664
|
+
/* Special Secondary Color for Lime Theme (Dark Mode Override) */
|
|
665
|
+
--secondary: oklch(0.3 0.15 135); /* Darker Olive Green */
|
|
666
|
+
--secondary-foreground: oklch(0.95 0.1 135); /* Light Lime Text */
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/* =============================================================================
|
|
670
|
+
* SPECIAL THEME EFFECTS
|
|
671
|
+
* =============================================================================
|
|
672
|
+
* Custom visual effects for distinctive themes. These add shadows, borders,
|
|
673
|
+
* glows, and other visual treatments beyond basic colors.
|
|
674
|
+
*/
|
|
675
|
+
|
|
676
|
+
/* -----------------------------------------------------------------------------
|
|
677
|
+
* NEO BRUTALISM THEME
|
|
678
|
+
* Hard shadows, thick borders, bold multi-color palette
|
|
679
|
+
* -------------------------------------------------------------------------- */
|
|
680
|
+
[data-theme='ne-neo-brutal'] {
|
|
681
|
+
/* Neo-Brutalist Color Palette - bold, clashing, vibrant */
|
|
682
|
+
--brutal-yellow: #ffde59;
|
|
683
|
+
--brutal-pink: #ff6b9d;
|
|
684
|
+
--brutal-blue: #00d4ff;
|
|
685
|
+
--brutal-green: #7fff00;
|
|
686
|
+
--brutal-orange: #ff5722;
|
|
687
|
+
--brutal-purple: #b388ff;
|
|
688
|
+
--brutal-red: #ff1744;
|
|
689
|
+
--brutal-black: #000000;
|
|
690
|
+
--brutal-white: #ffffff;
|
|
691
|
+
|
|
692
|
+
/* Brutalist shadow - hard offset, no blur */
|
|
693
|
+
--shadow-brutal: 4px 4px 0 0 var(--brutal-black);
|
|
694
|
+
--shadow-brutal-sm: 2px 2px 0 0 var(--brutal-black);
|
|
695
|
+
--shadow-brutal-lg: 6px 6px 0 0 var(--brutal-black);
|
|
696
|
+
|
|
697
|
+
/* Override soft shadow with brutal shadow */
|
|
698
|
+
--shadow-soft: var(--shadow-brutal-sm);
|
|
699
|
+
|
|
700
|
+
/* Thick borders */
|
|
701
|
+
--border-width: 3px;
|
|
702
|
+
--border-brutal-color: var(--brutal-black);
|
|
703
|
+
|
|
704
|
+
/* High contrast divider */
|
|
705
|
+
--divider: var(--brutal-black);
|
|
706
|
+
|
|
707
|
+
/* Map semantic colors to brutal palette */
|
|
708
|
+
--success: var(--brutal-green);
|
|
709
|
+
--success-foreground: var(--brutal-black);
|
|
710
|
+
--warning: var(--brutal-yellow);
|
|
711
|
+
--warning-foreground: var(--brutal-black);
|
|
712
|
+
--danger: var(--brutal-red);
|
|
713
|
+
--danger-foreground: var(--brutal-white);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
.dark[data-theme='ne-neo-brutal-dark'],
|
|
717
|
+
[data-theme='ne-neo-brutal-dark'] .dark {
|
|
718
|
+
/* Dark mode brutal palette - neon on black */
|
|
719
|
+
--brutal-yellow: #ffde59;
|
|
720
|
+
--brutal-pink: #ff6b9d;
|
|
721
|
+
--brutal-blue: #00d4ff;
|
|
722
|
+
--brutal-green: #00ff88;
|
|
723
|
+
--brutal-orange: #ff7043;
|
|
724
|
+
--brutal-purple: #e040fb;
|
|
725
|
+
--brutal-red: #ff5252;
|
|
726
|
+
--brutal-black: #000000;
|
|
727
|
+
--brutal-white: #ffffff;
|
|
728
|
+
|
|
729
|
+
/* Neon glow shadow for dark brutal */
|
|
730
|
+
--shadow-brutal: 4px 4px 0 0 var(--brutal-green);
|
|
731
|
+
--shadow-brutal-sm: 2px 2px 0 0 var(--brutal-green);
|
|
732
|
+
--shadow-brutal-lg: 6px 6px 0 0 var(--brutal-green);
|
|
733
|
+
--shadow-soft: var(--shadow-brutal-sm);
|
|
734
|
+
|
|
735
|
+
--border-width: 3px;
|
|
736
|
+
--border-brutal-color: var(--brutal-green);
|
|
737
|
+
--divider: var(--brutal-green);
|
|
738
|
+
|
|
739
|
+
/* Map semantic colors to brutal palette */
|
|
740
|
+
--success: var(--brutal-green);
|
|
741
|
+
--success-foreground: var(--brutal-black);
|
|
742
|
+
--warning: var(--brutal-yellow);
|
|
743
|
+
--warning-foreground: var(--brutal-black);
|
|
744
|
+
--danger: var(--brutal-red);
|
|
745
|
+
--danger-foreground: var(--brutal-white);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/* -----------------------------------------------------------------------------
|
|
749
|
+
* AURORA / GLASSMORPHISM THEME
|
|
750
|
+
* Frosted glass, gradients, soft glows, ethereal feel
|
|
751
|
+
* -------------------------------------------------------------------------- */
|
|
752
|
+
[data-theme='ne-aurora'] {
|
|
753
|
+
/* Frosted glass effect */
|
|
754
|
+
--glass-blur: 12px;
|
|
755
|
+
--glass-saturation: 180%;
|
|
756
|
+
--glass-bg: rgba(255, 255, 255, 0.7);
|
|
757
|
+
|
|
758
|
+
/* Soft glow shadows */
|
|
759
|
+
--glow-primary: 0 0 20px rgba(99, 102, 241, 0.3);
|
|
760
|
+
--glow-secondary: 0 0 30px rgba(139, 92, 246, 0.2);
|
|
761
|
+
|
|
762
|
+
/* Beautiful multi-stop gradients */
|
|
763
|
+
--gradient-primary: linear-gradient(145deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%);
|
|
764
|
+
--gradient-accent: linear-gradient(135deg, #ec4899 0%, #8b5cf6 50%, #6366f1 100%);
|
|
765
|
+
--gradient-subtle: linear-gradient(180deg, #f0f4ff 0%, #e0e7ff 100%);
|
|
766
|
+
--gradient-success: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
|
|
767
|
+
--gradient-foreground: #ffffff;
|
|
768
|
+
|
|
769
|
+
/* Enhanced soft shadow with glow */
|
|
770
|
+
--shadow-soft: 0 4px 20px rgba(99, 102, 241, 0.15), 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
771
|
+
|
|
772
|
+
/* Subtle border */
|
|
773
|
+
--divider: rgba(99, 102, 241, 0.2);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
.dark[data-theme='ne-aurora-dark'],
|
|
777
|
+
[data-theme='ne-aurora-dark'] .dark {
|
|
778
|
+
/* Dark frosted glass */
|
|
779
|
+
--glass-blur: 16px;
|
|
780
|
+
--glass-saturation: 150%;
|
|
781
|
+
--glass-bg: rgba(15, 10, 26, 0.8);
|
|
782
|
+
|
|
783
|
+
/* Brighter glows for dark mode */
|
|
784
|
+
--glow-primary: 0 0 30px rgba(129, 140, 248, 0.4);
|
|
785
|
+
--glow-secondary: 0 0 40px rgba(167, 139, 250, 0.3);
|
|
786
|
+
|
|
787
|
+
/* Vibrant dark mode gradients */
|
|
788
|
+
--gradient-primary: linear-gradient(145deg, #818cf8 0%, #a78bfa 50%, #c084fc 100%);
|
|
789
|
+
--gradient-accent: linear-gradient(135deg, #f472b6 0%, #a78bfa 50%, #818cf8 100%);
|
|
790
|
+
--gradient-subtle: linear-gradient(180deg, #0f0a1a 0%, #1e1b4b 100%);
|
|
791
|
+
--gradient-success: linear-gradient(135deg, #34d399 0%, #22d3ee 100%);
|
|
792
|
+
--gradient-foreground: #ffffff;
|
|
793
|
+
|
|
794
|
+
/* Glowing shadow */
|
|
795
|
+
--shadow-soft: 0 4px 30px rgba(129, 140, 248, 0.2), 0 0 60px rgba(139, 92, 246, 0.1);
|
|
796
|
+
|
|
797
|
+
--divider: rgba(129, 140, 248, 0.3);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/* -----------------------------------------------------------------------------
|
|
801
|
+
* CANDY / PLAYFUL THEME
|
|
802
|
+
* Bright colors, fun shadows, bubbly personality
|
|
803
|
+
* -------------------------------------------------------------------------- */
|
|
804
|
+
[data-theme='ne-candy'] {
|
|
805
|
+
/* Playful colored shadow */
|
|
806
|
+
--shadow-candy: 0 4px 14px rgba(236, 72, 153, 0.3), 0 2px 6px rgba(249, 115, 22, 0.2);
|
|
807
|
+
|
|
808
|
+
/* Fun candy gradients - smooth pink to rose transition */
|
|
809
|
+
--gradient-primary: linear-gradient(145deg, #ec4899 0%, #f472b6 50%, #fb7185 100%);
|
|
810
|
+
--gradient-accent: linear-gradient(135deg, #fbbf24 0%, #f472b6 50%, #8b5cf6 100%);
|
|
811
|
+
--gradient-subtle: linear-gradient(180deg, #fff5f7 0%, #fdf2f8 100%);
|
|
812
|
+
--gradient-success: linear-gradient(135deg, #34d399 0%, #fbbf24 100%);
|
|
813
|
+
--gradient-warning: linear-gradient(135deg, #fbbf24 0%, #f97316 100%);
|
|
814
|
+
--gradient-danger: linear-gradient(135deg, #f43f5e 0%, #ec4899 100%);
|
|
815
|
+
--gradient-foreground: #ffffff;
|
|
816
|
+
|
|
817
|
+
--shadow-soft: var(--shadow-candy);
|
|
818
|
+
|
|
819
|
+
/* Vibrant divider */
|
|
820
|
+
--divider: rgba(236, 72, 153, 0.3);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
.dark[data-theme='ne-candy-dark'],
|
|
824
|
+
[data-theme='ne-candy-dark'] .dark {
|
|
825
|
+
/* Neon candy glow */
|
|
826
|
+
--shadow-candy: 0 4px 20px rgba(244, 114, 182, 0.4), 0 0 40px rgba(251, 146, 60, 0.2);
|
|
827
|
+
|
|
828
|
+
/* Vibrant neon gradients - smooth pink to rose transition */
|
|
829
|
+
--gradient-primary: linear-gradient(145deg, #f472b6 0%, #fb7185 50%, #f9a8d4 100%);
|
|
830
|
+
--gradient-accent: linear-gradient(135deg, #facc15 0%, #f472b6 50%, #a78bfa 100%);
|
|
831
|
+
--gradient-subtle: linear-gradient(180deg, #1a0a14 0%, #2e1065 100%);
|
|
832
|
+
--gradient-success: linear-gradient(135deg, #4ade80 0%, #facc15 100%);
|
|
833
|
+
--gradient-warning: linear-gradient(135deg, #facc15 0%, #fb923c 100%);
|
|
834
|
+
--gradient-danger: linear-gradient(135deg, #fb7185 0%, #f472b6 100%);
|
|
835
|
+
--gradient-foreground: #ffffff;
|
|
836
|
+
|
|
837
|
+
--shadow-soft: var(--shadow-candy);
|
|
838
|
+
|
|
839
|
+
--divider: rgba(244, 114, 182, 0.4);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/* Tailwind theme customization */
|
|
843
|
+
@theme {
|
|
844
|
+
/* Customize line-heights for font sizes */
|
|
845
|
+
--text-xs--line-height: 1.5;
|
|
846
|
+
--text-sm--line-height: 1.5;
|
|
847
|
+
--text-base--line-height: 1.5;
|
|
848
|
+
--text-lg--line-height: 1.5;
|
|
849
|
+
--text-xl--line-height: 1.5;
|
|
850
|
+
--text-2xl--line-height: 1.5;
|
|
851
|
+
--text-3xl--line-height: 1.5;
|
|
852
|
+
--text-4xl--line-height: 1.4;
|
|
853
|
+
--text-5xl--line-height: 1.3;
|
|
854
|
+
--text-6xl--line-height: 1.2;
|
|
855
|
+
--text-7xl--line-height: 1.1;
|
|
856
|
+
--text-8xl--line-height: 1;
|
|
857
|
+
--text-9xl--line-height: 0.9;
|
|
858
|
+
|
|
859
|
+
/* Letter spacing */
|
|
860
|
+
--text-xs--letter-spacing: -0.02em;
|
|
861
|
+
--text-sm--letter-spacing: -0.02em;
|
|
862
|
+
--text-base--letter-spacing: -0.02em;
|
|
863
|
+
--text-lg--letter-spacing: -0.02em;
|
|
864
|
+
--text-xl--letter-spacing: -0.02em;
|
|
865
|
+
--text-2xl--letter-spacing: -0.02em;
|
|
866
|
+
--text-3xl--letter-spacing: -0.03em;
|
|
867
|
+
--text-4xl--letter-spacing: -0.04em;
|
|
868
|
+
--text-5xl--letter-spacing: -0.04em;
|
|
869
|
+
--text-6xl--letter-spacing: -0.04em;
|
|
870
|
+
--text-7xl--letter-spacing: -0.04em;
|
|
871
|
+
--text-8xl--letter-spacing: -0.04em;
|
|
872
|
+
--text-9xl--letter-spacing: -0.04em;
|
|
873
|
+
|
|
874
|
+
/* Z-index scale from tokens.css */
|
|
875
|
+
--z-base: 1;
|
|
876
|
+
--z-sticky: 1000;
|
|
877
|
+
--z-dropdown: 1001;
|
|
878
|
+
--z-drawer: 10002; /* Drawers must be highest (above modals at 10000) */
|
|
879
|
+
--z-overlay: 10001; /* Drawer overlay (above modals at 10000) */
|
|
880
|
+
--z-modal: 10000;
|
|
881
|
+
--z-tooltip: 2147483647;
|
|
882
|
+
|
|
883
|
+
/* ===== Semantic Radius for Tailwind ===== */
|
|
884
|
+
/* Enables: rounded-button, rounded-input, rounded-card, etc. */
|
|
885
|
+
--radius-button: var(--radius-semantic-button);
|
|
886
|
+
--radius-input: var(--radius-semantic-input);
|
|
887
|
+
--radius-card: var(--radius-semantic-card);
|
|
888
|
+
--radius-modal: var(--radius-semantic-modal);
|
|
889
|
+
--radius-badge: var(--radius-semantic-badge);
|
|
890
|
+
--radius-avatar: var(--radius-semantic-avatar);
|
|
891
|
+
--radius-tooltip: var(--radius-semantic-tooltip);
|
|
892
|
+
--radius-image: var(--radius-semantic-image);
|
|
893
|
+
|
|
894
|
+
/* ===== Theme-specific shadow variants ===== */
|
|
895
|
+
--shadow-brutal: var(--shadow-brutal, 4px 4px 0 0 currentColor);
|
|
896
|
+
--shadow-brutal-sm: var(--shadow-brutal-sm, 2px 2px 0 0 currentColor);
|
|
897
|
+
--shadow-brutal-lg: var(--shadow-brutal-lg, 6px 6px 0 0 currentColor);
|
|
898
|
+
--shadow-glow: var(--glow-primary, 0 0 20px currentColor);
|
|
899
|
+
--shadow-candy: var(--shadow-candy, 0 4px 14px currentColor);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
/* =============================================================================
|
|
903
|
+
* THEME-SPECIFIC UTILITY CLASSES
|
|
904
|
+
* =============================================================================
|
|
905
|
+
* Utility classes that leverage theme-specific CSS variables.
|
|
906
|
+
* These adapt automatically based on the active theme.
|
|
907
|
+
*/
|
|
908
|
+
|
|
909
|
+
/* Glassmorphism / Frosted glass effect */
|
|
910
|
+
.glass {
|
|
911
|
+
background: var(--glass-bg, rgba(255, 255, 255, 0.7));
|
|
912
|
+
backdrop-filter: blur(var(--glass-blur, 12px)) saturate(var(--glass-saturation, 180%));
|
|
913
|
+
-webkit-backdrop-filter: blur(var(--glass-blur, 12px)) saturate(var(--glass-saturation, 180%));
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/* Gradient background using theme primary gradient */
|
|
917
|
+
.bg-gradient-primary {
|
|
918
|
+
background: var(--gradient-primary, linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%));
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/* Text color for gradient backgrounds */
|
|
922
|
+
.text-gradient-foreground {
|
|
923
|
+
color: var(--gradient-foreground, var(--primary-foreground));
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
/* Auto-gradient primary button: uses gradient if theme defines one, otherwise solid primary */
|
|
927
|
+
.btn-primary-auto {
|
|
928
|
+
background: var(--gradient-primary, var(--primary));
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
/* Glow effect using theme glow */
|
|
932
|
+
.shadow-glow {
|
|
933
|
+
box-shadow: var(--glow-primary, 0 0 20px rgba(99, 102, 241, 0.3));
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/* Soft shadow - now defined in utilities.css (imported by apps) */
|
|
937
|
+
/* Variable --shadow-soft is set in :root above and can be overridden by themes */
|
|
938
|
+
|
|
939
|
+
/* Brutal shadow for neo-brutalism */
|
|
940
|
+
.shadow-brutal {
|
|
941
|
+
box-shadow: var(--shadow-brutal, 4px 4px 0 0 currentColor);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
.shadow-brutal-sm {
|
|
945
|
+
box-shadow: var(--shadow-brutal-sm, 2px 2px 0 0 currentColor);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
.shadow-brutal-lg {
|
|
949
|
+
box-shadow: var(--shadow-brutal-lg, 6px 6px 0 0 currentColor);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
/* Thick border for brutalism */
|
|
953
|
+
.border-brutal {
|
|
954
|
+
border-width: var(--border-width, 3px);
|
|
955
|
+
border-style: solid;
|
|
956
|
+
border-color: var(--border-brutal-color, currentColor);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/* -----------------------------------------------------------------------------
|
|
960
|
+
* FIXED RADIUS UTILITIES
|
|
961
|
+
* Use these when an element MUST maintain a specific radius regardless of theme.
|
|
962
|
+
*
|
|
963
|
+
* When to use:
|
|
964
|
+
* - Heart/favorite buttons that should always be circular
|
|
965
|
+
* - Avatar placeholders that must stay round in brutalist themes
|
|
966
|
+
* - Any element where the shape is functional, not aesthetic
|
|
967
|
+
*
|
|
968
|
+
* Pattern: .rounded-fixed-{size}
|
|
969
|
+
* These use !important to override theme styles intentionally.
|
|
970
|
+
* -------------------------------------------------------------------------- */
|
|
971
|
+
.rounded-fixed-full {
|
|
972
|
+
border-radius: 9999px !important;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
.rounded-fixed-none {
|
|
976
|
+
border-radius: 0 !important;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
/* -----------------------------------------------------------------------------
|
|
980
|
+
* Neo-Brutalist Color Utilities
|
|
981
|
+
* Use these classes to access the brutal color palette
|
|
982
|
+
* -------------------------------------------------------------------------- */
|
|
983
|
+
|
|
984
|
+
/* Background colors */
|
|
985
|
+
.bg-brutal-yellow { background-color: var(--brutal-yellow, #ffde59); }
|
|
986
|
+
.bg-brutal-pink { background-color: var(--brutal-pink, #ff6b9d); }
|
|
987
|
+
.bg-brutal-blue { background-color: var(--brutal-blue, #00d4ff); }
|
|
988
|
+
.bg-brutal-green { background-color: var(--brutal-green, #7fff00); }
|
|
989
|
+
.bg-brutal-orange { background-color: var(--brutal-orange, #ff5722); }
|
|
990
|
+
.bg-brutal-purple { background-color: var(--brutal-purple, #b388ff); }
|
|
991
|
+
.bg-brutal-red { background-color: var(--brutal-red, #ff1744); }
|
|
992
|
+
.bg-brutal-black { background-color: var(--brutal-black, #000000); }
|
|
993
|
+
.bg-brutal-white { background-color: var(--brutal-white, #ffffff); }
|
|
994
|
+
|
|
995
|
+
/* Text colors */
|
|
996
|
+
.text-brutal-yellow { color: var(--brutal-yellow, #ffde59); }
|
|
997
|
+
.text-brutal-pink { color: var(--brutal-pink, #ff6b9d); }
|
|
998
|
+
.text-brutal-blue { color: var(--brutal-blue, #00d4ff); }
|
|
999
|
+
.text-brutal-green { color: var(--brutal-green, #7fff00); }
|
|
1000
|
+
.text-brutal-orange { color: var(--brutal-orange, #ff5722); }
|
|
1001
|
+
.text-brutal-purple { color: var(--brutal-purple, #b388ff); }
|
|
1002
|
+
.text-brutal-red { color: var(--brutal-red, #ff1744); }
|
|
1003
|
+
.text-brutal-black { color: var(--brutal-black, #000000); }
|
|
1004
|
+
.text-brutal-white { color: var(--brutal-white, #ffffff); }
|
|
1005
|
+
|
|
1006
|
+
/* Border colors */
|
|
1007
|
+
.border-brutal-yellow { border-color: var(--brutal-yellow, #ffde59); }
|
|
1008
|
+
.border-brutal-pink { border-color: var(--brutal-pink, #ff6b9d); }
|
|
1009
|
+
.border-brutal-blue { border-color: var(--brutal-blue, #00d4ff); }
|
|
1010
|
+
.border-brutal-green { border-color: var(--brutal-green, #7fff00); }
|
|
1011
|
+
.border-brutal-orange { border-color: var(--brutal-orange, #ff5722); }
|
|
1012
|
+
.border-brutal-purple { border-color: var(--brutal-purple, #b388ff); }
|
|
1013
|
+
.border-brutal-red { border-color: var(--brutal-red, #ff1744); }
|
|
1014
|
+
.border-brutal-black { border-color: var(--brutal-black, #000000); }
|
|
1015
|
+
.border-brutal-white { border-color: var(--brutal-white, #ffffff); }
|
|
1016
|
+
|
|
1017
|
+
/* Shadow with specific brutal colors */
|
|
1018
|
+
.shadow-brutal-yellow { box-shadow: 4px 4px 0 0 var(--brutal-yellow, #ffde59); }
|
|
1019
|
+
.shadow-brutal-pink { box-shadow: 4px 4px 0 0 var(--brutal-pink, #ff6b9d); }
|
|
1020
|
+
.shadow-brutal-blue { box-shadow: 4px 4px 0 0 var(--brutal-blue, #00d4ff); }
|
|
1021
|
+
.shadow-brutal-green { box-shadow: 4px 4px 0 0 var(--brutal-green, #7fff00); }
|
|
1022
|
+
.shadow-brutal-orange { box-shadow: 4px 4px 0 0 var(--brutal-orange, #ff5722); }
|
|
1023
|
+
.shadow-brutal-purple { box-shadow: 4px 4px 0 0 var(--brutal-purple, #b388ff); }
|
|
1024
|
+
.shadow-brutal-red { box-shadow: 4px 4px 0 0 var(--brutal-red, #ff1744); }
|
|
1025
|
+
.shadow-brutal-black { box-shadow: 4px 4px 0 0 var(--brutal-black, #000000); }
|
|
1026
|
+
|
|
1027
|
+
/* ===== Radix UI Animation Keyframes ===== */
|
|
1028
|
+
/* Used by Accordion, Collapsible, and other collapsible components */
|
|
1029
|
+
@keyframes accordion-down {
|
|
1030
|
+
from {
|
|
1031
|
+
height: 0;
|
|
1032
|
+
}
|
|
1033
|
+
to {
|
|
1034
|
+
height: var(--radix-accordion-content-height);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
@keyframes accordion-up {
|
|
1039
|
+
from {
|
|
1040
|
+
height: var(--radix-accordion-content-height);
|
|
1041
|
+
}
|
|
1042
|
+
to {
|
|
1043
|
+
height: 0;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
@keyframes collapsible-down {
|
|
1048
|
+
from {
|
|
1049
|
+
height: 0;
|
|
1050
|
+
}
|
|
1051
|
+
to {
|
|
1052
|
+
height: var(--radix-collapsible-content-height);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
@keyframes collapsible-up {
|
|
1057
|
+
from {
|
|
1058
|
+
height: var(--radix-collapsible-content-height);
|
|
1059
|
+
}
|
|
1060
|
+
to {
|
|
1061
|
+
height: 0;
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/* Apply Inter font features and tighter letter spacing globally */
|
|
1066
|
+
@layer theme {
|
|
1067
|
+
:root {
|
|
1068
|
+
font-feature-settings:
|
|
1069
|
+
'blwf' 1,
|
|
1070
|
+
'cv03' 1,
|
|
1071
|
+
'cv04' 1,
|
|
1072
|
+
'cv09' 1,
|
|
1073
|
+
'cv11' 1;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
body {
|
|
1078
|
+
font-family: var(--font-inter);
|
|
1079
|
+
font-feature-settings:
|
|
1080
|
+
'blwf' 1,
|
|
1081
|
+
'cv03' 1,
|
|
1082
|
+
'cv04' 1,
|
|
1083
|
+
'cv09' 1,
|
|
1084
|
+
'cv11' 1;
|
|
1085
|
+
|
|
1086
|
+
/* iOS 26+ Safari: Required for position:absolute backdrops to cover full viewport */
|
|
1087
|
+
/* See: https://base-ui.com/react/overview/quick-start#ios-26-safari */
|
|
1088
|
+
position: relative;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/* Legacy CSS variables for panels/drawers/modals */
|
|
1092
|
+
:root {
|
|
1093
|
+
/* Background Colors - aligned with HeroUI v3 defaults */
|
|
1094
|
+
--color-bg-primary: #ffffff;
|
|
1095
|
+
--color-bg-secondary: #f5f5f5; /* HeroUI default background (neutral-100) */
|
|
1096
|
+
--color-bg-tertiary: #fafafa;
|
|
1097
|
+
--color-bg-input: #f3f4f6;
|
|
1098
|
+
--color-bg-hover: #f1f5f9;
|
|
1099
|
+
--color-bg-active: #e5f7d6;
|
|
1100
|
+
|
|
1101
|
+
/* Text Colors */
|
|
1102
|
+
--color-text-primary: #0f172a;
|
|
1103
|
+
--color-text-secondary: #111827;
|
|
1104
|
+
--color-text-tertiary: #1f2937;
|
|
1105
|
+
--color-text-muted: #64748b;
|
|
1106
|
+
--color-text-subtle: #6b7280;
|
|
1107
|
+
--color-text-placeholder: #9ca3af;
|
|
1108
|
+
|
|
1109
|
+
/* Border Colors */
|
|
1110
|
+
--color-border-primary: #e5e7eb;
|
|
1111
|
+
--color-border-secondary: #d1d5db;
|
|
1112
|
+
--color-border-focus: #94a3b8;
|
|
1113
|
+
--color-border-hover: #d1d5db;
|
|
1114
|
+
|
|
1115
|
+
/* Accent Colors - Map to HeroUI theme */
|
|
1116
|
+
--color-accent-primary: var(--accent);
|
|
1117
|
+
--color-accent-hover: var(--accent);
|
|
1118
|
+
--color-accent-light: color-mix(in oklch, var(--accent) 20%, transparent);
|
|
1119
|
+
|
|
1120
|
+
/* Status Colors - HeroUI v3 exact semantic colors */
|
|
1121
|
+
--color-status-success: oklch(0.7329 0.1935 150.81); /* HeroUI success green */
|
|
1122
|
+
--color-status-success-foreground: oklch(0.2103 0.0059 285.89); /* Eclipse (dark text) */
|
|
1123
|
+
--color-status-warning: oklch(0.7819 0.1585 72.33); /* HeroUI warning amber */
|
|
1124
|
+
--color-status-warning-foreground: oklch(0.2103 0.0059 285.89); /* Eclipse (dark text) */
|
|
1125
|
+
--color-status-error: oklch(0.6532 0.2328 25.74); /* HeroUI danger red */
|
|
1126
|
+
--color-status-error-foreground: oklch(0.9911 0 0); /* Snow (light text) */
|
|
1127
|
+
--color-status-info: oklch(0.6204 0.195 253.83); /* HeroUI accent blue */
|
|
1128
|
+
--color-status-info-foreground: oklch(0.9911 0 0); /* Snow (light text) */
|
|
1129
|
+
|
|
1130
|
+
/* Drawer/Panel backgrounds */
|
|
1131
|
+
--color-drawer-bg: #ffffff;
|
|
1132
|
+
--color-drawer-handle: #d1d5db;
|
|
1133
|
+
--gradient-drawer-overlay: rgba(0, 0, 0, 0.4);
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
.dark {
|
|
1137
|
+
/* Background Colors - aligned with HeroUI v3 defaults */
|
|
1138
|
+
--color-bg-primary: #080809; /* Standardized dark background */
|
|
1139
|
+
--color-bg-secondary: #18181b; /* zinc-900 */
|
|
1140
|
+
--color-bg-tertiary: #333333;
|
|
1141
|
+
--color-bg-input: #242424;
|
|
1142
|
+
--color-bg-hover: #3a3a3a;
|
|
1143
|
+
--color-bg-active: #4a4a4a;
|
|
1144
|
+
|
|
1145
|
+
/* Text Colors */
|
|
1146
|
+
--color-text-primary: #f1f5f9;
|
|
1147
|
+
--color-text-secondary: #e2e8f0;
|
|
1148
|
+
--color-text-tertiary: #cbd5e1;
|
|
1149
|
+
--color-text-muted: #94a3b8;
|
|
1150
|
+
--color-text-subtle: #64748b;
|
|
1151
|
+
--color-text-placeholder: #475569;
|
|
1152
|
+
|
|
1153
|
+
/* Border Colors — bumped to stay visible on the lifted --surface
|
|
1154
|
+
* (oklch 0.30). The previous values (#3a3a3a ≈ oklch 0.31) sat at the
|
|
1155
|
+
* same lightness as the new surface and disappeared on every bordered
|
|
1156
|
+
* card, drawer, and dropdown. */
|
|
1157
|
+
--color-border-primary: #545454; /* ≈ oklch 0.42 */
|
|
1158
|
+
--color-border-secondary: #5f5f5f; /* ≈ oklch 0.46 */
|
|
1159
|
+
--color-border-focus: #6e7f96; /* unchanged role; nudged slightly */
|
|
1160
|
+
--color-border-hover: #6a6a6a; /* ≈ oklch 0.50 */
|
|
1161
|
+
|
|
1162
|
+
/* Accent Colors - Map to HeroUI theme */
|
|
1163
|
+
--color-accent-primary: var(--accent);
|
|
1164
|
+
--color-accent-hover: var(--accent);
|
|
1165
|
+
--color-accent-light: color-mix(in oklch, var(--accent) 20%, transparent);
|
|
1166
|
+
|
|
1167
|
+
/* Status Colors - HeroUI v3 exact semantic colors (dark mode) */
|
|
1168
|
+
--color-status-success: oklch(0.7329 0.1935 150.81); /* HeroUI success green (same) */
|
|
1169
|
+
--color-status-success-foreground: oklch(0.2103 0.0059 285.89); /* Eclipse (dark text) */
|
|
1170
|
+
--color-status-warning: oklch(0.8203 0.1388 76.34); /* HeroUI warning amber (brighter) */
|
|
1171
|
+
--color-status-warning-foreground: oklch(0.2103 0.0059 285.89); /* Eclipse (dark text) */
|
|
1172
|
+
--color-status-error: oklch(0.594 0.1967 24.63); /* HeroUI danger red (dark mode) */
|
|
1173
|
+
--color-status-error-foreground: oklch(0.9911 0 0); /* Snow (light text) */
|
|
1174
|
+
--color-status-info: oklch(0.6204 0.195 253.83); /* HeroUI accent blue */
|
|
1175
|
+
--color-status-info-foreground: oklch(0.9911 0 0); /* Snow (light text) */
|
|
1176
|
+
|
|
1177
|
+
/* Tailwind v4 color mappings (must be defined here for proper cascade) */
|
|
1178
|
+
--color-default: var(--default);
|
|
1179
|
+
--color-default-foreground: var(--default-foreground);
|
|
1180
|
+
|
|
1181
|
+
/* Drawer/Panel backgrounds */
|
|
1182
|
+
--color-drawer-bg: #1a1a1a;
|
|
1183
|
+
--color-drawer-handle: #444444;
|
|
1184
|
+
--gradient-drawer-overlay: rgba(0, 0, 0, 0.6);
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
/* Component Overrides */
|
|
1188
|
+
@layer components {
|
|
1189
|
+
/**
|
|
1190
|
+
* Slider Thumb - Override HeroUI's hardcoded white background
|
|
1191
|
+
* Use --accent-foreground to ensure contrast with black/white accent colors
|
|
1192
|
+
*
|
|
1193
|
+
* Light mode: accent is black → thumb is white
|
|
1194
|
+
* Dark mode: accent is white → thumb is black
|
|
1195
|
+
*/
|
|
1196
|
+
.slider__thumb::after {
|
|
1197
|
+
background: var(--accent-foreground) !important;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
/**
|
|
1201
|
+
* Slider No Fill - Hide track endcaps when there's no fill
|
|
1202
|
+
* Add 'slider-no-fill' class to hide the accent-colored borders at track edges
|
|
1203
|
+
*/
|
|
1204
|
+
.slider.slider-no-fill .slider__track {
|
|
1205
|
+
border-left-color: transparent !important;
|
|
1206
|
+
border-right-color: transparent !important;
|
|
1207
|
+
border-top-color: transparent !important;
|
|
1208
|
+
border-bottom-color: transparent !important;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
/* Enhanced visibility when on Surface components */
|
|
1212
|
+
.surface .slider.slider-no-fill .slider__track {
|
|
1213
|
+
background: rgba(0, 0, 0, 0.15) !important;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
.dark .surface .slider.slider-no-fill .slider__track {
|
|
1217
|
+
background: rgba(255, 255, 255, 0.15) !important;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
/* Accessibility Utilities */
|
|
1222
|
+
@layer utilities {
|
|
1223
|
+
/* Screen reader only - visually hidden but accessible to screen readers */
|
|
1224
|
+
.sr-only {
|
|
1225
|
+
position: absolute;
|
|
1226
|
+
width: 1px;
|
|
1227
|
+
height: 1px;
|
|
1228
|
+
padding: 0;
|
|
1229
|
+
margin: -1px;
|
|
1230
|
+
overflow: hidden;
|
|
1231
|
+
clip: rect(0, 0, 0, 0);
|
|
1232
|
+
white-space: nowrap;
|
|
1233
|
+
border-width: 0;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
/* View Transitions API - Theme Toggle Animation */
|
|
1238
|
+
::view-transition-old(root),
|
|
1239
|
+
::view-transition-new(root) {
|
|
1240
|
+
animation: none;
|
|
1241
|
+
mix-blend-mode: normal;
|
|
1242
|
+
}
|