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
-
-
50
-
100
-
200
-
300
-
400
-
500 ★
-
600
-
700
-
800
-
900
-
- -
Cod Gray · neutrals
-
-
50
-
100
-
200
-
300
-
400
-
500
-
600
-
700
-
800 ★
-
900
-
- -
-
-
-
-
#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 @@ - - - -
-
-
Light · neutrals
-
-
bg-0#FFFFFF
-
bg-1#FFFFFF
-
bg-2#F5F5F5
-
bg-3#E5E5E5
-
-
fg-1#1C1C1C
-
fg-2#3D3D3D
-
fg-3#5A5A5A
-
fg-4#A6A6A6
-
-
-
-
Dark · neutrals
-
-
bg-0#1C1C1C
-
bg-1#2B2B2B
-
bg-2#3D3D3D
-
bg-3#4A4A4A
-
-
fg-1#FFFFFF
-
fg-2#CCCCCC
-
fg-3#808080
-
fg-4#5A5A5A
-
-
-
- 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
-
-
-
-
-
success
-
-
Deployed in 2.3s
-
-
-
-
-
warning
-
-
Cert expires in 6d
-
-
-
-
-
danger
-
-
Connection refused
-
-
-
-
-
info
-
-
New version 0.14
-
-
-
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 - - hover - - press - -
-
- -
-
Dark · Cod Gray
bg #1C1C1C · fg #FFFFFF
-
- default - - hover - -
-
- -
-
Secondary
bg #FFFFFF · border rgba(28,28,28,0.14)
-
- default - - hover - -
-
- -
-
Ghost · disabled
bg transparent
-
- default - - hover - - disabled - -
-
- -
-
Sizes
sm · md · lg
-
- - - -
-
-
-
- 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
-
-
-
-
-
-
vault-primary
-
-
RUNNING
-
-
-
uptime  14d 02:11
-
memory  48.2 MB
-
req/s    12.4
-
-
-
-
-
-
-
gateway
-
-
DEGRADED
-
-
-
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 - -
    -
  • api38.0%
  • -
  • db24.0%
  • -
  • cache16.0%
  • -
  • queue12.0%
  • -
  • other10.0%
  • -
-
-
- -
-
-
RadialGauge · capacity · neutral
-
- - - - - - 76% - -
-
Disk capacity
-
-
-
RadialGauge · uptime SLO · good
-
- - - - - 99.97% - -
-
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/secp99 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
-
- - - -
-
-
-
p99 latency
-
142ms
-
- - - - -
-
-
-
Error rate
-
0.04%
-
- - - -
-
-
-
Active sessions
-
3,284
-
- - - -
-
-
- - -
-
Resource breakdown · cluster usage
-
SVG · clickable segments · accent + mono palette
-
- - - - - - - 847 - cores - -
    -
  • Compute45.0%
  • -
  • Database25.0%
  • -
  • Cache18.0%
  • -
  • Other12.0%
  • -
-
-
- - -
-
Radial gauges · capacity indicators
-
SVG · tone: good / warning / bad
-
-
- - - - 33% - -
Disk
-
-
- - - - 76% - -
Memory
-
-
- - - - 93% - -
CPU
-
-
-
-
- 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
-
-
-
line
- -
-
-
area
- - - - -
-
-
mono
- -
-
-
noisy / dense
- - - -
-
-
- -
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 - - 1H6H24H7D - 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 -
- -
- - -
-
api-gateway
1.24M LOC
-
-
-
user-service
680k LOC
-
-
-
billing
498k LOC
-
-
-
notifications
580k LOC
-
-
-
analytics
472k LOC
-
- - -
-
scheduler
540k LOC
-
-
-
webhooks
474k LOC
-
-
-
search
258k LOC
-
-
-
audit
128k LOC
-
-
-
storage
312k LOC
-
-
-
queue
242k LOC
-
-
-
docs
186k 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% -
-
- cdn.edge -
- 99.99% -
- -
- 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. -
-
-
- -
-
R
-
-
- -
-
Suggested
-
- Re-issue the cert with full chain - Roll back to v0.3.0 - Open the runbook for TLS errors - Page on-call -
-
-
- -
-
-
📎 audit-shipper.log ×
- -
- - - - ⌘ + ↵ to send - -
-
-
-
-
- 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 - -
-
-
123456789
-
-# 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 -fstreaming
-
-
-
14:32:01.412infolistener bound to 0.0.0.0:8443 (tls)
-
14:32:01.418inforaft peer connected: 10.0.1.42
-
14:32:01.420inforaft peer connected: 10.0.1.43
-
14:32:02.001dbgleader election: term=14 leader=self
-
14:32:14.207warnslow request: GET /v1/secrets took 1.4s
-
14:32:18.114errtls handshake failed: x509: unknown authority
-
14:32:18.115infoaudit-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]
-
13backend = "file"
-
13+backend = "raft"
-
14path = "/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
-
-
-
JS
-
MK
-
PB
-
-
Group · max 4
-
-
JS
-
MK
-
PB
-
RT
-
+8
-
-
QR code
-
-
-
-
- -
-
Calendar · month view
-
-
-

