Skip to content

Commit bcf094c

Browse files
authored
Auto-merged main into codex/reference-docs-landing-a346cf4 on deployment.
2 parents a346cf4 + 570e4b6 commit bcf094c

940 files changed

Lines changed: 23298 additions & 19325 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CODE.md‎

Lines changed: 108 additions & 508 deletions
Large diffs are not rendered by default.

‎PLAN.md‎

Lines changed: 937 additions & 331 deletions
Large diffs are not rendered by default.

‎SKILL.md‎

Lines changed: 195 additions & 42 deletions
Large diffs are not rendered by default.
File renamed without changes.
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import {
2+
Badge,
3+
Chip,
4+
Cluster,
5+
type ComponentRegistryEntry,
6+
Container,
7+
componentRegistry,
8+
Grid,
9+
PageSection,
10+
renderComponentExample,
11+
Section,
12+
Stack
13+
} from '@rubriclab/concrete'
14+
import { CatalogCard, CatalogIntro } from '@/catalog-card'
15+
16+
type ComponentCategory = ComponentRegistryEntry['category']
17+
18+
const componentCategoryOrder = [
19+
'navigation',
20+
'control',
21+
'surface',
22+
'diagram',
23+
'data',
24+
'feedback',
25+
'layout',
26+
'form',
27+
'media'
28+
] as const satisfies readonly ComponentCategory[]
29+
30+
export default function ComponentsPage() {
31+
const groupedComponents = getComponentCategories(componentRegistry)
32+
.map(category => ({
33+
category,
34+
components: componentRegistry.filter(component => component.category === category)
35+
}))
36+
.filter(group => group.components.length > 0)
37+
38+
return (
39+
<>
40+
<PageSection ground="field" rhythm="chapter" separated>
41+
<Container as="main" density="editorial" measure="wide">
42+
<Stack density="editorial">
43+
<CatalogIntro
44+
count={componentRegistry.length}
45+
description="Components assemble primitives and approved lower-tier components. They can own deterministic local behavior, but they do not own CSS or app-specific product policy."
46+
eyebrow="Each component exposes typed props, examples, states, playground controls, and render routes."
47+
title="Compositions with contracts"
48+
/>
49+
<Cluster density="compact">
50+
<Badge intent="terminal">registry backed</Badge>
51+
<Chip selected>typed props</Chip>
52+
<Chip>render routes</Chip>
53+
</Cluster>
54+
</Stack>
55+
</Container>
56+
</PageSection>
57+
58+
<PageSection rhythm="chapter">
59+
<Container density="editorial" measure="wide">
60+
<Stack density="editorial">
61+
{groupedComponents.map(group => (
62+
<Section
63+
description={getCategoryDescription(group.category)}
64+
key={group.category}
65+
title={getCategoryTitle(group.category)}
66+
>
67+
<Grid columns="three">
68+
{group.components.map(component => (
69+
<CatalogCard
70+
category={component.category}
71+
description={component.description}
72+
href={`/components/${component.slug}`}
73+
key={component.slug}
74+
name={component.name}
75+
pressure={component.pressure}
76+
states={component.states.length}
77+
>
78+
<Stack align="center">{renderComponentExample(component.slug)}</Stack>
79+
</CatalogCard>
80+
))}
81+
</Grid>
82+
</Section>
83+
))}
84+
</Stack>
85+
</Container>
86+
</PageSection>
87+
</>
88+
)
89+
}
90+
91+
function getComponentCategories(
92+
registry: readonly ComponentRegistryEntry[]
93+
): readonly ComponentCategory[] {
94+
const knownCategories = new Set<ComponentCategory>(componentCategoryOrder)
95+
const unlistedCategories = registry
96+
.map(component => component.category)
97+
.filter(category => !knownCategories.has(category))
98+
99+
return [...componentCategoryOrder, ...new Set(unlistedCategories)]
100+
}
101+
102+
function getCategoryTitle(category: ComponentCategory): string {
103+
switch (category) {
104+
case 'control':
105+
return 'Interaction controls'
106+
case 'data':
107+
return 'Data surfaces'
108+
case 'diagram':
109+
return 'Explainer diagrams'
110+
case 'feedback':
111+
return 'Agent process artifacts'
112+
case 'form':
113+
return 'Input systems'
114+
case 'layout':
115+
return 'Form and editor shells'
116+
case 'media':
117+
return 'Upload compositions'
118+
case 'navigation':
119+
return 'Navigation and command surfaces'
120+
case 'surface':
121+
return 'Transcript surfaces'
122+
default:
123+
return 'Component group'
124+
}
125+
}
126+
127+
function getCategoryDescription(category: ComponentCategory): string {
128+
switch (category) {
129+
case 'control':
130+
return 'Small but stateful control clusters that coordinate keyboard, focus, and selected state.'
131+
case 'data':
132+
return 'Typed KPI, chart, table, meter, and diagram components for dense product data and generated UI.'
133+
case 'diagram':
134+
return 'Concept frames and graph canvases for editorial and educational explanation.'
135+
case 'feedback':
136+
return 'Subdued, expandable artifacts for visible reasoning, validation, and tool execution.'
137+
case 'form':
138+
return 'Field-level compositions for typed values, choices, dates, times, numbers, ranges, and uploads.'
139+
case 'layout':
140+
return 'Larger component shells that standardize dense product form rhythm without owning product policy.'
141+
case 'media':
142+
return 'Upload surfaces specialized around local previews and queue state.'
143+
case 'navigation':
144+
return 'Top-level navigation, footer, search, and command entry points for agentic interfaces.'
145+
case 'surface':
146+
return 'Role-aware message surfaces for multiplayer and multi-agent transcripts.'
147+
default:
148+
return 'Registry-backed components ready for render routes and screenshots.'
149+
}
150+
}
File renamed without changes.
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import {
2+
Badge,
3+
Chip,
4+
Cluster,
5+
Container,
6+
Frame,
7+
foundationRegistry,
8+
Grid,
9+
Heading,
10+
PageSection,
11+
renderFoundationExample,
12+
Section,
13+
Split,
14+
Stack,
15+
Text
16+
} from '@rubriclab/concrete'
17+
import { CatalogCard, CatalogIntro } from '@/catalog-card'
18+
19+
const foundationShowcases = [
20+
'typography',
21+
'colors',
22+
'spacing',
23+
'radii',
24+
'elevation',
25+
'motion',
26+
'textures',
27+
'iconography',
28+
'state',
29+
'accessibility'
30+
] as const
31+
32+
export default function FoundationsRoute() {
33+
return (
34+
<>
35+
<PageSection ground="field" rhythm="chapter" separated>
36+
<Container as="main" density="editorial" measure="wide">
37+
<Stack density="editorial">
38+
<CatalogIntro
39+
count={foundationRegistry.length}
40+
description="Foundations own values, shared schemas, reset-level utilities, and raw design tokens. They do not render product UI."
41+
eyebrow="Variables, utility classes, examples, and token records are package-owned."
42+
title="Foundations"
43+
/>
44+
<Split
45+
aside={
46+
<Frame
47+
align="stretch"
48+
header="Display"
49+
headerMeta="Fraunces"
50+
scale="showcase"
51+
texture="field"
52+
>
53+
<Stack density="compact">
54+
<Heading hierarchy="hero" level="2">
55+
Two <em>families,</em> one voice.
56+
</Heading>
57+
<Text as="p" intent="muted" purpose="lead">
58+
Plus Jakarta Sans carries the interface. Fraunces is reserved for display moments,
59+
chapter plates, and pull quotes.
60+
</Text>
61+
</Stack>
62+
</Frame>
63+
}
64+
density="editorial"
65+
ratio="even"
66+
>
67+
<Stack density="compact">
68+
<Frame align="stretch" header="Typography" scale="showcase" texture="lines">
69+
{renderFoundationExample('typography')}
70+
</Frame>
71+
</Stack>
72+
</Split>
73+
</Stack>
74+
</Container>
75+
</PageSection>
76+
77+
<PageSection rhythm="chapter" separated>
78+
<Container density="editorial" measure="wide">
79+
<Stack density="editorial">
80+
<Section
81+
description="Curated specimens are rendered from package-owned foundation examples, so the docs page stays a consumer instead of duplicating token truth."
82+
title="Foundation specimens"
83+
>
84+
<Grid columns="two">
85+
{foundationShowcases.map(slug => (
86+
<Frame
87+
align="stretch"
88+
header={getFoundationName(slug)}
89+
key={slug}
90+
scale="showcase"
91+
texture="field"
92+
>
93+
{renderFoundationExample(slug)}
94+
</Frame>
95+
))}
96+
</Grid>
97+
</Section>
98+
<Section
99+
description="Each foundation page shows the live item definition, token role, states, props, and render routes."
100+
title="Registry"
101+
>
102+
<Grid columns="three">
103+
{foundationRegistry.map(entry => (
104+
<CatalogCard
105+
category={entry.category}
106+
description={entry.description}
107+
href={`/foundations/${entry.slug}`}
108+
key={entry.slug}
109+
name={entry.name}
110+
pressure={entry.pressure}
111+
states={entry.states.length}
112+
>
113+
<Stack align="center">{renderFoundationExample(entry.slug)}</Stack>
114+
</CatalogCard>
115+
))}
116+
</Grid>
117+
</Section>
118+
<Cluster density="compact">
119+
<Badge intent="terminal">registry backed</Badge>
120+
<Chip>token records</Chip>
121+
<Chip>render routes</Chip>
122+
</Cluster>
123+
</Stack>
124+
</Container>
125+
</PageSection>
126+
</>
127+
)
128+
}
129+
130+
function getFoundationName(slug: (typeof foundationShowcases)[number]): string {
131+
return foundationRegistry.find(entry => entry.slug === slug)?.name ?? slug
132+
}

