diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 1b27c1b..75a3508 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -12,7 +12,6 @@ on:
- "tests/e2e/**"
- "playwright.config.ts"
- "colors_and_type.css"
- - "preview/**"
- "ui_kits/**"
- "package.json"
- "pnpm-lock.yaml"
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 5b4a945..069fb7a 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -1,8 +1,8 @@
name: Pages
# Deploys the demo site to GitHub Pages.
-# Source published: colors_and_type.css + assets/ + preview/ + ui_kits/
-# plus an auto-generated landing index.html and preview/index.html.
+# Source published: colors_and_type.css + assets/ + ui_kits/
+# plus the auto-generated landing index.html and per-component pages.
on:
push:
@@ -10,7 +10,6 @@ on:
paths:
- "colors_and_type.css"
- "assets/**"
- - "preview/**"
- "ui_kits/**"
- "src/**"
- "scripts/**"
diff --git a/preview/_card.css b/preview/_card.css
deleted file mode 100644
index 15c5efe..0000000
--- a/preview/_card.css
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Shared styles for preview cards — keeps each card file tight */
-@import url('../colors_and_type.css');
-
-/*
- * RESPONSIVE STRATEGY
- * ───────────────────
- * Cards render in the design-system gallery at 700px (the “design width”).
- * Outside the gallery — full browser, iPad, iPhone, Galaxy S24 — they need to
- * adapt without breaking layout. Approach:
- * • Card width is fluid (max 700px, min 100vw) so it never overflows narrow viewports.
- * • Padding scales with viewport: clamp() between 14px (mobile) and 24px (desktop).
- * • Internal grids fall back to a single column under 560px.
- * • Horizontal overflow is allowed only inside .scroll-x wrappers (tables, code).
- * • Touch targets stay ≥ 36px tall via min-height on interactive elements.
- *
- * Tested against the breakpoints below:
- * iPhone 15/16 ............ 393 × 852 (logical, 3x DPR)
- * iPhone 15/16 Pro Max .... 430 × 932
- * iPad mini / Air ......... 744 × 1133 (portrait)
- * iPad Pro 11" / 13" ...... 834 / 1024 wide
- * Galaxy S24 / S25 ........ 360 × 780
- * Galaxy S24 / S25 Ultra .. 412 × 915
- * Desktop ................. 1280+ wide
- */
-
-html, body {
- margin: 0; padding: 0;
- background: var(--bg-0);
- color: var(--fg-1);
- width: 100%;
- max-width: 100vw;
- overflow-x: hidden;
- -webkit-text-size-adjust: 100%;
- text-size-adjust: 100%;
- /* Kill rubber-band / bounce overscroll on iOS Safari + Android Chrome */
- overscroll-behavior: none;
- overscroll-behavior-y: none;
- overscroll-behavior-x: none;
- /* Avoid double-tap zoom and let the browser do fast taps */
- touch-action: manipulation;
-}
-
-html { height: 100%; }
-body { min-height: 100%; }
-
-/* Any inner scroll container (terminals, tables, code blocks) keeps its bounce contained */
-.scroll-x, .card pre, .card .xt, .card .code, .card .term, .card .diff,
-.card table, .card .panel { overscroll-behavior: contain; }
-
-/* Form controls: 16px+ font on phones prevents iOS Safari focus-zoom.
- Apply universally (not only under @media pointer:coarse) so older Android skins behave too. */
-input, select, textarea {
- font-size: 16px;
- /* Honor design font sizes on desktop where zoom isn't a risk */
-}
-@media (min-width: 768px) {
- input, select, textarea { font-size: inherit; }
-}
-
-.card {
- padding: clamp(14px, 3.4vw, 24px);
- box-sizing: border-box;
- width: 100%;
- max-width: 700px;
- margin: 0 auto;
- display: flex;
- flex-direction: column;
- gap: clamp(12px, 2.4vw, 16px);
-}
-
-.card.sbs { flex-direction: row; gap: 20px; flex-wrap: wrap; }
-
-.card-split {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 0;
- width: 100%;
- max-width: 700px;
- margin: 0 auto;
- min-height: 100%;
-}
-.card-split > div { padding: clamp(14px, 3.4vw, 24px); box-sizing: border-box; }
-.card-split .light { background: #FFFFFF; color: #1C1C1C; }
-.card-split .dark { background: #1C1C1C; color: #FFFFFF; }
-
-/* ── Narrow viewports (Galaxy S24 360px, iPhone 393–430px) ────────────── */
-@media (max-width: 560px) {
- /* Any 2-col grid in a card collapses to single column */
- .card > div[style*="grid-template-columns:1fr 1fr"],
- .card > div[style*="grid-template-columns: 1fr 1fr"] {
- grid-template-columns: 1fr !important;
- }
- /* Side-by-side card splits stack */
- .card-split { grid-template-columns: 1fr; }
- /* Side-by-side cards stack */
- .card.sbs { flex-direction: column; }
-}
-
-/* ── Phones in landscape / small tablets ─────────────────────────────── */
-@media (max-width: 480px) {
- /* Tighten interior panel padding so things still breathe */
- .card .panel { padding: 12px !important; }
-}
-
-/* ── Touch-target floor for interactive bits ─────────────────────────── */
-@media (pointer: coarse) {
- button, [role="button"], .btn, input[type="checkbox"], input[type="radio"] {
- min-height: 36px;
- }
- input[type="text"], input[type="search"], input[type="email"], input[type="number"], textarea, select {
- min-height: 38px;
- font-size: 16px; /* prevents iOS Safari zoom on focus */
- }
-}
-
-/* ── Wide viewports (iPad Pro landscape, desktop) ────────────────────── */
-@media (min-width: 1024px) {
- .card { max-width: 760px; } /* slight breathing room beyond gallery default */
-}
-
-/* ── Horizontal overflow escape hatches ──────────────────────────────── */
-.scroll-x {
- overflow-x: auto;
- -webkit-overflow-scrolling: touch;
- scrollbar-width: thin;
-}
-.scroll-x > * { min-width: max-content; }
-
-/* Tables, code blocks, terminals get auto-wrapped scroll on narrow ─────── */
-@media (max-width: 560px) {
- .card table,
- .card pre,
- .card .xt,
- .card .code,
- .card .term,
- .card .diff {
- max-width: 100%;
- overflow-x: auto;
- -webkit-overflow-scrolling: touch;
- }
-}
-
-/* Hide scrollbars in previews (kept for gallery flush look) */
-::-webkit-scrollbar { display: none; }
diff --git a/preview/brand-iconography.html b/preview/brand-iconography.html
deleted file mode 100644
index ddb5c9b..0000000
--- a/preview/brand-iconography.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
Iconography · Lucide · 1.5px stroke
-
-
terminal
-
server
-
shield
-
key
-
database
-
git-branch
-
settings
-
search
-
activity
-
box
-
-
- Unicode glyphs:
- → ← ↗ · ✓ ✕ ⌘ ⌥ ⇧ ⌃
- no emoji
-
-
-
-
diff --git a/preview/brand-logo.html b/preview/brand-logo.html
deleted file mode 100644
index 86e72a4..0000000
--- a/preview/brand-logo.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
Logo · mark & wordmark
-
-
-
-
-
-
-
-
-
-
-
-
-
randomcodespace
-
-
-
-
-
-
-
-
randomcodespace
-
-
-
Bracket-pair with center dot. Mark uses currentColor throughout — strokes and dot inherit the surrounding text color. Pure monochrome, no chroma.
-
-
diff --git a/preview/brand-motion.html b/preview/brand-motion.html
deleted file mode 100644
index 2d36001..0000000
--- a/preview/brand-motion.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
Motion · crisp, small, fast
-
-
-
Hover
-
140ms
-
out-quart
-
-
-
State
-
220ms
-
out-quart
-
-
-
Route
-
380ms
-
out-expo
-
-
-
Success ★
-
spring
-
.34, 1.56
-
-
-
-
easing · out-quart
-
-
-
-
-
-
-
No bouncy nav. No wiggles. Respects prefers-reduced-motion.
-
-
diff --git a/preview/brand-voice.html b/preview/brand-voice.html
deleted file mode 100644
index 40484cd..0000000
--- a/preview/brand-voice.html
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
Voice · copy examples
-
-
-
✓ Write
-
Tools you own.
-
Self-host in three minutes.
-
No services yet. Run rcs deploy to add one.
-
Connection refused — check the port.
-
-
-
✕ Don't
-
Empowering developers with next-gen open source!
-
Start your amazing journey today!
-
Oh! It looks like there's nothing here yet 🙂
-
Oops! Something went wrong.
-
-
-
Declarative. Technical. Sentence case. No exclamations. No emoji. No hype words.
-
-
diff --git a/preview/colors-brand.html b/preview/colors-brand.html
deleted file mode 100644
index 6fe1b2c..0000000
--- a/preview/colors-brand.html
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
Brand · Red + Cod Gray + White
-
-
Red · accent
-
-
-
Cod Gray · neutrals
-
-
-
-
-
-
-
#E60000
-
Red · accent
-
-
-
-
-
-
#1C1C1C
-
Cod Gray · text
-
-
-
-
-
-
#FFFFFF
-
White · surface
-
-
-
-
-
- Three colors only: Signal Red for accent, Cod Gray for text and dark mode surfaces, White for light surfaces. Hierarchy uses gray steps for depth; red is reserved for primary actions and brand moments.
-
-
-
diff --git a/preview/colors-neutrals.html b/preview/colors-neutrals.html
deleted file mode 100644
index fb1af6d..0000000
--- a/preview/colors-neutrals.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
diff --git a/preview/colors-semantic.html b/preview/colors-semantic.html
deleted file mode 100644
index 78c45c5..0000000
--- a/preview/colors-semantic.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
Semantic
-
-
Muted semantic colors — they signal, they don't shout. Each pairs with a 10% tint surface and a 25% border.
-
-
diff --git a/preview/components-badges.html b/preview/components-badges.html
deleted file mode 100644
index 2f08d70..0000000
--- a/preview/components-badges.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
Badges & chips
-
- Running
- Degraded
- Down
- Stopped
- New
- v0.14.2
-
-
- self-hosted
- wireguard
- tls
- cli
- + add
-
-
-
diff --git a/preview/components-buttons.html b/preview/components-buttons.html
deleted file mode 100644
index 012ce31..0000000
--- a/preview/components-buttons.html
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
-
-
Buttons · core palette
-
-
-
-
Primary · Signal Red
bg #E60000 · fg #FFFFFF
-
- default
- Open account
- hover
- Open account
- press
- Open account
-
-
-
-
-
Dark · Cod Gray
bg #1C1C1C · fg #FFFFFF
-
- default
- Continue
- hover
- Continue
-
-
-
-
-
Secondary
bg #FFFFFF · border rgba(28,28,28,0.14)
-
- default
- Read more
- hover
- Read more
-
-
-
-
-
Ghost · disabled
bg transparent
-
- default
- Cancel
- hover
- Cancel
- disabled
- Cancel
-
-
-
-
-
-
- Small
- Medium
- Large
-
-
-
-
-
diff --git a/preview/components-cards.html b/preview/components-cards.html
deleted file mode 100644
index fdb803a..0000000
--- a/preview/components-cards.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
Cards
-
-
-
-
-
uptime 14d 02:11
-
memory 48.2 MB
-
req/s 12.4
-
-
-
-
-
-
uptime 03:14
-
memory 112 MB
-
req/s 0.3 ↓
-
-
-
-
Flat by default · 1px border · 4px radius · shadow only on hover for interactive cards.
-
-
diff --git a/preview/components-charts-donut.html b/preview/components-charts-donut.html
deleted file mode 100644
index eda0d3c..0000000
--- a/preview/components-charts-donut.html
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
-
-
Charts · Donut · RadialGauge · proportional + scalar · pure SVG
-
-
-
Donut · resource usage breakdown
-
-
-
-
-
-
-
-
-
- 2.4TB
- total
-
-
- api 38.0%
- db 24.0%
- cache 16.0%
- queue 12.0%
- other 10.0%
-
-
-
-
-
-
-
RadialGauge · capacity · neutral
-
-
Disk capacity
-
-
-
RadialGauge · uptime SLO · good
-
-
30-day SLO
-
-
-
-
Donut: ≤50 segments · click to drill down · RadialGauge tones: neutral / good / warning / bad
-
-
diff --git a/preview/components-charts-line.html b/preview/components-charts-line.html
deleted file mode 100644
index 2ebda54..0000000
--- a/preview/components-charts-line.html
+++ /dev/null
@@ -1,99 +0,0 @@
-
-Charts — Line / Area / Bar
-
-
-
-
-
Charts · Chart (line · area · bar)
-
engine: auto · canvas → webgl → webgpu
-
-
-
-
-
-
-
Request rate · last 24h
-
2 series · 144 points · uPlot canvas
-
-
canvas
-
-
-
-
-
-
-
-
-
-
-
-
requests/sec p99 latency (ms)
-
-
-
-
-
-
-
CPU utilization · 4 services
-
stacked area · 720 points · uPlot canvas
-
-
canvas
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Deployments · last 14 days
-
bar · 14 buckets
-
-
canvas
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/preview/components-charts-radial.html b/preview/components-charts-radial.html
deleted file mode 100644
index a74f12a..0000000
--- a/preview/components-charts-radial.html
+++ /dev/null
@@ -1,123 +0,0 @@
-
-Charts — Sparkline · Donut · Gauge
-
-
-
-
Charts · Sparkline · Donut · RadialGauge
-
-
-
-
Sparklines · embedded in Stat tiles
-
SVG · 80×24 · zero deps
-
-
-
-
Requests / min
-
12.4k
-
-
-
-
-
-
-
-
-
-
Active sessions
-
3,284
-
-
-
-
-
-
-
-
-
-
-
Resource breakdown · cluster usage
-
SVG · clickable segments · accent + mono palette
-
-
-
-
-
-
-
- 847
- cores
-
-
- Compute 45.0%
- Database 25.0%
- Cache 18.0%
- Other 12.0%
-
-
-
-
-
-
-
Radial gauges · capacity indicators
-
SVG · tone: good / warning / bad
-
-
-
-
diff --git a/preview/components-charts-servicemap.html b/preview/components-charts-servicemap.html
deleted file mode 100644
index a6f0731..0000000
--- a/preview/components-charts-servicemap.html
+++ /dev/null
@@ -1,233 +0,0 @@
-
-Charts — ServiceMap
-
-
-
-
Charts · ServiceMap · directed flow · labels reveal on focus
-
-
-
-
-
Production topology
-
cytoscape · cose-bilkent · webgl handoff at 200+ nodes
-
-
canvas
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- http
-
-
-
- http
-
-
-
- http
-
-
-
- grpc
-
-
-
- grpc
-
-
-
- grpc · 5xx
-
-
-
- amqp
-
-
-
- amqp
-
-
-
- sql
-
-
-
- cache
-
-
-
- amqp
-
-
-
- http
-
-
-
- backup
-
-
-
- snapshot
-
-
-
- events
-
-
-
- events
-
-
-
-
-
- load-balancer
- api-gateway
- auth-service
- webhooks
- user-service
- billing
- notifications
- scheduler
- postgres
- redis
- queue
- search
- storage
- analytics
-
-
-
-
-
Hover or tap a service to light its connections and reveal edge labels.
-
-
- healthy
- degraded
- failing
- unknown
- degree
-
-
-
- Nodes 14
- Edges 16
- Min/Max degree 1 / 4
- Latency probe 1s
- Layout cose-bilkent
-
-
-
-
-
-
diff --git a/preview/components-charts-sparkline.html b/preview/components-charts-sparkline.html
deleted file mode 100644
index 8eab4c5..0000000
--- a/preview/components-charts-sparkline.html
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
Charts · Sparkline · embedded in Stat cards · pure SVG, zero deps
-
-
-
-
Requests / min
-
12,481
-
↑ 4.2%
-
-
-
-
-
-
Error rate
-
0.024%
-
↓ 38%
-
-
-
-
-
-
-
P99 latency
-
142ms
-
↑ 3ms
-
-
-
-
-
-
-
-
Sparkline · variants
-
-
-
-
Sparkline auto-fits container · respects accent color · also rendered inline by <Stat>
-
-
diff --git a/preview/components-charts-timeseries.html b/preview/components-charts-timeseries.html
deleted file mode 100644
index 2d40980..0000000
--- a/preview/components-charts-timeseries.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
-
Charts · Time-series · CPU / RPS / latency · uPlot canvas + WebGL2/WebGPU
-
-
-
-
- Line · CPU per node · 24h
-
- 1H 6H 24H 7D
- canvas
-
-
-
-
-
-
-
-
-
-
-
-
-
- 0
- 25
- 50
- 75
- 100
-
- 00:00
- 06:00
- 12:00
- 18:00
- 24:00
-
-
-
-
-
-
-
-
-
-
-
-
-
- node-a
- node-b
- node-c
- 14:42:18 · 78% / 41% / 33%
-
-
-
-
-
-
- Area · Requests / sec · stacked
- webgl
-
-
-
-
-
-
-
- 0
- 5k
- 12k
-
-
-
-
-
-
-
-
- api
- auth
- static
-
-
-
-
-
-
- Bar · Deployments per day
- canvas
-
-
-
-
-
- 0
- 10
- 20
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Apr 22 → today · peak 33 deploys on Apr 27
-
-
-
Performance · uPlot for ≤100k pts (~2ms/frame) · deck.gl WebGL2 path for 100k–1M (~6ms/frame) · WebGPU on supported browsers
-
-
diff --git a/preview/components-charts-treemap.html b/preview/components-charts-treemap.html
deleted file mode 100644
index b1628fe..0000000
--- a/preview/components-charts-treemap.html
+++ /dev/null
@@ -1,79 +0,0 @@
-
-Charts — Treemap
-
-
-
-
Charts · Treemap · 5.4M LOC across 12 services
-
-
-
-
-
Codebase explorer · lines of code
-
d3-hierarchy squarify · canvas2d · quadtree picking
-
-
webgl auto
-
-
-
-
-
-
-
-
-
-
notifications
580k LOC
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Total 5.4M LOC
- Services 12
- Files 43,217
- Hover quadtree O(log n)
-
-
-
-
diff --git a/preview/components-charts-uptime.html b/preview/components-charts-uptime.html
deleted file mode 100644
index 036e1e5..0000000
--- a/preview/components-charts-uptime.html
+++ /dev/null
@@ -1,79 +0,0 @@
-
-Charts — UptimeBar
-
-
-
-
Charts · UptimeBar · 90 day status grid
-
-
-
Service uptime · last 90 days
-
canvas · hover for incident details
-
-
-
api.gateway
-
-
99.98%
-
-
-
postgres.primary
-
-
99.92%
-
-
-
redis.cache
-
-
100.00%
-
-
-
worker.queue
-
-
98.74%
-
-
-
-
- operational
- degraded
- outage
- maintenance
- no data
-
-
-
-
-
diff --git a/preview/components-chat.html b/preview/components-chat.html
deleted file mode 100644
index f22fe68..0000000
--- a/preview/components-chat.html
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
-
-
Chat · bubble · sender · prompts · thinking
-
-
-
-
R
-
- RCS Copilot
- claude-haiku-4-5 · ready
-
-
- ●●● 3 tools
- ⌘K
-
-
-
-
-
-
R
-
Hey — I see audit-shipper just failed in us-east-1. Want me to pull the last 50 log lines or roll back to v0.3.0?
-
-
-
-
JS
-
Pull the logs first. Filter for panic and tls.
-
-
-
-
R
-
-
-
▸ tool · fetch_logs
-
audit-shipper · since=15m · grep="panic|tls" → 4 matches
-
-
- Found 4 hits. The TLS handshake is failing because the cert chain doesn't include the intermediate. panic: x509: unknown authority at 12:14:02.
- Fix: re-issue with --full-chain or pin the intermediate in tls.ca.
-
-
-
-
-
-
-
-
Suggested
-
- Re-issue the cert with full chain
- Roll back to v0.3.0
- Open the runbook for TLS errors
- Page on-call
-
-
-
-
-
-
-
-
diff --git a/preview/components-code.html b/preview/components-code.html
deleted file mode 100644
index 096718f..0000000
--- a/preview/components-code.html
+++ /dev/null
@@ -1,131 +0,0 @@
-
-
-
-
-
-
Code & console · code block · terminal · log tail · diff
-
-
-
Code block · with filename, copy, line numbers, highlight
-
-
- vault.toml
- toml
- ⧉ Copy
-
-
-
1 2 3 4 5 6 7 8 9
-
-# Production vault config
-[server]
-port = 8443
-tls = true
-
-[storage]
-backend = "raft"
-path = "/var/rcs/data"
-replicas = 3
-
-
-
-
Inline: install with curl -fsSL get.rcs.dev | sh or pull from ghcr.io/rcs/vault:v0.14.2 .
-
-
-
-
Terminal · live log tail
-
-
-
-
~/rcs · vault-primary
-
tail -f streaming
-
-
-
14:32:01.412 info listener bound to 0.0.0.0:8443 (tls)
-
14:32:01.418 info raft peer connected: 10.0.1.42
-
14:32:01.420 info raft peer connected: 10.0.1.43
-
14:32:02.001 dbg leader election: term=14 leader=self
-
14:32:14.207 warn slow request: GET /v1/secrets took 1.4s
-
14:32:18.114 err tls handshake failed: x509: unknown authority
-
14:32:18.115 info audit-shipper: 4 hits on grep="panic|tls"
-
14:32:22.500 $ rcs logs vault-primary --since 5m --grep tls
-
-
-
-
-
-
Diff · config change preview
-
-
vault.toml +3 −2 · staged
-
-
12 [storage]
-
13 − backend = "file"
-
13 + backend = "raft"
-
14 − path = "/tmp/data"
-
14 + path = "/var/rcs/data"
-
15 + replicas = 3
-
16
-
-
-
-
-
diff --git a/preview/components-data-display-extras.html b/preview/components-data-display-extras.html
deleted file mode 100644
index 207fed6..0000000
--- a/preview/components-data-display-extras.html
+++ /dev/null
@@ -1,238 +0,0 @@
-
-
-
-
-
-
Data display · tree · avatar · calendar · carousel · collapse · list · qr · timeline · tour
-
-
-
-
Tree
-
-
-
▾ ▦ production12
-
-
▾ ▦ us-east-15
-
-
● vault-primary
-
● tunnel-edge
-
○ webhook-relay
-
-
▸ ▦ eu-west-14
-
▸ ▦ ap-southeast-13
-
-
▸ ▦ staging8
-
▸ ▦ development4
-
-
-
-
-
Avatar
-
-
-
Group · max 4
-
-
JS
-
MK
-
PB
-
RT
-
+8
-
-
QR code
-
-
-
-
-
-
-
Calendar · month view
-
-
-
-
-
Mon
Tue
Wed
Thu
Fri
Sat
Sun
-
30
31
1
2 deploy
3
4
5
-
6
7 incident
8
9
10 deploy
11
12
-
13
14
15
16 deploy
17
18
19
-
20
21
22 audit
23
24
25
26 today
-
27
28
29
30
1
2
3
-
-
-
-
-
-
-
-
Carousel
-
-
-
Self-host without the ops tax
-
Deploy in one command. We handle TLS, autoscale, and rolling restarts.
-
-
-
-
Image
-
PLACEHOLDER · 1024×640
-
-
-
Collapse
-
-
-
▾ Environment variables12
-
DATABASE_URL · REDIS_URL · TLS_CERT · SECRET_KEY · …
-
-
-
-
-
▸ Build & cachedefault
-
-
-
-
-
-
-
-
List
-
-
-
JS
Jordan Smith
jordan@rcs.dev · admin
-
MK
Maya Kim
maya@rcs.dev · member
-
PB
Priya Banerjee
priya@rcs.dev · member
-
RT
Renee Tan
renee@rcs.dev · viewer
-
-
-
-
-
Timeline
-
-
-
14:32 · today
Deployed v0.14.2 to us-east-1
-
12:14 · today
audit-shipper failed: TLS handshake error
-
09:01 · today
Maya Kim invited 2 members
-
yesterday
Rotated production secrets
-
3 days ago
Migrated webhook-relay → v1.2.0
-
-
-
-
-
-
-
Tour · onboarding spotlight
-
-
-
+ Deploy
-
-
Deploy your first service
-
Click here to spin up a service from a Git repo or a container image.
-
-
Step 1 of 4
-
- Skip
- Next
-
-
-
-
-
-
-
diff --git a/preview/components-data-entry.html b/preview/components-data-entry.html
deleted file mode 100644
index 47a361b..0000000
--- a/preview/components-data-entry.html
+++ /dev/null
@@ -1,277 +0,0 @@
-
-
-
-
-
-
Data entry · date · time · upload · slider · rate · cascader · autocomplete · mentions · color · transfer
-
-
-
-
DatePicker
-
-
2026-04-26 📅
-
-
‹ April 2026 ›
-
-
M
T
W
T
F
S
S
-
30
31
1
2
3
4
5
-
6
7
8
9
10
11
12
-
13
14
15
16
17
18
19
-
20
21
22
23
24
25
26
-
27
28
29
30
1
2
3
-
-
-
-
-
-
-
-
-
Color picker
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Rate
-
★ ★ ★ ★ ★
-
-
-
-
-
-
-
Upload · drag & drop
-
-
-
↑
-
Drop files here or click to upload
-
PNG, JPG, PDF · up to 25 MB
-
-
-
▦ deploy-config.yaml 4.2 KB ✓
-
▦ audit-2026-04.pdf 12.4 MB 64%
-
-
-
-
-
Slider
-
-
Memory limit 2.5 GB
-
-
0 2 4 6 8
-
-
Replicas (range) 3 → 7
-
-
-
-
-
-
-
-
Cascader
-
-
us / east / us-east-1 ›
-
-
-
Americas ›
-
Europe ›
-
Asia Pacific ›
-
-
-
United States ›
-
Canada ›
-
Brazil ›
-
-
-
us-east-1 (N. Virginia)
-
us-east-2 (Ohio)
-
us-west-1 (N. Cal.)
-
us-west-2 (Oregon)
-
-
-
-
-
-
AutoComplete
-
-
-
-
-
vau lt-primaryus-east-1
-
vau lt-replica-eueu-west-1
-
vau lt-archiveus-west-2
-
-
-
Mentions
-
- Hey
@miguel , can you look at the
@audit-shipper alert?
-
-
M miguel.santos
-
M maya.kim
-
M marcus.lee
-
-
-
-
-
-
-
-
Transfer
-
-
-
-
Available · 4 2 selected
-
-
-
- ›
- ‹
-
-
-
Granted · 3 0 selected
-
-
-
-
-
-
-
diff --git a/preview/components-data.html b/preview/components-data.html
deleted file mode 100644
index 1e85738..0000000
--- a/preview/components-data.html
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-
-
-
-
Data display · stats · skeleton · progress · tooltip · descriptions
-
-
-
-
-
Requests / min
12.4k
↓ 8.2%
-
Failed deploys
2
last: 22m ago
-
-
-
-
-
-
-
-
Descriptions
-
-
- name vault-primary
- version v0.14.2
- region us-east-1
- status ● running
-
-
-
-
-
-
-
Empty state
-
-
-
-
-
No services deployed yet
-
Deploy your first service with rcs deploy.
-
+ Deploy service
-
-
-
-
diff --git a/preview/components-feedback-extras.html b/preview/components-feedback-extras.html
deleted file mode 100644
index 27d6df9..0000000
--- a/preview/components-feedback-extras.html
+++ /dev/null
@@ -1,169 +0,0 @@
-
-
-
-
-
-
Feedback extras · result · spin · watermark · popconfirm · notification · banner
-
-
-
-
Result · success
-
-
-
✓
-
Deployment successful
-
vault-primary v0.14.2 is live in us-east-1.
-
View logs Open service
-
-
-
-
-
Result · error
-
-
-
✕
-
Deployment failed
-
Health check timed out after 60s. Logs available below.
-
View logs Retry
-
-
-
-
-
Result · 404
-
-
-
404
-
Service not found
-
That service may have been deleted or you don't have access.
-
Back Dashboard
-
-
-
-
-
-
-
-
-
Watermark
-
-
-
RCS · CONFIDENTIAL · RCS · CONFIDENTIAL
-
RCS · CONFIDENTIAL · RCS · CONFIDENTIAL
-
-
Production secrets export
-
Generated for jordan@rcs.dev · audit-id: 4f2c-9b1e
-
DATABASE_URL=postgres://… REDIS_URL=redis://… TLS_CERT=-----BEGIN…
-
-
-
-
-
-
-
-
-
Popconfirm
-
-
Delete service
-
-
! Delete vault-primary?
-
This action cannot be undone.
-
Cancel Delete
-
-
-
-
-
Notification stack (top-right)
-
-
-
✓
-
Deploy succeeded vault-primary is live · 2.3s
-
×
-
-
-
!
-
Cert expires soon vault.rcs.dev expires in 7 days. Renew now.
-
×
-
-
-
✕
-
audit-shipper failed panic: x509 unknown authority. Check the cert chain.
-
×
-
-
-
-
-
-
-
Banner · global announcement
-
-
-
-
diff --git a/preview/components-feedback.html b/preview/components-feedback.html
deleted file mode 100644
index f1a1d24..0000000
--- a/preview/components-feedback.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
-
Feedback · alert · modal · drawer · toast
-
-
-
i New version available
v0.14.3 ships with TLS 1.3 by default. Update with rcs upgrade.
×
-
✓ Deployed in 2.3s
vault-primary v0.14.2 is live in us-east-1.
×
-
! Certificate expires in 7 days
Renew now or enable auto-renewal in Settings.
×
-
✕ Connection refused
tunnel-edge cannot reach the upstream. Check the port binding and firewall rules.
×
-
-
-
-
-
Modal
-
-
-
-
Delete vault-primary?
- ×
-
-
This will permanently remove the service and all its secrets. This action cannot be undone.
-
- Cancel
- Delete
-
-
-
-
-
-
Drawer (right)
-
-
-
-
-
Service details
- ×
-
-
-
name vault-primary
-
version v0.14.2
-
port 8443
-
uptime 14d 6h
-
-
-
-
-
-
-
-
Toast (bottom-right)
-
-
- ✓
- Configuration saved
- undo
-
-
- ✕
- Failed to deploy — check the logs.
-
-
-
-
-
diff --git a/preview/components-form.html b/preview/components-form.html
deleted file mode 100644
index e714c23..0000000
--- a/preview/components-form.html
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-
-
-
-
Form & inputs
-
-
-
-
Service name *
-
-
-
Lowercase, hyphens allowed. 3–32 characters.
-
-
-
-
-
Tags
-
-
- self-hosted ×
- tls ×
- production ×
- add tag…
-
-
-
-
-
Port
-
-
-
✕ Port must be a number between 1 and 65535.
-
-
-
-
-
Visibility
-
- Private
- Team
- Public
-
-
-
-
Features
-
- TLS
- Audit log
- Metrics export
- Webhooks
-
-
-
-
-
-
diff --git a/preview/components-inputs-extras.html b/preview/components-inputs-extras.html
deleted file mode 100644
index f59e3ee..0000000
--- a/preview/components-inputs-extras.html
+++ /dev/null
@@ -1,221 +0,0 @@
-
-
-
-
-
-
Inputs extras · number · pin · icon button · kbd · status · combobox · chips · file · toggle tip
-
-
-
-
NumberInput
-
-
-
-
replicas
-
-
min 1 · max 16
-
-
-
-
-
-
PinInput · OTP / 2FA
-
-
-
-
-
-
-
IconButton · variants & sizes
-
-
- ⚙
- ▶
- ✕
- ⋯
- ?
- ↑
-
-
- ⚙
- ⚙
- ⚙
- sm · md · lg
-
-
-
-
-
Kbd · keyboard shortcuts
-
-
Open command menu⌘ K
-
Quick deploy⇧ ⌘ D
-
Search/
-
Toggle theme⌘ .
-
-
-
-
-
-
-
Status indicators
-
- Running
- Degraded
- Failed
- Idle
- Live · streaming
- Stopped
-
-
-
-
Choice chips · filter
-
-
- All×
- Production
- us-east-1×
- eu-west-1
- ap-southeast-1
- + tag
-
-
File trigger
-
- 📎 Attach file
- deploy-config.yaml · 4.2 KB
-
-
-
-
-
-
-
-
Combobox · multi-select with search
-
-
-
- read:logs×
- read:metrics×
- deploy:services×
-
-
-
-
write:secretsscope
-
write:configsscope
-
admin:billingscope · admin
-
-
-
-
-
-
Toggle tip · rich hover card
-
-
- API rate limit
-
- i
-
- Per-token rate limit
- Tokens are capped at 1k req/min. Exceed and you get a 429. Bursts up to 200/sec are allowed.
-
-
-
-
-
-
-
-
diff --git a/preview/components-inputs.html b/preview/components-inputs.html
deleted file mode 100644
index 22df678..0000000
--- a/preview/components-inputs.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
Inputs
-
-
-
Service name
-
-
Lowercase, hyphens only.
-
-
-
Port
-
-
Default 8443
-
-
-
-
-
-
Secret
-
-
Must be at least 32 characters.
-
-
-
-
diff --git a/preview/components-layout.html b/preview/components-layout.html
deleted file mode 100644
index a80ac2a..0000000
--- a/preview/components-layout.html
+++ /dev/null
@@ -1,168 +0,0 @@
-
-
-
-
-
-
Layout · shell · divider · grid · space · splitter · fab · affix
-
-
-
App shell · header + sider + content + footer
-
-
-
-
RCS·
-
Services Logs Activity Settings
-
⌘K JS
-
-
-
Production
-
▦ vault-primary
-
▦ tunnel-edge
-
▦ webhook-relay
-
Staging
-
▦ vault-staging
-
▦ tunnel-stg
-
-
-
vault-primary
-
us-east-1 · v0.14.2 · running
-
-
-
-
-
-
-
-
-
-
Grid · 12 columns · 6/24 gutter
-
-
-
-
Splitter · resizable panes
-
-
$ ls -la /etc/rcs drwxr-xr-x config/ drwxr-xr-x secrets/ -rw-r--r-- vault.toml -rw-r--r-- tunnel.toml
-
-
-
vault.toml
-
[server] port = 8443 tls = true [storage] backend = "raft"
-
-
-
-
-
-
-
-
Divider
-
-
Plain horizontal
-
-
section · production
-
v0.14.2
us-east-1
14d uptime
-
-
-
-
Space · inline + wrap
-
-
running tls audit v0.14.2
-
running tls audit
-
production staging development
-
-
-
-
-
-
-
Float button · BackTop
-
-
-
-
Affix · sticky on scroll
-
-
vault-primary · overview affixed
-
As the user scrolls down a long page, the header above stays pinned to the top of the viewport. Use Affix for breadcrumbs, action bars, table headers, or anything that should remain visible during scroll.
-
-
-
-
-
diff --git a/preview/components-markdown.html b/preview/components-markdown.html
deleted file mode 100644
index 2831995..0000000
--- a/preview/components-markdown.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
Markdown · headings · lists · code · tables · blockquote · callouts · tasks
-
-
Deploy your first service
-
Self-host any RCS service in under three minutes. No SaaS, no telemetry, no tax.
-
-
Install
-
RCS ships as a single binary. Pick your platform:
-
bash ⧉ copy
-
curl -fsSL get.rcs.dev | sh
-rcs --version
-# rcs 0.14.2 (linux/amd64)
-
-
Or pull the container image directly: ghcr.io/rcs/vault:v0.14.2.
-
-
Configure
-
Drop a vault.toml next to the binary. The minimum viable config:
-
vault.toml ⧉ copy
-
[server]
-port = 8443
-tls = true
-
-[storage]
-backend = "raft"
-replicas = 3
-
-
i Tip
Use
rcs config validate before starting — it catches bad TLS chains and missing peers.
-
-
Pre-flight checklist
-
-
-
Supported regions
-
- Region Code Latency p50 Status
-
- N. Virginia us-east-114ms ● running
- Frankfurt eu-central-122ms ● running
- Singapore ap-southeast-138ms ● degraded
-
-
-
-
Shortcuts
-
Open the command menu with ⌘ K , deploy with ⇧ ⌘ D .
-
-
RCS gives you back ownership of your stack. Self-host without the ops tax.
-
-
! Heads up
v0.14 changed the default storage backend from
file to
raft. Run
rcs migrate before upgrading.
-
-
-
See also
-
- Production checklist
- TLS & certificates
- Backups & disaster recovery
-
-
-
-
diff --git a/preview/components-menu.html b/preview/components-menu.html
deleted file mode 100644
index 45294fe..0000000
--- a/preview/components-menu.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
Menu
-
-
Service
-
- ▸
- Restart service
- ⌘ R
-
-
- ✎
- Edit configuration
- ⌘ E
-
-
- ↗
- Open logs
- ⌘ L
-
-
-
- ✕
- Remove
-
-
-
-
diff --git a/preview/components-navigation.html b/preview/components-navigation.html
deleted file mode 100644
index f175242..0000000
--- a/preview/components-navigation.html
+++ /dev/null
@@ -1,166 +0,0 @@
-
-
-
-
-
-
Navigation · steps · pagination · menu · anchor · dropdown
-
-
-
Steps · horizontal
-
-
-
✓
Connect repo
github.com/rcs/vault
-
-
-
-
-
-
-
-
-
-
Steps · vertical
-
-
-
-
-
●
Starting workers
3/8 ready
-
-
-
-
-
-
-
-
-
-
-
Pagination
-
-
- ‹
- 1
- 2
- 3
- 4
- …
- 12
- ›
- 20 / page
-
-
Mini
-
- ‹
- 2 / 12
- ›
-
-
Dropdown
-
- Actions ▾
-
-
-
-
-
-
-
diff --git a/preview/components-pageheader.html b/preview/components-pageheader.html
deleted file mode 100644
index 67c8de2..0000000
--- a/preview/components-pageheader.html
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
-
Page header · breadcrumb · actions
-
-
-
-
-
-
-
vault-primary
- ● running
- v0.14.2
-
-
Self-hosted secrets vault · us-east-1 · last deploy 2h ago
-
-
- ⋯
- Logs
- Restart
- Deploy
-
-
-
-
-
-
-
-
Team members
- + Invite
-
-
-
-
diff --git a/preview/components-rte.html b/preview/components-rte.html
deleted file mode 100644
index e6ad3b8..0000000
--- a/preview/components-rte.html
+++ /dev/null
@@ -1,253 +0,0 @@
-
-
-
-
-
-
Rich text editor · toolbar · slash menu · bubble menu · blocks
-
-
-
-
-
-
-
- Heading 1
-
-
- B
- I
- U
- S
- { }
- ●
-
-
- ≡
- 1.
- ✓
- "
- —
-
-
- 🔗
- @
- ▣
- </>
- ⊞
-
-
- ↤
- ↔
- ↦
-
-
- ↶⌘Z
- ↷
-
-
-
-
-
-
Production runbook · vault-primary
-
When the primary fails over, follow these steps before paging on-call. Most incidents resolve once raft consensus rebuilds — don't restart blindly .
-
-
Owners
-
Reach out to @jordan.k or @priya.r . Tag the incident with #sev2 if degraded for > 5 minutes.
-
-
Pre-flight
-
-
-
If raft status reports a split brain, do not force-promote a replica. Open a SEV1 bridge first.
-
-
Failover snippet
-
-# promote replica-a if primary is unreachable for > 60s
-rcs raft promote "vault-replica-a" --confirm
-rcs deploy --region us-east-1 --version "v0.14.2"
-
-
-
Recent incidents
-
- Date Severity Resolution
-
- 2026-04-18 SEV2 raft re-quorum, 4m
- 2026-03-02 SEV3 tls renew, no impact
- 2026-02-09 SEV1 storage migration
-
-
-
-
-
-
-
- 1,402 chars · 248 words
- markdown · gfm
-
-
- jordan.k editing
- Saved · 12:42:18
-
-
-
-
-
-
- B
- I
- U
- 🔗
- "
- ●
-
-
-
-
-
-
-
-
-
Toolbar variants
-
-
-
Compact · inline
-
- B
- I
- U
- { }
- 🔗
-
-
-
-
Single-line · with placeholder
-
-
- B
- I
- 🔗
- @
-
-
Leave a comment…
-
-
-
-
-
-
-
-
API
-
-
<RichTextEditor value placeholder onChange // gfm markdown round-trips />
-
toolbar="full | compact | inline" collab="off | live" slashMenu bubbleMenu
-
blocks: heading · paragraph · list · task · quote · code · table · image · mention · tag
-
marks: bold · italic · underline · strike · code · highlight · link
-
shortcuts: ⌘B / ⌘I / ⌘U / ⌘E / ⌘K / ⌘Z · markdown shortcuts (#, *, >, ```)
-
-
-
-
diff --git a/preview/components-space-scroll.html b/preview/components-space-scroll.html
deleted file mode 100644
index 3986921..0000000
--- a/preview/components-space-scroll.html
+++ /dev/null
@@ -1,223 +0,0 @@
-
-
-
-
-
-
Space & ScrollDiv · alignment + contained scroll
-
-
-
-
<Space> · horizontal · sizes xs · sm · md · lg · xl
-
-
xs · 4 item item item
-
sm · 8 item item item
-
md · 12 item item item
-
lg · 16 item item item
-
xl · 24 item item item
-
-
-
-
-
-
<Space direction="vertical">
-
-
- Deploy now
- Schedule deploy
- View diff
- Cancel rollout
-
-
-
-
-
<Space> · justify · between
-
-
- vault-primary
- Logs Restart
-
-
-
-
-
-
-
-
-
<Space split=<Divider/>>
-
-
- Edit Duplicate Delete
-
-
-
-
-
<Space wrap> · responsive tag bar
-
-
- prod us-east-1 v0.14.2
- raft tls 3 replicas
- audit + tag
-
-
-
-
-
-
-
<Space align="baseline"> · mixed type sizes line up on baseline
-
-
- 2.4k
- requests / min
- ▲ 12%
-
-
-
-
-
-
-
<ScrollDiv> · vertical · contained · sticky head · fade edges
-
-
page does not scroll · only the inner list does
-
-
-
overscroll-behavior: contain · -webkit-overflow-scrolling: touch · 8px thumb
-
-
-
-
-
<ScrollDiv direction="x"> · horizontal card track
-
-
drag → · contained, won't pull the whole page
-
-
-
-
-
-
-
<ScrollDiv direction="both"> · large data grid in a fixed window
-
-
scrolls in both axes · sticky table head · contained bounce
-
-
-
-
-
API
-
-
<Space direction "horizontal" | "vertical" size xs|sm|md|lg|xl|number align start|center|end|baseline wrap split />
-
<ScrollDiv direction "y" | "x" | "both" height number|css shadow contain />
-
-
-
-
diff --git a/preview/components-table.html b/preview/components-table.html
deleted file mode 100644
index b120fd3..0000000
--- a/preview/components-table.html
+++ /dev/null
@@ -1,99 +0,0 @@
-
-
-
-
-
-
Table · sortable · selectable · sticky · dense + comfortable
-
-
-
-
-
+ Filter
-
2 selected
-
- comfortable
- compact
-
-
-
-
-
-
-
-
Empty state
-
-
-
-
[ ]
-
No services match your filter
-
Clear filters or deploy your first service.
-
-
-
-
-
diff --git a/preview/components-tabs.html b/preview/components-tabs.html
deleted file mode 100644
index b2b3aed..0000000
--- a/preview/components-tabs.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
Tabs · line · card · segmented
-
-
-
Line · default
-
-
Overview
-
Logs 128
-
Configuration
-
Activity
-
Billing
-
-
-
-
-
Card
-
-
Production
-
Staging
-
Development
-
-
-
-
-
-
Segmented
-
-
All
-
Running
-
Stopped
-
Failed
-
-
-
-
diff --git a/preview/components-terminal.html b/preview/components-terminal.html
deleted file mode 100644
index e30c3f9..0000000
--- a/preview/components-terminal.html
+++ /dev/null
@@ -1,167 +0,0 @@
-
-
-
-
-
-
xterm.js terminal · ANSI · tabs · search · status bar
-
-
-
-
-
-
vault-primary · /etc/rcs
-
zsh · 80×24 tmux 0:1
-
-
- ▸ vault-primary ×
- ▸ tunnel-edge ×
- ▸ logs:audit ×
- +
-
-
-
jordan @ops :~/rcs (main) ❯ rcs status vault-primary
-
-
SERVICE REGION VERSION STATUS UPTIME
-
vault-primary us-east-1 v0.14.2 ● running 14d 6h
-
-
jordan @ops :~/rcs (main) ❯ rcs deploy vault-primary --region us-east-1
-
→ pulling image ghcr.io/rcs/vault:v0.14.2
-
[████████████████████████ ──────── ] 72% 18.4 MB/25.6 MB eta 2s
-
→ pulled in 4.2s
-
→ migrating storage backend file → raft
-
✓ vault.toml applied
-
✓ peers.toml applied (3 peers)
-
✓ tls.pem validated (full chain)
-
→ starting vault-primary ...
-
[14:32:01.412] INFO listener bound to 0.0.0.0:8443 (tls)
-
[14:32:01.418] INFO raft peer connected: 10.0.1.42
-
[14:32:01.420] INFO raft peer connected: 10.0.1.43
-
[14:32:14.207] WARN slow request: GET /v1/secrets took 1.4s
-
[14:32:18.114] ERR tls handshake failed: x509: unknown authority
-
[14:32:18.115] INFO audit-shipper: 4 hits on grep="panic|tls"
-
-
✓ deployed in 2.3s · https://vault.rcs.dev
-
-
jordan @ops :~/rcs (main) ❯ rcs logs vault-primary --since 5m --grep tls
-
-
- ⎇ main
- ○ clean
- utf-8
- LF
- zsh
- Ln 24, Col 53 · 2 tabs · ⌘F to search
-
-
-
- ⌕
-
- 2 / 4
- ‹
- ›
- ×
-
-
-
-
-
-
ANSI palette · 8 + bold
-
-
-
red bold red
-
green bold green
-
yellow bold yellow
-
blue bold blue
-
magenta bold magenta
-
cyan bold cyan
-
white bold white
-
dim underline reverse
-
-
-
-
-
Inline progress · sparkbar · spinner
-
-
-
building ⠋ webpack 5.91 · 14% modules
-
[1/4] ✓ pull [██████████ ] 100%
-
[2/4] ✓ migrate [██████████ ] 100%
-
[3/4] ▸ deploy [█████████ ─ ] 92%
-
[4/4] ○ verify [────────── ] 0%
-
-
cpu ▁▂▃▅▆▇█▇▆▅▃▂▁
-
mem ▂▃▃▄▄▅▅▆▆▆▆▅▅
-
net ▁▁▂▂▃▃▄▅▆▇█▇▅
-
-
-
-
-
-
diff --git a/preview/responsive-check.html b/preview/responsive-check.html
deleted file mode 100644
index 6a3c6ed..0000000
--- a/preview/responsive-check.html
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-
-
-Responsive · device check
-
-
-
-
-
- Responsive component check
- device
-
- Galaxy S24 · 360 × 780
- Galaxy S24 Ultra · 412 × 915
- iPhone 15 · 393 × 852
- iPhone 15 Pro Max · 430 × 932
- iPad mini · 744 × 1133
- iPad Pro 11" · 834 × 1194
- iPad Pro 13" landscape · 1024 × 1366
- Desktop · 1280 × 820
- Desktop · 1440 × 900
-
- card
-
- components-buttons
- components-form
- components-inputs-extras
- components-data
- components-table
- components-data-entry
- components-navigation
- components-layout
- components-feedback
- components-feedback-extras
- components-data-display-extras
- components-cards
- components-chat
- components-tabs
- components-menu
- components-pageheader
- components-code
- components-markdown
- components-terminal
- components-badges
- components-inputs
-
- 393 × 852
-
-
-
-
-
-
diff --git a/preview/spacing-radii.html b/preview/spacing-radii.html
deleted file mode 100644
index e4e72b4..0000000
--- a/preview/spacing-radii.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
Radii
-
-
-
-
xs · 2
-
inline code
-
-
-
-
-
-
-
full
-
avatars, pills
-
-
-
-
diff --git a/preview/spacing-scale.html b/preview/spacing-scale.html
deleted file mode 100644
index ef5868d..0000000
--- a/preview/spacing-scale.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
Spacing · 4px base
-
-
All spacing is a multiple of 4. 8-point grid governs layout; 4-point for internals. Section rhythm: 64–96px.
-
-
diff --git a/preview/spacing-shadows.html b/preview/spacing-shadows.html
deleted file mode 100644
index eed7acd..0000000
--- a/preview/spacing-shadows.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
Elevation · shadows
-
-
Shadows are structural, not decorative. Borders do most of the work.
-
-
diff --git a/preview/type-body.html b/preview/type-body.html
deleted file mode 100644
index 3f4c255..0000000
--- a/preview/type-body.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
Type · body & small
-
-
-
A single binary. No daemon, no broker.
-
h3 · 22/1.25 · –0.014em · 500
-
-
-
RandomCodeSpace ships as a statically-linked binary under 12 MB. It starts in 180 ms, handles its own TLS, and stores state in a local SQLite file you can rsync anywhere.
-
body · 15/1.55 · 0 · 400 — with inline code
-
-
-
Last updated 3 days ago · 4 contributors · v0.14.2
-
small · 13/1.5 · metadata
-
-
-
01 — Installation
-
micro · 11/1.4 · +0.04em · uppercase mono — section eyebrows
-
-
-
-
diff --git a/preview/type-display.html b/preview/type-display.html
deleted file mode 100644
index 16fc3a9..0000000
--- a/preview/type-display.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
Type · display & headings
-
-
-
Tools you own.
-
display · 64/1.02 · –0.035em · 600
-
-
-
Self-host in three minutes
-
h1 · 44/1.06 · –0.028em · 600
-
-
-
Services, logs, and secrets
-
h2 · 32/1.12 · –0.022em · 600
-
-
-
-
diff --git a/preview/type-mono.html b/preview/type-mono.html
deleted file mode 100644
index 751b4cf..0000000
--- a/preview/type-mono.html
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
Type · mono & code
-
-
-
- terminal
-
-
-
-$ curl -sSL rcs.sh/install | sh
-→ fetching rcs v0.14.2...
-→ verifying signature...
-✓ installed to /usr/local/bin/rcs
-
-$ rcs serve --port 8443
-listening on https://0.0.0.0:8443
-
-
-
- ⌘
- K
- open command menu
- ·
- v0.14.2
- ·
- sha: 4f2a9c1
-
-
-
diff --git a/preview/typescript-types.html b/preview/typescript-types.html
deleted file mode 100644
index 69dd758..0000000
--- a/preview/typescript-types.html
+++ /dev/null
@@ -1,356 +0,0 @@
-
-
-
-
-TypeScript types · RandomCodeSpace DS
-
-
-
-
-
- TypeScript types · component reference
- Strongly-typed prop interfaces for every component in the RandomCodeSpace design system. Pure types — pair with your runtime implementations.
-
- strict: true
- noUncheckedIndexedAccess: true
- exactOptionalPropertyTypes: true
- react ≥ 18
- 30 components · 9 token types
-
-
-
-
- tokens
- Button
- Input
- Select / Combobox
- Space / ScrollDiv
- Table
- Chat
- RichTextEditor
- Terminal
- CodeBlock
- toast
- all components
-
-
-
-
-
- tokens
Design token types src/tokens.ts
-export type SpaceSize = "xs" | "sm" | "md" | "lg" | "xl" | number ;
-export type Radius = "none" | "sm" | "md" | "lg" | "pill" | "circle" | number ;
-export type Size = "xs" | "sm" | "md" | "lg" ;
-export type Density = "comfortable" | "default" | "compact" ;
-export type ThemeMode = "light" | "dark" ;
-export type Direction = "horizontal" | "vertical" ;
-export type Axis = "x" | "y" | "both" ;
-export type Align = "start" | "center" | "end" | "baseline" | "stretch" ;
-export type Justify = "start" | "center" | "end" | "between" | "around" | "evenly" ;
-
-
-
-
-
-
-
- select
Select<V> · Combobox<V> generic over value type
-// Generic preserves value type from options through to onChange
-export interface SelectOption <V extends string | number = string > {
- readonly label: string ;
- readonly value: V;
- readonly disabled? : boolean ;
-}
-
-export interface SelectProps <V extends string | number = string > extends BaseProps {
- readonly options: readonly SelectOption <V>[];
- readonly value? : V;
- readonly onChange? : (value: V, option: SelectOption <V>) => void ;
-}
-
-// Usage — V is inferred from options literal
-type Region = "us-east-1" | "eu-central-1" | "ap-southeast-1" ;
-const regions: readonly SelectOption <Region >[] = [
- { label: "N. Virginia" , value: "us-east-1" },
- { label: "Frankfurt" , value: "eu-central-1" },
-];
-<Select options={regions} onChange={(v) => console.log(v)} />
- // ↑ v is `Region`, not `string`
-
-
-
- layout
Space · ScrollDiv layout primitives
-export interface SpaceProps extends BaseProps {
- readonly direction? : Direction ;
- readonly size? : SpaceSize ; // xs|sm|md|lg|xl|number
- readonly align? : Align ;
- readonly justify? : Justify ;
- readonly wrap? : boolean ;
- readonly split? : ReactNode ;
- readonly children: ReactNode ;
-}
-
-export interface ScrollDivProps extends BaseProps {
- readonly direction? : Axis ; // "x" | "y" | "both"
- readonly height? : number | string ;
- readonly shadow? : boolean ;
- readonly contain? : boolean ; // overscroll-behavior: contain
- readonly children: ReactNode ;
- readonly onScroll? : (s: { scrollTop: number ; atTop: boolean ; atBottom: boolean }) => void ;
-}
-
-
-
- data
Table<T> generic over row type · narrowed render
-export interface TableColumn <T extends object , K extends keyof T = keyof T> {
- readonly key: string ;
- readonly title: ReactNode ;
- readonly dataKey? : K;
- readonly width? : number | string ;
- readonly align? : "left" | "center" | "right" ;
- readonly sortable? : boolean ;
- readonly sticky? : "left" | "right" ;
- readonly render? : (value: T[K], row: T, index: number ) => ReactNode ;
-} // ↑ value type narrows to T[K]
-
-// Usage
-interface Service { id: string ; region: Region ; cpu: number ; }
-
-const columns: readonly TableColumn <Service >[] = [
- { key: "id" , title: "ID" , dataKey: "id" },
- { key: "region" , title: "Region" , dataKey: "region" },
- { key: "cpu" , title: "CPU" , dataKey: "cpu" ,
- render: (cpu) => ` ${cpu}%` // ↑ cpu: number, no `as`
- },
-];
-
-<Table <Service > columns={columns} data={services} rowKey="id" />
-
-
-
- chat
Chat streaming + attachments
-export type ChatRole = "user" | "assistant" | "system" | "tool" ;
-
-export interface ChatMessage {
- readonly id: string ;
- readonly role: ChatRole ;
- readonly content: ReactNode ;
- readonly status? : "sending" | "sent" | "error" | "streaming" ;
- readonly attachments? : readonly { name: string ; size: number ; url? : string }[];
-}
-
-export interface ChatProps extends BaseProps {
- readonly messages: readonly ChatMessage [];
- readonly streaming? : boolean ;
- readonly onSend? : (text: string , attachments: readonly File []) => void | Promise <void >;
- readonly onStop? : () => void ;
-}
-
-
-
- rte
RichTextEditor collab + slash + bubble
-export interface RichTextEditorProps extends BaseProps {
- readonly value? : string ; // gfm markdown
- readonly toolbar? : "full" | "compact" | "inline" | "none" ;
- readonly slashMenu? : boolean ;
- readonly bubbleMenu? : boolean ;
- readonly mentionsSource? : (q: string ) => Promise <readonly { id: string ; label: string }[]>;
- readonly collab? : { room: string ; user: { id: string ; name: string ; color?: string } };
- readonly onChange? : (markdown: string ) => void ;
-}
-
-
-
- terminal
Terminal discriminated line types
-export interface TerminalLine {
- readonly type: "stdout" | "stderr" | "info" | "warn" | "error" | "debug" | "prompt" ;
- readonly text: string ; // ANSI sequences allowed
- readonly timestamp?: Date ;
-}
-
-export interface TerminalProps extends BaseProps {
- readonly lines: readonly TerminalLine [];
- readonly tabs?: readonly { key: string ; label: string ; active?: boolean }[];
- readonly streaming?: boolean ;
- readonly searchable?: boolean ;
- readonly onInput?: (cmd: string ) => void ;
- readonly onTabChange?: (key: string ) => void ;
-}
-
-
-
- code
CodeBlock · Markdown literal language union
-export type CodeLanguage =
- | "ts" | "tsx" | "js" | "jsx"
- | "json" | "yaml" | "toml"
- | "bash" | "sh" | "zsh"
- | "py" | "go" | "rust"
- | "html" | "css" | "sql"
- | "diff" | "plain" ;
-
-export interface CodeBlockProps extends BaseProps {
- readonly code: string ;
- readonly language?: CodeLanguage ; // ← typo-proof
- readonly filename?: string ;
- readonly showLineNumbers?: boolean ;
- readonly highlightLines?: readonly number [];
- readonly copyable?: boolean ;
- readonly onCopy?: () => void ;
-}
-
-
-
- imperative
toast api imperative · global
-export interface ToastApi {
- show(opts: ToastOptions ): string ;
- dismiss(id: string ): void ;
- promise<T>(p: Promise <T>, msgs: { loading: string ; success: string ; error: string }): Promise <T>;
-}
-
-// Usage
-await toast.promise(rcs.deploy("vault-primary" ), {
- loading: "Deploying…" ,
- success: "Deployed." ,
- error: "Deploy failed." ,
-});
-
-
-
- surface
Full export surface 30 components
-
-
Button.tsx
-
IconButton.tsx
-
ButtonGroup.tsx
-
Input.tsx
-
NumberInput.tsx
-
PinInput.tsx
-
Textarea.tsx
-
Select<V>.tsx
-
Combobox<V>.tsx
-
Checkbox.tsx
-
RadioGroup<V>.tsx
-
Switch.tsx
-
Slider.tsx
-
DatePicker.tsx
-
DateRangePicker.tsx
-
FileUpload.tsx
-
FormField.tsx
-
Badge.tsx
-
StatusDot.tsx
-
Card.tsx
-
Space.tsx
-
ScrollDiv.tsx
-
Divider.tsx
-
Grid.tsx
-
Tabs<K>.tsx
-
Menu<K>.tsx
-
Breadcrumb.tsx
-
Pagination.tsx
-
Steps.tsx
-
Alert.tsx
-
Modal.tsx
-
Drawer.tsx
-
Progress.tsx
-
Skeleton.tsx
-
Spin.tsx
-
Tooltip.tsx
-
Table<T>.tsx
-
Stat.tsx
-
Avatar.tsx
-
Timeline.tsx
-
Chat.tsx
-
CodeBlock.tsx
-
Markdown.tsx
-
Terminal.tsx
-
RichTextEditor.tsx
-
PageHeader.tsx
-
AppShell.tsx
-
ThemeProvider.tsx
-
toastapi
-
-
-
-
-
diff --git a/scripts/build-docs.mjs b/scripts/build-docs.mjs
index 31c7585..dd2cc57 100644
--- a/scripts/build-docs.mjs
+++ b/scripts/build-docs.mjs
@@ -8,7 +8,6 @@
* /index.html (site landing)
* /site.css (shared header/footer + global)
* /apps/index.html (sample apps gallery)
- * /preview/index.html (brand spec cards index)
* /dist/styles.css (concat colors_and_type.css + src/styles.css)
* /docs/index.html (component reference, card grid)
* /docs/docs.css (per-component page styles)
@@ -22,8 +21,8 @@
* src/index.tsx (runtime export → category file)
* src/charts/index.ts (charts subpath exports — "Charts" category)
*
- * The Pages workflow stages assets/, preview/*.html, ui_kits/, then runs
- * this script (which overwrites /preview/index.html with a styled one).
+ * Every component page renders the live React component via the IIFE
+ * bundle plus Babel-standalone. There are no hand-written HTML cards.
*
* Pure Node built-ins.
*/
@@ -146,7 +145,6 @@ const NAV_ITEMS = [
{ id: "components", label: "Components", path: "docs/" },
{ id: "playground", label: "Playground", path: "docs/playground/" },
{ id: "apps", label: "Sample apps", path: "apps/" },
- { id: "spec", label: "Spec cards", path: "preview/" },
];
function renderHeader(active, depth) {
@@ -209,7 +207,6 @@ function renderFooter(depth) {
Components
Playground
Sample apps
- Spec cards
+
+ Foundations
+ Start with the design tokens — colors, typography, spacing, radii, shadows, motion. Live values, theme-aware.
+
+
${cats}
`;
return htmlShell({ title: `Components — ${pkg.name}`, depth: 1, active: "components", body });
}
function renderSidebar(activeName) {
+ const foundationsBlock = `
+ Foundations
+
+ `;
const blocks = DOCS_CATEGORIES.map((cat) => {
const items = exportsByCategory.get(cat.id);
if (!items.length) return "";
@@ -994,7 +954,7 @@ function renderSidebar(activeName) {
`;
}).join("");
- return ``;
+ return `${foundationsBlock}${blocks} `;
}
function renderPropsTable(iface) {
@@ -1036,11 +996,7 @@ function renderComponentPage(name) {
const demosHtml = demos.map((d, i) => `
- ${chart
- ? `
-
Live preview not available — charts load peer deps outside the bundle. See
spec card or copy the code.
-
`
- : `
`}
+
-
+
@@ -1109,24 +1065,27 @@ function renderComponentPage(name) {
const head = `
-
`;
+
${chart ? `
+
` : ""}`;
// Build a script that runs each demo and wires up copy / toggle / sidebar drawer.
- // Charts skip the live runner — they're not in the IIFE bundle.
- const runCalls = chart
- ? ""
- : demos.map((d, i) => `runExample(${JSON.stringify(d.code)}, "demo-render-${i}");`).join("\n ");
+ // The runner functions themselves verify their bundle is loaded (window.RCS
+ // for runExample, window.RCSCharts for runChartExample) and surface the
+ // failure inline, so we only need to guard against runner.js itself failing.
+ const runFn = chart ? "runChartExample" : "runExample";
+ const runCalls = demos.map((d, i) => `${runFn}(${JSON.stringify(d.code)}, "demo-render-${i}");`).join("\n ");
const codeJson = JSON.stringify(demos.map((d) => d.code));
const tail = `
-
+ ${chart ? `
+ ` : ""}
`;
+
+ return htmlShell({ title: `Foundations — ${pkg.name}`, depth: 2, active: "components", body, head, tail });
+}
+
// ─── 9. Write all output files ────────────────────────────────────────
mkdirSync(outDir, { recursive: true });
mkdirSync(join(outDir, "dist"), { recursive: true });
mkdirSync(join(outDir, "apps"), { recursive: true });
-mkdirSync(join(outDir, "preview"), { recursive: true });
mkdirSync(join(outDir, "docs"), { recursive: true });
mkdirSync(join(outDir, "docs/playground"), { recursive: true });
+mkdirSync(join(outDir, "docs/foundations"), { recursive: true });
writeFileSync(join(outDir, "site.css"), renderSiteCss());
writeFileSync(join(outDir, "dist/styles.css"), colorsAndTypeCss + "\n" + componentStylesCss);
@@ -1298,18 +1577,11 @@ writeFileSync(join(outDir, "dist/styles.css"), colorsAndTypeCss + "\n" + compone
writeFileSync(join(outDir, "index.html"), renderRootIndex());
writeFileSync(join(outDir, "apps/index.html"), renderAppsIndex());
-// /preview/index.html — list every preview HTML card we've staged
-let previewFiles = [];
-try {
- const { readdirSync } = await import("node:fs");
- previewFiles = readdirSync(join(outDir, "preview")).filter((f) => f.endsWith(".html"));
-} catch { /* preview/ not staged yet — script may run before workflow's cp */ }
-writeFileSync(join(outDir, "preview/index.html"), renderBrandIndex(previewFiles));
-
writeFileSync(join(outDir, "docs/index.html"), renderDocsIndex());
writeFileSync(join(outDir, "docs/docs.css"), renderDocsCss());
writeFileSync(join(outDir, "docs/runner.js"), renderRunner());
writeFileSync(join(outDir, "docs/playground/index.html"), renderPlaygroundPage());
+writeFileSync(join(outDir, "docs/foundations/index.html"), renderFoundationsPage());
let count = 0;
for (const name of ALL_NAMES) {
@@ -1320,7 +1592,6 @@ for (const name of ALL_NAMES) {
}
console.log(`Wrote site to ${outDir}`);
-console.log(` ${count} component pages (${runtimeExports.size} core + ${chartExports.size} charts), 1 docs index, 1 playground, 1 apps index, 1 brand index, 1 root`);
+console.log(` ${count} component pages (${runtimeExports.size} core + ${chartExports.size} charts), 1 foundations, 1 docs index, 1 playground, 1 apps index, 1 root`);
console.log(` ${runtimeExports.size + chartExports.size} runtime exports across ${DOCS_CATEGORIES.filter((c) => exportsByCategory.get(c.id).length > 0).length} docs categories`);
console.log(` ${tokenTypeAliases.length} tokens, ${interfaces.length} interfaces, ${componentTypeAliases.length} type aliases`);
-console.log(` preview cards listed: ${previewFiles.filter((f) => f !== "index.html").length}`);
diff --git a/scripts/build-site.mjs b/scripts/build-site.mjs
index c389960..8cc71be 100644
--- a/scripts/build-site.mjs
+++ b/scripts/build-site.mjs
@@ -8,7 +8,7 @@
*
* Steps:
* 1. Recreate
/
- * 2. Stage colors_and_type.css + assets/ + preview/ + ui_kits/
+ * 2. Stage colors_and_type.css + assets/ + ui_kits/
* 3. Bundle src → /docs/bundle/rcs.iife.js (esbuild IIFE)
* 4. Run scripts/build-docs.mjs to write per-component pages
*/
@@ -25,7 +25,7 @@ rmSync(out, { recursive: true, force: true });
mkdirSync(join(out, "docs/bundle"), { recursive: true });
cpSync(join(root, "colors_and_type.css"), join(out, "colors_and_type.css"));
-for (const dir of ["assets", "preview", "ui_kits"]) {
+for (const dir of ["assets", "ui_kits"]) {
const src = join(root, dir);
if (existsSync(src)) cpSync(src, join(out, dir), { recursive: true });
}
@@ -49,6 +49,24 @@ const r1 = spawnSync(esbuildBin, [
], { stdio: "inherit" });
if (r1.status !== 0) process.exit(r1.status ?? 1);
+// Charts bundle — loaded only by chart docs pages. Heavy WebGL peer deps
+// stay external; chart components fall back to canvas2d / SVG paths.
+const r1b = spawnSync(esbuildBin, [
+ "scripts/bundle-entry-charts.ts",
+ "--bundle",
+ "--format=iife",
+ "--global-name=RCSCharts",
+ `--outfile=${join(out, "docs/bundle/rcs-charts.iife.js")}`,
+ "--target=es2020",
+ "--jsx=automatic",
+ "--minify",
+ '--define:process.env.NODE_ENV="production"',
+ "--external:@deck.gl/core",
+ "--external:@deck.gl/layers",
+ "--external:d3-force",
+], { stdio: "inherit" });
+if (r1b.status !== 0) process.exit(r1b.status ?? 1);
+
const r2 = spawnSync(process.execPath, ["scripts/build-docs.mjs", out], { stdio: "inherit" });
if (r2.status !== 0) process.exit(r2.status ?? 1);
diff --git a/scripts/bundle-entry-charts.ts b/scripts/bundle-entry-charts.ts
new file mode 100644
index 0000000..ff86dc4
--- /dev/null
+++ b/scripts/bundle-entry-charts.ts
@@ -0,0 +1,31 @@
+/**
+ * Bundle entry for the charts subpath live previews.
+ *
+ * Mirrors scripts/bundle-entry.ts but bundles only the chart components
+ * plus the chart-only peer deps (uplot, d3-hierarchy, cytoscape,
+ * cytoscape-cose-bilkent). React and ReactDOM's createRoot are bundled
+ * inline so chart demos can render without sharing the main bundle's
+ * React instance — this avoids the "two React instances in one tree"
+ * footgun, since chart demos never nest inside core components.
+ *
+ * Heavy GPU peer deps (@deck.gl/core, @deck.gl/layers, d3-force) are
+ * marked `--external` at bundle time. Chart components already have a
+ * canvas2d / SVG fallback path when the WebGL handoff fails to import,
+ * so the docs site renders charts via the canvas paths and skips
+ * deck.gl entirely. That keeps the chart bundle ~700 KB instead of
+ * pulling in another ~1.5 MB of WebGL machinery.
+ *
+ * Built by esbuild as IIFE → `window.RCSCharts = { Chart, Donut, …,
+ * React, createRoot }`. Loaded only by chart docs pages, never by the
+ * main docs site or playground.
+ *
+ * Used by:
+ * - scripts/build-site.mjs (bundle pass)
+ * - scripts/build-docs.mjs renderComponentPage (chart pages)
+ */
+
+import * as React from "react";
+import { createRoot } from "react-dom/client";
+
+export * from "../src/charts";
+export { React, createRoot };
diff --git a/tests/unit/Sparkline.test.tsx b/tests/unit/Sparkline.test.tsx
index 466b0bf..3950072 100644
--- a/tests/unit/Sparkline.test.tsx
+++ b/tests/unit/Sparkline.test.tsx
@@ -1,9 +1,9 @@
/**
* Sparkline — minimal smoke test.
- * The chart components live behind the optional "/charts" subpath
- * and depend on optional peer deps; only Sparkline is dependency-free
- * so it's the only chart we test in unit-land. The rest are covered
- * by playwright e2e against rendered preview cards.
+ * Chart components live behind the optional "/charts" subpath and
+ * depend on optional peer deps; Sparkline is dependency-free (pure
+ * SVG) so it's the easiest one to exercise in jsdom. Heavier charts
+ * are covered by playwright e2e against the live docs pages.
*/
import { describe, it, expect } from "vitest";
import { render } from "@testing-library/react";