vibecarbon 0.7.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 (44) hide show
  1. package/carbon/biome.json +3 -2
  2. package/carbon/package.json +20 -20
  3. package/carbon/scripts/dev-init.js +6 -2
  4. package/carbon/src/client/assets/vibecarbon-icon.svg +6 -6
  5. package/carbon/src/client/assets/vibecarbon-wordmark-text-dark.svg +12 -0
  6. package/carbon/src/client/assets/vibecarbon-wordmark-text-light.svg +12 -0
  7. package/carbon/src/client/components/AIIntegrationSection.tsx +1 -3
  8. package/carbon/src/client/components/AppSidebar.tsx +35 -28
  9. package/carbon/src/client/components/CTAFooter.tsx +1 -1
  10. package/carbon/src/client/components/ComparisonSection.tsx +1 -3
  11. package/carbon/src/client/components/ContentPanel.tsx +1 -1
  12. package/carbon/src/client/components/DeploymentScenariosSection.tsx +1 -3
  13. package/carbon/src/client/components/FAQSection.tsx +1 -1
  14. package/carbon/src/client/components/Hero.tsx +13 -1
  15. package/carbon/src/client/components/Logo.tsx +66 -49
  16. package/carbon/src/client/components/Nav.tsx +1 -1
  17. package/carbon/src/client/components/NewsletterSignup.tsx +1 -1
  18. package/carbon/src/client/components/NotificationDrawer.tsx +3 -3
  19. package/carbon/src/client/components/PageHeader.tsx +1 -1
  20. package/carbon/src/client/components/PricingSection.tsx +2 -6
  21. package/carbon/src/client/components/TechStackSection.tsx +1 -3
  22. package/carbon/src/client/components/effects/FilmGrainOverlay.tsx +5 -0
  23. package/carbon/src/client/components/ui/button.tsx +1 -1
  24. package/carbon/src/client/components/ui/card.tsx +1 -1
  25. package/carbon/src/client/components/ui/dialog.tsx +1 -1
  26. package/carbon/src/client/components/ui/dropdown-menu.tsx +2 -2
  27. package/carbon/src/client/components/ui/popover.tsx +1 -1
  28. package/carbon/src/client/components/ui/select.tsx +1 -1
  29. package/carbon/src/client/components/ui/sidebar.tsx +1 -1
  30. package/carbon/src/client/index.css +186 -104
  31. package/carbon/src/client/lib/theme.ts +14 -14
  32. package/carbon/src/client/locales/en.json +4 -4
  33. package/carbon/src/client/pages/Blog.tsx +1 -1
  34. package/carbon/src/client/pages/Changelog.tsx +1 -1
  35. package/carbon/src/client/pages/Dashboard.tsx +33 -40
  36. package/carbon/src/client/pages/Docs.tsx +1 -1
  37. package/carbon/src/client/pages/Home.tsx +1 -1
  38. package/carbon/src/client/pages/Legal.tsx +1 -1
  39. package/carbon/src/server/lib/env.ts +1 -1
  40. package/package.json +13 -13
  41. package/src/lib/orphan.js +221 -0
  42. package/src/up.js +22 -7
  43. package/carbon/src/client/assets/vibecarbon-logo-dark.svg +0 -29
  44. package/carbon/src/client/assets/vibecarbon-logo-light.svg +0 -29
package/carbon/biome.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
2
+ "root": false,
3
+ "$schema": "https://biomejs.dev/schemas/2.5.1/schema.json",
3
4
  "linter": {
4
5
  "enabled": true,
5
6
  "rules": {
6
- "recommended": true,
7
+ "preset": "recommended",
7
8
  "complexity": {
8
9
  "noUselessFragments": "warn"
9
10
  },
@@ -50,7 +50,7 @@
50
50
  "stripe:listen": "stripe listen --forward-to localhost:3000/api/webhooks/stripe"
51
51
  },
52
52
  "dependencies": {
53
- "@base-ui/react": "^1.5.0",
53
+ "@base-ui/react": "^1.6.0",
54
54
  "@fontsource-variable/noto-sans": "^5.2.10",
55
55
  "@fontsource/jetbrains-mono": "^5.2.8",
56
56
  "@hono/node-server": "^2.0.6",
@@ -58,39 +58,39 @@
58
58
  "@hookform/resolvers": "^5.4.0",
59
59
  "@mdx-js/react": "^3.1.1",
60
60
  "@mdx-js/rollup": "^3.1.1",
61
- "@scalar/api-reference-react": "^0.9.49",
62
- "@supabase/supabase-js": "^2.108.2",
63
- "@tanstack/react-query": "^5.100.14",
61
+ "@scalar/api-reference-react": "^0.9.50",
62
+ "@supabase/supabase-js": "^2.110.0",
63
+ "@tanstack/react-query": "^5.101.2",
64
64
  "class-variance-authority": "^0.7.1",
65
65
  "clsx": "^2.1.1",
66
66
  "cmdk": "^1.1.1",
67
67
  "date-fns": "^4.4.0",
68
68
  "embla-carousel-react": "^8.6.0",
69
- "framer-motion": "^12.40.0",
69
+ "framer-motion": "^12.42.2",
70
70
  "hono": "^4.12.27",
71
- "i18next": "^26.3.3",
71
+ "i18next": "^26.3.4",
72
72
  "i18next-browser-languagedetector": "^8.2.1",
73
73
  "input-otp": "^1.4.2",
74
74
  "ioredis": "^5.11.1",
75
75
  "lenis": "^1.3.25",
76
- "lucide-react": "^1.17.0",
76
+ "lucide-react": "^1.22.0",
77
77
  "next-themes": "^0.4.6",
78
- "nodemailer": "^9.0.1",
78
+ "nodemailer": "^9.0.3",
79
79
  "pino": "^10.3.1",
80
80
  "react": "^19.2.7",
81
81
  "react-day-picker": "^10.0.1",
82
82
  "react-dom": "^19.2.7",
83
- "react-hook-form": "^7.77.0",
83
+ "react-hook-form": "^7.80.0",
84
84
  "react-i18next": "^17.0.8",
85
- "react-resizable-panels": "^4.11.2",
86
- "react-router-dom": "^7.16.0",
87
- "recharts": "^3.8.1",
85
+ "react-resizable-panels": "^4.12.0",
86
+ "react-router-dom": "^7.18.1",
87
+ "recharts": "^3.9.1",
88
88
  "rehype-autolink-headings": "^7.1.0",
89
89
  "rehype-slug": "^6.0.0",
90
90
  "remark-frontmatter": "^5.0.0",
91
91
  "remark-mdx-frontmatter": "^5.2.0",
92
92
  "sonner": "^2.0.7",
93
- "stripe": "^22.2.0",
93
+ "stripe": "^22.3.0",
94
94
  "tailwind-merge": "^3.6.0",
95
95
  "vaul": "^1.1.2",
96
96
  "zod": "^4.4.3"
@@ -122,16 +122,16 @@
122
122
  }
123
123
  },