‎apps/docs/app/(site)/layout.tsx‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { CodeBlock, Footer, Nav } from '@rubriclab/concrete'
2+
3+
const navigationItems = [
4+
{ href: '/', id: 'home', label: 'Home' },
5+
{ href: '/foundations', id: 'foundations', label: 'Foundations' },
6+
{ href: '/primitives', id: 'primitives', label: 'Primitives' },
7+
{ href: '/components', id: 'components', label: 'Components' }
8+
] as const
9+
10+
const navigationActions = [
11+
{
12+
external: true,
13+
href: 'https://www.npmjs.com/package/@rubriclab/concrete',
14+
id: 'npm',
15+
label: 'npm'
16+
},
17+
{
18+
external: true,
19+
href: 'https://github.com/RubricLab/concrete',
20+
id: 'github',
21+
label: 'GitHub'
22+
}
23+
] as const
24+
25+
const footerColumns = [
26+
{
27+
id: 'catalog',
28+
links: [
29+
{ href: '/foundations', id: 'foundations', label: 'Foundations' },
30+
{ href: '/primitives', id: 'primitives', label: 'Primitives' },
31+
{ href: '/components', id: 'components', label: 'Components' }
32+
],
33+
title: 'Catalog'
34+
},
35+
{
36+
id: 'render',
37+
links: [
38+
{ href: '/render/foundation/colors', id: 'foundation-render', label: 'Foundation render' },
39+
{ href: '/render/primitive/button', id: 'primitive-render', label: 'Primitive render' },
40+
{ href: '/render/component/nav', id: 'component-render', label: 'Component render' }
41+
],
42+
title: 'Render'
43+
},
44+
{
45+
id: 'package',
46+
links: navigationActions,
47+
title: 'Package'
48+
}
49+
] as const
50+
51+
export default function SiteLayout({ children }: Readonly<{ children: React.ReactNode }>) {
52+
return (
53+
<>
54+
<Nav actions={navigationActions} brandHref="/" items={navigationItems} placement="sticky" />
55+
{children}
56+
<Footer
57+
actions={navigationActions}
58+
aside={<CodeBlock code="npm install @rubriclab/concrete" language="Shell" mode="command" />}
59+
columns={footerColumns}
60+
description="Soft, powerful, compact UI vocabulary for AI-native software."
61+
meta="Rubric Labs"
62+
title="Concrete"
63+
/>
64+
</>
65+
)
66+
}

0 commit comments

Comments
 (0)