Skip to content

Commit 954de05

Browse files
authored
improvement(docs): align components with the platform design system (#5227)
* improvement(docs): align components with the platform design system Bring the docs app's chrome in line with the main Sim design system, validated against the canonical emcn source in apps/sim. - ask-ai: fix undefined tokens (--text-base x6, --text-link) that broke the send-button fill and link/text colors; send button now matches the canonical primary fill (text-primary/text-inverse, dark:bg-white); use --shadow-medium and chip gap rhythm - not-found: replace the hand-rolled brand pill with <ChipLink variant='brand'> and swap fumadocs tokens for platform tokens - search-trigger: compose the exported chip chrome constants instead of re-spelling them (single source of truth) - what-you-will-learn, video-chapters: fumadocs fd-* tokens -> platform tokens - workflow-preview: add --wp-highlight token; route the #33b4ff highlight, #ef4444 error dots, and toggle/slider green through tokens - video-placeholder: tokenize the status pill (bespoke illustration art intentionally left as-is) dropdown-menu, faq, theme-toggle, and page-type-badge were deliberately left at their canonical values (14px row icons, rounded-md badge) after validation showed those match the platform, not the chip-pill, standard. * improvement(docs): neutral primary chip for nav CTA + fix cluster spacing Align the docs navbar with the main app, which reserves green for accents/status and uses a neutral high-contrast CTA in nav. - add a canonical `primary` chip variant (inverse fill: dark in light mode, white in dark mode), mirroring the emcn chip's primary action - "Get started" and the 404 "Go home" now use variant='primary' instead of the green brand surface - retire the now-unused `brand` chip variant (no parallel path left behind) - fix navbar right-cluster spacing: gap-2 to match the landing navbar and drop the asymmetric ml-1 on the CTA
1 parent a33c173 commit 954de05

14 files changed

Lines changed: 69 additions & 48 deletions

apps/docs/app/[lang]/not-found.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { DocsPage } from 'fumadocs-ui/page'
2-
import Link from 'next/link'
2+
import { ChipLink } from '@/components/ui/chip'
33

44
export const metadata = {
55
title: 'Page Not Found',
@@ -9,19 +9,16 @@ export default function NotFound() {
99
return (
1010
<DocsPage>
1111
<div className='flex min-h-[70vh] flex-col items-center justify-center gap-4 text-center'>
12-
<h1 className='bg-gradient-to-b from-[#47d991] to-[#33c482] bg-clip-text font-semibold text-8xl text-transparent'>
12+
<h1 className='bg-gradient-to-b from-[var(--brand-accent)] to-[var(--brand-accent-hover)] bg-clip-text font-semibold text-8xl text-transparent'>
1313
404
1414
</h1>
15-
<h2 className='font-semibold text-2xl text-foreground'>Page Not Found</h2>
16-
<p className='text-muted-foreground'>
15+
<h2 className='font-semibold text-2xl text-[var(--text-primary)]'>Page Not Found</h2>
16+
<p className='text-[var(--text-muted)]'>
1717
The page you're looking for doesn't exist or has been moved.
1818
</p>
19-
<Link
20-
href='/'
21-
className='ml-1 flex items-center rounded-[8px] bg-[#33c482] px-2.5 py-1.5 text-[13px] text-white transition-colors duration-200 hover:bg-[#2DAC72]'
22-
>
19+
<ChipLink href='/' variant='primary'>
2320
Go home
24-
</Link>
21+
</ChipLink>
2522
</div>
2623
</DocsPage>
2724
)

apps/docs/app/global.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,7 @@ main article blockquote {
16691669
--wp-chip-text: var(--text-body);
16701670
--wp-divider: #ededed; /* --divider */
16711671
--wp-edge: #e0e0e0; /* --workflow-edge */
1672+
--wp-highlight: #33b4ff; /* traced edge / highlighted output node */
16721673

16731674
/* text */
16741675
--wp-text: var(--text-primary);

apps/docs/components/ai/ask-ai.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,17 @@ export function AskAI({ locale }: AskAIProps) {
8484
type='button'
8585
aria-label='Ask AI'
8686
onClick={() => setOpen(true)}
87-
className='fixed right-4 bottom-4 z-50 flex h-11 items-center gap-2 rounded-full border border-[var(--border-1)] bg-[var(--surface-5)] px-4 font-season text-[var(--text-base)] text-sm shadow-lg transition-colors hover:bg-[var(--surface-active)] dark:bg-[var(--surface-4)]'
87+
className='fixed right-4 bottom-4 z-50 flex h-11 items-center gap-1.5 rounded-full border border-[var(--border-1)] bg-[var(--surface-5)] px-4 font-season text-[var(--text-body)] text-sm shadow-[var(--shadow-medium)] transition-colors hover:bg-[var(--surface-active)] dark:bg-[var(--surface-4)]'
8888
>
8989
<MessageCircle className='size-[16px] text-[var(--text-icon)]' />
9090
Ask AI
9191
</button>
9292
)}
9393

9494
{open && (
95-
<div className='fixed right-4 bottom-4 z-50 flex h-[600px] max-h-[calc(100vh-2rem)] w-[400px] max-w-[calc(100vw-2rem)] flex-col overflow-hidden rounded-xl border border-[var(--border-1)] bg-[var(--surface-5)] shadow-xl dark:bg-[var(--surface-4)]'>
95+
<div className='fixed right-4 bottom-4 z-50 flex h-[600px] max-h-[calc(100vh-2rem)] w-[400px] max-w-[calc(100vw-2rem)] flex-col overflow-hidden rounded-xl border border-[var(--border-1)] bg-[var(--surface-5)] shadow-[var(--shadow-medium)] dark:bg-[var(--surface-4)]'>
9696
<div className='flex items-center justify-between border-[var(--border-1)] border-b px-4 py-3'>
97-
<span className='flex items-center gap-2 font-season text-[var(--text-base)] text-sm'>
97+
<span className='flex items-center gap-1.5 font-season text-[var(--text-body)] text-sm'>
9898
<MessageCircle className='size-[16px] text-[var(--text-icon)]' />
9999
Ask AI
100100
</span>
@@ -105,7 +105,7 @@ export function AskAI({ locale }: AskAIProps) {
105105
stop()
106106
setOpen(false)
107107
}}
108-
className='flex size-7 items-center justify-center rounded-md text-[var(--text-icon)] transition-colors hover:bg-[var(--surface-active)]'
108+
className='flex size-7 items-center justify-center rounded-lg text-[var(--text-icon)] transition-colors hover:bg-[var(--surface-active)]'
109109
>
110110
<X className='size-[16px]' />
111111
</button>
@@ -132,13 +132,13 @@ export function AskAI({ locale }: AskAIProps) {
132132
)}
133133
>
134134
{message.role === 'user' ? (
135-
<div className='max-w-[90%] whitespace-pre-wrap rounded-lg bg-[var(--surface-active)] px-3 py-2 text-[var(--text-base)] text-sm'>
135+
<div className='max-w-[90%] whitespace-pre-wrap rounded-lg bg-[var(--surface-active)] px-3 py-2 text-[var(--text-body)] text-sm'>
136136
{text}
137137
</div>
138138
) : (
139-
<div className='max-w-[90%] text-[var(--text-base)] text-sm'>
139+
<div className='max-w-[90%] text-[var(--text-body)] text-sm'>
140140
{text ? (
141-
<Streamdown className='space-y-2 text-sm leading-relaxed [&_a]:text-[var(--text-link)] [&_a]:underline [&_li]:my-0.5 [&_ol]:list-decimal [&_ol]:pl-5 [&_ul]:list-disc [&_ul]:pl-5'>
141+
<Streamdown className='space-y-2 text-sm leading-relaxed [&_a]:text-[var(--brand-accent)] [&_a]:underline [&_li]:my-0.5 [&_ol]:list-decimal [&_ol]:pl-5 [&_ul]:list-disc [&_ul]:pl-5'>
142142
{text}
143143
</Streamdown>
144144
) : isStreaming ? (
@@ -156,7 +156,7 @@ export function AskAI({ locale }: AskAIProps) {
156156
href={source.url}
157157
target='_blank'
158158
rel='noopener noreferrer'
159-
className='rounded-md border border-[var(--border-1)] px-2 py-0.5 text-[var(--text-muted)] text-xs transition-colors hover:bg-[var(--surface-active)]'
159+
className='rounded-lg border border-[var(--border-1)] px-2 py-0.5 text-[var(--text-muted)] text-xs transition-colors hover:bg-[var(--surface-active)]'
160160
>
161161
{source.title || source.url}
162162
</a>
@@ -189,7 +189,7 @@ export function AskAI({ locale }: AskAIProps) {
189189
}}
190190
rows={1}
191191
placeholder='Ask a question…'
192-
className='max-h-32 flex-1 resize-none bg-transparent font-season text-[var(--text-base)] text-sm outline-none placeholder:text-[var(--text-muted)]'
192+
className='max-h-32 flex-1 resize-none bg-transparent font-season text-[var(--text-body)] text-sm outline-none placeholder:text-[var(--text-muted)]'
193193
/>
194194
{isBusy ? (
195195
<button
@@ -198,14 +198,14 @@ export function AskAI({ locale }: AskAIProps) {
198198
onClick={() => stop()}
199199
className='flex size-8 shrink-0 items-center justify-center rounded-lg bg-[var(--surface-active)] text-[var(--text-icon)]'
200200
>
201-
<Square className='size-[14px]' />
201+
<Square className='size-[16px]' />
202202
</button>
203203
) : (
204204
<button
205205
type='submit'
206206
aria-label='Send'
207207
disabled={!input.trim()}
208-
className='flex size-8 shrink-0 items-center justify-center rounded-lg bg-[var(--text-base)] text-[var(--surface-5)] transition-opacity disabled:opacity-40 dark:bg-[var(--text-base)]'
208+
className='flex size-8 shrink-0 items-center justify-center rounded-lg bg-[var(--text-primary)] text-[var(--text-inverse)] transition-opacity disabled:opacity-40 dark:bg-white dark:text-[var(--bg)]'
209209
>
210210
<ArrowUp className='size-[16px]' />
211211
</button>

apps/docs/components/navbar/navbar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ export function Navbar() {
5252
<SearchTrigger />
5353
</div>
5454

55-
<div className='flex items-center gap-1'>
55+
<div className='flex items-center gap-2'>
5656
<LanguageDropdown />
5757
<ThemeToggle />
58-
<ChipLink href='https://sim.ai' variant='brand' className='ml-1'>
58+
<ChipLink href='https://sim.ai' variant='primary'>
5959
Get started
6060
</ChipLink>
6161
</div>

apps/docs/components/ui/chip.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export const chipContentIconClass = 'size-[16px] flex-shrink-0 text-[var(--text-
2626
export const chipContentLabelClass = 'min-w-0 truncate text-[var(--text-body)] text-sm'
2727
/** The filled FILL (surface only, no border) — `--surface-5` light / `--surface-4` dark. */
2828
export const chipFilledFillTokens = 'bg-[var(--surface-5)] dark:bg-[var(--surface-4)]'
29+
/** The inverse/primary FILL — dark surface + inverse text in light, white + `--bg` text in dark. */
30+
const chipPrimaryFillTokens =
31+
'bg-[var(--text-primary)] text-[var(--text-inverse)] dark:bg-white dark:text-[var(--bg)]'
2932
/** 1px `--border-1` border applied to chip triggers so they read as controls. */
3033
export const TRIGGER_BORDER_CLASS = 'border border-[var(--border-1)]'
3134

@@ -34,8 +37,9 @@ export const TRIGGER_BORDER_CLASS = 'border border-[var(--border-1)]'
3437
*
3538
* @remarks
3639
* The implicit default variant is the bare pill — transparent, `--surface-active`
37-
* on hover. `filled` adds the filled surface; `brand` is the green CTA surface
38-
* (`--brand-accent`) used for the "Get started" link.
40+
* on hover. `filled` adds the filled surface; `primary` is the canonical inverse
41+
* CTA surface (dark in light mode, white in dark mode) used for the "Get started"
42+
* link.
3943
*/
4044
const chipVariants = cva(
4145
`group cursor-pointer font-season ${chipGeometryClass} transition-colors disabled:cursor-not-allowed disabled:opacity-60`,
@@ -44,8 +48,7 @@ const chipVariants = cva(
4448
variant: {
4549
default: 'hover:bg-[var(--surface-active)]',
4650
filled: `${chipFilledFillTokens} hover:bg-[var(--surface-active)]`,
47-
brand:
48-
'bg-[var(--brand-accent)] text-white hover:bg-[var(--brand-accent-hover)] hover:text-white',
51+
primary: `${chipPrimaryFillTokens} hover:bg-[var(--text-body)] dark:hover:bg-[var(--text-secondary)]`,
4952
},
5053
fullWidth: { true: 'flex', false: 'inline-flex' },
5154
},
@@ -66,7 +69,7 @@ interface ChipBaseProps extends VariantProps<typeof chipVariants> {
6669
}
6770

6871
/**
69-
* `brand` sets text color on the chip itself — its icon and label inherit via
72+
* `primary` sets text color on the chip itself — its icon and label inherit via
7073
* `currentColor`. The default and `filled` chips use explicit icon
7174
* (`--text-icon`) and label (`--text-body`) colors.
7275
*/
@@ -76,7 +79,7 @@ function ChipContent({
7679
rightIcon: RightIcon,
7780
children,
7881
}: ChipBaseProps) {
79-
const isInverse = variant === 'brand'
82+
const isInverse = variant === 'primary'
8083
const iconClass = cn(chipContentIconClass, isInverse && 'text-current')
8184
const labelClass = cn(chipContentLabelClass, 'flex-1', isInverse && 'text-current')
8285
return (
@@ -121,7 +124,7 @@ interface ChipLinkProps
121124
ChipBaseProps {}
122125

123126
/**
124-
* @example <ChipLink href='https://sim.ai' variant='brand'>Get started</ChipLink>
127+
* @example <ChipLink href='https://sim.ai' variant='primary'>Get started</ChipLink>
125128
*/
126129
const ChipLink = forwardRef<HTMLAnchorElement, ChipLinkProps>(function ChipLink(
127130
{ className, variant, fullWidth, leftIcon, rightIcon, children, ...props },

apps/docs/components/ui/search-trigger.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
'use client'
22

33
import { Search } from 'lucide-react'
4+
import {
5+
chipContentIconClass,
6+
chipFilledFillTokens,
7+
chipGeometryClass,
8+
TRIGGER_BORDER_CLASS,
9+
} from '@/components/ui/chip'
10+
import { cn } from '@/lib/utils'
411

512
export function SearchTrigger() {
613
const openSearchDialog = () => {
@@ -16,10 +23,15 @@ export function SearchTrigger() {
1623
<button
1724
type='button'
1825
data-search-trigger
19-
className='flex h-[30px] w-[360px] cursor-pointer items-center gap-1.5 rounded-lg border border-[var(--border-1)] bg-[var(--surface-5)] px-2 font-season text-[var(--text-muted)] text-sm transition-colors hover:bg-[var(--surface-active)] dark:bg-[var(--surface-4)]'
26+
className={cn(
27+
chipGeometryClass,
28+
chipFilledFillTokens,
29+
TRIGGER_BORDER_CLASS,
30+
'flex w-[360px] cursor-pointer font-season text-[var(--text-muted)] transition-colors hover:bg-[var(--surface-active)]'
31+
)}
2032
onClick={openSearchDialog}
2133
>
22-
<Search className='size-[14px] text-[var(--text-icon)]' />
34+
<Search className={chipContentIconClass} />
2335
<span>Search&hellip;</span>
2436
<kbd className='ml-auto flex items-center'>
2537
<span className='text-[15px]'></span>

apps/docs/components/ui/video-chapters.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ export function VideoChapters({ title = 'Chapters', chapters, className }: Video
4343

4444
return (
4545
<aside
46-
className={cn('not-prose rounded-xl border border-fd-border bg-fd-card/40 p-5', className)}
46+
className={cn(
47+
'not-prose rounded-xl border border-[var(--border-1)] bg-[var(--surface-3)] p-5',
48+
className
49+
)}
4750
>
48-
<h2 className='mt-0 mb-3 font-semibold text-fd-foreground text-lg'>{title}</h2>
51+
<h2 className='mt-0 mb-3 font-semibold text-[var(--text-primary)] text-lg'>{title}</h2>
4952
<ul className='m-0 flex list-none flex-col gap-0.5 p-0'>
5053
{chapters.map((chapter) => (
5154
<li key={chapter.title}>
@@ -58,12 +61,12 @@ export function VideoChapters({ title = 'Chapters', chapters, className }: Video
5861
new CustomEvent('academy:seek', { detail: { time: parseTime(chapter.time) } })
5962
)
6063
}}
61-
className='flex w-full cursor-pointer items-start gap-2.5 rounded-lg px-2.5 py-2 text-left text-fd-muted-foreground text-sm transition-colors hover:bg-fd-accent/50 disabled:cursor-default disabled:hover:bg-transparent'
64+
className='flex w-full cursor-pointer items-start gap-2.5 rounded-lg px-2.5 py-2 text-left text-[var(--text-secondary)] text-sm transition-colors hover:bg-[var(--surface-active)] disabled:cursor-default disabled:hover:bg-transparent'
6265
>
6366
<CirclePlay className='mt-0.5 size-4 shrink-0' />
6467
<span className='min-w-0 flex-1 break-words'>{chapter.title}</span>
6568
{chapter.time && (
66-
<span className='mt-0.5 shrink-0 text-fd-muted-foreground text-xs tabular-nums'>
69+
<span className='mt-0.5 shrink-0 text-[var(--text-muted)] text-xs tabular-nums'>
6770
{chapter.time}
6871
</span>
6972
)}

apps/docs/components/ui/video-placeholder.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ export function VideoPlaceholder({
143143

144144
{/* Top-right status pill — only until a video is wired up */}
145145
{!hasVideo && (
146-
<span className='absolute top-6 right-6 z-10 inline-flex items-center gap-2 rounded-full border border-[#E6E6E6] bg-white px-4 py-2 font-medium text-[#5F5F5F] text-[12px] uppercase tracking-[0.14em] md:top-8 md:right-8 dark:border-white/12 dark:bg-[#1A1A1A] dark:text-[#E6E6E6]'>
147-
<span className='size-1.5 rounded-full bg-[#1F8A5B]' />
146+
<span className='absolute top-6 right-6 z-10 inline-flex items-center gap-2 rounded-full border border-[var(--border-1)] bg-[var(--surface-2)] px-4 py-2 font-medium text-[12px] text-[var(--text-secondary)] uppercase tracking-[0.14em] md:top-8 md:right-8 dark:bg-[var(--surface-1)]'>
147+
<span className='size-1.5 rounded-full bg-[var(--brand-accent)]' />
148148
{label}
149149
</span>
150150
)}

apps/docs/components/ui/what-you-will-learn.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,19 @@ interface WhatYouWillLearnProps {
1414
export function WhatYouWillLearn({ items, className }: WhatYouWillLearnProps) {
1515
return (
1616
<div
17-
className={cn('not-prose rounded-xl border border-fd-border bg-fd-card/40 p-6', className)}
17+
className={cn(
18+
'not-prose rounded-xl border border-[var(--border-1)] bg-[var(--surface-3)] p-6',
19+
className
20+
)}
1821
>
19-
<h2 className='mt-0 mb-5 font-semibold text-fd-foreground text-xl'>What you will learn</h2>
22+
<h2 className='mt-0 mb-5 font-semibold text-[var(--text-primary)] text-xl'>
23+
What you will learn
24+
</h2>
2025
<div className='flex flex-col gap-5'>
2126
{items.map((item) => (
2227
<div key={item.title}>
23-
<p className='mb-1 font-semibold text-fd-foreground text-sm'>{item.title}</p>
24-
<p className='m-0 text-fd-muted-foreground text-sm leading-relaxed'>{item.body}</p>
28+
<p className='mb-1 font-semibold text-[var(--text-primary)] text-sm'>{item.title}</p>
29+
<p className='m-0 text-[var(--text-secondary)] text-sm leading-relaxed'>{item.body}</p>
2530
</div>
2631
))}
2732
</div>

apps/docs/components/workflow-preview/block-inspector.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ function FieldControl({ field }: { field: InspectorField }) {
7676
<div className='flex items-center gap-2'>
7777
<div
7878
className='flex h-[18px] w-[32px] items-center rounded-full px-[2px] transition-colors'
79-
style={{ background: on ? '#33C482' : 'var(--wp-border-1)' }}
79+
style={{ background: on ? 'var(--brand-accent)' : 'var(--wp-border-1)' }}
8080
>
8181
<div
8282
className='size-[14px] rounded-full bg-white'
@@ -94,7 +94,7 @@ function FieldControl({ field }: { field: InspectorField }) {
9494
<div className='flex w-full items-center gap-3'>
9595
<div className='relative h-[4px] flex-1 rounded-full bg-[var(--wp-border-1)]'>
9696
<div
97-
className='absolute inset-y-0 left-0 rounded-full bg-[#33C482]'
97+
className='absolute inset-y-0 left-0 rounded-full bg-[var(--brand-accent)]'
9898
style={{ width: `${percent}%` }}
9999
/>
100100
<div

0 commit comments

Comments
 (0)