diff --git a/DESIGN.md b/DESIGN.md index 2eb3200..f1569ec 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -9,11 +9,10 @@ ## Aesthetic Direction -- **Direction:** Warm technical editorial in marketing; cinematic black creative operating system across Studio, Canvas, and comparison-led Pricing. +- **Direction:** Warm technical editorial in marketing; cinematic black creative operating system across Studio and Canvas. - **Decoration:** Intentional. Typography, product media, fine grid lines, dark glass controls, and restrained highlights create character without ornamental UI noise. - **Layout:** Hybrid. Marketing uses editorial scale and asymmetry; local project surfaces use a strict, predictable grid. - **Mood:** Capable, cinematic, and crafted. Creation surfaces should feel like focused production tools, while the marketing site stays warmer and more editorial. -- **Reference language:** A focused editorial pricing language, not a separately selectable theme. ## Typography @@ -31,7 +30,6 @@ - **Brand soft:** `#FFF0E5` — selected surfaces and subtle callouts. - **Marketing canvas:** `#F6F0E7` — warm cream. - **Studio / Canvas / Assets canvas:** `#08090A` — near-black production workspace. -- **Pricing canvas:** `#08090A` with graphite `#141517` plan cards, warm-white type, and clear comparison geometry. - **Dark surface:** `#111214`; raised surface `#17181B`; control surface `#202126`. - **Dark ink:** `#F6F6F4`; secondary `rgba(246,246,244,.58)`; faint `rgba(246,246,244,.34)`. - **Surface:** `#FFFFFF`; raised surface `#FCFCFA`. @@ -39,7 +37,7 @@ - **Borders:** `#DDDED8`; strong `#C7C9C0`. - **Highlight:** `#C7F36B` — sparse proof or status accent, never a primary CTA. - **Success:** `#208A55`; warning `#B66A09`; error `#C23B32`; info `#2563A9`. -- **Dark product surfaces:** Near-black canvas with charcoal cards. Orange stays saturated because it is the only brand action color; cold blue is limited to Canvas graph semantics. Pricing keeps a clear commercial hierarchy while using the same dark product vocabulary as Studio, Canvas, and Assets. +- **Dark product surfaces:** Near-black canvas with charcoal cards. Orange stays saturated because it is the only brand action color; cold blue is limited to Canvas graph semantics. ## Spacing and Shape @@ -66,7 +64,7 @@ Button, IconButton, Input, Textarea, Select, Checkbox, Switch, Tabs, Tooltip, Di ### Marketing -MarketingHeader, HeroStatement, HeroDemoFrame, ProofStrip, FeatureStory, MediaShowcase, WorkflowSteps, CodePreview, PricingSection, FAQ, CTA, and MarketingFooter. +MarketingHeader, HeroStatement, HeroDemoFrame, ProofStrip, FeatureStory, MediaShowcase, WorkflowSteps, CodePreview, FAQ, CTA, and MarketingFooter. ### Product @@ -120,9 +118,7 @@ Homepage emphasis is approximately 70% what can be built with BeatAPI, 20% what | 2026-08-12 | Shared AppShell with Studio, Canvas, and Assets modes | Preserves every project view without duplicating workspace chrome. | | 2026-08-12 | Orange primary, cream marketing, neutral app | Connects the brand across marketing and product while preserving workspace clarity. | | 2026-08-12 | Figtree + Geist Mono | Keeps creative brand expression and developer readability in one family of interfaces. | -| 2026-08-15 | Unified black Studio, Canvas, and Pricing | Pricing retains a clear comparison structure while matching the cinematic product environment. | | 2026-08-15 | Studio has no sidebar | The media wall and composer are the product; permanent navigation would dilute focus and reduce working width. | -| 2026-08-15 | Independent BeatDesign pricing route | Pricing is linkable, uses consistent card geometry, and preserves BeatAPI price-comparison behavior. | | 2026-08-18 | Studio/Canvas composers unified on the beat token system | Both composers share one vocabulary (`@/components/app/composer-styles.ts`): the homepage hero card recipe, `--beat-*` tokens, and one orange Generate action. `--beat-studio-*` became aliases; `--beatcanvas-*` surface/ink tokens map onto the beat neutral scale. | | 2026-08-18 | Canvas graph semantics moved from purple to cold blue (`--beat-graph` #7fb0f2) | The previous purple graph accent is retired. Cold blue selection/edges/minimap echoes the Start Here thumbnails the product opens with, and keeps "selected" visually distinct from the orange action color. | | 2026-08-18 | Start Here empty state is the protected quality bar | The four cold-blue thumbnails + "Create Here" stay untouched; dark product surfaces are tuned around them. | diff --git a/messages/en.json b/messages/en.json index 515398b..62010d9 100644 --- a/messages/en.json +++ b/messages/en.json @@ -4,7 +4,6 @@ "product.shell.create": "Create", "product.shell.studio": "Studio", "product.shell.canvas": "Canvas", - "product.shell.pricing": "Pricing", "product.shell.projects": "Projects", "product.shell.openNavigation": "Open navigation", "product.shell.closeNavigation": "Close navigation", @@ -51,22 +50,6 @@ "product.history.startFirst": "Start your first project", "product.history.emptyDescription": "One project keeps your Studio generations and Canvas workflow together.", "product.history.newProject": "New project", - "product.pricing.titleLead": "Pay less for the same ", - "product.pricing.titleAccent": "models.", - "product.pricing.descriptionLead": "Pay only for what you generate.", - "product.pricing.descriptionRest": "BeatDesign is powered by BeatAPI. One balance, every workflow.", - "product.pricing.statCheaperHint": "cheaper than competitor", - "product.pricing.statSavingsHint": "average savings", - "product.pricing.filterAll": "All models", - "product.pricing.filterVideo": "AI Video", - "product.pricing.filterImage": "AI Image", - "product.pricing.search": "Search model or spec", - "product.pricing.empty": "No matching prices.", - "product.pricing.colSpec": "Spec", - "product.pricing.colCompetitor": "API Competitor (R/F)", - "product.pricing.colHiggsfield": "Competitor H", - "product.pricing.colDiscount": "Discount", - "product.pricing.ctaPrimary": "Start creating", "common.pages.back_to_home": "Back to home", "common.pages.last_updated": "Last updated", "common.pages.not_found": "Page not found", diff --git a/messages/zh.json b/messages/zh.json index 7f28f72..3b3f64e 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -4,7 +4,6 @@ "product.shell.create": "创作", "product.shell.studio": "Studio", "product.shell.canvas": "Canvas", - "product.shell.pricing": "价格", "product.shell.projects": "项目", "product.shell.openNavigation": "打开导航", "product.shell.closeNavigation": "关闭导航", @@ -51,22 +50,6 @@ "product.history.startFirst": "开始你的第一个项目", "product.history.emptyDescription": "一个项目同时保存 Studio 生成结果和 Canvas 工作流。", "product.history.newProject": "新建项目", - "product.pricing.titleLead": "同样的模型,更低的", - "product.pricing.titleAccent": "价格。", - "product.pricing.descriptionLead": "只为生成的内容付费。", - "product.pricing.descriptionRest": "BeatDesign 由 BeatAPI 驱动。一个余额,贯穿每个工作流。", - "product.pricing.statCheaperHint": "对比竞品最高优惠", - "product.pricing.statSavingsHint": "平均节省", - "product.pricing.filterAll": "所有模型", - "product.pricing.filterVideo": "AI 视频", - "product.pricing.filterImage": "AI 图片", - "product.pricing.search": "搜索模型或规格", - "product.pricing.empty": "没有符合条件的价格。", - "product.pricing.colSpec": "规格", - "product.pricing.colCompetitor": "API 竞品 (R/F)", - "product.pricing.colHiggsfield": "竞品 H", - "product.pricing.colDiscount": "优惠", - "product.pricing.ctaPrimary": "开始创作", "common.pages.back_to_home": "返回首页", "common.pages.last_updated": "最近更新", "common.pages.not_found": "页面不存在", diff --git a/src/components/marketing/beatapi-product-shell.test.ts b/src/components/marketing/beatapi-product-shell.test.ts index c2b3d4a..cb50f15 100644 --- a/src/components/marketing/beatapi-product-shell.test.ts +++ b/src/components/marketing/beatapi-product-shell.test.ts @@ -7,11 +7,12 @@ const source = readFileSync( 'utf8' ); -test('product shell keeps workspace navigation with pricing and hides SaaS auth', () => { +test('product shell keeps workspace navigation and hides SaaS auth', () => { assert.match(source, /label: copy\.home, href: '\/'/); assert.match(source, /label: copy\.create, href: '\/studio'/); - assert.match(source, /href: '\/pricing'/); assert.match(source, /href: '\/projects'/); + assert.doesNotMatch(source, /href: '\/pricing'/); + assert.doesNotMatch(source, /ProductSurface.*pricing/); assert.doesNotMatch(source, /href="\/sign-in"/); assert.doesNotMatch(source, /useSession/); }); diff --git a/src/components/marketing/beatapi-product-shell.tsx b/src/components/marketing/beatapi-product-shell.tsx index 3324fdd..ec0514a 100644 --- a/src/components/marketing/beatapi-product-shell.tsx +++ b/src/components/marketing/beatapi-product-shell.tsx @@ -12,7 +12,7 @@ import { appConfig } from '@/config'; import { m } from '@/paraglide/messages.js'; import { setLocale } from '@/paraglide/runtime.js'; -type ProductSurface = 'home' | 'projects' | 'pricing'; +type ProductSurface = 'home' | 'projects'; type ProductLocale = 'en' | 'zh'; @@ -25,7 +25,6 @@ function getShellCopy(locale: string) { return { home: m['product.shell.home']({}, { locale: messageLocale }), create: m['product.shell.create']({}, { locale: messageLocale }), - pricing: m['product.shell.pricing']({}, { locale: messageLocale }), projects: m['product.shell.projects']({}, { locale: messageLocale }), openNavigation: m['product.shell.openNavigation']( {}, @@ -52,7 +51,6 @@ function getNavItems(copy: ShellCopy) { return [ { label: copy.home, href: '/' }, { label: copy.create, href: '/studio' }, - { label: copy.pricing, href: '/pricing' }, { label: copy.projects, href: '/projects' }, ] as const; } @@ -60,7 +58,6 @@ function getNavItems(copy: ShellCopy) { const activeNavHref: Record = { home: '/', projects: '/projects', - pricing: '/pricing', }; export function Brand({ href = '/' }: { href?: string }) { @@ -89,7 +86,7 @@ function CapsuleNav({ }) { const activeHref = activeNavHref[active]; return ( -