April 2026

today
-
-
Mon
Tue
Wed
Thu
Fri
Sat
Sun
-
30
31
1
2deploy
3
4
5
-
6
7incident
8
9
10deploy
11
12
-
13
14
15
16deploy
17
18
19
-
20
21
22audit
23
24
25
26today
-
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 · …
-
-
-
Networking3 rules
-
-
-
Secrets5
-
-
-
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 -
- - -
-
-
-
-
-
- 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
-
-
-
-
- -
-
TimePicker
-
-
14 : 30 : 00
-
-
-
12
13
14
15
16
17
-
-
-
15
20
25
30
35
40
-
-
-
00
15
30
45
50
55
-
-
-
-
- -
-
Color picker
-
-
-
- -
-
- - - - - - - - - -
-
Rate
-
-
-
-
- -
-
-
Upload · drag & drop
-
-
-
-
Drop files here or click to upload
-
PNG, JPG, PDF · up to 25 MB
-
-
-
deploy-config.yaml4.2 KB
-
audit-2026-04.pdf12.4 MB
64%
-
-
-
-
-
Slider
-
-
Memory limit2.5 GB
-
-
-
-
-
02468
- -
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
-
-
- -
-
vault-primaryus-east-1
-
vault-replica-eueu-west-1
-
vault-archiveus-west-2
-
-
-
Mentions
-
- Hey @miguel, can you look at the @audit-shipper alert? -
-
Mmiguel.santos
-
Mmaya.kim
-
Mmarcus.lee
-
-
-
-
-
- -
-
Transfer
-
-
-
-
Available · 42 selected
-
-
read:logs
-
read:metrics
-
write:secrets
-
admin:billing
-
-
-
- - -
-
-
Granted · 30 selected
-
-
deploy:services
-
manage:team
-
read:audit
-
-
-
-
-
-
- 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
- -
-
Services
24
+3 this week
-
Uptime
99.97%
↑ 0.04%
-
Requests / min
12.4k
↓ 8.2%
-
Failed deploys
2
last: 22m ago
-
- -
-
-
Skeleton
-
-
-
-
-
-
-
-
-
Progress
-
-
-
Storage72%
-
-
-
-
Bandwidth34%
-
-
-
-
CPU91%
-
-
-
-
-
- -
-
-
Tooltip
-
-
- -
Shift + ⌘ + K to open
-
-
-
-
-
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.
- -
-
-
- 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.

-
-
-
-
-
-
Result · error
-
-
-
-

Deployment failed

-

Health check timed out after 60s. Logs available below.

-
-
-
-
-
-
Result · 404
-
-
-
404
-

Service not found

-

That service may have been deleted or you don't have access.

-
-
-
-
-
- -
-
-
Spin · loading
-
-
-
-
-
- Top progress bar -
-
-
-
-
-
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 vault-primary?
-

This action cannot be undone.

-
-
-
-
-
-
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.
-
- - -
-
-
-
-
-
Drawer (right)
-
-
-
-
-

Service details

- × -
-
-
namevault-primary
-
versionv0.14.2
-
port8443
-
uptime14d 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.
-
-
-
-
Region
-
-
-
us-east-1
- -
-
-
-
-
Tags
-
-
- self-hosted × - tls × - production × - add tag… -
-
-
-
-
Port
-
- -
✕ Port must be a number between 1 and 65535.
-
-
-
-
Auto-restart
-
-
- Restart on crash -
-
-
-
Visibility
-
- Private - Team - Public -
-
-
-
Features
-
- TLS - Audit log - Metrics export - Webhooks -
-
-
-
Notes
-
- -
-
-
-
- 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
-
-
- port -
-
-
- replicas -
- min 1 · max 16 -
-
- timeout -
- seconds -
-
-
-
-
PinInput · OTP / 2FA
-
-
- - - - · - - - -
-
enter the 6-digit code from your authenticator
-
-
-
- -
-
-
IconButton · variants & sizes
-
-
- - - - - - -
-
- - - - sm · md · lg -
-
-
-
-
Kbd · keyboard shortcuts
-
-
Open command menuK
-
Quick deployD
-
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
-
- - 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
-
-
- - -
Lowercase, hyphens only.
-
-
- - -
Default 8443
-
-
-
-
- - -
Focused
-
-
- - -
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
-
-
-
- - -
⌘KJS
-
-
-
Production
-
▦ vault-primary
-
▦ tunnel-edge
-
▦ webhook-relay
-
Staging
-
▦ vault-staging
-
▦ tunnel-stg
-
-
-
vault-primary
-
us-east-1 · v0.14.2 · running
-
-
Uptime
14d
-
RPS
214
-
P99
42ms
-
-
-
● connectedregion us-east-1v2026.04.26
-
-
-
- -
-
-
Grid · 12 columns · 6/24 gutter
-
-
-
4
4
4
-
-
-
6
6
-
-
-
8
4
-
-
-
3
3
3
3
-
-
-
-
-
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
-
-
runningtlsauditv0.14.2
-
runningtlsaudit
-
productionstagingdevelopment
-
-
-
- -
-
-
Float button · BackTop
-
-
-
- - -
-
-
-
-
Affix · sticky on scroll
-
-
vault-primary · overviewaffixed
-
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

