vibecarbon 0.8.0 → 0.9.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.
Files changed (39) hide show
  1. package/carbon/scripts/dev-init.js +6 -2
  2. package/carbon/src/client/assets/vibecarbon-icon.svg +6 -6
  3. package/carbon/src/client/assets/vibecarbon-wordmark-text-dark.svg +12 -0
  4. package/carbon/src/client/assets/vibecarbon-wordmark-text-light.svg +12 -0
  5. package/carbon/src/client/components/AIIntegrationSection.tsx +1 -3
  6. package/carbon/src/client/components/AppSidebar.tsx +35 -28
  7. package/carbon/src/client/components/CTAFooter.tsx +1 -1
  8. package/carbon/src/client/components/ComparisonSection.tsx +1 -3
  9. package/carbon/src/client/components/ContentPanel.tsx +1 -1
  10. package/carbon/src/client/components/DeploymentScenariosSection.tsx +1 -3
  11. package/carbon/src/client/components/FAQSection.tsx +1 -1
  12. package/carbon/src/client/components/Hero.tsx +13 -1
  13. package/carbon/src/client/components/Logo.tsx +66 -49
  14. package/carbon/src/client/components/Nav.tsx +1 -1
  15. package/carbon/src/client/components/NewsletterSignup.tsx +1 -1
  16. package/carbon/src/client/components/NotificationDrawer.tsx +3 -3
  17. package/carbon/src/client/components/PageHeader.tsx +1 -1
  18. package/carbon/src/client/components/PricingSection.tsx +2 -6
  19. package/carbon/src/client/components/TechStackSection.tsx +1 -3
  20. package/carbon/src/client/components/effects/FilmGrainOverlay.tsx +5 -0
  21. package/carbon/src/client/components/ui/button.tsx +1 -1
  22. package/carbon/src/client/components/ui/card.tsx +1 -1
  23. package/carbon/src/client/components/ui/dialog.tsx +1 -1
  24. package/carbon/src/client/components/ui/dropdown-menu.tsx +2 -2
  25. package/carbon/src/client/components/ui/popover.tsx +1 -1
  26. package/carbon/src/client/components/ui/select.tsx +1 -1
  27. package/carbon/src/client/components/ui/sidebar.tsx +1 -1
  28. package/carbon/src/client/index.css +186 -104
  29. package/carbon/src/client/lib/theme.ts +14 -14
  30. package/carbon/src/client/locales/en.json +4 -4
  31. package/carbon/src/client/pages/Blog.tsx +1 -1
  32. package/carbon/src/client/pages/Changelog.tsx +1 -1
  33. package/carbon/src/client/pages/Dashboard.tsx +33 -40
  34. package/carbon/src/client/pages/Docs.tsx +1 -1
  35. package/carbon/src/client/pages/Home.tsx +1 -1
  36. package/carbon/src/client/pages/Legal.tsx +1 -1
  37. package/package.json +1 -1
  38. package/carbon/src/client/assets/vibecarbon-logo-dark.svg +0 -29
  39. package/carbon/src/client/assets/vibecarbon-logo-light.svg +0 -29