124
124
  "devDependencies": {
125
- "@biomejs/biome": "^2.4.16",
125
+ "@biomejs/biome": "^2.5.1",
126
126
  "@hono/swagger-ui": "^0.6.1",
127
- "@scalar/hono-api-reference": "^0.10.19",
127
+ "@scalar/hono-api-reference": "^0.11.7",
128
128
  "@tailwindcss/typography": "^0.5.20",
129
129
  "@tailwindcss/vite": "^4.3.2",
130
130
  "@testing-library/jest-dom": "^6.9.1",
131
131
  "@testing-library/react": "^16.3.2",
132
132
  "@testing-library/user-event": "^14.6.1",
133
- "@types/node": "^25.9.1",
134
- "@types/nodemailer": "^8.0.0",
133
+ "@types/node": "^26.0.1",
134
+ "@types/nodemailer": "^8.0.1",
135
135
  "@types/pg": "^8.20.0",
136
136
  "@types/react": "^19.2.17",
137
137
  "@types/react-dom": "^19.2.3",
@@ -139,15 +139,15 @@
139
139
  "@vitest/coverage-v8": "^4.1.9",
140
140
  "esbuild": "^0.28.1",
141
141
  "jsdom": "^29.1.1",
142
- "pg": "^8.21.0",
142
+ "pg": "^8.22.0",
143
143
  "pino-pretty": "^13.1.3",
144
144
  "remark-gfm": "^4.0.1",
145
- "shadcn": "^4.10.0",
145
+ "shadcn": "^4.12.0",
146
146
  "tailwindcss": "^4.3.2",
147
147
  "tsx": "^4.22.4",
148
148
  "tw-animate-css": "^1.4.0",
149
149
  "typescript": "^6.0.3",
150
- "vite": "^8.0.16",
150
+ "vite": "^8.1.2",
151
151
  "vitest": "^4.1.9"
152
152
  }
153
153
  }