- - - - - - - -
RegionCodeLatency p50Status
N. Virginiaus-east-114ms● running
Frankfurteu-central-122ms● running
Singaporeap-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

-
    -
  1. Production checklist
  2. -
  3. TLS & certificates
  4. -
  5. Backups & disaster recovery
  6. -
-
-
- 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
-
Configure
port, env vars
-
3
Deploy
In progress…
-
4
Verify
Health check
-
-
-
- -
-
-
Steps · vertical
-
-
-
Pulled image
2.1s
-
Migrated DB
0.4s
-
Starting workers
3/8 ready
-
4
Health check
pending
-
-
-
-
-
Anchor (in-page)
-
- -
-
-
- -
-
-
Menu · sidebar
- -
-
-
Pagination
-
-
- - 1 - 2 - 3 - 4 - - 12 - - -
-
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
- -
-
- Services - / - Production - / - vault-primary -
-
-
-
-

vault-primary

- ● running - v0.14.2 -
-
Self-hosted secrets vault · us-east-1 · last deploy 2h ago
-
-
- - - - -
-
-
- -
-
- Settings - / - Team -
-
-

Team members

- -
-
-
- 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
- - -
-
- -
-
- -
-
- - - - - - -
-
- - - - - -
-
- - - - - -
-
- - - -
-
- - -
-
- - -
-

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

-
    -
  • Confirm raft has quorum: rcs raft status
  • -
  • TLS chain still valid (not after > 30 days)
  • -
  • Audit log shipper is draining
  • -
  • Page secondary on-call if rollback fails
  • -
- -
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

