registry:ui · Shell
terminal-card — the typing terminal
The Broadside hero terminal, composed after the openspecui reference: a traffic-light title bar, one large typed command, outputs that surface line by line, and the 4px hard offset shadow. The entrance is one-shot — it types once and settles, never looping; the cursor is a static block per the motion law. Prerendered and no-JS loads show the settled terminal; reduced motion skips straight to it.
terminal-card
The typing demo: the command types character by character with jittered cadence, then the outputs surface one line at a time. Replay re-mounts the card and restarts the story from the first character.
$npx jixoai-ui add terminal-card
terminal-card.svelte → src/lib/ui/
one-shot typing · static cursor · no blink
speed prop paces the entrance
<!-- command is a plain string prop; outputs surface line by
line after the typing completes. One-shot entrance, never looping. -->
<TerminalCard
barTitle="quick-start — zsh"
command="npx jixoai-ui add terminal-card"
outputs={[
'terminal-card.svelte → src/lib/ui/',
'one-shot typing · static cursor · no blink',
]}
/>
<!-- pace: speed multiplies the typing rhythm (2 = twice as fast);
pacing is read on mount, so re-mount to apply ({#key} works) -->
{#key replay}
<TerminalCard {barTitle} {command} {outputs} speed={2} />
{/key}law
One entrance, then stillness
The typing story exists to prove the component is alive, not to entertain forever. Every timing derives from one rhythm: the per-character delay is 42ms plus a 0–40ms jitter, outputs follow at 110ms, and the whole chain divides by the speed multiplier — nothing loops, nothing blinks.
- prerender emits the settled terminal (
typed = commandin markup); hydration restarts the entrance - reduced motion (
prefers-reduced-motion) returns before the first timer — the card renders fully settled - the cursor is a static block; the reference's blink predates the motion law and was dropped deliberately
- bezel law: dark-locked by default;
theme="light" | "system"opts into the light CRT shell through the scoped token class -
speed(default 1, clamped ≥ 0.25) divides every delay — a live control applies it by re-mounting, which is exactly what the playground slider does
types
Types
Two bezel shells: the dark lock by default, the light CRT shell by opt-in.
terminal-card · bezels
$npx jixoai-ui add terminal-card
terminal-card.svelte → src/lib/ui/
$npx jixoai-ui add terminal-card
light CRT shell — scoped token class
<script lang="ts">
import TerminalCard from '@ui/terminal-card.svelte';
</script>
<div class="flex flex-wrap items-start gap-6">
<div class="flex min-w-64 flex-1 flex-col gap-3 border border-border p-4">
<span class="font-nav text-primary text-[11px] uppercase tracking-[0.24em]">theme dark (default)</span>
<TerminalCard
barTitle="quick-start — zsh"
command="npx jixoai-ui add terminal-card"
outputs={['terminal-card.svelte → src/lib/ui/']}
/>
<span class="text-muted-foreground text-[12.5px]">the dark-locked bezel</span>
</div>
<div class="flex min-w-64 flex-1 flex-col gap-3 border border-border p-4">
<span class="font-nav text-primary text-[11px] uppercase tracking-[0.24em]">theme light</span>
<TerminalCard
theme="light"
barTitle="quick-start — zsh"
command="npx jixoai-ui add terminal-card"
outputs={['light CRT shell — scoped token class']}
/>
<span class="text-muted-foreground text-[12.5px]">'light' | 'system' opts into the light shell</span>
</div>
</div>usage
Usage
command as a plain string; outputs surface line by line after the typing completes — replay by re-mounting.
<!-- command is a plain string prop; outputs surface line by
line after the typing completes. One-shot entrance, never looping. -->
<TerminalCard
barTitle="quick-start — zsh"
command="npx jixoai-ui add terminal-card"
outputs={[
'terminal-card.svelte → src/lib/ui/',
'one-shot typing · static cursor · no blink',
]}
/>
<!-- pace: speed multiplies the typing rhythm (2 = twice as fast);
pacing is read on mount, so re-mount to apply ({#key} works) -->
{#key replay}
<TerminalCard {barTitle} {command} {outputs} speed={2} />
{/key}a11y
Accessibility
The settled terminal is real text in the markup; the entrance is decoration hidden from readers.
ARIA
| Attribute | Value | Description |
|---|---|---|
| aria-hidden | true | On the traffic-light dots and the static block cursor — pure scenery |
| prerendered output | settled | typed = command in markup: the full command + outputs are real text before any JS |
| prefers-reduced-motion | instant | Returns before the first timer — the card renders fully settled |
theming
Theming
No density footprint: the bezel is fixed chrome. The scoped token class swaps dark for the light CRT shell; one rhythm divides by speed.
$npx jixoai-ui add terminal-card
one-shot typing · static cursor
$npx jixoai-ui add terminal-card
one-shot typing · static cursor
$npx jixoai-ui add terminal-card
one-shot typing · static cursor
$npx jixoai-ui add terminal-card
one-shot typing · static cursor
| Token | Default | Source |
|---|---|---|
| jx-light | scoped token class | component |
| type rhythm | 42ms + 0-40ms jitter / 110ms outputs | component |
| shadow | 4px hard offset | component |
axes
Universal props
The eight-axis surface (explicit-props): size · shape · radius · density · color · theme · elevation · motion — each axis takes named steps, auto (inherit the ambient context; stamps nothing), an exact number (px · coefficient · dp · hue per axis), or query() for responsive/container-conditional values. The bezel carries SEVEN lanes: its `theme` prop is the SHELL lock (own-before-ambient, dark-locked regardless of the tree) — NOT the theme axis' ambient-first law; §13 rules no rename, so the theme axis forwards ambient, unadopted (the ghostty-term precedent). Elevation carries NO own — the bezel's 4px hard offset shadow is its own documented law; an explicit lane steps the §7 table over it.
TerminalCard · universal props
$jixoai deploy --axes
eight axes · resolved in one record
theme axis forwarded ambient (the shell lock owns the name)
<TerminalCard barTitle="jixoai/ui — zsh" command="deploy" outputs={[...]} size={14} />api
API
Props from the TerminalCard Props interface — title, command, outputs, theme, pace.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| barTitle * | string | — | Title-bar text (e.g. "quick-start — zsh"). |
| command * | string | — | The one large typed command. |
| outputs * | readonly string[] | — | Lines surfacing one by one after the typing completes. |
| speed | number | 1 | Divides every delay; clamped ≥ 0.25 — read on mount, re-mount to apply. |
Universal props
| Property | Type | Default | Description |
|---|---|---|---|
| size | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | the base scale — root font-size; parts size in em |
| shape | 'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto' | 'auto' · ambient scope | corner geometry (CSS corner-shape; §14 degrade table) |
| radius | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | corner size; auto = the concentric broadcast (§3) |
| density | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | spacing/leading scale over the kernel channels (§4) |
| color | 'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string | 'auto' · ambient scope | the hue axis of the fixed oklch primary system (§5) |
| theme | 'light' | 'dark' | 'system' | 'auto' | 'auto' · ambient scope | light/dark profile; system = the JS-mutable global (§6) |
| elevation | 'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number | 'auto' · ambient scope | official M3 levels over the surface ladder (§7) |
| motion | 'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number | 'auto' · ambient scope | intensity across the motion kernels (§8) |