@@ -174,12 +174,16 @@ if (existsSync(sqlTemplatePath)) {
174
174
  writeFileSync(sqlGeneratedPath, sql);
175
175
  console.log(` CREATED: ${sqlGeneratedPath} (dev admin credentials)`);
176
176
 
177
- // Write a compose override that mounts the generated SQL instead of the template
177
+ // Write a compose override that mounts the generated SQL instead of the template.
178
+ // Must target /tmp/super-admin.sql — that's the path `db:migrate` executes, and
179
+ // docker-compose.override.yml mounts the raw template there. This file is loaded
180
+ // after the override (getComposeFiles), so the same target wins and the seeded
181
+ // admin gets real credentials instead of literal {{ADMIN_EMAIL}} placeholders.
178
182
  const composeOverride = `# Generated by dev-init.js — DO NOT COMMIT
179
183
  services:
180
184
  db:
181
185
  volumes:
182
- - ./volumes/db/super-admin.generated.sql:/docker-entrypoint-initdb.d/post-init/super-admin.sql:Z
186
+ - ./volumes/db/super-admin.generated.sql:/tmp/super-admin.sql:Z
183
187
  `;
184
188
  writeFileSync('docker-compose.dev-init.yml', composeOverride);
185
189
  console.log(' CREATED: docker-compose.dev-init.yml (mounts generated admin SQL)');
@@ -1,18 +1,18 @@
1
1
  <svg width="877" height="1012" viewBox="0 0 877 1012" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <g clip-path="url(#clip0_77_141)">
3
- <path fill-rule="evenodd" clip-rule="evenodd" d="M434.346 2.3064C436.82 0.879051 439.867 0.879058 442.342 2.30641L872.685 250.582C875.162 252.01 876.688 254.652 876.688 257.511V754.051C876.688 756.91 875.162 759.552 872.685 760.981L442.342 1009.26C439.867 1010.68 436.82 1010.68 434.346 1009.26L4.00221 760.981C1.52575 759.552 0 756.91 0 754.051V257.511C0 254.652 1.52576 252.01 4.00222 250.582L434.346 2.3064ZM708.094 505.781C708.094 577.323 679.674 645.935 629.086 696.523C578.498 747.111 509.886 775.531 438.344 775.531C366.802 775.531 298.19 747.111 247.602 696.523C197.014 645.935 168.594 577.323 168.594 505.781C168.594 434.239 197.014 365.627 247.602 315.039C298.19 264.451 366.802 236.031 438.344 236.031C509.886 236.031 578.498 264.451 629.086 315.039C679.674 365.627 708.094 434.239 708.094 505.781Z" fill="url(#paint0_linear_77_141)"/>
4
- <path d="M876.688 252.891V472.062L438.344 606.938L0 472.062V252.891L438.344 0L876.688 252.891Z" fill="url(#paint1_linear_77_141)"/>
2
+ <g clip-path="url(#clip0_114_6)">
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M434.346 2.3064C436.82 0.879051 439.867 0.879058 442.342 2.30641L872.685 250.582C875.162 252.01 876.688 254.652 876.688 257.511V754.051C876.688 756.91 875.162 759.552 872.685 760.981L442.342 1009.26C439.867 1010.68 436.82 1010.68 434.346 1009.26L4.00221 760.981C1.52575 759.552 0 756.91 0 754.051V257.511C0 254.652 1.52576 252.01 4.00222 250.582L434.346 2.3064ZM708.094 505.781C708.094 577.323 679.674 645.935 629.086 696.523C578.498 747.111 509.886 775.531 438.344 775.531C366.802 775.531 298.19 747.111 247.602 696.523C197.014 645.935 168.594 577.323 168.594 505.781C168.594 434.239 197.014 365.627 247.602 315.039C298.19 264.451 366.802 236.031 438.344 236.031C509.886 236.031 578.498 264.451 629.086 315.039C679.674 365.627 708.094 434.239 708.094 505.781Z" fill="url(#paint0_linear_114_6)"/>
4
+ <path d="M876.688 252.891V472.062L438.344 606.938L0 472.062V252.891L438.344 0L876.688 252.891Z" fill="url(#paint1_linear_114_6)"/>
5
5
  </g>
6
6
  <defs>
7
- <linearGradient id="paint0_linear_77_141" x1="0" y1="0" x2="0" y2="1011.56" gradientUnits="userSpaceOnUse">
7
+ <linearGradient id="paint0_linear_114_6" x1="0" y1="0" x2="0" y2="1011.56" gradientUnits="userSpaceOnUse">
8
8
  <stop stop-color="#5EEAD4"/>
9
9
  <stop offset="1" stop-color="#0D9488"/>
10
10
  </linearGradient>
11
- <linearGradient id="paint1_linear_77_141" x1="175.338" y1="-5.42644e-06" x2="516.194" y2="492.348" gradientUnits="userSpaceOnUse">
11
+ <linearGradient id="paint1_linear_114_6" x1="175.338" y1="-5.42644e-06" x2="516.194" y2="492.348" gradientUnits="userSpaceOnUse">
12
12
  <stop stop-color="white" stop-opacity="0.5"/>
13
13
  <stop offset="1" stop-color="white" stop-opacity="0"/>
14
14
  </linearGradient>
15
- <clipPath id="clip0_77_141">
15
+ <clipPath id="clip0_114_6">
16
16
  <rect width="876.688" height="1011.56" fill="white"/>
17
17
  </clipPath>
18
18
  </defs>
@@ -0,0 +1,12 @@
1
+ <svg width="5175" height="1061" viewBox="0 0 5175 1061" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M189.981 758.92C186.619 758.92 183.616 756.818 182.465 753.66L3.91491 263.842C2.01266 258.623 5.87675 253.102 11.4311 253.102H128.387C131.803 253.102 134.842 255.271 135.952 258.501L255.668 606.681C258.146 613.888 268.343 613.876 270.804 606.663L389.594 258.519C390.699 255.279 393.743 253.102 397.165 253.102H511.149C516.703 253.102 520.567 258.623 518.665 263.842L340.115 753.66C338.964 756.818 335.961 758.92 332.599 758.92H189.981Z" fill="white"/>
3
+ <path d="M586.913 758.92C582.495 758.92 578.913 755.338 578.913 750.92V261.102C578.913 256.684 582.495 253.102 586.913 253.102H696.135C700.553 253.102 704.135 256.684 704.135 261.102V750.92C704.135 755.338 700.553 758.92 696.135 758.92H586.913ZM641.031 187.04C600.605 187.04 571.025 157.46 571.025 118.02C571.025 78.58 600.605 49 641.031 49C680.471 49 711.037 78.58 711.037 118.02C711.037 157.46 680.471 187.04 641.031 187.04Z" fill="white"/>
4
+ <path d="M1092 764.836C1024.91 764.836 976.303 739.429 944.129 702.222C939.464 696.826 930.128 698.971 928.878 705.993L920.628 752.323C919.948 756.14 916.629 758.92 912.751 758.92H818.007C813.588 758.92 810.007 755.338 810.007 750.92V76.72C810.007 72.3017 813.588 68.72 818.007 68.72H927.229C931.647 68.72 935.229 72.3017 935.229 76.72V298.558C935.229 306.201 945.285 309.773 950.605 304.285C982.946 270.932 1028.97 247.186 1092.99 247.186C1229.06 247.186 1328.64 343.814 1328.64 505.518C1328.64 661.306 1229.06 764.836 1092 764.836ZM1067.35 661.306C1148.2 661.306 1201.45 599.188 1201.45 506.504C1201.45 412.834 1148.2 350.716 1067.35 350.716C986.501 350.716 933.257 412.834 933.257 505.518C933.257 599.188 986.501 661.306 1067.35 661.306Z" fill="white"/>
5
+ <path d="M1655.33 764.836C1490.67 764.836 1390.1 662.292 1390.1 507.49C1390.1 350.716 1492.64 247.186 1645.47 247.186C1794.36 247.186 1895.92 341.842 1895.92 492.7C1895.92 503.334 1895.92 514.647 1895.35 526.639C1895.16 530.846 1891.66 534.112 1887.45 534.112H1527.15C1523.88 534.112 1521.24 536.761 1521.24 540.028C1521.24 617.922 1573.49 667.222 1649.42 667.222C1708.04 667.222 1750.35 641.829 1765.02 596.261C1766.14 592.793 1769.29 590.314 1772.94 590.314H1881.48C1886.44 590.314 1890.22 594.795 1889.14 599.64C1868.5 691.905 1782.22 764.836 1655.33 764.836ZM1524.87 439.185C1523.84 443.964 1527.6 448.33 1532.49 448.33H1760.6C1765.43 448.33 1769.17 444.061 1768.29 439.314C1756.7 376.993 1712.41 342.828 1647.44 342.828C1587.31 342.828 1537.92 378.645 1524.87 439.185Z" fill="white"/>
6
+ <path d="M2212.61 764.836C2053.87 764.836 1957.24 665.25 1957.24 506.504C1957.24 349.73 2058.8 247.186 2216.56 247.186C2347.1 247.186 2430.93 316.338 2453.47 429.168C2454.44 434.016 2450.67 438.47 2445.73 438.47H2330.48C2326.71 438.47 2323.48 435.836 2322.52 432.199C2309.16 381.668 2271.43 350.716 2214.59 350.716C2135.71 350.716 2085.42 414.806 2085.42 506.504C2085.42 598.202 2134.72 661.306 2214.59 661.306C2272.41 661.306 2310.19 629.409 2323.53 577.881C2324.48 574.229 2327.71 571.58 2331.49 571.58H2445.82C2450.73 571.58 2454.49 575.983 2453.56 580.809C2431.73 694.688 2343.22 764.836 2212.61 764.836Z" fill="white"/>
7
+ <path d="M2750.45 764.836C2616.36 764.836 2512.83 666.236 2512.83 506.504C2512.83 350.716 2616.36 247.186 2750.45 247.186C2817.76 247.186 2865.7 271.986 2898.38 309.905C2903.03 315.295 2912.31 313.151 2913.56 306.146L2921.83 259.699C2922.51 255.882 2925.83 253.102 2929.71 253.102H3024.45C3028.87 253.102 3032.45 256.684 3032.45 261.102V750.92C3032.45 755.338 3028.87 758.92 3024.45 758.92H2929.72C2925.84 758.92 2922.51 756.13 2921.84 752.304L2913.41 704.325C2912.2 697.4 2903.13 695.195 2898.49 700.478C2865.28 738.288 2818.02 764.836 2750.45 764.836ZM2775.1 661.306C2855.96 661.306 2908.21 599.188 2908.21 507.49C2908.21 412.834 2855.96 350.716 2775.1 350.716C2693.27 350.716 2641.01 412.834 2641.01 506.504C2641.01 599.188 2693.27 661.306 2775.1 661.306Z" fill="white"/>
8
+ <path d="M3146.28 758.92C3141.86 758.92 3138.28 755.338 3138.28 750.92V261.102C3138.28 256.684 3141.86 253.102 3146.28 253.102H3240.87C3244.81 253.102 3248.17 255.975 3248.78 259.87L3256.21 307.536C3257.35 314.889 3267.31 316.992 3271.87 311.112C3298.35 276.986 3337.34 253.102 3407.45 253.102H3426.08C3430.49 253.102 3434.08 256.684 3434.08 261.102V359.478C3434.08 363.896 3430.49 367.478 3426.08 367.478H3381.82C3294.06 367.478 3263.5 430.582 3263.5 508.476V750.92C3263.5 755.338 3259.92 758.92 3255.5 758.92H3146.28Z" fill="white"/>
9
+ <path d="M3783.28 764.836C3716.19 764.836 3667.58 739.429 3635.41 702.221C3630.74 696.826 3621.41 698.971 3620.16 705.993L3611.91 752.323C3611.23 756.14 3607.91 758.92 3604.03 758.92H3509.29C3504.87 758.92 3501.29 755.338 3501.29 750.92V76.72C3501.29 72.3017 3504.87 68.72 3509.29 68.72H3618.51C3622.93 68.72 3626.51 72.3017 3626.51 76.72V298.558C3626.51 306.201 3636.56 309.773 3641.88 304.285C3674.23 270.932 3720.25 247.186 3784.27 247.186C3920.34 247.186 4019.92 343.814 4019.92 505.518C4019.92 661.306 3920.34 764.836 3783.28 764.836ZM3758.63 661.306C3839.48 661.306 3892.73 599.188 3892.73 506.504C3892.73 412.834 3839.48 350.716 3758.63 350.716C3677.78 350.716 3624.54 412.834 3624.54 505.518C3624.54 599.188 3677.78 661.306 3758.63 661.306Z" fill="white"/>
10
+ <path d="M4344.64 764.836C4186.88 764.836 4081.38 661.306 4081.38 506.504C4081.38 350.716 4186.88 247.186 4344.64 247.186C4502.4 247.186 4607.9 350.716 4607.9 506.504C4607.9 661.306 4502.4 764.836 4344.64 764.836ZM4344.64 661.306C4427.46 661.306 4479.72 597.216 4479.72 506.504C4479.72 414.806 4427.46 350.716 4344.64 350.716C4261.82 350.716 4209.56 414.806 4209.56 506.504C4209.56 597.216 4261.82 661.306 4344.64 661.306Z" fill="white"/>
11
+ <path d="M4699.42 758.92C4695 758.92 4691.42 755.338 4691.42 750.92V261.102C4691.42 256.684 4695 253.102 4699.42 253.102H4794.19C4798.05 253.102 4801.37 255.867 4802.06 259.671L4809.55 300.893C4810.78 307.645 4819.5 309.909 4824.22 304.93C4855.56 271.903 4900.75 247.186 4971.44 247.186C5081.88 247.186 5174.56 306.346 5174.56 477.91V750.92C5174.56 755.338 5170.98 758.92 5166.56 758.92H5057.34C5052.92 758.92 5049.34 755.338 5049.34 750.92V487.77C5049.34 398.044 5011.87 351.702 4938.9 351.702C4859.04 351.702 4816.64 401.988 4816.64 492.7V750.92C4816.64 755.338 4813.06 758.92 4808.64 758.92H4699.42Z" fill="white"/>
12
+ </svg>
@@ -0,0 +1,12 @@
1
+ <svg width="5175" height="1061" viewBox="0 0 5175 1061" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M189.981 758.92C186.619 758.92 183.616 756.818 182.465 753.66L3.91491 263.842C2.01266 258.623 5.87675 253.102 11.4311 253.102H128.387C131.803 253.102 134.842 255.271 135.952 258.501L255.668 606.681C258.146 613.888 268.343 613.876 270.804 606.663L389.594 258.519C390.699 255.279 393.743 253.102 397.165 253.102H511.149C516.703 253.102 520.567 258.623 518.665 263.842L340.115 753.66C338.964 756.818 335.961 758.92 332.599 758.92H189.981Z" fill="black"/>
3
+ <path d="M586.913 758.92C582.495 758.92 578.913 755.338 578.913 750.92V261.102C578.913 256.684 582.495 253.102 586.913 253.102H696.135C700.553 253.102 704.135 256.684 704.135 261.102V750.92C704.135 755.338 700.553 758.92 696.135 758.92H586.913ZM641.031 187.04C600.605 187.04 571.025 157.46 571.025 118.02C571.025 78.58 600.605 49 641.031 49C680.471 49 711.037 78.58 711.037 118.02C711.037 157.46 680.471 187.04 641.031 187.04Z" fill="black"/>
4
+ <path d="M1092 764.836C1024.91 764.836 976.303 739.429 944.129 702.222C939.464 696.826 930.128 698.971 928.878 705.993L920.628 752.323C919.948 756.14 916.629 758.92 912.751 758.92H818.007C813.588 758.92 810.007 755.338 810.007 750.92V76.72C810.007 72.3017 813.588 68.72 818.007 68.72H927.229C931.647 68.72 935.229 72.3017 935.229 76.72V298.558C935.229 306.201 945.285 309.773 950.605 304.285C982.946 270.932 1028.97 247.186 1092.99 247.186C1229.06 247.186 1328.64 343.814 1328.64 505.518C1328.64 661.306 1229.06 764.836 1092 764.836ZM1067.35 661.306C1148.2 661.306 1201.45 599.188 1201.45 506.504C1201.45 412.834 1148.2 350.716 1067.35 350.716C986.501 350.716 933.257 412.834 933.257 505.518C933.257 599.188 986.501 661.306 1067.35 661.306Z" fill="black"/>
5
+ <path d="M1655.33 764.836C1490.67 764.836 1390.1 662.292 1390.1 507.49C1390.1 350.716 1492.64 247.186 1645.47 247.186C1794.36 247.186 1895.92 341.842 1895.92 492.7C1895.92 503.334 1895.92 514.647 1895.35 526.639C1895.16 530.846 1891.66 534.112 1887.45 534.112H1527.15C1523.88 534.112 1521.24 536.761 1521.24 540.028C1521.24 617.922 1573.49 667.222 1649.42 667.222C1708.04 667.222 1750.35 641.829 1765.02 596.261C1766.14 592.793 1769.29 590.314 1772.94 590.314H1881.48C1886.44 590.314 1890.22 594.795 1889.14 599.64C1868.5 691.905 1782.22 764.836 1655.33 764.836ZM1524.87 439.185C1523.84 443.964 1527.6 448.33 1532.49 448.33H1760.6C1765.43 448.33 1769.17 444.061 1768.29 439.314C1756.7 376.993 1712.41 342.828 1647.44 342.828C1587.31 342.828 1537.92 378.645 1524.87 439.185Z" fill="black"/>
6
+ <path d="M2212.61 764.836C2053.87 764.836 1957.24 665.25 1957.24 506.504C1957.24 349.73 2058.8 247.186 2216.56 247.186C2347.1 247.186 2430.93 316.338 2453.47 429.168C2454.44 434.016 2450.67 438.47 2445.73 438.47H2330.48C2326.71 438.47 2323.48 435.836 2322.52 432.199C2309.16 381.668 2271.43 350.716 2214.59 350.716C2135.71 350.716 2085.42 414.806 2085.42 506.504C2085.42 598.202 2134.72 661.306 2214.59 661.306C2272.41 661.306 2310.19 629.409 2323.53 577.881C2324.48 574.229 2327.71 571.58 2331.49 571.58H2445.82C2450.73 571.58 2454.49 575.983 2453.56 580.809C2431.73 694.688 2343.22 764.836 2212.61 764.836Z" fill="black"/>
7
+ <path d="M2750.45 764.836C2616.36 764.836 2512.83 666.236 2512.83 506.504C2512.83 350.716 2616.36 247.186 2750.45 247.186C2817.76 247.186 2865.7 271.986 2898.38 309.905C2903.03 315.295 2912.31 313.151 2913.56 306.146L2921.83 259.699C2922.51 255.882 2925.83 253.102 2929.71 253.102H3024.45C3028.87 253.102 3032.45 256.684 3032.45 261.102V750.92C3032.45 755.338 3028.87 758.92 3024.45 758.92H2929.72C2925.84 758.92 2922.51 756.13 2921.84 752.304L2913.41 704.325C2912.2 697.4 2903.13 695.195 2898.49 700.478C2865.28 738.288 2818.02 764.836 2750.45 764.836ZM2775.1 661.306C2855.96 661.306 2908.21 599.188 2908.21 507.49C2908.21 412.834 2855.96 350.716 2775.1 350.716C2693.27 350.716 2641.01 412.834 2641.01 506.504C2641.01 599.188 2693.27 661.306 2775.1 661.306Z" fill="black"/>
8
+ <path d="M3146.28 758.92C3141.86 758.92 3138.28 755.338 3138.28 750.92V261.102C3138.28 256.684 3141.86 253.102 3146.28 253.102H3240.87C3244.81 253.102 3248.17 255.975 3248.78 259.87L3256.21 307.536C3257.35 314.889 3267.31 316.992 3271.87 311.112C3298.35 276.986 3337.34 253.102 3407.45 253.102H3426.08C3430.49 253.102 3434.08 256.684 3434.08 261.102V359.478C3434.08 363.896 3430.49 367.478 3426.08 367.478H3381.82C3294.06 367.478 3263.5 430.582 3263.5 508.476V750.92C3263.5 755.338 3259.92 758.92 3255.5 758.92H3146.28Z" fill="black"/>
9
+ <path d="M3783.28 764.836C3716.19 764.836 3667.58 739.429 3635.41 702.221C3630.74 696.826 3621.41 698.971 3620.16 705.993L3611.91 752.323C3611.23 756.14 3607.91 758.92 3604.03 758.92H3509.29C3504.87 758.92 3501.29 755.338 3501.29 750.92V76.72C3501.29 72.3017 3504.87 68.72 3509.29 68.72H3618.51C3622.93 68.72 3626.51 72.3017 3626.51 76.72V298.558C3626.51 306.201 3636.56 309.773 3641.88 304.285C3674.23 270.932 3720.25 247.186 3784.27 247.186C3920.34 247.186 4019.92 343.814 4019.92 505.518C4019.92 661.306 3920.34 764.836 3783.28 764.836ZM3758.63 661.306C3839.48 661.306 3892.73 599.188 3892.73 506.504C3892.73 412.834 3839.48 350.716 3758.63 350.716C3677.78 350.716 3624.54 412.834 3624.54 505.518C3624.54 599.188 3677.78 661.306 3758.63 661.306Z" fill="black"/>
10
+ <path d="M4344.64 764.836C4186.88 764.836 4081.38 661.306 4081.38 506.504C4081.38 350.716 4186.88 247.186 4344.64 247.186C4502.4 247.186 4607.9 350.716 4607.9 506.504C4607.9 661.306 4502.4 764.836 4344.64 764.836ZM4344.64 661.306C4427.46 661.306 4479.72 597.216 4479.72 506.504C4479.72 414.806 4427.46 350.716 4344.64 350.716C4261.82 350.716 4209.56 414.806 4209.56 506.504C4209.56 597.216 4261.82 661.306 4344.64 661.306Z" fill="black"/>
11
+ <path d="M4699.42 758.92C4695 758.92 4691.42 755.338 4691.42 750.92V261.102C4691.42 256.684 4695 253.102 4699.42 253.102H4794.19C4798.05 253.102 4801.37 255.867 4802.06 259.671L4809.55 300.893C4810.78 307.645 4819.5 309.909 4824.22 304.93C4855.56 271.903 4900.75 247.186 4971.44 247.186C5081.88 247.186 5174.56 306.346 5174.56 477.91V750.92C5174.56 755.338 5170.98 758.92 5166.56 758.92H5057.34C5052.92 758.92 5049.34 755.338 5049.34 750.92V487.77C5049.34 398.044 5011.87 351.702 4938.9 351.702C4859.04 351.702 4816.64 401.988 4816.64 492.7V750.92C4816.64 755.338 4813.06 758.92 4808.64 758.92H4699.42Z" fill="black"/>
12
+ </svg>
@@ -58,9 +58,7 @@ export function AIIntegrationSection() {
58
58
  </motion.div>
59
59
  <h2 className="text-3xl md:text-5xl font-black tracking-tight mb-4">
60
60
  {t('landing.aiIntegration.headline1')}{' '}
61
- <span className="bg-gradient-to-r from-primary via-cyan-400 to-secondary-accent bg-clip-text text-transparent">
62
- {t('landing.aiIntegration.headlineHighlight')}
63
- </span>{' '}
61
+ <span className="text-primary">{t('landing.aiIntegration.headlineHighlight')}</span>{' '}
64
62
  {t('landing.aiIntegration.headline2')}
65
63
  </h2>
66
64
  <p className="text-lg text-muted-foreground max-w-2xl mx-auto">
@@ -63,7 +63,7 @@ import { useEnabledServices } from '@/hooks/useRunningServices';
63
63
  import { getServiceUrl } from '@/lib/admin-services';
64
64
  import { cn, getUserInitials } from '@/lib/utils';
65
65
  import { useAuth } from './auth/AuthProvider';
66
- import { Wordmark } from './Logo';
66
+ import { Logo, WordmarkText } from './Logo';
67
67
 
68
68
  const prefetchMap: Record<string, () => Promise<unknown>> = {
69
69
  '/dashboard': () => import('@/pages/Dashboard'),
@@ -188,7 +188,14 @@ export function AppSidebar() {
188
188
  onClick={toggleSidebar}
189
189
  className="flex h-full w-full cursor-pointer items-center"
190
190
  >
191
- <Wordmark textClassName="group-data-[collapsible=icon]:hidden" />
191
+ <IconSlot>
192
+ <Logo size="sm" />
193
+ </IconSlot>
194
+ <span className="grid shrink-0 grid-cols-[1fr] opacity-100 transition-[grid-template-columns,opacity] duration-300 ease-in-out group-data-[collapsible=icon]:grid-cols-[0fr] group-data-[collapsible=icon]:opacity-0">
195
+ <span className="overflow-hidden">
196
+ <WordmarkText size="sm" className="font-display text-2xl font-bold" />
197
+ </span>
198
+ </span>
192
199
  </button>
193
200
  </SidebarHeader>
194
201
 
@@ -200,7 +207,7 @@ export function AppSidebar() {
200
207
  <SidebarMenu>
201
208
  <SidebarMenuItem>
202
209
  <DropdownMenu>
203
- <DropdownMenuTrigger className="flex w-full items-center gap-2 rounded-md border border-border text-left text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-10 transition-colors cursor-pointer group-data-[collapsible=icon]:size-10 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-0">
210
+ <DropdownMenuTrigger className="flex w-full items-center rounded-md border border-border text-left text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-10 transition-colors cursor-pointer group-data-[collapsible=icon]:size-10 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-0">
204
211
  <IconSlot>
205
212
  <Building2 className="size-4" />
206
213
  </IconSlot>
@@ -262,7 +269,7 @@ export function AppSidebar() {
262
269
  onMouseEnter={() => prefetch(item.path)}
263
270
  onFocus={() => prefetch(item.path)}
264
271
  tooltip={t(item.titleKey)}
265
- className="p-0"
272
+ className="gap-0 p-0"
266
273
  >
267
274
  <IconSlot>
268
275
  <item.icon className="size-4" />
@@ -288,7 +295,7 @@ export function AppSidebar() {
288
295
  <SidebarMenuButton
289
296
  onClick={() => navigate('/dashboard')}
290
297
  tooltip={t('common.back')}
291
- className="p-0"
298
+ className="gap-0 p-0"
292
299
  >
293
300
  <IconSlot>
294
301
  <ArrowLeft className="size-4" />
@@ -313,7 +320,7 @@ export function AppSidebar() {
313
320
  onMouseEnter={() => prefetch('/settings/profile')}
314
321
  onFocus={() => prefetch('/settings/profile')}
315
322
  tooltip={t('sidebar.profile')}
316
- className="p-0"
323
+ className="gap-0 p-0"
317
324
  >
318
325
  <IconSlot>
319
326
  <User className="size-4" />
@@ -330,7 +337,7 @@ export function AppSidebar() {
330
337
  onMouseEnter={() => prefetch('/settings/billing')}
331
338
  onFocus={() => prefetch('/settings/billing')}
332
339
  tooltip={t('sidebar.billing')}
333
- className="p-0"
340
+ className="gap-0 p-0"
334
341
  >
335
342
  <IconSlot>
336
343
  <CreditCard className="size-4" />
@@ -347,7 +354,7 @@ export function AppSidebar() {
347
354
  onMouseEnter={() => prefetch('/settings/security')}
348
355
  onFocus={() => prefetch('/settings/security')}
349
356
  tooltip={t('sidebar.security')}
350
- className="p-0"
357
+ className="gap-0 p-0"
351
358
  >
352
359
  <IconSlot>
353
360
  <Shield className="size-4" />
@@ -372,7 +379,7 @@ export function AppSidebar() {
372
379
  <SidebarMenuButton
373
380
  onClick={() => navigate('/dashboard')}
374
381
  tooltip={t('common.back')}
375
- className="p-0"
382
+ className="gap-0 p-0"
376
383
  >
377
384
  <IconSlot>
378
385
  <ArrowLeft className="size-4" />
@@ -395,7 +402,7 @@ export function AppSidebar() {
395
402
  isActive={location.pathname === `/organizations/${currentOrgId}/details`}
396
403
  onClick={() => navigate(`/organizations/${currentOrgId}/details`)}
397
404
  tooltip={t('sidebar.orgDetails')}
398
- className="p-0"
405
+ className="gap-0 p-0"
399
406
  >
400
407
  <IconSlot>
401
408
  <Building2 className="size-4" />
@@ -410,7 +417,7 @@ export function AppSidebar() {
410
417
  isActive={location.pathname === `/organizations/${currentOrgId}/members`}
411
418
  onClick={() => navigate(`/organizations/${currentOrgId}/members`)}
412
419
  tooltip={t('sidebar.members')}
413
- className="p-0"
420
+ className="gap-0 p-0"
414
421
  >
415
422
  <IconSlot>
416
423
  <Users className="size-4" />
@@ -435,7 +442,7 @@ export function AppSidebar() {
435
442
  <SidebarMenuButton
436
443
  onClick={() => navigate('/dashboard')}
437
444
  tooltip={t('common.back')}
438
- className="p-0"
445
+ className="gap-0 p-0"
439
446
  >
440
447
  <IconSlot>
441
448
  <ArrowLeft className="size-4" />
@@ -460,7 +467,7 @@ export function AppSidebar() {
460
467
  onMouseEnter={() => prefetch('/admin/dashboard')}
461
468
  onFocus={() => prefetch('/admin/dashboard')}
462
469
  tooltip={t('sidebar.overview')}
463
- className="p-0"
470
+ className="gap-0 p-0"
464
471
  >
465
472
  <IconSlot>
466
473
  <LayoutDashboard className="size-4" />
@@ -477,7 +484,7 @@ export function AppSidebar() {
477
484
  onMouseEnter={() => prefetch('/admin/organizations')}
478
485
  onFocus={() => prefetch('/admin/organizations')}
479
486
  tooltip={t('sidebar.organizations')}
480
- className="p-0"
487
+ className="gap-0 p-0"
481
488
  >
482
489
  <IconSlot>
483
490
  <Building2 className="size-4" />
@@ -494,7 +501,7 @@ export function AppSidebar() {
494
501
  onMouseEnter={() => prefetch('/admin/users')}
495
502
  onFocus={() => prefetch('/admin/users')}
496
503
  tooltip={t('sidebar.users')}
497
- className="p-0"
504
+ className="gap-0 p-0"
498
505
  >
499
506
  <IconSlot>
500
507
  <Users className="size-4" />
@@ -511,7 +518,7 @@ export function AppSidebar() {
511
518
  onMouseEnter={() => prefetch('/admin/notifications')}
512
519
  onFocus={() => prefetch('/admin/notifications')}
513
520
  tooltip={t('sidebar.notifications')}
514
- className="p-0"
521
+ className="gap-0 p-0"
515
522
  >
516
523
  <IconSlot>
517
524
  <Bell className="size-4" />
@@ -528,7 +535,7 @@ export function AppSidebar() {
528
535
  onMouseEnter={() => prefetch('/admin/logs')}
529
536
  onFocus={() => prefetch('/admin/logs')}
530
537
  tooltip={t('sidebar.logs')}
531
- className="p-0"
538
+ className="gap-0 p-0"
532
539
  >
533
540
  <IconSlot>
534
541
  <FileText className="size-4" />
@@ -545,7 +552,7 @@ export function AppSidebar() {
545
552
  onMouseEnter={() => prefetch('/admin/theme')}
546
553
  onFocus={() => prefetch('/admin/theme')}
547
554
  tooltip={t('sidebar.theme')}
548
- className="p-0"
555
+ className="gap-0 p-0"
549
556
  >
550
557
  <IconSlot>
551
558
  <Palette className="size-4" />
@@ -562,7 +569,7 @@ export function AppSidebar() {
562
569
  onMouseEnter={() => prefetch('/admin/jobs')}
563
570
  onFocus={() => prefetch('/admin/jobs')}
564
571
  tooltip="Background Jobs"
565
- className="p-0"
572
+ className="gap-0 p-0"
566
573
  >
567
574
  <IconSlot>
568
575
  <Clock className="size-4" />
@@ -577,7 +584,7 @@ export function AppSidebar() {
577
584
  onMouseEnter={() => prefetch('/admin/contact')}
578
585
  onFocus={() => prefetch('/admin/contact')}
579
586
  tooltip="Contact Submissions"
580
- className="p-0"
587
+ className="gap-0 p-0"
581
588
  >
582
589
  <IconSlot>
583
590
  <MessageSquare className="size-4" />
@@ -592,7 +599,7 @@ export function AppSidebar() {
592
599
  onMouseEnter={() => prefetch('/admin/newsletter')}
593
600
  onFocus={() => prefetch('/admin/newsletter')}
594
601
  tooltip="Newsletter"
595
- className="p-0"
602
+ className="gap-0 p-0"
596
603
  >
597
604
  <IconSlot>
598
605
  <Mail className="size-4" />
@@ -607,7 +614,7 @@ export function AppSidebar() {
607
614
  onMouseEnter={() => prefetch('/admin/settings')}
608
615
  onFocus={() => prefetch('/admin/settings')}
609
616
  tooltip={t('sidebar.settings')}
610
- className="p-0"
617
+ className="gap-0 p-0"
611
618
  >
612
619
  <IconSlot>
613
620
  <Settings className="size-4" />
@@ -628,7 +635,7 @@ export function AppSidebar() {
628
635
  ? service.description
629
636
  : 'Internal only — kubectl port-forward svc/traefik-dashboard 8080:8080 -n vibecarbon'
630
637
  }
631
- className={cn('p-0', !url && 'cursor-default opacity-50')}
638
+ className={cn('gap-0 p-0', !url && 'cursor-default opacity-50')}
632
639
  >
633
640
  <IconSlot>
634
641
  <service.icon className="size-4" />
@@ -653,7 +660,7 @@ export function AppSidebar() {
653
660
  <SidebarFooter>
654
661
  {/* User Menu */}
655
662
  <DropdownMenu>
656
- <DropdownMenuTrigger className="group/user flex w-full items-center gap-2 rounded-md text-left text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-12 transition-colors group-data-[collapsible=icon]:size-10 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-0">
663
+ <DropdownMenuTrigger className="group/user flex w-full items-center rounded-md text-left text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-12 transition-colors group-data-[collapsible=icon]:size-10 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-0">
657
664
  <IconSlot>
658
665
  <Avatar size="sm">
659
666
  <AvatarFallback>{getUserInitials(user)}</AvatarFallback>
@@ -672,7 +679,7 @@ export function AppSidebar() {
672
679
  <DropdownMenuContent
673
680
  align="start"
674
681
  side={isCollapsed ? 'right' : 'top'}
675
- className="w-56"
682
+ className="min-w-56"
676
683
  >
677
684
  <div className="flex items-start justify-between px-3 py-2">
678
685
  <div>
@@ -691,18 +698,18 @@ export function AppSidebar() {
691
698
  </div>
692
699
  <DropdownMenuSeparator />
693
700
  <DropdownMenuItem onClick={() => navigate('/settings/profile')}>
694
- <Settings className="size-4 mr-2" />
701
+ <Settings className="size-4" />
695
702
  {t('common.settings')}
696
703
  </DropdownMenuItem>
697
704
  {isSuperAdmin && (
698
705
  <DropdownMenuItem onClick={() => navigate('/admin/dashboard')}>
699
- <Shield className="size-4 mr-2" />
706
+ <Shield className="size-4" />
700
707
  {t('sidebar.superAdmin')}
701
708
  </DropdownMenuItem>
702
709
  )}
703
710
  <DropdownMenuSeparator />
704
711
  <DropdownMenuItem onClick={handleSignOut}>
705
- <LogOut className="size-4 mr-2" />
712
+ <LogOut className="size-4" />
706
713
  {t('common.signOut')}
707
714
  </DropdownMenuItem>
708
715
  </DropdownMenuContent>
@@ -51,7 +51,7 @@ export function CTAFooter({
51
51
 
52
52
  {/* Footer */}
53
53
  <div className="relative mx-auto flex max-w-7xl flex-col items-center justify-between gap-4 px-6 py-8 sm:flex-row">
54
- <Wordmark size="sm" className="text-white" />
54
+ <Wordmark size="sm" className="text-white" forceTheme="dark" />
55
55
  {footerLinks}
56
56
  </div>
57
57
  </footer>
@@ -72,9 +72,7 @@ export function ComparisonSection() {
72
72
  </motion.div>
73
73
  <h2 className="text-3xl md:text-5xl font-black tracking-tight mb-4">
74
74
  {t('landing.comparison.headline')}{' '}
75
- <span className="bg-gradient-to-r from-secondary-accent to-fuchsia-400 bg-clip-text text-transparent">
76
- {t('landing.comparison.headlineHighlight')}
77
- </span>
75
+ <span className="text-primary">{t('landing.comparison.headlineHighlight')}</span>
78
76
  </h2>
79
77
  <p className="text-lg text-muted-foreground max-w-xl mx-auto">
80
78
  {t('landing.comparison.subheading')}
@@ -59,7 +59,7 @@ export function ContentPanel({
59
59
  const resolvedWidth = maxWidth ?? variantToWidth[variant];
60
60
 
61
61
  return (
62
- <div className="flex-1 pl-1 pr-6 py-6">
62
+ <div className="flex-1 pr-8 py-6">
63
63
  <div className={cn(maxWidthClasses[resolvedWidth], 'space-y-6', className)}>{children}</div>
64
64
  </div>
65
65
  );
@@ -106,9 +106,7 @@ export function DeploymentScenariosSection() {
106
106
  </motion.div>
107
107
  <h2 className="mb-4 text-3xl font-black tracking-tight md:text-5xl">
108
108
  {t('landing.deploy.headline')}{' '}
109
- <span className="bg-gradient-to-r from-primary via-cyan-400 to-secondary-accent bg-clip-text text-transparent">
110
- {t('landing.deploy.headlineHighlight')}
111
- </span>
109
+ <span className="text-primary">{t('landing.deploy.headlineHighlight')}</span>
112
110
  </h2>
113
111
  <p className="mx-auto max-w-2xl text-lg text-muted-foreground">
114
112
  {t('landing.deploy.subheading')}
@@ -60,7 +60,7 @@ export function FAQSection() {
60
60
  >
61
61
  <AccordionItem
62
62
  value={faq.question}
63
- className="border border-white/8 dark:border-white/8 bg-white/[0.02] dark:bg-white/[0.02] rounded-xl mb-3 overflow-hidden backdrop-blur-sm"
63
+ className="border border-border bg-card/40 dark:border-white/8 dark:bg-white/[0.02] rounded-xl mb-3 overflow-hidden backdrop-blur-sm"
64
64
  >
65
65
  <AccordionTrigger>{faq.question}</AccordionTrigger>
66
66
  <AccordionContent>
@@ -532,7 +532,19 @@ export default function Hero() {
532
532
  transition={{ duration: 0.8, delay: 0.2 }}
533
533
  className="text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto mb-6"
534
534
  >
535
- <span className="text-foreground/80">{t('landing.hero.subheading')}</span>
535
+ <span className="text-foreground/80">
536
+ {(() => {
537
+ const subheading = t('landing.hero.subheading');
538
+ const [first, second] = subheading.split(/\.\s+/);
539
+ if (second === undefined) return subheading;
540
+ return (
541
+ <>
542
+ {first}.<br />
543
+ {second}
544
+ </>
545
+ );
546
+ })()}
547
+ </span>
536
548
  </motion.p>
537
549
  </div>
538
550