- - - - - - - -
DateSeverityResolution
2026-04-18SEV2raft re-quorum, 4m
2026-03-02SEV3tls renew, no impact
2026-02-09SEV1storage migration
-
- - -
- - 1,402 chars · 248 words - markdown · gfm - - - jordan.k editing - Saved · 12:42:18 - -
-
- - -
- - - - - - -
- - -
-
Basic blocks
-
H1Heading 1⌘ ⌥ 1
-
H2Heading 2⌘ ⌥ 2
-
Bullet list
-
Task list
-
Embed
-
{ }Code block```
-
Table
-
@Mention person
-
-
- - -
-
Toolbar variants
-
-
-
Compact · inline
-
- - - - - -
-
-
-
Single-line · with placeholder
-
-
- - - - -
-
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 · 4itemitemitem
-
sm · 8itemitemitem
-
md · 12itemitemitem
-
lg · 16itemitemitem
-
xl · 24itemitemitem
-
-
- -
-
-
<Space direction="vertical">
-
-
- - - - -
-
-
-
-
<Space> · justify · between
-
-
- vault-primary - -
-
-
-
- - -
-
-
<Space split=<Divider/>>
-
-
- EditDuplicateDelete -
-
-
-
-
<Space wrap> · responsive tag bar
-
-
- produs-east-1v0.14.2 - rafttls3 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
-
-
serviceregion · status
-
vault-primaryus-east-1 · ● running
-
vault-replica-aus-east-1 · ● running
-
vault-replica-bus-east-1 · ● running
-
tunnel-edge-01eu-central-1 · ● running
-
tunnel-edge-02eu-central-1 · ▲ degraded
-
logs-shipperap-southeast-1 · ● running
-
metrics-aggap-southeast-1 · ● running
-
auth-brokerus-west-2 · ● running
-
auth-broker-replicaus-west-2 · ○ idle
-
build-runner-01us-east-1 · ● running
-
build-runner-02us-east-1 · ● running
-
-
-
overscroll-behavior: contain · -webkit-overflow-scrolling: touch · 8px thumb
-
- - -
-
<ScrollDiv direction="x"> · horizontal card track
-
-
drag → · contained, won't pull the whole page
-
-
-
requests / min
2,401
-
latency p50
14ms
-
latency p99
142ms
-
error rate
0.42%
-
cpu · primary
68%
-
memory
3.2/8 GB
-
storage
142 GB
-
-
-
-
- - -
-
<ScrollDiv direction="both"> · large data grid in a fixed window
-
- - - - - - - - - - - - - - - - - - - - -
idserviceregionversioncpumemoryuptime
svc_8a2fvault-primaryus-east-1v0.14.268%3.2 GB14d 6h
svc_3c91vault-replica-aus-east-1v0.14.242%2.8 GB14d 6h
svc_4d20tunnel-edge-01eu-central-1v0.14.231%1.4 GB7d 2h
svc_7e44tunnel-edge-02eu-central-1▲ degraded88%1.9 GB7d 2h
svc_b108logs-shipperap-southeast-1v0.14.122%0.8 GB21d
svc_c930metrics-aggap-southeast-1v0.14.119%0.6 GB21d
-
-
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
- -
-
- - - 2 selected -
- - -
-
-
- - - - - - - - - - - - - - - - - - - - -
ServiceStatus RegionVersionLast deployActions
vault-primary● runningus-east-1v0.14.22h ago
tunnel-edge● runningeu-west-1v0.9.414m ago
webhook-relay● stoppedus-east-1v1.2.03d ago
audit-shipper● failedus-east-1v0.3.122m ago
db-replica-eu● runningeu-west-1v2.0.05d ago
cache-edge-sg● runningap-southeast-1v0.7.81d ago
-
- -
- -
-
Empty state
-
- - -
ServiceStatusRegion
-
-
[ ]
-
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×24tmux 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 -
-
- -
- -
-
-
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 - - card - - 393 × 852 -
-
-
-
iPhone 15393 × 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
-
-
-
-
sm · 4 ★
-
default
-
-
-
-
md · 6
-
-
-
-
-
lg · 8
-
modals
-
-
-
-
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
-
-
1 · 4
-
2 · 8
-
3 · 12
-
4 · 16
-
6 · 24
-
8 · 32
-
12 · 48
-
16 · 64
-
-
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
-
-
-
-
none
-
-
-
-
xs
-
-
-
-
sm · hover
-
-
-
-
md · dropdown
-
-
-
-
lg · modal
-
-
-
-
focus
-
-
-
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

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";
-
- -
-
button

Button · IconButton · ButtonGroup

discriminated variants
-
export type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "link";
-
-export interface ButtonProps extends BaseProps {
-  readonly variant?: ButtonVariant;
-  readonly size?: Size;
-  readonly shape?: "rect" | "pill" | "square" | "circle";
-  readonly loading?: boolean;
-  readonly disabled?: boolean;
-  readonly block?: boolean;
-  readonly iconLeft?: ReactNode;
-  readonly iconRight?: ReactNode;
-  readonly children?: ReactNode;
-  readonly onClick?: (e: MouseEvent<HTMLButtonElement>) => void;
-}
-
-export interface IconButtonProps extends Omit<ButtonProps, "iconLeft" | "iconRight" | "block" | "children"> {
-  readonly icon: ReactNode;
-  readonly "aria-label": string;       // ← required for a11y
-  readonly round?: boolean;
-}
-
- -
-
input

Input · NumberInput · PinInput · Textarea

strict event signatures
-
export interface InputProps extends BaseProps {
-  readonly value?: string;
-  readonly placeholder?: string;
-  readonly status?: "default" | "error" | "warning" | "success";
-  readonly prefix?: ReactNode;
-  readonly suffix?: ReactNode;
-  readonly clearable?: boolean;
-  readonly onChange?: (value: string, e: ChangeEvent<HTMLInputElement>) => void;
-}
-
-export interface NumberInputProps extends Omit<InputProps, "value" | "onChange" | "type"> {
-  readonly value?: number;
-  readonly min?: number;
-  readonly max?: number;
-  readonly step?: number;
-  readonly onChange?: (value: number) => void;
-}
-
-export interface PinInputProps extends BaseProps {
-  readonly length: 4 | 6 | 8;     // ← literal union, not just `number`
-  readonly mask?: boolean;
-  readonly onComplete?: (value: string) => void;
-}
-
- -
-
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 ``; } 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.
    -
    ` - : `
    `} +

    ${escapeHtml(d.title)}

    @@ -1051,10 +1007,10 @@ function renderComponentPage(name) { ${chart ? "" : `↗ Playground`} - +
    -
    +
    @@ -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";