@@ -201,13 +201,9 @@ export function PricingSection() {
201
201
  </motion.div>
202
202
  <h2 className="mb-4 text-3xl font-black tracking-tight md:text-5xl">
203
203
  {t('landing.pricing.headline1')}{' '}
204
- <span className="bg-gradient-to-r from-muted-foreground to-foreground bg-clip-text text-transparent">
205
- {t('landing.pricing.headlineSketch')}
206
- </span>{' '}
204
+ <span className="text-foreground">{t('landing.pricing.headlineSketch')}</span>{' '}
207
205
  {t('landing.pricing.headline2')}{' '}
208
- <span className="bg-gradient-to-r from-primary to-secondary-accent bg-clip-text text-transparent">
209
- {t('landing.pricing.headlineScale')}
210
- </span>
206
+ <span className="text-primary">{t('landing.pricing.headlineScale')}</span>
211
207
  </h2>
212
208
  <p className="text-lg text-muted-foreground">{t('landing.pricing.subheading')}</p>
213
209
  </motion.div>
@@ -60,9 +60,7 @@ export function TechStackSection() {
60
60
  </motion.div>
61
61
  <h2 className="text-3xl md:text-5xl font-black tracking-tight mb-4">
62
62
  {t('landing.techStack.headline')}{' '}
63
- <span className="bg-gradient-to-r from-primary via-cyan-400 to-secondary-accent bg-clip-text text-transparent">
64
- {t('landing.techStack.headlineHighlight')}
65
- </span>
63
+ <span className="text-primary">{t('landing.techStack.headlineHighlight')}</span>
66
64
  </h2>
67
65
  <p className="text-lg text-muted-foreground max-w-2xl mx-auto">
68
66
  {t('landing.techStack.subheading')}
@@ -1,3 +1,4 @@
1
+ import { useTheme } from 'next-themes';
1
2
  import { useReducedMotion } from '../../hooks/useReducedMotion';
2
3
 
3
4
  interface FilmGrainOverlayProps {
@@ -8,11 +9,15 @@ interface FilmGrainOverlayProps {
8
9
  /**
9
10
  * Film grain overlay for anodized metal/industrial feel
10
11
  * Uses SVG noise filter for subtle texture
12
+ * Dark mode only — grain reads as dirt on light surfaces
11
13
  */
12
14
  export function FilmGrainOverlay({ opacity = 0.03, animated = false }: FilmGrainOverlayProps) {
13
15
  const prefersReducedMotion = useReducedMotion();
16
+ const { resolvedTheme } = useTheme();
14
17
  const shouldAnimate = animated && !prefersReducedMotion;
15
18
 
19
+ if (resolvedTheme !== 'dark') return null;
20
+
16
21
  return (
17
22
  <div
18
23
  className="fixed inset-0 pointer-events-none z-[9999]"
@@ -18,7 +18,7 @@ const buttonVariants = cva(
18
18
  secondary:
19
19
  'border-transparent bg-secondary text-secondary-foreground hover:brightness-125 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground',
20
20
  ghost:
21
- 'border-transparent hover:bg-white/10 hover:text-foreground hover:brightness-125 aria-expanded:bg-muted aria-expanded:text-foreground',
21
+ 'border-transparent hover:bg-foreground/8 hover:text-foreground dark:hover:brightness-125 aria-expanded:bg-muted aria-expanded:text-foreground',
22
22
  destructive:
23
23
  'border-transparent bg-destructive/10 hover:bg-destructive/25 hover:brightness-115 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40',
24
24
  link: 'border-transparent text-primary underline-offset-4 hover:underline hover:brightness-115',
@@ -12,7 +12,7 @@ function Card({
12
12
  data-slot="card"
13
13
  data-size={size}
14
14
  className={cn(
15
- 'bg-card text-card-foreground gap-6 overflow-hidden rounded-[var(--radius-card)] py-6 text-sm ring-1 ring-border has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-[var(--radius-card)] *:[img:last-child]:rounded-b-[var(--radius-card)] group/card flex flex-col backdrop-blur-sm',
15
+ 'bg-card text-card-foreground gap-6 overflow-hidden rounded-[var(--radius-card)] py-6 text-sm ring-1 ring-border shadow-card has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-[var(--radius-card)] *:[img:last-child]:rounded-b-[var(--radius-card)] group/card flex flex-col',
16
16
  className
17
17
  )}
18
18
  {...props}
@@ -47,7 +47,7 @@ function DialogContent({
47
47
  <DialogPrimitive.Popup
48
48
  data-slot="dialog-content"
49
49
  className={cn(
50
- 'bg-card text-card-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-border grid max-w-[calc(100%-2rem)] gap-6 rounded-[var(--radius-card)] p-6 text-sm ring-1 duration-100 sm:max-w-md fixed top-1/2 left-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2 outline-none',
50
+ 'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-border grid max-w-[calc(100%-2rem)] gap-6 rounded-[var(--radius-card)] p-6 text-sm ring-1 shadow-pop duration-100 sm:max-w-md fixed top-1/2 left-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2 outline-none',
51
51
  className
52
52
  )}
53
53
  {...props}
@@ -38,7 +38,7 @@ function DropdownMenuContent({
38
38
  <MenuPrimitive.Popup
39
39
  data-slot="dropdown-menu-content"
40
40
  className={cn(
41
- 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border border-border bg-popover text-popover-foreground min-w-48 rounded-md p-1 shadow-lg duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden',
41
+ 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border border-border bg-popover text-popover-foreground min-w-48 rounded-md p-1 shadow-pop duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden',
42
42
  className
43
43
  )}
44
44
  {...props}
@@ -132,7 +132,7 @@ function DropdownMenuSubContent({
132
132
  <DropdownMenuContent
133
133
  data-slot="dropdown-menu-sub-content"
134
134
  className={cn(
135
- 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border border-border bg-popover text-popover-foreground min-w-36 rounded-md p-1 shadow-lg duration-100 w-auto',
135
+ 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border border-border bg-popover text-popover-foreground min-w-36 rounded-md p-1 shadow-pop duration-100 w-auto',
136
136
  className
137
137
  )}
138
138
  align={align}
@@ -32,7 +32,7 @@ function PopoverContent({
32
32
  <PopoverPrimitive.Popup
33
33
  data-slot="popover-content"
34
34
  className={cn(
35
- 'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 flex flex-col gap-4 rounded-2xl p-4 text-sm shadow-2xl ring-1 duration-100 z-50 w-72 origin-(--transform-origin) outline-hidden',
35
+ 'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 flex flex-col gap-4 rounded-2xl p-4 text-sm shadow-pop ring-1 duration-100 z-50 w-72 origin-(--transform-origin) outline-hidden',
36
36
  className
37
37
  )}
38
38
  {...props}
@@ -78,7 +78,7 @@ function SelectContent({
78
78
  <SelectPrimitive.Popup
79
79
  data-slot="select-content"
80
80
  className={cn(
81
- 'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 min-w-36 rounded-2xl shadow-2xl ring-1 duration-100 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto',
81
+ 'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 min-w-36 rounded-2xl shadow-pop ring-1 duration-100 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto',
82
82
  className
83
83
  )}
84
84
  {...props}
@@ -245,7 +245,7 @@ function Sidebar({
245
245
  <div
246
246
  data-sidebar="sidebar"
247
247
  data-slot="sidebar-inner"
248
- className="bg-sidebar group-data-[variant=floating]:ring-sidebar-border group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 flex size-full flex-col gap-6 p-6"
248
+ className="bg-sidebar backdrop-blur-md dark:backdrop-blur-none group-data-[variant=floating]:ring-sidebar-border group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 flex size-full flex-col gap-6 p-6"
249
249
  >
250
250
  {children}
251
251
  </div>
@@ -32,146 +32,169 @@ body {
32
32
 
33
33
  @custom-variant dark (&:is(.dark *));
34
34
 
35
- /* Theme: Teal with Glassmorphism */
36
- /* Primary: Bright Teal, Secondary Accent: Magenta */
37
- /* Typography: Noto Sans, JetBrains Mono (code) */
35
+ /* Theme: Refined Depth (dark) / Light Glass (light) */
36
+ /* Primary: Teal, Secondary Accent: Magenta — single interactive accent,
37
+ semantic colors reserved for status, glass applied selectively (.glass) */
38
+ /* Typography: Noto Sans (body + display), JetBrains Mono (code/data) */
38
39
 
39
40
  :root {
40
41
  /* ============================================
41
42
  CUSTOMIZE YOUR BRAND - Edit these values
42
43
  ============================================ */
43
- --primary: oklch(0.82 0.14 192); /* Brand primary (teal) */
44
- --primary-dim: oklch(0.55 0.12 192); /* Dimmed variant */
45
- --primary-foreground: oklch(0.98 0.01 181);
46
- --secondary-accent: oklch(0.45 0.2 350); /* Brand accent (magenta) */
44
+ --primary: oklch(0.52 0.124 192); /* Brand primary (deep teal, AA on light surfaces) */
45
+ --primary-dim: oklch(0.42 0.1 192); /* Dimmed variant */
46
+ --primary-foreground: oklch(0.99 0.005 192);
47
+ --secondary-accent: oklch(0.47 0.2 350); /* Brand accent (magenta) */
47
48
  --secondary-accent-foreground: oklch(0.99 0 0);
48
- --destructive: oklch(0.525 0.223 3.958); /* pink-700 */
49
+ --destructive: oklch(0.5 0.21 3.958);
49
50
  --info: var(--primary);
50
- --warning: oklch(0.769 0.188 70.08);
51
- --success: oklch(0.704 0.14 181);
51
+ --warning: oklch(0.62 0.13 75);
52
+ --success: oklch(0.5 0.12 181);
52
53
  --radius: 0.625rem; /* Border radius base */
53
54
  --radius-card: var(--radius-xl); /* Cards, dialogs, panels */
54
55
 
55
56
  /* Glow effects (derived from brand colors) */
56
- --glow-primary: oklch(0.82 0.14 192 / 0.25);
57
- --glow-accent: oklch(0.58 0.24 350 / 0.25);
57
+ --glow-primary: oklch(0.52 0.124 192 / 0.12);
58
+ --glow-accent: oklch(0.47 0.2 350 / 0.1);
58
59
 
59
- /* Light mode gradient (not visible by default) */
60
- --gradient-start: oklch(1 0 0);
61
- --gradient-end: oklch(0.98 0 0);
60
+ /* Canvas - pale cool gradient + faint ambient wash */
61
+ --gradient-start: oklch(0.985 0.005 220);
62
+ --gradient-end: oklch(0.945 0.014 215);
63
+ --canvas-wash: oklch(0.52 0.124 192 / 0.05);
62
64
 
63
65
  /* ============================================
64
66
  SURFACE COLORS - Rarely need customization
65
67
  ============================================ */
66
- --background: oklch(1 0 0);
67
- --foreground: oklch(0.13 0.028 261.692);
68
+ /* Transparent background to show canvas (both modes) */
69
+ --background: transparent;
70
+ --foreground: oklch(0.17 0.025 250);
71
+
72
+ /* Standard cards - quiet near-opaque surfaces (glass is opt-in via .glass) */
73
+ --card: oklch(0.995 0.004 210 / 0.92);
74
+ --card-foreground: oklch(0.17 0.025 250);
68
75
 
69
- --card: oklch(1 0 0);
70
- --card-foreground: oklch(0.13 0.028 261.692);
76
+ /* Glass surfaces - alpha gradient, light source top-left */
77
+ --glass-from: oklch(1 0 0 / 0.78);
78
+ --glass-to: oklch(0.97 0.01 215 / 0.58);
79
+ --glass-edge: oklch(1 0 0 / 0.65);
71
80
 
72
- --popover: oklch(1 0 0);
73
- --popover-foreground: oklch(0.13 0.028 261.692);
81
+ /* Popovers/dropdowns - SOLID (float over arbitrary content) */
82
+ --popover: oklch(0.99 0.004 210);
83
+ --popover-foreground: oklch(0.17 0.025 250);
74
84
 
75
- --secondary: oklch(0.967 0.001 286.375);
76
- --secondary-foreground: oklch(0.21 0.006 285.885);
85
+ --secondary: oklch(0.93 0.012 220 / 0.8);
86
+ --secondary-foreground: oklch(0.25 0.025 245);
77
87
 
78
- --muted: oklch(0.967 0.003 264.542);
79
- --muted-foreground: oklch(0.551 0.027 264.364);
88
+ --muted: oklch(0.94 0.01 220 / 0.7);
89
+ --muted-foreground: oklch(0.44 0.025 240);
80
90
 
81
- /* Accent matches primary for bold menu accent */
82
- --accent: var(--primary);
83
- --accent-foreground: var(--primary-foreground);
91
+ /* Accent - subtle primary tint for hover states */
92
+ --accent: oklch(0.52 0.124 192 / 0.1);
93
+ --accent-foreground: oklch(0.3 0.08 192);
94
+
95
+ /* Hairline borders */
96
+ --border: oklch(0.45 0.03 230 / 0.16);
97
+ --input: oklch(0.5 0.03 230 / 0.3);
98
+ --ring: var(--primary);
84
99
 
85
- --border: oklch(0.928 0.006 264.531);
86
- --input: oklch(0.928 0.006 264.531);
87
- --ring: oklch(0.707 0.022 261.325);
100
+ /* Elevation shadows - soft diffuse, cool-tinted */
101
+ --shadow-card: 0 1px 2px oklch(0.3 0.04 240 / 0.05), 0 10px 30px -10px oklch(0.3 0.05 240 / 0.12);
102
+ --shadow-pop: 0 4px 12px oklch(0.3 0.04 240 / 0.08), 0 16px 40px -12px oklch(0.3 0.05 240 / 0.18);
88
103
 
89
- /* Chart colors - vibrant multi-hue palette */
104
+ /* Chart colors - brand pair first, then supporting hues */
90
105
  --chart-1: var(--primary);
91
- --chart-2: var(--warning);
92
- --chart-3: var(--destructive);
93
- --chart-4: var(--success);
94
- --chart-5: oklch(0.65 0.22 290);
95
-
96
- /* Sidebar - Maia defaults with brand primary */
97
- --sidebar: oklch(0.985 0.002 247.839);
98
- --sidebar-foreground: oklch(0.13 0.028 261.692);
106
+ --chart-2: var(--secondary-accent);
107
+ --chart-3: oklch(0.5 0.17 275);
108
+ --chart-4: oklch(0.62 0.13 75);
109
+ --chart-5: oklch(0.54 0.11 155);
110
+
111
+ /* Sidebar - light glass rail */
112
+ --sidebar: oklch(0.975 0.007 212 / 0.55);
113
+ --sidebar-foreground: oklch(0.22 0.025 248);
99
114
  --sidebar-primary: var(--primary);
100
115
  --sidebar-primary-foreground: var(--primary-foreground);
101
- --sidebar-accent: var(--primary);
102
- --sidebar-accent-foreground: var(--primary-foreground);
103
- --sidebar-border: oklch(0.928 0.006 264.531);
104
- --sidebar-ring: oklch(0.707 0.022 261.325);
116
+ --sidebar-accent: oklch(0.52 0.124 192 / 0.12);
117
+ --sidebar-accent-foreground: oklch(0.3 0.08 192);
118
+ --sidebar-border: oklch(0.45 0.03 230 / 0.12);
119
+ --sidebar-ring: var(--primary);
105
120
  }
106
121
 
107
122
  .dark {
108
- /* Primary - brighter dim variant in dark mode */
123
+ /* Primary - bright teal on dark, brighter dim variant */
109
124
  --primary: oklch(0.82 0.14 192);
110
125
  --primary-dim: oklch(0.65 0.12 192);
111
- --primary-foreground: oklch(0.08 0 0);
126
+ --primary-foreground: oklch(0.1 0.02 220);
112
127
 
113
128
  /* Secondary accent (magenta) - brighter in dark mode */
114
129
  --secondary-accent: oklch(0.65 0.26 350);
115
130
  --secondary-accent-foreground: oklch(0.99 0 0);
116
131
 
117
- /* Glow colors */
118
- --glow-primary: oklch(0.82 0.14 192 / 0.5);
119
- --glow-accent: oklch(0.65 0.26 350 / 0.5);
132
+ /* Glow colors - restrained, focal points only */
133
+ --glow-primary: oklch(0.82 0.14 192 / 0.28);
134
+ --glow-accent: oklch(0.65 0.26 350 / 0.25);
120
135
 
121
- /* Body gradient colors */
122
- --gradient-start: oklch(0.12 0.02 265);
123
- --gradient-end: oklch(0.17 0.03 260);
136
+ /* Canvas - deep teal-tinted near-black + faint ambient wash */
137
+ --gradient-start: oklch(0.105 0.018 252);
138
+ --gradient-end: oklch(0.145 0.028 228);
139
+ --canvas-wash: oklch(0.82 0.14 192 / 0.09);
124
140
 
125
- /* Transparent background to show gradient */
141
+ /* Transparent background to show canvas */
126
142
  --background: transparent;
127
- --foreground: oklch(0.98 0 0);
143
+ --foreground: oklch(0.96 0.005 210);
144
+
145
+ /* Standard cards - quiet near-opaque surfaces */
146
+ --card: oklch(0.19 0.024 242 / 0.78);
147
+ --card-foreground: oklch(0.96 0.005 210);
128
148
 
129
- /* Card surfaces - with transparency */
130
- --card: oklch(0.28 0.04 255 / 0.5);
131
- --card-foreground: oklch(0.98 0 0);
149
+ /* Glass surfaces - alpha gradient, light source top-left */
150
+ --glass-from: oklch(0.25 0.028 238 / 0.6);
151
+ --glass-to: oklch(0.16 0.022 246 / 0.45);
152
+ --glass-edge: oklch(1 0 0 / 0.1);
132
153
 
133
- /* Popovers/dropdowns - cool-tinted to match body gradient */
134
- --popover: oklch(0.18 0.02 260);
135
- --popover-foreground: oklch(0.985 0 0);
154
+ /* Popovers/dropdowns - SOLID, cool-tinted to match canvas */
155
+ --popover: oklch(0.175 0.022 242);
156
+ --popover-foreground: oklch(0.97 0 0);
136
157
 
137
- /* Secondary - muted gray */
138
- --secondary: oklch(0.18 0 0);
139
- --secondary-foreground: oklch(0.9 0 0);
158
+ --secondary: oklch(0.25 0.02 240);
159
+ --secondary-foreground: oklch(0.92 0.008 220);
140
160
 
141
- /* Muted surfaces */
142
- --muted: oklch(0.15 0 0);
143
- --muted-foreground: oklch(0.707 0.022 261.325);
161
+ --muted: oklch(0.2 0.02 240 / 0.7);
162
+ --muted-foreground: oklch(0.71 0.02 228);
144
163
 
145
164
  /* Accent - subtle primary tint for hover states */
146
- --accent: oklch(0.30 0.04 200 / 0.5);
147
- --accent-foreground: oklch(0.98 0 0);
165
+ --accent: oklch(0.82 0.14 192 / 0.13);
166
+ --accent-foreground: oklch(0.96 0.005 210);
148
167
 
149
- /* Destructive - vibrant red */
150
- --destructive: oklch(0.525 0.223 3.958);
168
+ /* Status - lifted for dark-bg contrast */
169
+ --destructive: oklch(0.62 0.21 3.958);
151
170
  --info: var(--primary);
152
- --warning: oklch(0.769 0.188 70.08);
171
+ --warning: oklch(0.77 0.188 70.08);
153
172
  --success: oklch(0.704 0.14 181);
154
173
 
155
- /* Borders */
156
- --border: oklch(0.33 0.025 195);
157
- --input: oklch(1 0 0 / 15%);
174
+ /* Hairline borders - faint teal */
175
+ --border: oklch(0.9 0.03 200 / 0.12);
176
+ --input: oklch(1 0 0 / 0.12);
158
177
  --ring: var(--primary);
159
178
 
160
- /* Chart colors - vibrant multi-hue palette */
179
+ /* Elevation shadows - inner top edge-light + deep soft drop */
180
+ --shadow-card: inset 0 1px 0 oklch(1 0 0 / 0.06), 0 8px 24px -12px oklch(0 0 0 / 0.5);
181
+ --shadow-pop: inset 0 1px 0 oklch(1 0 0 / 0.08), 0 16px 48px -16px oklch(0 0 0 / 0.65);
182
+
183
+ /* Chart colors - brand pair first, then supporting hues */
161
184
  --chart-1: var(--primary);
162
- --chart-2: var(--warning);
163
- --chart-3: var(--destructive);
164
- --chart-4: var(--success);
165
- --chart-5: oklch(0.65 0.22 290);
185
+ --chart-2: var(--secondary-accent);
186
+ --chart-3: oklch(0.72 0.15 275);
187
+ --chart-4: oklch(0.8 0.15 80);
188
+ --chart-5: oklch(0.76 0.12 155);
166
189
 
167
- /* Sidebar */
190
+ /* Sidebar - transparent rail, canvas shows through */
168
191
  --sidebar: transparent;
169
- --sidebar-foreground: oklch(0.98 0 0);
192
+ --sidebar-foreground: oklch(0.96 0.005 210);
170
193
  --sidebar-primary: var(--primary);
171
- --sidebar-primary-foreground: oklch(0.08 0 0);
172
- --sidebar-accent: var(--primary);
173
- --sidebar-accent-foreground: oklch(0.08 0 0);
174
- --sidebar-border: transparent;
194
+ --sidebar-primary-foreground: oklch(0.1 0.02 220);
195
+ --sidebar-accent: oklch(0.82 0.14 192 / 0.13);
196
+ --sidebar-accent-foreground: oklch(0.96 0.005 210);
197
+ --sidebar-border: oklch(0.9 0.03 200 / 0.08);
175
198
  --sidebar-ring: var(--primary);
176
199
  }
177
200
 
@@ -179,6 +202,12 @@ body {
179
202
  /* Typography */
180
203
  --font-sans: "Noto Sans Variable", "Noto Sans", system-ui, sans-serif;
181
204
  --font-mono: "JetBrains Mono", ui-monospace, monospace;
205
+ /* Display slot kept as an extension point; defaults to the body sans face. */
206
+ --font-display: var(--font-sans);
207
+
208
+ /* Elevation shadows (values cascade from :root/.dark) */
209
+ --shadow-card: var(--shadow-card);
210
+ --shadow-pop: var(--shadow-pop);
182
211
 
183
212
  /* Extended primary colors */
184
213
  --color-primary-dim: var(--primary-dim);
@@ -242,21 +271,31 @@ body {
242
271
  body {
243
272
  @apply font-sans bg-background text-foreground antialiased cursor-default;
244
273
  }
245
- .dark body {
246
- background: linear-gradient(180deg, var(--gradient-start) 0%, var(--gradient-end) 100%);
274
+ /* Canvas: gradient + faint ambient wash (the "light" glass surfaces catch).
275
+ Both modes --background is transparent so this shows through. */
276
+ body {
277
+ background:
278
+ radial-gradient(120% 80% at 75% -20%, var(--canvas-wash), transparent 55%),
279
+ linear-gradient(180deg, var(--gradient-start) 0%, var(--gradient-end) 100%);
247
280
  background-attachment: fixed;
248
281
  }
249
282
  html {
250
283
  @apply font-sans;
251
284
  }
252
285
 
253
- /* Bold headlines */
286
+ /* Headlines: refined weights + balanced wrapping (display slot = body sans) */
254
287
  h1,
255
- h2,
288
+ h2 {
289
+ font-family: var(--font-display);
290
+ font-weight: 700;
291
+ letter-spacing: -0.015em;
292
+ text-wrap: balance;
293
+ }
256
294
  h3,
257
295
  h4 {
258
- font-weight: 900;
259
- letter-spacing: -0.02em;
296
+ font-weight: 700;
297
+ letter-spacing: -0.01em;
298
+ text-wrap: balance;
260
299
  }
261
300
  }
262
301
 
@@ -274,8 +313,19 @@ body {
274
313
  EFFECTS SYSTEM
275
314
  ============================================ */
276
315
 
277
- /* Film Grain Overlay */
278
- .film-grain::after {
316
+ /* Glass surface the ONLY glass treatment; applied selectively
317
+ (KPI strip, sidebar rail, marketing hero panels). Alpha gradient
318
+ mimics a top-left light source; border-top catches the light. */
319
+ .glass {
320
+ background: linear-gradient(135deg, var(--glass-from), var(--glass-to));
321
+ backdrop-filter: blur(14px);
322
+ border: 1px solid var(--border);
323
+ border-top-color: var(--glass-edge);
324
+ box-shadow: var(--shadow-card);
325
+ }
326
+
327
+ /* Film Grain Overlay (dark mode only — reads as dirt on light surfaces) */
328
+ .dark .film-grain::after {
279
329
  content: "";
280
330
  position: fixed;
281
331
  inset: 0;
@@ -287,30 +337,37 @@ body {
287
337
  background-repeat: repeat;
288
338
  }
289
339
 
290
- /* Glow utilities */
340
+ /* Active nav — teal icon, the sidebar's single focal accent */
341
+ [data-sidebar="menu-button"][data-active] svg {
342
+ color: var(--primary);
343
+ filter: drop-shadow(0 0 6px var(--glow-primary));
344
+ }
345
+
346
+ /* Glow utilities — restrained radii; reserved for focal points
347
+ (active nav, primary CTA, brand marks). Do not add new consumers. */
291
348
  .glow-teal {
292
- box-shadow: 0 0 20px var(--glow-primary), 0 0 40px var(--glow-primary);
349
+ box-shadow: 0 0 12px var(--glow-primary), 0 0 28px var(--glow-primary);
293
350
  }
294
351
 
295
352
  .glow-magenta {
296
- box-shadow: 0 0 20px var(--glow-accent), 0 0 40px var(--glow-accent);
353
+ box-shadow: 0 0 12px var(--glow-accent), 0 0 28px var(--glow-accent);
297
354
  }
298
355
 
299
356
  .glow-teal-subtle {
300
- box-shadow: 0 0 15px var(--glow-primary);
357
+ box-shadow: 0 0 10px var(--glow-primary);
301
358
  }
302
359
 
303
360
  .glow-magenta-subtle {
304
- box-shadow: 0 0 15px var(--glow-accent);
361
+ box-shadow: 0 0 10px var(--glow-accent);
305
362
  }
306
363
 
307
364
  /* Text glow */
308
365
  .text-glow-teal {
309
- text-shadow: 0 0 20px var(--glow-primary), 0 0 40px var(--glow-primary);
366
+ text-shadow: 0 0 12px var(--glow-primary), 0 0 28px var(--glow-primary);
310
367
  }
311
368
 
312
369
  .text-glow-magenta {
313
- text-shadow: 0 0 20px var(--glow-accent), 0 0 40px var(--glow-accent);
370
+ text-shadow: 0 0 12px var(--glow-accent), 0 0 28px var(--glow-accent);
314
371
  }
315
372
 
316
373
  /* Border glow on hover */
@@ -319,11 +376,11 @@ body {
319
376
  }
320
377
 
321
378
  .border-glow-teal:hover {
322
- box-shadow: 0 0 0 1px var(--primary), 0 0 15px var(--glow-primary);
379
+ box-shadow: 0 0 0 1px var(--primary), 0 0 10px var(--glow-primary);
323
380
  }
324
381
 
325
382
  .border-glow-magenta:hover {
326
- box-shadow: 0 0 0 1px var(--secondary-accent), 0 0 15px var(--glow-accent);
383
+ box-shadow: 0 0 0 1px var(--secondary-accent), 0 0 10px var(--glow-accent);
327
384
  }
328
385
 
329
386
  /* Sparkle shimmer for premium badges */
@@ -336,6 +393,7 @@ body {
336
393
  background-size: 200% 100%;
337
394
  animation: shimmer 3s ease-in-out infinite;
338
395
  }
396
+ @media (prefers-reduced-motion: reduce) { .badge-shimmer { animation: none; } }
339
397
 
340
398
  /* Marquee for LogoStrip */
341
399
  @keyframes marquee-scroll {
@@ -357,8 +415,9 @@ body {
357
415
  .hero-orb { animation: orb-pulse 6s ease-in-out infinite; }
358
416
  @media (prefers-reduced-motion: reduce) { .hero-orb { animation: none; } }
359
417
 
360
- /* Spotlight particle dots for glass containers */
361
- .spotlight-particles {
418
+ /* Spotlight particle dots for glass containers (dark mode only — white dots
419
+ read as noise on light surfaces) */
420
+ .dark .spotlight-particles {
362
421
  background-image: radial-gradient(circle, oklch(1 0 0 / 0.5) 1px, transparent 1px);
363
422
  background-size: 24px 24px;
364
423
  mask-image: radial-gradient(ellipse 80% 50% at 50% 0%, black 0%, transparent 80%);
@@ -458,4 +517,27 @@ body {
458
517
  :where(tr):not(:where([class~="not-prose"], [class~="not-prose"] *)):hover {
459
518
  background-color: oklch(0.20 0.02 260 / 0.3);
460
519
  }
520
+ }
521
+
522
+ /* ============================================
523
+ REDUCED TRANSPARENCY - solidify glass surfaces
524
+ ============================================ */
525
+
526
+ @media (prefers-reduced-transparency: reduce) {
527
+ :root {
528
+ --card: oklch(0.99 0.004 210);
529
+ --sidebar: oklch(0.975 0.007 212);
530
+ --glass-from: oklch(0.99 0.004 210);
531
+ --glass-to: oklch(0.97 0.008 212);
532
+ }
533
+ .dark {
534
+ --card: oklch(0.19 0.024 242);
535
+ --sidebar: oklch(0.13 0.02 245);
536
+ --glass-from: oklch(0.21 0.024 242);
537
+ --glass-to: oklch(0.17 0.022 244);
538
+ }
539
+ .glass,
540
+ [data-slot="sidebar-inner"] {
541
+ backdrop-filter: none;
542
+ }
461
543
  }
@@ -1,25 +1,25 @@
1
1
  // Default values mirroring index.css
2
2
  export const DEFAULT_THEME = {
3
3
  light: {
4
- gradientStart: 'oklch(1 0 0)',
5
- gradientEnd: 'oklch(0.98 0 0)',
6
- card: 'oklch(1 0 0)',
7
- primary: 'oklch(0.82 0.14 192)',
8
- primaryDim: 'oklch(0.55 0.12 192)',
9
- primaryForeground: 'oklch(0.98 0.01 181)',
10
- secondaryAccent: 'oklch(0.45 0.2 350)',
4
+ gradientStart: 'oklch(0.985 0.005 220)',
5
+ gradientEnd: 'oklch(0.945 0.014 215)',
6
+ card: 'oklch(0.995 0.004 210 / 0.92)',
7
+ primary: 'oklch(0.52 0.124 192)',
8
+ primaryDim: 'oklch(0.42 0.1 192)',
9
+ primaryForeground: 'oklch(0.99 0.005 192)',
10
+ secondaryAccent: 'oklch(0.47 0.2 350)',
11
11
  secondaryAccentForeground: 'oklch(0.99 0 0)',
12
- destructive: 'oklch(0.525 0.223 3.958)',
13
- warning: 'oklch(0.769 0.188 70.08)',
14
- success: 'oklch(0.704 0.14 181)',
12
+ destructive: 'oklch(0.5 0.21 3.958)',
13
+ warning: 'oklch(0.62 0.13 75)',
14
+ success: 'oklch(0.5 0.12 181)',
15
15
  },
16
16
  dark: {
17
- gradientStart: 'oklch(0.12 0.02 265)',
18
- gradientEnd: 'oklch(0.17 0.03 260)',
19
- card: 'oklch(0.28 0.04 255 / 0.5)',
17
+ gradientStart: 'oklch(0.105 0.018 252)',
18
+ gradientEnd: 'oklch(0.145 0.028 228)',
19
+ card: 'oklch(0.19 0.024 242 / 0.78)',
20
20
  primary: 'oklch(0.82 0.14 192)',
21
21
  primaryDim: 'oklch(0.65 0.12 192)',
22
- primaryForeground: 'oklch(0.08 0 0)',
22
+ primaryForeground: 'oklch(0.1 0.02 220)',
23
23
  secondaryAccent: 'oklch(0.65 0.26 350)',
24
24
  secondaryAccentForeground: 'oklch(0.99 0 0)',
25
25
  },
@@ -274,7 +274,7 @@
274
274
  "hero": {
275
275
  "badge": "Fully Automated · Self-Hosted",
276
276
  "headline1": "Professional Grade",
277
- "subheading": "Full-stack SaaS starter kit with automated everything built for AI-driven development.",
277
+ "subheading": "Full-stack SaaS starter with the most easy-to-use DevOps CLI ever. Built for AI-driven development.",
278
278
  "getUpdates": "Get Updates"
279
279
  },
280
280
  "logoStrip": {
@@ -285,15 +285,15 @@
285
285
  "subheading": "Provision, deploy, and scale from the CLI",
286
286
  "create": {
287
287
  "label": "Create",
288
- "description": "Full-stack app with auth, database, API, and Kubernetes manifests — ready to go."
288
+ "description": "Full-stack SaaS template with everything you need build, deploy, and maintain advanced applications."
289
289
  },
290
290
  "develop": {
291
291
  "label": "Develop",
292
- "description": "Spin up your entire dev environment: database, auth, API, and hot-reloading frontend."
292
+ "description": "Spin up a dev environment for building your app using AI, complete with security guardrails and a hot-reloading frontend."
293
293
  },
294
294
  "deploy": {
295
295
  "label": "Deploy",
296
- "description": "Provision a VPS or Kubernetes cluster with SSL, HA, backups, and CI/CD in one command."
296
+ "description": "Deploy on Hetzner with Docker Compose or Kubernetes. Complete with backups, auto-scaling, high-availability, and more advanced features with simple commands."
297
297
  }
298
298
  },
299
299
  "techStack": {