From e025bf3339bdf4ba3f738ea631a697e03d9af470 Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Thu, 21 May 2026 09:48:10 +0900 Subject: [PATCH 01/14] Refactoring: ReModeling Page Vespertide --- .../landing/src/app/_components/code-tabs.tsx | 72 + .../landing/src/app/_components/code-theme.ts | 19 + .../src/app/_components/code-window.tsx | 71 + .../src/app/_components/copy-install.tsx | 61 + apps/landing/src/app/_components/example.tsx | 102 -- .../src/app/_components/join-icon-button.tsx | 21 - apps/landing/src/app/_lib/highlight.ts | 19 + apps/landing/src/app/page.tsx | 1168 +++++++++++++---- 8 files changed, 1161 insertions(+), 372 deletions(-) create mode 100644 apps/landing/src/app/_components/code-tabs.tsx create mode 100644 apps/landing/src/app/_components/code-theme.ts create mode 100644 apps/landing/src/app/_components/code-window.tsx create mode 100644 apps/landing/src/app/_components/copy-install.tsx delete mode 100644 apps/landing/src/app/_components/example.tsx delete mode 100644 apps/landing/src/app/_components/join-icon-button.tsx create mode 100644 apps/landing/src/app/_lib/highlight.ts diff --git a/apps/landing/src/app/_components/code-tabs.tsx b/apps/landing/src/app/_components/code-tabs.tsx new file mode 100644 index 00000000..3774c8ba --- /dev/null +++ b/apps/landing/src/app/_components/code-tabs.tsx @@ -0,0 +1,72 @@ +'use client' + +import { Box, Flex, Text } from '@devup-ui/react' +import { useState } from 'react' + +import { CodeWindow, HighlightedCode } from './code-window' + +export interface CodeExample { + key: string + label: string + file: string + html: string +} + +export function CodeTabs({ examples }: { examples: CodeExample[] }) { + const [active, setActive] = useState(examples[0]?.key ?? '') + const current = examples.find((e) => e.key === active) ?? examples[0] + + if (!current) return null + + return ( + ( + setActive(ex.key)} + px="12px" + py="5px" + transition="color .15s, background .15s" + > + + {ex.label} + + + ))} + title={current.file} + > + + + ) +} + +export function StaticCodeBlock({ + title, + html, +}: { + title: string + html: string +}) { + return ( + + + + ) +} + +export function HeroCodeWrapper({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/apps/landing/src/app/_components/code-theme.ts b/apps/landing/src/app/_components/code-theme.ts new file mode 100644 index 00000000..9db3dfef --- /dev/null +++ b/apps/landing/src/app/_components/code-theme.ts @@ -0,0 +1,19 @@ +import { globalCss } from '@devup-ui/react' + +globalCss({ + '.shiki, .shiki span': { + fontFamily: 'D2Coding', + fontSize: '13px', + lineHeight: '1.65', + }, + '.shiki': { + background: 'transparent !important', + padding: '0', + margin: '0', + overflowX: 'auto', + }, + '[data-theme="dark"] .shiki, [data-theme="dark"] .shiki span': { + color: 'var(--shiki-dark) !important', + backgroundColor: 'transparent !important', + }, +}) diff --git a/apps/landing/src/app/_components/code-window.tsx b/apps/landing/src/app/_components/code-window.tsx new file mode 100644 index 00000000..63a71e2f --- /dev/null +++ b/apps/landing/src/app/_components/code-window.tsx @@ -0,0 +1,71 @@ +import { Box, Flex, Text } from '@devup-ui/react' +import type { ComponentProps, ReactNode } from 'react' + +import './code-theme' + +export function CodeWindow({ + title, + tabs, + children, + ...props +}: { + title: string + tabs?: ReactNode + children: ReactNode +} & ComponentProps>) { + return ( + + + + {[0, 1, 2].map((i) => ( + + ))} + + + {title} + + {tabs && ( + + {tabs} + + )} + + + {children} + + + ) +} + +export function HighlightedCode({ html }: { html: string }) { + return
+} diff --git a/apps/landing/src/app/_components/copy-install.tsx b/apps/landing/src/app/_components/copy-install.tsx new file mode 100644 index 00000000..f867ce08 --- /dev/null +++ b/apps/landing/src/app/_components/copy-install.tsx @@ -0,0 +1,61 @@ +'use client' + +import { Box, Flex, Text } from '@devup-ui/react' +import { useState } from 'react' + +export function CopyInstall({ + command = 'cargo install vespertide-cli', +}: { + command?: string +}) { + const [copied, setCopied] = useState(false) + + const copy = () => { + navigator.clipboard?.writeText(command) + setCopied(true) + setTimeout(() => setCopied(false), 1400) + } + + return ( + + + $ + + + {command} + + { + e.stopPropagation() + copy() + }} + px="9px" + py="5px" + transition="color .15s, border-color .15s" + > + {copied ? 'copied' : 'copy'} + + + ) +} diff --git a/apps/landing/src/app/_components/example.tsx b/apps/landing/src/app/_components/example.tsx deleted file mode 100644 index 6e69244b..00000000 --- a/apps/landing/src/app/_components/example.tsx +++ /dev/null @@ -1,102 +0,0 @@ -'use client' - -import { Flex, Image } from '@devup-ui/react' -import { ComponentProps, createContext, useContext, useState } from 'react' - -const ExampleContext = createContext<{ - selected: string - setSelected: (selected: string) => void - selectedExample?: { - id: string - title: string - description: string - imageUrl: string - } -} | null>(null) - -export function useExample() { - const context = useContext(ExampleContext) - if (!context) { - throw new Error('useExample must be used within a ExampleProvider') - } - return context -} - -export function ExampleProvider({ - defaultSelected = '', - examples, - children, -}: { - defaultSelected?: string - examples: { - id: string - title: string - description: string - imageUrl: string - }[] - children: React.ReactNode -}) { - const [selected, setSelected] = useState(defaultSelected) - const selectedExample = examples.find((example) => example.id === selected) - return ( - - {children} - - ) -} - -export function ExampleContainer({ - value, - ...props -}: ComponentProps> & { value?: string }) { - const { selected, setSelected } = useExample() - const isSelected = selected === value - return ( - setSelected(value) : undefined} - overflow="hidden" - px="$spacingSpacing24" - py="$spacingSpacing20" - styleOrder={1} - transition="all .1s" - {...props} - /> - ) -} - -export function ExampleImage({ - ...props -}: Omit>, 'src'>) { - const { selectedExample } = useExample() - return ( - {selectedExample?.title - ) -} - -export function Example() {} diff --git a/apps/landing/src/app/_components/join-icon-button.tsx b/apps/landing/src/app/_components/join-icon-button.tsx deleted file mode 100644 index 24128d88..00000000 --- a/apps/landing/src/app/_components/join-icon-button.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Flex } from '@devup-ui/react' -import { ComponentProps } from 'react' - -export function JoinIconButton(props: ComponentProps>) { - return ( - - ) -} diff --git a/apps/landing/src/app/_lib/highlight.ts b/apps/landing/src/app/_lib/highlight.ts new file mode 100644 index 00000000..82e8cf23 --- /dev/null +++ b/apps/landing/src/app/_lib/highlight.ts @@ -0,0 +1,19 @@ +import { codeToHtml } from 'shiki' + +export type CodeLang = 'json' | 'shell' | 'rust' + +const LANG_MAP: Record = { + json: 'json', + shell: 'bash', + rust: 'rust', +} + +export async function highlight(code: string, lang: CodeLang): Promise { + return codeToHtml(code, { + lang: LANG_MAP[lang], + themes: { + light: 'github-light', + dark: 'github-dark', + }, + }) +} diff --git a/apps/landing/src/app/page.tsx b/apps/landing/src/app/page.tsx index b61eaf4c..bd9468a1 100644 --- a/apps/landing/src/app/page.tsx +++ b/apps/landing/src/app/page.tsx @@ -1,18 +1,14 @@ -import { JoinIconButton } from '@app/_components/join-icon-button' -import { Box, Center, css, Flex, Text, VStack } from '@devup-ui/react' -import { Image } from '@devup-ui/react' +import { Box, Flex, Text, VStack } from '@devup-ui/react' import type { Metadata } from 'next' import Link from 'next/link' +import type { ComponentProps } from 'react' import { Button } from '@/components/button' -import { GnbIcon } from '@/components/header/gnb-icon' -import { HeaderSentinel } from '@/components/header/header-sentinel' -import { - ExampleContainer, - ExampleImage, - ExampleProvider, -} from './_components/example' +import { CodeTabs, type CodeExample } from './_components/code-tabs' +import { CodeWindow, HighlightedCode } from './_components/code-window' +import { CopyInstall } from './_components/copy-install' +import { highlight } from './_lib/highlight' export const metadata: Metadata = { alternates: { @@ -20,290 +16,964 @@ export const metadata: Metadata = { }, } -const EXAMPLES = [ +const VERSION = '0.1.61' +const GITHUB_URL = 'https://github.com/dev-five-git/vespertide' +const DOCS_URL = '/documentation' +const DISCORD_URL = 'https://discord.com/invite/8zjcGc7cWh' +const KAKAO_URL = 'https://open.kakao.com/o/giONwVAh' +const CRATES_URL = 'https://crates.io/crates/vespertide-cli' + +const HERO_MODEL_JSON = `{ + "$schema": "https://raw.githubusercontent.com/dev-five-git/vespertide/main/schemas/model.schema.json", + "name": "user", + "columns": [ + { "name": "id", "type": "integer", "primary_key": true }, + { "name": "email", "type": "text", "unique": true, "index": true }, + { "name": "name", "type": { "kind": "varchar", "length": 100 } }, + { + "name": "status", + "type": { "kind": "enum", "name": "user_status", + "values": ["active", "inactive", "banned"] }, + "default": "'active'" + }, + { "name": "created_at", "type": "timestamptz", "default": "NOW()" } + ] +}` + +const EXAMPLE_MODEL = `{ + "$schema": "https://raw.githubusercontent.com/dev-five-git/vespertide/main/schemas/model.schema.json", + "name": "post", + "columns": [ + { "name": "id", "type": "integer", "primary_key": true }, + { "name": "title", "type": { "kind": "varchar", "length": 200 } }, + { "name": "body", "type": "text" }, + { + "name": "author_id", + "type": "integer", + "foreign_key": { + "ref_table": "user", + "ref_columns": ["id"], + "on_delete": "cascade" + }, + "index": true + }, + { + "name": "status", + "type": { "kind": "enum", "name": "post_status", + "values": ["draft", "published", "archived"] }, + "default": "'draft'" + } + ] +}` + +const EXAMPLE_CLI = `# Initialize a new project +$ vespertide init + +# Scaffold a model +$ vespertide new post + +# Edit models/post.json, then preview the diff +$ vespertide diff ++ create_table post (id, title, body, author_id, status) ++ create_enum post_status [draft, published, archived] ++ create_index ix_post_author_id ON post (author_id) + +# Inspect dialect-specific SQL +$ vespertide sql --backend postgres + +# Persist as a migration file +$ vespertide revision -m "create post table"` + +const EXAMPLE_RUNTIME = `use sea_orm::Database; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let db = Database::connect("postgres://user:pass@localhost/mydb").await?; + + // Generated at compile time, run on startup. + vespertide::vespertide_migration!(db).await?; + + Ok(()) +}` + +const EXAMPLE_EXPORT = `# Generate Rust SeaORM entities +$ vespertide export --orm seaorm + +# Or Python — SQLAlchemy +$ vespertide export --orm sqlalchemy + +# Or FastAPI-flavoured SQLModel +$ vespertide export --orm sqlmodel + +# Or Go — GORM +$ vespertide export --orm gorm` + +type FeatureIconName = + | 'hamburger' + | 'arrow-up-right' + | 'chevron' + | 'logo-image' + | 'devfive' + | 'theme-dark' + | 'search' + | 'external-link' + | 'github' + +const FEATURES: { icon: FeatureIconName; title: string; desc: string }[] = [ + { + icon: 'hamburger', + title: 'Declarative schema', + desc: 'Describe your desired database state in JSON files. The current model is the source of truth.', + }, + { + icon: 'arrow-up-right', + title: 'Automatic diffing', + desc: 'Vespertide replays applied migrations and compares them to your models to compute changes.', + }, + { + icon: 'chevron', + title: 'Typed migration plans', + desc: 'Generates safe, portable MigrationAction enums — not raw SQL. Review before you commit.', + }, { - id: '1', - title: 'How to Use', - description: - 'Lorem ipsum dolor sit amet. Etiam sit amet feugiat turpis. Proin nec ante a sem vestibulum sodales non ut ex.', - imageUrl: '/images/hero-figure.webp', + icon: 'logo-image', + title: 'Multi-database', + desc: 'PostgreSQL, MySQL, and SQLite — same schema, identical semantics, backend-aware quoting.', }, { - id: '2', - title: 'How to Use', - description: - 'Lorem ipsum dolor sit amet. Etiam sit amet feugiat turpis. Proin nec ante a sem vestibulum sodales non ut ex.', - imageUrl: '/images/join-us-bg.webp', + icon: 'devfive', + title: 'Native enums', + desc: 'First-class string and integer enums. Add new integer values without ever touching the DB.', }, { - id: '3', - title: 'How to Use', - description: - 'Lorem ipsum dolor sit amet. Etiam sit amet feugiat turpis. Proin nec ante a sem vestibulum sodales non ut ex.', - imageUrl: '/images/code.webp', + icon: 'theme-dark', + title: 'Zero-runtime macro', + desc: 'vespertide_migration!() generates database-specific SQL at compile time. Nothing to ship at runtime.', + }, + { + icon: 'search', + title: 'JSON Schema validation', + desc: 'Ships with JSON Schemas — autocomplete, hover docs, and instant errors in your editor.', + }, + { + icon: 'external-link', + title: 'ORM export', + desc: 'One command emits SeaORM, SQLAlchemy, SQLModel, or GORM — entities stay in lockstep with schema.', + }, + { + icon: 'github', + title: 'Built in Rust', + desc: "Single binary CLI, no Node, no Python, no JVM. cargo install vespertide-cli and you're done.", }, ] -export default function HomePage() { +const STEPS: { title: string; desc: string; mono: string }[] = [ + { + title: 'Define', + desc: 'Author JSON models in your editor with full IDE validation via JSON Schema.', + mono: 'models/user.json', + }, + { + title: 'Replay', + desc: 'Vespertide reconstructs the baseline schema by replaying applied migrations.', + mono: 'migrations/*.sql', + }, + { + title: 'Diff', + desc: 'Current models are compared to the baseline to find what changed.', + mono: 'vespertide diff', + }, + { + title: 'Plan', + desc: 'Differences are converted into typed MigrationAction enums.', + mono: 'MigrationAction', + }, + { + title: 'Emit', + desc: 'Actions translate to dialect-specific SQL — Postgres, MySQL, or SQLite.', + mono: 'vespertide sql', + }, +] + +const DBS = [ + { + key: 'PG', + name: 'PostgreSQL', + quote: '"identifier"', + note: 'Full feature support — native enums, JSONB, INET, CIDR, TSVECTOR.', + }, + { + key: 'MY', + name: 'MySQL', + quote: '`identifier`', + note: 'Full feature support with MySQL-aware identifier quoting and types.', + }, + { + key: 'SL', + name: 'SQLite', + quote: '"identifier"', + note: 'Full feature support — perfect for tests, CLIs, and embedded apps.', + }, +] + +const ORMS = [ + { lang: 'Rust', name: 'SeaORM' }, + { lang: 'Python', name: 'SQLAlchemy' }, + { lang: 'Python', name: 'SQLModel · FastAPI' }, + { lang: 'Go', name: 'GORM' }, +] + +function MaskIcon({ + icon, + size = '24px', + color = '$vespertidePrimary', + ...props +}: { + icon: FeatureIconName | 'discord' | 'kakao' + size?: string + color?: string +} & ComponentProps>) { + return ( + + ) +} + +function SectionHead({ + eyebrow, + title, + emphasis, + lede, +}: { + eyebrow: string + title: string + emphasis?: string + lede?: string +}) { return ( - <> - -
+ + — {eyebrow} + + + {title} + {emphasis && ( + <> + {' '} + + {emphasis} + + + )} + + {lede && ( + + {lede} + + )} + + ) +} + +function HeroSection({ codeHtml }: { codeHtml: string }) { + return ( + + + + + + + + + v{VERSION} · Apache-2.0 · Rust + + + + + Define schemas. +
+ + Forget migrations. + +
+ + + Vespertide is a declarative database schema manager for Rust. Write + your tables in JSON, and let it diff, plan, and emit type-safe + migrations to Postgres, MySQL, and SQLite — automatically. + + + + + + + + + + + View on GitHub + + + + + + + + + {[ + { num: `v${VERSION}`, lbl: 'Version' }, + { num: '3', lbl: 'Databases' }, + { num: '4', lbl: 'ORM exports' }, + { num: '0ms', lbl: 'Runtime cost' }, + ].map((s) => ( + + + {s.num} + + + {s.lbl} + + + ))} + +
+ + + + + + +
+
+
+ ) +} + +function FeaturesSection() { + return ( + + + + + + - + {FEATURES.map((f) => ( - - Lorem ipsum dolor sit amet,
- consectetur adipiscing elit. + + + {f.title} - - Etiam sit amet feugiat turpis. Proin nec ante a sem vestibulum - sodales non ut ex.
- Morbi diam turpis, fringilla vitae enim et, egestas consequat - nibh.
- Etiam auctor cursus urna sit amet elementum. + + {f.desc}
- - -
-
+ ))} +
+
+ + ) +} -
+ + + + + - - - - Title + {STEPS.map((s, i) => ( + + + {String(i + 1).padStart(2, '0')} - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam - venenatis, elit in hendrerit porta, augue ante scelerisque diam,{' '} -
- ac egestas lacus est nec urna. Cras commodo risus hendrerit, - suscipit nibh at, porttitor dui. + + {s.title} -
- - {[0, 1, 2, 3].map((i) => ( - + {s.desc} +
+ + - + +
+ ))} +
+
+ + ) +} + +function ExamplesSection({ examples }: { examples: CodeExample[] }) { + return ( + + + + + + — Examples + + + One source of truth, +
+ four ways to use it. +
+ + Your JSON models drive the diff, the SQL, the ORM entities, and the + runtime macro. Pick the workflow that fits your team — Vespertide + stays consistent. + + + {[ + { + k: 'Models.', + v: 'Inline foreign keys, enums, and constraints — no separate schema language.', + }, + { + k: 'CLI.', + v: 'diff, sql, revision, status, log — every step is a plain command.', + }, + { + k: 'Runtime.', + v: 'Compile-time macro, zero overhead, no migrations folder shipped to prod.', + }, + { + k: 'Export.', + v: 'SeaORM, SQLAlchemy, SQLModel, GORM — typed entities, generated.', + }, + ].map((it) => ( + + - - Feature title - - - Lorem ipsum dolor sit amet. Etiam sit amet feugiat turpis. - Proin nec ante a sem vestibulum sodales non ut ex.{' '} - - + → + + + + {it.k} + {' '} + {it.v} +
))} -
- - -
- - - - Title - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Nullam venenatis ac egestas lacus est nec urna.{' '} - - - + + + + + + + ) +} + +function CompatibilitySection() { + return ( + + + + + + + + {DBS.map((db) => ( + + - - - - + {db.key} + - - {EXAMPLES.map(({ id, title, description }) => ( - - - - {title} - - - {description} - - - - ))} - - + + {db.name} + + + + {db.quote} + + + {db.note} + -
-
- - + + + + — ORM export + + + Generate typed entities for the runtime you use. + + + + vespertide export --orm <target> + {' '} + emits up-to-date entities from your current models. + + + {ORMS.map((orm) => ( + + + {orm.lang} + + {orm.name} + + ))} + + + + + ) +} + +function ChannelRow({ + href, + icon, + name, + meta, +}: { + href: string + icon: 'github' | 'discord' | 'kakao' + name: string + meta: string +}) { + return ( + + + + + + + {name} + + - + + + ) +} + +function CommunitySection() { + return ( + + + + + - - - - Join our community - - - Join our Discord and help build the future of frontend with - CSS-in-JS!{' '} + + + — Get started + + + Install once.{' '} + + Iterate forever. - - - - - - - - - - - + + + Vespertide is open source under Apache-2.0 and built in public. + Join the community, file an issue, or pair with us in Discord. + + + + + - - - + + + + Star on GitHub + + - join us background image - - + + + + + +
+ + + + + Apache-2.0 · v{VERSION} ·{' '} + + crates.io + + + + built with Rust · maintained in Seoul + + - + + ) +} + +export default async function HomePage() { + const [heroHtml, modelHtml, cliHtml, runtimeHtml, exportHtml] = + await Promise.all([ + highlight(HERO_MODEL_JSON, 'json'), + highlight(EXAMPLE_MODEL, 'json'), + highlight(EXAMPLE_CLI, 'shell'), + highlight(EXAMPLE_RUNTIME, 'rust'), + highlight(EXAMPLE_EXPORT, 'shell'), + ]) + + const examples: CodeExample[] = [ + { key: 'model', label: 'Model', file: 'models/post.json', html: modelHtml }, + { key: 'cli', label: 'CLI', file: '~/projects/blog', html: cliHtml }, + { key: 'runtime', label: 'Runtime', file: 'src/main.rs', html: runtimeHtml }, + { + key: 'export', + label: 'ORM export', + file: '$ vespertide export', + html: exportHtml, + }, + ] + + return ( + + + + + + + + ) } From 674ec65be6a678508660dfb1a5757c7767ff6231 Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Sat, 27 Jun 2026 19:00:51 +0900 Subject: [PATCH 02/14] Merge upstream/main into main (landing) --- apps/landing/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/landing/package.json b/apps/landing/package.json index 4a3fd6a7..e5adda5f 100644 --- a/apps/landing/package.json +++ b/apps/landing/package.json @@ -18,24 +18,24 @@ "@devup-ui/reset-css": "^1", "@mdx-js/loader": "^3.1.1", "@mdx-js/react": "^3.1.1", - "@next/mdx": "^16.3.1", + "@next/mdx": "^16.2.7", "clsx": "^2.1.1", "next": "^16", "react": "^19", - "rehype-pretty-code": "^0.14.5", + "rehype-pretty-code": "^0.14.3", "rehype-sanitize": "^6.0.0", "rehype-slug": "^6.0.0", "rehype-stringify": "^10.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", - "shiki": "^4.4.3", + "shiki": "^4.2.0", "unified": "^11.0.5" }, "devDependencies": { "@types/mdx": "^2.0.14", "@devup-api/next-plugin": "^0.1", "@devup-ui/next-plugin": "^1", - "@types/node": "^26", + "@types/node": "^25", "@types/react": "^19", "@types/react-syntax-highlighter": "^15.5.13", "babel-plugin-react-compiler": "^1.0.0", From ad76a7ec8baa7f5016edfb9c824710a63545fbfe Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Sat, 11 Jul 2026 23:12:20 +0900 Subject: [PATCH 03/14] =?UTF-8?q?feat=20:=20Django=20=EC=A7=80=EC=9B=90=20?= =?UTF-8?q?(landing)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../landing/src/app/_components/code-tabs.tsx | 23 +--------- .../landing/src/app/_components/code-theme.ts | 19 --------- .../src/app/_components/code-window.tsx | 42 ++++++++++++++++++- 3 files changed, 41 insertions(+), 43 deletions(-) delete mode 100644 apps/landing/src/app/_components/code-theme.ts diff --git a/apps/landing/src/app/_components/code-tabs.tsx b/apps/landing/src/app/_components/code-tabs.tsx index 3774c8ba..22a15a0c 100644 --- a/apps/landing/src/app/_components/code-tabs.tsx +++ b/apps/landing/src/app/_components/code-tabs.tsx @@ -1,6 +1,6 @@ 'use client' -import { Box, Flex, Text } from '@devup-ui/react' +import { Box, Text } from '@devup-ui/react' import { useState } from 'react' import { CodeWindow, HighlightedCode } from './code-window' @@ -49,24 +49,3 @@ export function CodeTabs({ examples }: { examples: CodeExample[] }) { ) } -export function StaticCodeBlock({ - title, - html, -}: { - title: string - html: string -}) { - return ( - - - - ) -} - -export function HeroCodeWrapper({ children }: { children: React.ReactNode }) { - return ( - - {children} - - ) -} diff --git a/apps/landing/src/app/_components/code-theme.ts b/apps/landing/src/app/_components/code-theme.ts deleted file mode 100644 index 9db3dfef..00000000 --- a/apps/landing/src/app/_components/code-theme.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { globalCss } from '@devup-ui/react' - -globalCss({ - '.shiki, .shiki span': { - fontFamily: 'D2Coding', - fontSize: '13px', - lineHeight: '1.65', - }, - '.shiki': { - background: 'transparent !important', - padding: '0', - margin: '0', - overflowX: 'auto', - }, - '[data-theme="dark"] .shiki, [data-theme="dark"] .shiki span': { - color: 'var(--shiki-dark) !important', - backgroundColor: 'transparent !important', - }, -}) diff --git a/apps/landing/src/app/_components/code-window.tsx b/apps/landing/src/app/_components/code-window.tsx index 63a71e2f..ec1c77a3 100644 --- a/apps/landing/src/app/_components/code-window.tsx +++ b/apps/landing/src/app/_components/code-window.tsx @@ -1,7 +1,23 @@ -import { Box, Flex, Text } from '@devup-ui/react' +import { Box, Flex, globalCss, Text } from '@devup-ui/react' import type { ComponentProps, ReactNode } from 'react' -import './code-theme' +globalCss({ + '.shiki, .shiki span': { + fontFamily: 'D2Coding', + fontSize: '13px', + lineHeight: '1.65', + }, + '.shiki': { + background: 'transparent !important', + padding: '0', + margin: '0', + overflowX: 'auto', + }, + '[data-theme="dark"] .shiki, [data-theme="dark"] .shiki span': { + color: 'var(--shiki-dark) !important', + backgroundColor: 'transparent !important', + }, +}) export function CodeWindow({ title, @@ -69,3 +85,25 @@ export function CodeWindow({ export function HighlightedCode({ html }: { html: string }) { return
} + +export function StaticCodeBlock({ + title, + html, +}: { + title: string + html: string +}) { + return ( + + + + ) +} + +export function HeroCodeWrapper({ children }: { children: ReactNode }) { + return ( + + {children} + + ) +} From a8fa261ebbca1ef33055f3f8b7c9fcd463a23a8a Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Sat, 11 Jul 2026 23:15:59 +0900 Subject: [PATCH 04/14] =?UTF-8?q?feat=20:=20Django=20=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/landing/public/search.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/landing/public/search.json b/apps/landing/public/search.json index 6ef48036..4e5e7d7f 100644 --- a/apps/landing/public/search.json +++ b/apps/landing/public/search.json @@ -1 +1 @@ -[null,null,null,null,{"text":"## What is Devup UI?eeeeeeeeeeee\n\n**Devup UI is not just another CSS-in-JS library — it's the future of CSS-in-JS itself.**\n\nDevup UI is a zero-runtime CSS-in-JS preprocessor powered by Rust and WebAssembly. It transforms all your styles at build time, completely eliminating runtime overhead while providing full CSS-in-JS syntax coverage.\n\n### The Problem with Traditional CSS-in-JS\n\nTraditional CSS-in-JS solutions force you to choose between:\n\n- **Developer Experience**: Intuitive APIs, co-located styles, dynamic theming\n- **Performance**: No runtime overhead, fast page loads, optimal Core Web Vitals\n\nLibraries like styled-components and Emotion offer great DX but execute JavaScript at runtime to generate styles. Zero-runtime alternatives like Vanilla Extract sacrifice some flexibility for performance.\n\n### The Devup UI Solution\n\nDevup UI eliminates this trade-off entirely. Our Rust-powered preprocessor analyzes your code at build time and handles every CSS-in-JS pattern:\n\n- **Variables** — Dynamic values become CSS custom properties\n- **Conditionals** — Ternary expressions are statically analyzed\n- **Responsive Arrays** — Breakpoint-based styles are pre-generated\n- **Pseudo Selectors** — `_hover`, `_focus`, `_active` work seamlessly\n- **Themes** — Type-safe theme tokens with zero-cost switching\n\n### Key Advantages\n\n\n \n \n Feature\n Devup UI\n styled-components\n Emotion\n Vanilla Extract\n \n \n \n \n Zero Runtime\n Yes\n No\n No\n Yes\n \n \n Dynamic Values\n Yes\n Yes\n Yes\n Limited\n \n \n Full Syntax Coverage\n Yes\n Yes\n Yes\n No\n \n \n Type-Safe Themes\n Yes\n Limited\n Limited\n Yes\n \n \n Build Performance\n Fastest\n N/A\n N/A\n Fast\n \n \n
\n\n### How It Works\n\n```tsx\n// You write familiar CSS-in-JS syntax\nconst example = \n\n// Devup UI transforms it at build time\nconst generated =
\n\n// With optimized atomic CSS\n// .a { background-color: red; }\n// .b { padding: 16px; } /* 4 * 4 = 16px */\n// .c:hover { background-color: blue; }\n```\n\n> Numeric values are multiplied by 4. `p={4}` becomes `padding: 16px`.\n\nClass names use compact base-37 encoding (`a`, `b`, ... `z`, `_`, `aa`, `ab`, ...) for minimal CSS output.\n\n### Familiar API\n\nIf you've used styled-components or Emotion, you'll feel right at home:\n\n```tsx\nimport { styled } from '@devup-ui/react'\n\nconst Card = styled('div', {\n bg: 'white',\n p: 4, // 4 * 4 = 16px\n borderRadius: '8px',\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\n _hover: {\n boxShadow: '0 10px 15px rgba(0, 0, 0, 0.1)',\n },\n})\n```\n\n### Proven Performance\n\nBenchmarks on Next.js (GitHub Actions - ubuntu-latest):\n\n\n \n \n Library\n Version\n Build Time\n Build Size\n \n \n \n \n tailwindcss\n 4.1.13\n 19.31s\n 59,521,539 bytes\n \n \n styleX\n 0.15.4\n 41.78s\n 86,869,452 bytes\n \n \n vanilla-extract\n 1.17.4\n 19.50s\n 61,494,033 bytes\n \n \n kuma-ui\n 1.5.9\n 20.93s\n 69,924,179 bytes\n \n \n panda-css\n 1.3.1\n 20.64s\n 64,573,260 bytes\n \n \n chakra-ui\n 3.27.0\n 28.81s\n 222,435,802 bytes\n \n \n mui\n 7.3.2\n 20.86s\n 97,964,458 bytes\n \n \n **devup-ui (per-file css)**\n **1.0.18**\n **16.90s**\n 59,540,459 bytes\n \n \n **devup-ui (single css)**\n **1.0.18**\n **17.05s**\n **59,520,196 bytes**\n \n \n tailwindcss (turbopack)\n 4.1.13\n 6.72s\n 5,355,082 bytes\n \n \n **devup-ui (single css + turbopack)**\n **1.0.18**\n 10.34s\n **4,772,050 bytes**\n \n \n
\n\n### Get Started\n\nReady to experience the future of CSS-in-JS? Head to the [Installation](/docs/installation) guide to get started in minutes.\n","title":"What is Devup UI?eeeeeeeeeeee","url":"/documentation/concept/concept-1"},null,null,null,null,null,{"text":"## What is Devup UI?\n\n**Devup UI is not just another CSS-in-JS library — it's the future of CSS-in-JS itself.**\n\nDevup UI is a zero-runtime CSS-in-JS preprocessor powered by Rust and WebAssembly. It transforms all your styles at build time, completely eliminating runtime overhead while providing full CSS-in-JS syntax coverage.\n\n### The Problem with Traditional CSS-in-JS\n\nTraditional CSS-in-JS solutions force you to choose between:\n\n- **Developer Experience**: Intuitive APIs, co-located styles, dynamic theming\n- **Performance**: No runtime overhead, fast page loads, optimal Core Web Vitals\n\nLibraries like styled-components and Emotion offer great DX but execute JavaScript at runtime to generate styles. Zero-runtime alternatives like Vanilla Extract sacrifice some flexibility for performance.\n\n### The Devup UI Solution\n\nDevup UI eliminates this trade-off entirely. Our Rust-powered preprocessor analyzes your code at build time and handles every CSS-in-JS pattern:\n\n- **Variables** — Dynamic values become CSS custom properties\n- **Conditionals** — Ternary expressions are statically analyzed\n- **Responsive Arrays** — Breakpoint-based styles are pre-generated\n- **Pseudo Selectors** — `_hover`, `_focus`, `_active` work seamlessly\n- **Themes** — Type-safe theme tokens with zero-cost switching\n\n### Key Advantages\n\n\n \n \n Feature\n Devup UI\n styled-components\n Emotion\n Vanilla Extract\n \n \n \n \n Zero Runtime\n Yes\n No\n No\n Yes\n \n \n Dynamic Values\n Yes\n Yes\n Yes\n Limited\n \n \n Full Syntax Coverage\n Yes\n Yes\n Yes\n No\n \n \n Type-Safe Themes\n Yes\n Limited\n Limited\n Yes\n \n \n Build Performance\n Fastest\n N/A\n N/A\n Fast\n \n \n
\n\n### How It Works\n\n```tsx\n// You write familiar CSS-in-JS syntax\nconst example = \n\n// Devup UI transforms it at build time\nconst generated =
\n\n// With optimized atomic CSS\n// .a { background-color: red; }\n// .b { padding: 16px; } /* 4 * 4 = 16px */\n// .c:hover { background-color: blue; }\n```\n\n> Numeric values are multiplied by 4. `p={4}` becomes `padding: 16px`.\n\nClass names use compact base-37 encoding (`a`, `b`, ... `z`, `_`, `aa`, `ab`, ...) for minimal CSS output.\n\n### Familiar API\n\nIf you've used styled-components or Emotion, you'll feel right at home:\n\n```tsx\nimport { styled } from '@devup-ui/react'\n\nconst Card = styled('div', {\n bg: 'white',\n p: 4, // 4 * 4 = 16px\n borderRadius: '8px',\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\n _hover: {\n boxShadow: '0 10px 15px rgba(0, 0, 0, 0.1)',\n },\n})\n```\n\n### Proven Performance\n\nBenchmarks on Next.js (GitHub Actions - ubuntu-latest):\n\n\n \n \n Library\n Version\n Build Time\n Build Size\n \n \n \n \n tailwindcss\n 4.1.13\n 19.31s\n 59,521,539 bytes\n \n \n styleX\n 0.15.4\n 41.78s\n 86,869,452 bytes\n \n \n vanilla-extract\n 1.17.4\n 19.50s\n 61,494,033 bytes\n \n \n kuma-ui\n 1.5.9\n 20.93s\n 69,924,179 bytes\n \n \n panda-css\n 1.3.1\n 20.64s\n 64,573,260 bytes\n \n \n chakra-ui\n 3.27.0\n 28.81s\n 222,435,802 bytes\n \n \n mui\n 7.3.2\n 20.86s\n 97,964,458 bytes\n \n \n **devup-ui (per-file css)**\n **1.0.18**\n **16.90s**\n 59,540,459 bytes\n \n \n **devup-ui (single css)**\n **1.0.18**\n **17.05s**\n **59,520,196 bytes**\n \n \n tailwindcss (turbopack)\n 4.1.13\n 6.72s\n 5,355,082 bytes\n \n \n **devup-ui (single css + turbopack)**\n **1.0.18**\n 10.34s\n **4,772,050 bytes**\n \n \n
\n\n### Get Started\n\nReady to experience the future of CSS-in-JS? Head to the [Installation](/docs/installation) guide to get started in minutes.\n","title":"What is Devup UI?","url":"/documentation/overview"},null,null,null,null] \ No newline at end of file +[null,null,null,null,{"text":"## What is Devup UI?eeeeeeeeeeee\r\n\r\n**Devup UI is not just another CSS-in-JS library — it's the future of CSS-in-JS itself.**\r\n\r\nDevup UI is a zero-runtime CSS-in-JS preprocessor powered by Rust and WebAssembly. It transforms all your styles at build time, completely eliminating runtime overhead while providing full CSS-in-JS syntax coverage.\r\n\r\n### The Problem with Traditional CSS-in-JS\r\n\r\nTraditional CSS-in-JS solutions force you to choose between:\r\n\r\n- **Developer Experience**: Intuitive APIs, co-located styles, dynamic theming\r\n- **Performance**: No runtime overhead, fast page loads, optimal Core Web Vitals\r\n\r\nLibraries like styled-components and Emotion offer great DX but execute JavaScript at runtime to generate styles. Zero-runtime alternatives like Vanilla Extract sacrifice some flexibility for performance.\r\n\r\n### The Devup UI Solution\r\n\r\nDevup UI eliminates this trade-off entirely. Our Rust-powered preprocessor analyzes your code at build time and handles every CSS-in-JS pattern:\r\n\r\n- **Variables** — Dynamic values become CSS custom properties\r\n- **Conditionals** — Ternary expressions are statically analyzed\r\n- **Responsive Arrays** — Breakpoint-based styles are pre-generated\r\n- **Pseudo Selectors** — `_hover`, `_focus`, `_active` work seamlessly\r\n- **Themes** — Type-safe theme tokens with zero-cost switching\r\n\r\n### Key Advantages\r\n\r\n\r\n \r\n \r\n Feature\r\n Devup UI\r\n styled-components\r\n Emotion\r\n Vanilla Extract\r\n \r\n \r\n \r\n \r\n Zero Runtime\r\n Yes\r\n No\r\n No\r\n Yes\r\n \r\n \r\n Dynamic Values\r\n Yes\r\n Yes\r\n Yes\r\n Limited\r\n \r\n \r\n Full Syntax Coverage\r\n Yes\r\n Yes\r\n Yes\r\n No\r\n \r\n \r\n Type-Safe Themes\r\n Yes\r\n Limited\r\n Limited\r\n Yes\r\n \r\n \r\n Build Performance\r\n Fastest\r\n N/A\r\n N/A\r\n Fast\r\n \r\n \r\n
\r\n\r\n### How It Works\r\n\r\n```tsx\r\n// You write familiar CSS-in-JS syntax\r\nconst example = \r\n\r\n// Devup UI transforms it at build time\r\nconst generated =
\r\n\r\n// With optimized atomic CSS\r\n// .a { background-color: red; }\r\n// .b { padding: 16px; } /* 4 * 4 = 16px */\r\n// .c:hover { background-color: blue; }\r\n```\r\n\r\n> Numeric values are multiplied by 4. `p={4}` becomes `padding: 16px`.\r\n\r\nClass names use compact base-37 encoding (`a`, `b`, ... `z`, `_`, `aa`, `ab`, ...) for minimal CSS output.\r\n\r\n### Familiar API\r\n\r\nIf you've used styled-components or Emotion, you'll feel right at home:\r\n\r\n```tsx\r\nimport { styled } from '@devup-ui/react'\r\n\r\nconst Card = styled('div', {\r\n bg: 'white',\r\n p: 4, // 4 * 4 = 16px\r\n borderRadius: '8px',\r\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\r\n _hover: {\r\n boxShadow: '0 10px 15px rgba(0, 0, 0, 0.1)',\r\n },\r\n})\r\n```\r\n\r\n### Proven Performance\r\n\r\nBenchmarks on Next.js (GitHub Actions - ubuntu-latest):\r\n\r\n\r\n \r\n \r\n Library\r\n Version\r\n Build Time\r\n Build Size\r\n \r\n \r\n \r\n \r\n tailwindcss\r\n 4.1.13\r\n 19.31s\r\n 59,521,539 bytes\r\n \r\n \r\n styleX\r\n 0.15.4\r\n 41.78s\r\n 86,869,452 bytes\r\n \r\n \r\n vanilla-extract\r\n 1.17.4\r\n 19.50s\r\n 61,494,033 bytes\r\n \r\n \r\n kuma-ui\r\n 1.5.9\r\n 20.93s\r\n 69,924,179 bytes\r\n \r\n \r\n panda-css\r\n 1.3.1\r\n 20.64s\r\n 64,573,260 bytes\r\n \r\n \r\n chakra-ui\r\n 3.27.0\r\n 28.81s\r\n 222,435,802 bytes\r\n \r\n \r\n mui\r\n 7.3.2\r\n 20.86s\r\n 97,964,458 bytes\r\n \r\n \r\n **devup-ui (per-file css)**\r\n **1.0.18**\r\n **16.90s**\r\n 59,540,459 bytes\r\n \r\n \r\n **devup-ui (single css)**\r\n **1.0.18**\r\n **17.05s**\r\n **59,520,196 bytes**\r\n \r\n \r\n tailwindcss (turbopack)\r\n 4.1.13\r\n 6.72s\r\n 5,355,082 bytes\r\n \r\n \r\n **devup-ui (single css + turbopack)**\r\n **1.0.18**\r\n 10.34s\r\n **4,772,050 bytes**\r\n \r\n \r\n
\r\n\r\n### Get Started\r\n\r\nReady to experience the future of CSS-in-JS? Head to the [Installation](/docs/installation) guide to get started in minutes.\r\n","title":"What is Devup UI?eeeeeeeeeeee","url":"/documentation/concept/concept-1"},null,null,null,null,null,{"text":"## What is Devup UI?\r\n\r\n**Devup UI is not just another CSS-in-JS library — it's the future of CSS-in-JS itself.**\r\n\r\nDevup UI is a zero-runtime CSS-in-JS preprocessor powered by Rust and WebAssembly. It transforms all your styles at build time, completely eliminating runtime overhead while providing full CSS-in-JS syntax coverage.\r\n\r\n### The Problem with Traditional CSS-in-JS\r\n\r\nTraditional CSS-in-JS solutions force you to choose between:\r\n\r\n- **Developer Experience**: Intuitive APIs, co-located styles, dynamic theming\r\n- **Performance**: No runtime overhead, fast page loads, optimal Core Web Vitals\r\n\r\nLibraries like styled-components and Emotion offer great DX but execute JavaScript at runtime to generate styles. Zero-runtime alternatives like Vanilla Extract sacrifice some flexibility for performance.\r\n\r\n### The Devup UI Solution\r\n\r\nDevup UI eliminates this trade-off entirely. Our Rust-powered preprocessor analyzes your code at build time and handles every CSS-in-JS pattern:\r\n\r\n- **Variables** — Dynamic values become CSS custom properties\r\n- **Conditionals** — Ternary expressions are statically analyzed\r\n- **Responsive Arrays** — Breakpoint-based styles are pre-generated\r\n- **Pseudo Selectors** — `_hover`, `_focus`, `_active` work seamlessly\r\n- **Themes** — Type-safe theme tokens with zero-cost switching\r\n\r\n### Key Advantages\r\n\r\n\r\n \r\n \r\n Feature\r\n Devup UI\r\n styled-components\r\n Emotion\r\n Vanilla Extract\r\n \r\n \r\n \r\n \r\n Zero Runtime\r\n Yes\r\n No\r\n No\r\n Yes\r\n \r\n \r\n Dynamic Values\r\n Yes\r\n Yes\r\n Yes\r\n Limited\r\n \r\n \r\n Full Syntax Coverage\r\n Yes\r\n Yes\r\n Yes\r\n No\r\n \r\n \r\n Type-Safe Themes\r\n Yes\r\n Limited\r\n Limited\r\n Yes\r\n \r\n \r\n Build Performance\r\n Fastest\r\n N/A\r\n N/A\r\n Fast\r\n \r\n \r\n
\r\n\r\n### How It Works\r\n\r\n```tsx\r\n// You write familiar CSS-in-JS syntax\r\nconst example = \r\n\r\n// Devup UI transforms it at build time\r\nconst generated =
\r\n\r\n// With optimized atomic CSS\r\n// .a { background-color: red; }\r\n// .b { padding: 16px; } /* 4 * 4 = 16px */\r\n// .c:hover { background-color: blue; }\r\n```\r\n\r\n> Numeric values are multiplied by 4. `p={4}` becomes `padding: 16px`.\r\n\r\nClass names use compact base-37 encoding (`a`, `b`, ... `z`, `_`, `aa`, `ab`, ...) for minimal CSS output.\r\n\r\n### Familiar API\r\n\r\nIf you've used styled-components or Emotion, you'll feel right at home:\r\n\r\n```tsx\r\nimport { styled } from '@devup-ui/react'\r\n\r\nconst Card = styled('div', {\r\n bg: 'white',\r\n p: 4, // 4 * 4 = 16px\r\n borderRadius: '8px',\r\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\r\n _hover: {\r\n boxShadow: '0 10px 15px rgba(0, 0, 0, 0.1)',\r\n },\r\n})\r\n```\r\n\r\n### Proven Performance\r\n\r\nBenchmarks on Next.js (GitHub Actions - ubuntu-latest):\r\n\r\n\r\n \r\n \r\n Library\r\n Version\r\n Build Time\r\n Build Size\r\n \r\n \r\n \r\n \r\n tailwindcss\r\n 4.1.13\r\n 19.31s\r\n 59,521,539 bytes\r\n \r\n \r\n styleX\r\n 0.15.4\r\n 41.78s\r\n 86,869,452 bytes\r\n \r\n \r\n vanilla-extract\r\n 1.17.4\r\n 19.50s\r\n 61,494,033 bytes\r\n \r\n \r\n kuma-ui\r\n 1.5.9\r\n 20.93s\r\n 69,924,179 bytes\r\n \r\n \r\n panda-css\r\n 1.3.1\r\n 20.64s\r\n 64,573,260 bytes\r\n \r\n \r\n chakra-ui\r\n 3.27.0\r\n 28.81s\r\n 222,435,802 bytes\r\n \r\n \r\n mui\r\n 7.3.2\r\n 20.86s\r\n 97,964,458 bytes\r\n \r\n \r\n **devup-ui (per-file css)**\r\n **1.0.18**\r\n **16.90s**\r\n 59,540,459 bytes\r\n \r\n \r\n **devup-ui (single css)**\r\n **1.0.18**\r\n **17.05s**\r\n **59,520,196 bytes**\r\n \r\n \r\n tailwindcss (turbopack)\r\n 4.1.13\r\n 6.72s\r\n 5,355,082 bytes\r\n \r\n \r\n **devup-ui (single css + turbopack)**\r\n **1.0.18**\r\n 10.34s\r\n **4,772,050 bytes**\r\n \r\n \r\n
\r\n\r\n### Get Started\r\n\r\nReady to experience the future of CSS-in-JS? Head to the [Installation](/docs/installation) guide to get started in minutes.\r\n","title":"What is Devup UI?","url":"/documentation/overview"},null,null,null,null] \ No newline at end of file From 610d32b0d2a9687ed98d705c0575ed1b111da908 Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Wed, 5 Aug 2026 11:06:33 +0900 Subject: [PATCH 05/14] =?UTF-8?q?refactor(landing):=20CodeTabs=EB=A5=BC=20?= =?UTF-8?q?CSS-only=20=EB=9D=BC=EB=94=94=EC=98=A4=20=ED=83=AD=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=84=ED=99=98=ED=95=B4=20use=20client=EC=99=80?= =?UTF-8?q?=20fallback=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../landing/src/app/_components/code-tabs.tsx | 228 +++++++++++++++--- .../src/app/_components/code-window.tsx | 4 +- apps/landing/src/app/page.tsx | 6 +- 3 files changed, 197 insertions(+), 41 deletions(-) diff --git a/apps/landing/src/app/_components/code-tabs.tsx b/apps/landing/src/app/_components/code-tabs.tsx index 22a15a0c..fbd71732 100644 --- a/apps/landing/src/app/_components/code-tabs.tsx +++ b/apps/landing/src/app/_components/code-tabs.tsx @@ -1,7 +1,4 @@ -'use client' - import { Box, Text } from '@devup-ui/react' -import { useState } from 'react' import { CodeWindow, HighlightedCode } from './code-window' @@ -12,40 +9,199 @@ export interface CodeExample { html: string } -export function CodeTabs({ examples }: { examples: CodeExample[] }) { - const [active, setActive] = useState(examples[0]?.key ?? '') - const current = examples.find((e) => e.key === active) ?? examples[0] - - if (!current) return null +export type CodeExampleQuad = [CodeExample, CodeExample, CodeExample, CodeExample] +// devup-ui extracts `selectors` strings at build time, so each of the 4 +// fixed tabs is written out literally (nth-of-type) rather than generated +// by a .map() over a runtime key — a template-literal selector key can't be +// statically extracted into CSS. +export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad }) { return ( - ( - setActive(ex.key)} - px="12px" - py="5px" - transition="color .15s, background .15s" - > - - {ex.label} - + + + + + + + + {a.label} + + + {b.label} + + + {c.label} + + + {d.label} + + + } + title={ + <> + + {a.file} + + + {b.file} + + + {c.file} + + + {d.file} + + + } + > + + + + + + + + - ))} - title={current.file} - > - - + + + + + ) -} - +} \ No newline at end of file diff --git a/apps/landing/src/app/_components/code-window.tsx b/apps/landing/src/app/_components/code-window.tsx index ec1c77a3..27017aa3 100644 --- a/apps/landing/src/app/_components/code-window.tsx +++ b/apps/landing/src/app/_components/code-window.tsx @@ -25,10 +25,10 @@ export function CodeWindow({ children, ...props }: { - title: string + title: ReactNode tabs?: ReactNode children: ReactNode -} & ComponentProps>) { +} & Omit>, 'title'>) { return ( Date: Wed, 5 Aug 2026 11:23:38 +0900 Subject: [PATCH 06/14] =?UTF-8?q?refactor(landing):=20CopyInstall=EC=97=90?= =?UTF-8?q?=20=EC=9D=B8=EB=9D=BC=EC=9D=B8=20D2Coding=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EB=8C=80=EC=8B=A0=20=EB=93=B1=EB=A1=9D=EB=90=9C=20?= =?UTF-8?q?typography=20=ED=94=84=EB=A6=AC=EC=85=8B=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/landing/devup.json | 9 ++++++++- apps/landing/src/app/_components/copy-install.tsx | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/landing/devup.json b/apps/landing/devup.json index b100ac5f..e6feb7cd 100644 --- a/apps/landing/devup.json +++ b/apps/landing/devup.json @@ -492,7 +492,14 @@ }, null, null - ] + ], + "code": { + "fontFamily": "D2Coding", + "fontWeight": 400, + "fontSize": "13px", + "lineHeight": 1.5, + "letterSpacing": "0em" + } } } } \ No newline at end of file diff --git a/apps/landing/src/app/_components/copy-install.tsx b/apps/landing/src/app/_components/copy-install.tsx index f867ce08..d63eaf98 100644 --- a/apps/landing/src/app/_components/copy-install.tsx +++ b/apps/landing/src/app/_components/copy-install.tsx @@ -31,10 +31,10 @@ export function CopyInstall({ transition="border-color .15s" w="fit-content" > - + $ - + {command} Date: Wed, 5 Aug 2026 11:35:03 +0900 Subject: [PATCH 07/14] =?UTF-8?q?refactor(landing):=20SectionHead=20?= =?UTF-8?q?=EC=A0=9C=EB=AA=A9-=EA=B0=95=EC=A1=B0=20=EA=B0=84=EA=B2=A9?= =?UTF-8?q?=EC=9D=84=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EA=B3=B5=EB=B0=B1=20?= =?UTF-8?q?=EB=8C=80=EC=8B=A0=20gap=EC=9C=BC=EB=A1=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/landing/src/app/page.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/landing/src/app/page.tsx b/apps/landing/src/app/page.tsx index 98b1324a..3791fd35 100644 --- a/apps/landing/src/app/page.tsx +++ b/apps/landing/src/app/page.tsx @@ -269,15 +269,18 @@ function SectionHead({ > — {eyebrow} - + {title} {emphasis && ( - <> - {' '} - - {emphasis} - - + + {emphasis} + )} {lede && ( From c88f8d06c43e888ea5314fbb3f5e367657c52500 Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Wed, 5 Aug 2026 11:55:56 +0900 Subject: [PATCH 08/14] =?UTF-8?q?refactor(landing):=20eyebrow=20typography?= =?UTF-8?q?=20=EB=93=B1=EB=A1=9D,=20pill=20radius=EB=A5=BC=20%=EB=A1=9C,?= =?UTF-8?q?=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20gap=3D"0"=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/landing/devup.json | 7 +++++++ apps/landing/src/app/page.tsx | 16 ++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/apps/landing/devup.json b/apps/landing/devup.json index e6feb7cd..b6db3ff7 100644 --- a/apps/landing/devup.json +++ b/apps/landing/devup.json @@ -499,6 +499,13 @@ "fontSize": "13px", "lineHeight": 1.5, "letterSpacing": "0em" + }, + "eyebrow": { + "fontFamily": "D2Coding", + "fontWeight": 400, + "fontSize": "11px", + "lineHeight": 1.4, + "letterSpacing": "0.14em" } } } diff --git a/apps/landing/src/app/page.tsx b/apps/landing/src/app/page.tsx index 3791fd35..dfc7d5b6 100644 --- a/apps/landing/src/app/page.tsx +++ b/apps/landing/src/app/page.tsx @@ -262,10 +262,8 @@ function SectionHead({ — {eyebrow} @@ -313,12 +311,12 @@ function HeroSection({ codeHtml }: { codeHtml: string }) { flexDir={['column', null, null, 'row']} gap={['40px', null, null, '60px']} > - + - + - + Date: Wed, 5 Aug 2026 13:33:45 +0900 Subject: [PATCH 09/14] =?UTF-8?q?refactor(landing):=ED=9E=88=EC=96=B4?= =?UTF-8?q?=EB=A1=9C=20=EC=84=B9=EC=85=98=20=EB=A7=88=ED=81=AC=EC=97=85=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=20(span=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0,=20mb=EB=A5=BC=20Box=EB=A1=9C,=20stretch=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC),HeroSection=20=EC=BB=A8=ED=85=8C=EC=9D=B4=EB=84=88?= =?UTF-8?q?=EB=A5=BC=20Flex=20=EB=8C=80=EC=8B=A0=20VStack=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/landing/src/app/page.tsx | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/apps/landing/src/app/page.tsx b/apps/landing/src/app/page.tsx index dfc7d5b6..b3e94950 100644 --- a/apps/landing/src/app/page.tsx +++ b/apps/landing/src/app/page.tsx @@ -276,7 +276,7 @@ function SectionHead({ > {title} {emphasis && ( - + {emphasis} )} @@ -306,12 +306,12 @@ function HeroSection({ codeHtml }: { codeHtml: string }) { pos="absolute" /> - - + Define schemas.
- + Forget migrations. - - Vespertide is a declarative database schema manager for Rust. Write - your tables in JSON, and let it diff, plan, and emit type-safe - migrations to Postgres, MySQL, and SQLite — automatically. - + + + Vespertide is a declarative database schema manager for Rust. Write + your tables in JSON, and let it diff, plan, and emit type-safe + migrations to Postgres, MySQL, and SQLite — automatically. + + @@ -386,7 +389,6 @@ function HeroSection({ codeHtml }: { codeHtml: string }) { gap={['20px', null, null, '40px']} mt="32px" pt="24px" - w="100%" > {[ { num: `v${VERSION}`, lbl: 'Version' }, @@ -417,7 +419,7 @@ function HeroSection({ codeHtml }: { codeHtml: string }) {
-
+
) From 7a20bf2f73d5486afd77af95c1c5cf3322d6c124 Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Sun, 9 Aug 2026 01:14:41 +0900 Subject: [PATCH 10/14] =?UTF-8?q?refactor(landing):=20PR=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98=EC=98=81=20?= =?UTF-8?q?(=ED=94=BC=EC=B2=98=20=EC=B9=B4=EB=93=9C=20=EB=AA=A8=EB=B0=94?= =?UTF-8?q?=EC=9D=BC=20=ED=8C=A8=EB=94=A9,=20Examples=20Flex->VStack,=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EA=B3=B5=EB=B0=B1=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0,=20eyebrow=20typography=20=EC=A0=81=EC=9A=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/landing/src/app/page.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/apps/landing/src/app/page.tsx b/apps/landing/src/app/page.tsx index b3e94950..2ec1823c 100644 --- a/apps/landing/src/app/page.tsx +++ b/apps/landing/src/app/page.tsx @@ -458,8 +458,8 @@ function FeaturesSection() { alignItems="flex-start" bg="$vespertideBg" key={f.title} - px="28px" - py="32px" + px={['20px', null, null, '28px']} + py={['24px', null, null, '32px']} transition="background .15s" > - @@ -616,10 +616,16 @@ function ExamplesSection({ examples }: { examples: CodeExampleQuad }) { > → - + {it.k} - {' '} + {it.v} @@ -629,7 +635,7 @@ function ExamplesSection({ examples }: { examples: CodeExampleQuad }) { - + ) @@ -712,11 +718,9 @@ function CompatibilitySection() { — ORM export From cb170b5d6acffa358b2fe41bec1fd24c68e06864 Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Thu, 20 Aug 2026 17:38:15 +0900 Subject: [PATCH 11/14] fix(landing): move code-tab visibility rules onto target elements --- apps/landing/public/search.json | 2 +- .../landing/src/app/_components/code-tabs.tsx | 155 +++++++++++------- 2 files changed, 96 insertions(+), 61 deletions(-) diff --git a/apps/landing/public/search.json b/apps/landing/public/search.json index 4e5e7d7f..6ef48036 100644 --- a/apps/landing/public/search.json +++ b/apps/landing/public/search.json @@ -1 +1 @@ -[null,null,null,null,{"text":"## What is Devup UI?eeeeeeeeeeee\r\n\r\n**Devup UI is not just another CSS-in-JS library — it's the future of CSS-in-JS itself.**\r\n\r\nDevup UI is a zero-runtime CSS-in-JS preprocessor powered by Rust and WebAssembly. It transforms all your styles at build time, completely eliminating runtime overhead while providing full CSS-in-JS syntax coverage.\r\n\r\n### The Problem with Traditional CSS-in-JS\r\n\r\nTraditional CSS-in-JS solutions force you to choose between:\r\n\r\n- **Developer Experience**: Intuitive APIs, co-located styles, dynamic theming\r\n- **Performance**: No runtime overhead, fast page loads, optimal Core Web Vitals\r\n\r\nLibraries like styled-components and Emotion offer great DX but execute JavaScript at runtime to generate styles. Zero-runtime alternatives like Vanilla Extract sacrifice some flexibility for performance.\r\n\r\n### The Devup UI Solution\r\n\r\nDevup UI eliminates this trade-off entirely. Our Rust-powered preprocessor analyzes your code at build time and handles every CSS-in-JS pattern:\r\n\r\n- **Variables** — Dynamic values become CSS custom properties\r\n- **Conditionals** — Ternary expressions are statically analyzed\r\n- **Responsive Arrays** — Breakpoint-based styles are pre-generated\r\n- **Pseudo Selectors** — `_hover`, `_focus`, `_active` work seamlessly\r\n- **Themes** — Type-safe theme tokens with zero-cost switching\r\n\r\n### Key Advantages\r\n\r\n\r\n \r\n \r\n Feature\r\n Devup UI\r\n styled-components\r\n Emotion\r\n Vanilla Extract\r\n \r\n \r\n \r\n \r\n Zero Runtime\r\n Yes\r\n No\r\n No\r\n Yes\r\n \r\n \r\n Dynamic Values\r\n Yes\r\n Yes\r\n Yes\r\n Limited\r\n \r\n \r\n Full Syntax Coverage\r\n Yes\r\n Yes\r\n Yes\r\n No\r\n \r\n \r\n Type-Safe Themes\r\n Yes\r\n Limited\r\n Limited\r\n Yes\r\n \r\n \r\n Build Performance\r\n Fastest\r\n N/A\r\n N/A\r\n Fast\r\n \r\n \r\n
\r\n\r\n### How It Works\r\n\r\n```tsx\r\n// You write familiar CSS-in-JS syntax\r\nconst example = \r\n\r\n// Devup UI transforms it at build time\r\nconst generated =
\r\n\r\n// With optimized atomic CSS\r\n// .a { background-color: red; }\r\n// .b { padding: 16px; } /* 4 * 4 = 16px */\r\n// .c:hover { background-color: blue; }\r\n```\r\n\r\n> Numeric values are multiplied by 4. `p={4}` becomes `padding: 16px`.\r\n\r\nClass names use compact base-37 encoding (`a`, `b`, ... `z`, `_`, `aa`, `ab`, ...) for minimal CSS output.\r\n\r\n### Familiar API\r\n\r\nIf you've used styled-components or Emotion, you'll feel right at home:\r\n\r\n```tsx\r\nimport { styled } from '@devup-ui/react'\r\n\r\nconst Card = styled('div', {\r\n bg: 'white',\r\n p: 4, // 4 * 4 = 16px\r\n borderRadius: '8px',\r\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\r\n _hover: {\r\n boxShadow: '0 10px 15px rgba(0, 0, 0, 0.1)',\r\n },\r\n})\r\n```\r\n\r\n### Proven Performance\r\n\r\nBenchmarks on Next.js (GitHub Actions - ubuntu-latest):\r\n\r\n\r\n \r\n \r\n Library\r\n Version\r\n Build Time\r\n Build Size\r\n \r\n \r\n \r\n \r\n tailwindcss\r\n 4.1.13\r\n 19.31s\r\n 59,521,539 bytes\r\n \r\n \r\n styleX\r\n 0.15.4\r\n 41.78s\r\n 86,869,452 bytes\r\n \r\n \r\n vanilla-extract\r\n 1.17.4\r\n 19.50s\r\n 61,494,033 bytes\r\n \r\n \r\n kuma-ui\r\n 1.5.9\r\n 20.93s\r\n 69,924,179 bytes\r\n \r\n \r\n panda-css\r\n 1.3.1\r\n 20.64s\r\n 64,573,260 bytes\r\n \r\n \r\n chakra-ui\r\n 3.27.0\r\n 28.81s\r\n 222,435,802 bytes\r\n \r\n \r\n mui\r\n 7.3.2\r\n 20.86s\r\n 97,964,458 bytes\r\n \r\n \r\n **devup-ui (per-file css)**\r\n **1.0.18**\r\n **16.90s**\r\n 59,540,459 bytes\r\n \r\n \r\n **devup-ui (single css)**\r\n **1.0.18**\r\n **17.05s**\r\n **59,520,196 bytes**\r\n \r\n \r\n tailwindcss (turbopack)\r\n 4.1.13\r\n 6.72s\r\n 5,355,082 bytes\r\n \r\n \r\n **devup-ui (single css + turbopack)**\r\n **1.0.18**\r\n 10.34s\r\n **4,772,050 bytes**\r\n \r\n \r\n
\r\n\r\n### Get Started\r\n\r\nReady to experience the future of CSS-in-JS? Head to the [Installation](/docs/installation) guide to get started in minutes.\r\n","title":"What is Devup UI?eeeeeeeeeeee","url":"/documentation/concept/concept-1"},null,null,null,null,null,{"text":"## What is Devup UI?\r\n\r\n**Devup UI is not just another CSS-in-JS library — it's the future of CSS-in-JS itself.**\r\n\r\nDevup UI is a zero-runtime CSS-in-JS preprocessor powered by Rust and WebAssembly. It transforms all your styles at build time, completely eliminating runtime overhead while providing full CSS-in-JS syntax coverage.\r\n\r\n### The Problem with Traditional CSS-in-JS\r\n\r\nTraditional CSS-in-JS solutions force you to choose between:\r\n\r\n- **Developer Experience**: Intuitive APIs, co-located styles, dynamic theming\r\n- **Performance**: No runtime overhead, fast page loads, optimal Core Web Vitals\r\n\r\nLibraries like styled-components and Emotion offer great DX but execute JavaScript at runtime to generate styles. Zero-runtime alternatives like Vanilla Extract sacrifice some flexibility for performance.\r\n\r\n### The Devup UI Solution\r\n\r\nDevup UI eliminates this trade-off entirely. Our Rust-powered preprocessor analyzes your code at build time and handles every CSS-in-JS pattern:\r\n\r\n- **Variables** — Dynamic values become CSS custom properties\r\n- **Conditionals** — Ternary expressions are statically analyzed\r\n- **Responsive Arrays** — Breakpoint-based styles are pre-generated\r\n- **Pseudo Selectors** — `_hover`, `_focus`, `_active` work seamlessly\r\n- **Themes** — Type-safe theme tokens with zero-cost switching\r\n\r\n### Key Advantages\r\n\r\n\r\n \r\n \r\n Feature\r\n Devup UI\r\n styled-components\r\n Emotion\r\n Vanilla Extract\r\n \r\n \r\n \r\n \r\n Zero Runtime\r\n Yes\r\n No\r\n No\r\n Yes\r\n \r\n \r\n Dynamic Values\r\n Yes\r\n Yes\r\n Yes\r\n Limited\r\n \r\n \r\n Full Syntax Coverage\r\n Yes\r\n Yes\r\n Yes\r\n No\r\n \r\n \r\n Type-Safe Themes\r\n Yes\r\n Limited\r\n Limited\r\n Yes\r\n \r\n \r\n Build Performance\r\n Fastest\r\n N/A\r\n N/A\r\n Fast\r\n \r\n \r\n
\r\n\r\n### How It Works\r\n\r\n```tsx\r\n// You write familiar CSS-in-JS syntax\r\nconst example = \r\n\r\n// Devup UI transforms it at build time\r\nconst generated =
\r\n\r\n// With optimized atomic CSS\r\n// .a { background-color: red; }\r\n// .b { padding: 16px; } /* 4 * 4 = 16px */\r\n// .c:hover { background-color: blue; }\r\n```\r\n\r\n> Numeric values are multiplied by 4. `p={4}` becomes `padding: 16px`.\r\n\r\nClass names use compact base-37 encoding (`a`, `b`, ... `z`, `_`, `aa`, `ab`, ...) for minimal CSS output.\r\n\r\n### Familiar API\r\n\r\nIf you've used styled-components or Emotion, you'll feel right at home:\r\n\r\n```tsx\r\nimport { styled } from '@devup-ui/react'\r\n\r\nconst Card = styled('div', {\r\n bg: 'white',\r\n p: 4, // 4 * 4 = 16px\r\n borderRadius: '8px',\r\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\r\n _hover: {\r\n boxShadow: '0 10px 15px rgba(0, 0, 0, 0.1)',\r\n },\r\n})\r\n```\r\n\r\n### Proven Performance\r\n\r\nBenchmarks on Next.js (GitHub Actions - ubuntu-latest):\r\n\r\n\r\n \r\n \r\n Library\r\n Version\r\n Build Time\r\n Build Size\r\n \r\n \r\n \r\n \r\n tailwindcss\r\n 4.1.13\r\n 19.31s\r\n 59,521,539 bytes\r\n \r\n \r\n styleX\r\n 0.15.4\r\n 41.78s\r\n 86,869,452 bytes\r\n \r\n \r\n vanilla-extract\r\n 1.17.4\r\n 19.50s\r\n 61,494,033 bytes\r\n \r\n \r\n kuma-ui\r\n 1.5.9\r\n 20.93s\r\n 69,924,179 bytes\r\n \r\n \r\n panda-css\r\n 1.3.1\r\n 20.64s\r\n 64,573,260 bytes\r\n \r\n \r\n chakra-ui\r\n 3.27.0\r\n 28.81s\r\n 222,435,802 bytes\r\n \r\n \r\n mui\r\n 7.3.2\r\n 20.86s\r\n 97,964,458 bytes\r\n \r\n \r\n **devup-ui (per-file css)**\r\n **1.0.18**\r\n **16.90s**\r\n 59,540,459 bytes\r\n \r\n \r\n **devup-ui (single css)**\r\n **1.0.18**\r\n **17.05s**\r\n **59,520,196 bytes**\r\n \r\n \r\n tailwindcss (turbopack)\r\n 4.1.13\r\n 6.72s\r\n 5,355,082 bytes\r\n \r\n \r\n **devup-ui (single css + turbopack)**\r\n **1.0.18**\r\n 10.34s\r\n **4,772,050 bytes**\r\n \r\n \r\n
\r\n\r\n### Get Started\r\n\r\nReady to experience the future of CSS-in-JS? Head to the [Installation](/docs/installation) guide to get started in minutes.\r\n","title":"What is Devup UI?","url":"/documentation/overview"},null,null,null,null] \ No newline at end of file +[null,null,null,null,{"text":"## What is Devup UI?eeeeeeeeeeee\n\n**Devup UI is not just another CSS-in-JS library — it's the future of CSS-in-JS itself.**\n\nDevup UI is a zero-runtime CSS-in-JS preprocessor powered by Rust and WebAssembly. It transforms all your styles at build time, completely eliminating runtime overhead while providing full CSS-in-JS syntax coverage.\n\n### The Problem with Traditional CSS-in-JS\n\nTraditional CSS-in-JS solutions force you to choose between:\n\n- **Developer Experience**: Intuitive APIs, co-located styles, dynamic theming\n- **Performance**: No runtime overhead, fast page loads, optimal Core Web Vitals\n\nLibraries like styled-components and Emotion offer great DX but execute JavaScript at runtime to generate styles. Zero-runtime alternatives like Vanilla Extract sacrifice some flexibility for performance.\n\n### The Devup UI Solution\n\nDevup UI eliminates this trade-off entirely. Our Rust-powered preprocessor analyzes your code at build time and handles every CSS-in-JS pattern:\n\n- **Variables** — Dynamic values become CSS custom properties\n- **Conditionals** — Ternary expressions are statically analyzed\n- **Responsive Arrays** — Breakpoint-based styles are pre-generated\n- **Pseudo Selectors** — `_hover`, `_focus`, `_active` work seamlessly\n- **Themes** — Type-safe theme tokens with zero-cost switching\n\n### Key Advantages\n\n\n \n \n Feature\n Devup UI\n styled-components\n Emotion\n Vanilla Extract\n \n \n \n \n Zero Runtime\n Yes\n No\n No\n Yes\n \n \n Dynamic Values\n Yes\n Yes\n Yes\n Limited\n \n \n Full Syntax Coverage\n Yes\n Yes\n Yes\n No\n \n \n Type-Safe Themes\n Yes\n Limited\n Limited\n Yes\n \n \n Build Performance\n Fastest\n N/A\n N/A\n Fast\n \n \n
\n\n### How It Works\n\n```tsx\n// You write familiar CSS-in-JS syntax\nconst example = \n\n// Devup UI transforms it at build time\nconst generated =
\n\n// With optimized atomic CSS\n// .a { background-color: red; }\n// .b { padding: 16px; } /* 4 * 4 = 16px */\n// .c:hover { background-color: blue; }\n```\n\n> Numeric values are multiplied by 4. `p={4}` becomes `padding: 16px`.\n\nClass names use compact base-37 encoding (`a`, `b`, ... `z`, `_`, `aa`, `ab`, ...) for minimal CSS output.\n\n### Familiar API\n\nIf you've used styled-components or Emotion, you'll feel right at home:\n\n```tsx\nimport { styled } from '@devup-ui/react'\n\nconst Card = styled('div', {\n bg: 'white',\n p: 4, // 4 * 4 = 16px\n borderRadius: '8px',\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\n _hover: {\n boxShadow: '0 10px 15px rgba(0, 0, 0, 0.1)',\n },\n})\n```\n\n### Proven Performance\n\nBenchmarks on Next.js (GitHub Actions - ubuntu-latest):\n\n\n \n \n Library\n Version\n Build Time\n Build Size\n \n \n \n \n tailwindcss\n 4.1.13\n 19.31s\n 59,521,539 bytes\n \n \n styleX\n 0.15.4\n 41.78s\n 86,869,452 bytes\n \n \n vanilla-extract\n 1.17.4\n 19.50s\n 61,494,033 bytes\n \n \n kuma-ui\n 1.5.9\n 20.93s\n 69,924,179 bytes\n \n \n panda-css\n 1.3.1\n 20.64s\n 64,573,260 bytes\n \n \n chakra-ui\n 3.27.0\n 28.81s\n 222,435,802 bytes\n \n \n mui\n 7.3.2\n 20.86s\n 97,964,458 bytes\n \n \n **devup-ui (per-file css)**\n **1.0.18**\n **16.90s**\n 59,540,459 bytes\n \n \n **devup-ui (single css)**\n **1.0.18**\n **17.05s**\n **59,520,196 bytes**\n \n \n tailwindcss (turbopack)\n 4.1.13\n 6.72s\n 5,355,082 bytes\n \n \n **devup-ui (single css + turbopack)**\n **1.0.18**\n 10.34s\n **4,772,050 bytes**\n \n \n
\n\n### Get Started\n\nReady to experience the future of CSS-in-JS? Head to the [Installation](/docs/installation) guide to get started in minutes.\n","title":"What is Devup UI?eeeeeeeeeeee","url":"/documentation/concept/concept-1"},null,null,null,null,null,{"text":"## What is Devup UI?\n\n**Devup UI is not just another CSS-in-JS library — it's the future of CSS-in-JS itself.**\n\nDevup UI is a zero-runtime CSS-in-JS preprocessor powered by Rust and WebAssembly. It transforms all your styles at build time, completely eliminating runtime overhead while providing full CSS-in-JS syntax coverage.\n\n### The Problem with Traditional CSS-in-JS\n\nTraditional CSS-in-JS solutions force you to choose between:\n\n- **Developer Experience**: Intuitive APIs, co-located styles, dynamic theming\n- **Performance**: No runtime overhead, fast page loads, optimal Core Web Vitals\n\nLibraries like styled-components and Emotion offer great DX but execute JavaScript at runtime to generate styles. Zero-runtime alternatives like Vanilla Extract sacrifice some flexibility for performance.\n\n### The Devup UI Solution\n\nDevup UI eliminates this trade-off entirely. Our Rust-powered preprocessor analyzes your code at build time and handles every CSS-in-JS pattern:\n\n- **Variables** — Dynamic values become CSS custom properties\n- **Conditionals** — Ternary expressions are statically analyzed\n- **Responsive Arrays** — Breakpoint-based styles are pre-generated\n- **Pseudo Selectors** — `_hover`, `_focus`, `_active` work seamlessly\n- **Themes** — Type-safe theme tokens with zero-cost switching\n\n### Key Advantages\n\n\n \n \n Feature\n Devup UI\n styled-components\n Emotion\n Vanilla Extract\n \n \n \n \n Zero Runtime\n Yes\n No\n No\n Yes\n \n \n Dynamic Values\n Yes\n Yes\n Yes\n Limited\n \n \n Full Syntax Coverage\n Yes\n Yes\n Yes\n No\n \n \n Type-Safe Themes\n Yes\n Limited\n Limited\n Yes\n \n \n Build Performance\n Fastest\n N/A\n N/A\n Fast\n \n \n
\n\n### How It Works\n\n```tsx\n// You write familiar CSS-in-JS syntax\nconst example = \n\n// Devup UI transforms it at build time\nconst generated =
\n\n// With optimized atomic CSS\n// .a { background-color: red; }\n// .b { padding: 16px; } /* 4 * 4 = 16px */\n// .c:hover { background-color: blue; }\n```\n\n> Numeric values are multiplied by 4. `p={4}` becomes `padding: 16px`.\n\nClass names use compact base-37 encoding (`a`, `b`, ... `z`, `_`, `aa`, `ab`, ...) for minimal CSS output.\n\n### Familiar API\n\nIf you've used styled-components or Emotion, you'll feel right at home:\n\n```tsx\nimport { styled } from '@devup-ui/react'\n\nconst Card = styled('div', {\n bg: 'white',\n p: 4, // 4 * 4 = 16px\n borderRadius: '8px',\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\n _hover: {\n boxShadow: '0 10px 15px rgba(0, 0, 0, 0.1)',\n },\n})\n```\n\n### Proven Performance\n\nBenchmarks on Next.js (GitHub Actions - ubuntu-latest):\n\n\n \n \n Library\n Version\n Build Time\n Build Size\n \n \n \n \n tailwindcss\n 4.1.13\n 19.31s\n 59,521,539 bytes\n \n \n styleX\n 0.15.4\n 41.78s\n 86,869,452 bytes\n \n \n vanilla-extract\n 1.17.4\n 19.50s\n 61,494,033 bytes\n \n \n kuma-ui\n 1.5.9\n 20.93s\n 69,924,179 bytes\n \n \n panda-css\n 1.3.1\n 20.64s\n 64,573,260 bytes\n \n \n chakra-ui\n 3.27.0\n 28.81s\n 222,435,802 bytes\n \n \n mui\n 7.3.2\n 20.86s\n 97,964,458 bytes\n \n \n **devup-ui (per-file css)**\n **1.0.18**\n **16.90s**\n 59,540,459 bytes\n \n \n **devup-ui (single css)**\n **1.0.18**\n **17.05s**\n **59,520,196 bytes**\n \n \n tailwindcss (turbopack)\n 4.1.13\n 6.72s\n 5,355,082 bytes\n \n \n **devup-ui (single css + turbopack)**\n **1.0.18**\n 10.34s\n **4,772,050 bytes**\n \n \n
\n\n### Get Started\n\nReady to experience the future of CSS-in-JS? Head to the [Installation](/docs/installation) guide to get started in minutes.\n","title":"What is Devup UI?","url":"/documentation/overview"},null,null,null,null] \ No newline at end of file diff --git a/apps/landing/src/app/_components/code-tabs.tsx b/apps/landing/src/app/_components/code-tabs.tsx index fbd71732..0a86d26b 100644 --- a/apps/landing/src/app/_components/code-tabs.tsx +++ b/apps/landing/src/app/_components/code-tabs.tsx @@ -12,9 +12,16 @@ export interface CodeExample { export type CodeExampleQuad = [CodeExample, CodeExample, CodeExample, CodeExample] // devup-ui extracts `selectors` strings at build time, so each of the 4 -// fixed tabs is written out literally (nth-of-type) rather than generated -// by a .map() over a runtime key — a template-literal selector key can't be -// statically extracted into CSS. +// fixed tabs is written out literally rather than generated by a .map() +// over a runtime key — a template-literal selector key can't be statically +// extracted into CSS. +// +// Each target element (label / title / panel) declares its own "when am I +// shown" condition anchored on the checkbox's id (`#code-tab-N:checked ~ * +// &`), rather than the checkbox declaring rules for elements elsewhere in +// the tree. The checkbox's own `:checked` state isn't observable from the +// checkbox's position in isolation, so ownership of the visibility rule +// belongs on the element it affects. export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad }) { return ( @@ -27,18 +34,6 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad opacity="0" overflow="hidden" position="absolute" - selectors={{ - '&:checked ~ * #code-panel-0': { display: 'block' }, - '&:checked ~ * #code-title-0': { display: 'block' }, - '&:checked ~ * label:nth-of-type(1)': { - bg: '$containerBackground', - border: '1px solid $border', - color: '$title', - }, - '&:focus-visible ~ * label:nth-of-type(1)': { - boxShadow: '0 0 0 2px $vespertidePrimary', - }, - }} type="radio" /> {a.label} @@ -136,6 +105,16 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad htmlFor="code-tab-1" px="12px" py="5px" + selectors={{ + '#code-tab-1:checked ~ * &': { + bg: '$containerBackground', + border: '1px solid $border', + color: '$title', + }, + '#code-tab-1:focus-visible ~ * &': { + boxShadow: '0 0 0 2px $vespertidePrimary', + }, + }} transition="color .15s, background .15s" > {b.label} @@ -151,6 +130,16 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad htmlFor="code-tab-2" px="12px" py="5px" + selectors={{ + '#code-tab-2:checked ~ * &': { + bg: '$containerBackground', + border: '1px solid $border', + color: '$title', + }, + '#code-tab-2:focus-visible ~ * &': { + boxShadow: '0 0 0 2px $vespertidePrimary', + }, + }} transition="color .15s, background .15s" > {c.label} @@ -166,6 +155,16 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad htmlFor="code-tab-3" px="12px" py="5px" + selectors={{ + '#code-tab-3:checked ~ * &': { + bg: '$containerBackground', + border: '1px solid $border', + color: '$title', + }, + '#code-tab-3:focus-visible ~ * &': { + boxShadow: '0 0 0 2px $vespertidePrimary', + }, + }} transition="color .15s, background .15s" > {d.label} @@ -174,34 +173,70 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad } title={ <> - + {a.file} - + {b.file} - + {c.file} - + {d.file} } > - + - + - + - + ) -} \ No newline at end of file +} From a145fb2dc4b233fdaec6c5183b40da7ebb98cd34 Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Thu, 20 Aug 2026 17:54:19 +0900 Subject: [PATCH 12/14] fix(landing): address PR review feedback on code-tabs/copy-install --- .../landing/src/app/_components/code-tabs.tsx | 20 ++++++++----------- .../src/app/_components/code-window.tsx | 3 +-- .../src/app/_components/copy-install.tsx | 3 +-- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/apps/landing/src/app/_components/code-tabs.tsx b/apps/landing/src/app/_components/code-tabs.tsx index 0a86d26b..506b1d7d 100644 --- a/apps/landing/src/app/_components/code-tabs.tsx +++ b/apps/landing/src/app/_components/code-tabs.tsx @@ -75,11 +75,9 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad borderRadius="4px" color="$caption" cursor="pointer" - fontFamily="D2Coding" - fontSize="11px" htmlFor="code-tab-0" px="12px" - py="5px" + py="6px" selectors={{ '#code-tab-0:checked ~ * &': { bg: '$containerBackground', @@ -91,6 +89,7 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad }, }} transition="color .15s, background .15s" + typography="eyebrow" > {a.label} @@ -100,11 +99,9 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad borderRadius="4px" color="$caption" cursor="pointer" - fontFamily="D2Coding" - fontSize="11px" htmlFor="code-tab-1" px="12px" - py="5px" + py="6px" selectors={{ '#code-tab-1:checked ~ * &': { bg: '$containerBackground', @@ -116,6 +113,7 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad }, }} transition="color .15s, background .15s" + typography="eyebrow" > {b.label} @@ -125,11 +123,9 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad borderRadius="4px" color="$caption" cursor="pointer" - fontFamily="D2Coding" - fontSize="11px" htmlFor="code-tab-2" px="12px" - py="5px" + py="6px" selectors={{ '#code-tab-2:checked ~ * &': { bg: '$containerBackground', @@ -141,6 +137,7 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad }, }} transition="color .15s, background .15s" + typography="eyebrow" > {c.label} @@ -150,11 +147,9 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad borderRadius="4px" color="$caption" cursor="pointer" - fontFamily="D2Coding" - fontSize="11px" htmlFor="code-tab-3" px="12px" - py="5px" + py="6px" selectors={{ '#code-tab-3:checked ~ * &': { bg: '$containerBackground', @@ -166,6 +161,7 @@ export function CodeTabs({ examples: [a, b, c, d] }: { examples: CodeExampleQuad }, }} transition="color .15s, background .15s" + typography="eyebrow" > {d.label} diff --git a/apps/landing/src/app/_components/code-window.tsx b/apps/landing/src/app/_components/code-window.tsx index 27017aa3..2200a9ff 100644 --- a/apps/landing/src/app/_components/code-window.tsx +++ b/apps/landing/src/app/_components/code-window.tsx @@ -36,7 +36,6 @@ export function CodeWindow({ borderRadius="$borderRadiusRadius12" boxShadow="0 30px 60px -30px rgba(0,0,0,.25)" overflow="hidden" - w="100%" {...props} > - {[0, 1, 2].map((i) => ( + {Array.from({ length: 3 }, (_, i) => ( { e.stopPropagation() copy() @@ -53,6 +51,7 @@ export function CopyInstall({ px="9px" py="5px" transition="color .15s, border-color .15s" + typography="eyebrow" > {copied ? 'copied' : 'copy'} From 7262b35874f80e2504607eb9ea79052e06d939ea Mon Sep 17 00:00:00 2001 From: 2heunxun Date: Thu, 27 Aug 2026 16:15:40 +0900 Subject: [PATCH 13/14] Merge remote-tracking branch 'upstream/main' (landing) --- apps/landing/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/landing/package.json b/apps/landing/package.json index e5adda5f..4a3fd6a7 100644 --- a/apps/landing/package.json +++ b/apps/landing/package.json @@ -18,24 +18,24 @@ "@devup-ui/reset-css": "^1", "@mdx-js/loader": "^3.1.1", "@mdx-js/react": "^3.1.1", - "@next/mdx": "^16.2.7", + "@next/mdx": "^16.3.1", "clsx": "^2.1.1", "next": "^16", "react": "^19", - "rehype-pretty-code": "^0.14.3", + "rehype-pretty-code": "^0.14.5", "rehype-sanitize": "^6.0.0", "rehype-slug": "^6.0.0", "rehype-stringify": "^10.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", - "shiki": "^4.2.0", + "shiki": "^4.4.3", "unified": "^11.0.5" }, "devDependencies": { "@types/mdx": "^2.0.14", "@devup-api/next-plugin": "^0.1", "@devup-ui/next-plugin": "^1", - "@types/node": "^25", + "@types/node": "^26", "@types/react": "^19", "@types/react-syntax-highlighter": "^15.5.13", "babel-plugin-react-compiler": "^1.0.0", From a6a988ecef5f4fca6e9e8cdc2a6ea4a2db2f7e68 Mon Sep 17 00:00:00 2001 From: JaeHyunAn <98042706+yyuneu@users.noreply.github.com> Date: Thu, 17 Sep 2026 22:50:56 +0900 Subject: [PATCH 14/14] =?UTF-8?q?docs(landing):=20ORM=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=EC=97=90=20Django=20=EB=93=B1=20=EC=A0=84=EC=B2=B4=20=EB=B0=B1?= =?UTF-8?q?=EC=97=94=EB=93=9C=20=ED=91=9C=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/landing/src/app/page.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/landing/src/app/page.tsx b/apps/landing/src/app/page.tsx index 2ec1823c..d7c80551 100644 --- a/apps/landing/src/app/page.tsx +++ b/apps/landing/src/app/page.tsx @@ -106,7 +106,10 @@ $ vespertide export --orm sqlalchemy $ vespertide export --orm sqlmodel # Or Go — GORM -$ vespertide export --orm gorm` +$ vespertide export --orm gorm + +# Or Django +$ vespertide export --orm django` type FeatureIconName = | 'hamburger' @@ -158,7 +161,7 @@ const FEATURES: { icon: FeatureIconName; title: string; desc: string }[] = [ { icon: 'external-link', title: 'ORM export', - desc: 'One command emits SeaORM, SQLAlchemy, SQLModel, or GORM — entities stay in lockstep with schema.', + desc: 'One command emits SeaORM, SQLAlchemy, Django, GORM and more — entities stay in lockstep with schema.', }, { icon: 'github', @@ -220,6 +223,10 @@ const ORMS = [ { lang: 'Rust', name: 'SeaORM' }, { lang: 'Python', name: 'SQLAlchemy' }, { lang: 'Python', name: 'SQLModel · FastAPI' }, + { lang: 'Python', name: 'Django' }, + { lang: 'Java', name: 'JPA · Hibernate' }, + { lang: 'TypeScript', name: 'Prisma' }, + { lang: 'TypeScript', name: 'Drizzle' }, { lang: 'Go', name: 'GORM' }, ] @@ -604,7 +611,7 @@ function ExamplesSection({ examples }: { examples: CodeExampleQuad }) { }, { k: 'Export.', - v: 'SeaORM, SQLAlchemy, SQLModel, GORM — typed entities, generated.', + v: 'SeaORM, SQLAlchemy, Django, GORM and more — typed entities, generated.', }, ].map((it) => (