diff --git a/src/App.css b/src/App.css
deleted file mode 100644
index 49b42df..0000000
--- a/src/App.css
+++ /dev/null
@@ -1,186 +0,0 @@
-.counter {
- font-size: 16px;
- padding: 5px 10px;
- border-radius: 5px;
- color: var(--accent);
- background: var(--accent-bg);
- border: 2px solid transparent;
- transition: border-color 0.3s;
- margin-bottom: 24px;
-
- &:hover {
- border-color: var(--accent-border);
- }
- &:focus-visible {
- outline: 2px solid var(--accent);
- outline-offset: 2px;
- }
-}
-
-
-
-.hero {
- position: relative;
-
- .base,
- .framework,
- .vite {
- inset-inline: 0;
- margin: 0 auto;
- }
-
- .base {
- width: 170px;
- position: relative;
- z-index: 0;
- }
-
- .framework,
- .vite {
- position: absolute;
- }
-
- .framework {
- z-index: 1;
- top: 34px;
- height: 28px;
- transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
- scale(1.4);
- }
-
- .vite {
- z-index: 0;
- top: 107px;
- height: 26px;
- width: auto;
- transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
- scale(0.8);
- }
-}
-
-#center {
- display: flex;
- flex-direction: column;
- gap: 25px;
- place-content: center;
- place-items: center;
- flex-grow: 1;
-
- @media (max-width: 1024px) {
- padding: 32px 20px 24px;
- gap: 18px;
- }
-}
-
-#next-steps {
- display: flex;
- border-top: 1px solid var(--border);
- text-align: left;
-
- & > div {
- flex: 1 1 0;
- padding: 32px;
- @media (max-width: 1024px) {
- padding: 24px 20px;
- }
- }
-
- .icon {
- margin-bottom: 16px;
- width: 22px;
- height: 22px;
- }
-
- @media (max-width: 1024px) {
- flex-direction: column;
- text-align: center;
- }
-}
-
-#docs {
- border-right: 1px solid var(--border);
-
- @media (max-width: 1024px) {
- border-right: none;
- border-bottom: 1px solid var(--border);
- }
-}
-
-#next-steps ul {
- list-style: none;
- padding: 0;
- display: flex;
- gap: 8px;
- margin: 32px 0 0;
-
- .logo {
- height: 18px;
- }
-
- a {
- color: var(--text-h);
- font-size: 16px;
- border-radius: 6px;
- background: var(--social-bg);
- display: flex;
- padding: 6px 12px;
- align-items: center;
- gap: 8px;
- text-decoration: none;
- transition: box-shadow 0.3s;
-
- &:hover {
- box-shadow: var(--shadow);
- }
- .button-icon {
- height: 18px;
- width: 18px;
- }
- }
-
- @media (max-width: 1024px) {
- margin-top: 20px;
- flex-wrap: wrap;
- justify-content: center;
-
- li {
- flex: 1 1 calc(50% - 8px);
- }
-
- a {
- width: 100%;
- justify-content: center;
- box-sizing: border-box;
- }
- }
-}
-
-#spacer {
- height: 88px;
- border-top: 1px solid var(--border);
- @media (max-width: 1024px) {
- height: 48px;
- }
-}
-
-.ticks {
- position: relative;
- width: 100%;
-
- &::before,
- &::after {
- content: '';
- position: absolute;
- top: -4.5px;
- border: 5px solid transparent;
- }
-
- &::before {
- left: 0;
- border-left-color: var(--border);
- }
- &::after {
- right: 0;
- border-right-color: var(--border);
- }
-}
diff --git a/src/App.tsx b/src/App.tsx
index e21f1e0..8079d24 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,4 +1,3 @@
-import './App.css'
import { useEffect } from "react";
import { Navigate, createBrowserRouter, useParams } from "react-router";
import { RouterProvider } from "react-router/dom";
@@ -46,6 +45,11 @@ import SettingsAccessibilityPage from "@/page/settings/accessibility";
import SettingsSecurityPage from "@/page/settings/security";
import SettingsTokensPage from "@/page/settings/tokens";
import SettingsSshKeysPage from "@/page/settings/ssh-keys";
+import LandingLayout from "@/page/landing/layout";
+import LandingHome from "@/page/landing/home";
+import FeaturesPage from "@/page/landing/features";
+import WorkflowPage from "@/page/landing/workflow";
+import PricingPage from "@/page/landing/pricing";
function WorkspaceCompatRedirect() {
const { projectName = "" } = useParams();
@@ -65,8 +69,25 @@ function App() {
element: ,
children: [
{
- path: "/",
- element: ,
+ element: ,
+ children: [
+ {
+ index: true,
+ element: ,
+ },
+ {
+ path: "features",
+ element: ,
+ },
+ {
+ path: "workflow",
+ element: ,
+ },
+ {
+ path: "pricing",
+ element: ,
+ },
+ ],
},
{
path: "/workspace/:projectName/*",
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 8cf4c32..6aca069 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -1,10 +1,11 @@
+import React from "react"
import { Button as ButtonPrimitive } from "@base-ui/react/button"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
- "group/button inline-flex shrink-0 items-center justify-center rounded-xl border border-transparent bg-clip-padding text-[13px] font-semibold whitespace-nowrap transition-all outline-none select-none focus-visible:ring-2 focus-visible:ring-ring/30 active:not-aria-[haspopup]:scale-[0.97] disabled:pointer-events-none disabled:opacity-40 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 shadow-sm",
+ "group/button inline-flex shrink-0 items-center justify-center rounded-xl border border-transparent bg-clip-padding text-[13px] font-semibold whitespace-nowrap transition-[background-color,border-color,color,box-shadow,transform] outline-none select-none focus-visible:ring-2 focus-visible:ring-ring/30 active:not-aria-[haspopup]:scale-[0.97] disabled:pointer-events-none disabled:opacity-40 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 shadow-sm",
{
variants: {
variant: {
@@ -42,14 +43,30 @@ function Button({
className,
variant = "default",
size = "default",
+ asChild,
+ children,
+ render,
...props
-}: ButtonPrimitive.Props & VariantProps) {
+}: ButtonPrimitive.Props & VariantProps & { asChild?: boolean }) {
+ const classes = cn(buttonVariants({ variant, size, className }))
+
+ let finalRender = render
+ let finalChildren = children
+
+ if (asChild && !finalRender) {
+ finalRender = React.Children.only(children) as React.ReactElement
+ finalChildren = undefined
+ }
+
return (
+ >
+ {finalChildren}
+
)
}
diff --git a/src/index.css b/src/index.css
index d4da028..fd11757 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,4 +1,5 @@
@import "tailwindcss";
+@plugin "@tailwindcss/typography";
@import "tw-animate-css";
@import "shadcn/tailwind.css";
@import "@fontsource-variable/space-grotesk";
@@ -29,6 +30,12 @@
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
+ --color-success: var(--success);
+ --color-success-foreground: var(--success-foreground);
+ --color-warning: var(--warning);
+ --color-warning-foreground: var(--warning-foreground);
+ --color-info: var(--info);
+ --color-info-foreground: var(--info-foreground);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
@@ -68,6 +75,12 @@
--accent: #f5f5f5;
--accent-foreground: #111111;
--destructive: #ef4444;
+ --success: #16a34a;
+ --success-foreground: #ffffff;
+ --warning: #d97706;
+ --warning-foreground: #ffffff;
+ --info: #2563eb;
+ --info-foreground: #ffffff;
--border: #e8e8e8;
--input: #e8e8e8;
--ring: #111111;
@@ -103,6 +116,12 @@
--accent: #1f2128;
--accent-foreground: #ececf1;
--destructive: #EF4444;
+ --success: #22c55e;
+ --success-foreground: #052e16;
+ --warning: #f59e0b;
+ --warning-foreground: #451a03;
+ --info: #60a5fa;
+ --info-foreground: #082f49;
--border: rgba(255, 255, 255, 0.08);
--input: rgba(255, 255, 255, 0.08);
--ring: #5E6AD2;
@@ -120,12 +139,29 @@
* {
@apply border-border outline-ring/50;
}
+ html {
+ @apply font-sans;
+ -webkit-tap-highlight-color: transparent;
+ }
body {
@apply bg-background text-foreground antialiased;
font-feature-settings: "cv02", "cv03", "cv04", "cv11";
}
- html {
- @apply font-sans;
+ button,
+ a,
+ input,
+ textarea,
+ select {
+ touch-action: manipulation;
+ }
+ h1,
+ h2,
+ h3 {
+ text-wrap: balance;
+ }
+ p,
+ li {
+ text-wrap: pretty;
}
}
diff --git a/src/lib/theme.ts b/src/lib/theme.ts
index abc85b3..ab686b4 100644
--- a/src/lib/theme.ts
+++ b/src/lib/theme.ts
@@ -348,6 +348,11 @@ export function applyTheme(preset: ThemePreset) {
root.style.setProperty("--chart-4", preset.isDark ? "#6e7681" : "#374151");
root.style.setProperty("--chart-5", preset.isDark ? "#4b5563" : "#1f2937");
+ root.style.setProperty("color-scheme", preset.isDark ? "dark" : "light");
+
+ const themeColorMeta = document.querySelector('meta[name="theme-color"]');
+ themeColorMeta?.setAttribute("content", c.background);
+
// Toggle dark class for any tailwind dark: variants still in use
if (preset.isDark) {
root.classList.add("dark");