J3W1 / DESIGN SYSTEM
Terminal
Terminal text on the terminal surface with the sixteen heritage ANSI slots carried exactly, the cursor, the selection and the six text attributes; a transcript, the slot grid and the attributes.
stable · LIGHT DOM · 1.1.0
Light DOM retains static content, native semantics, label relationships and host composition without duplicating controls.
Live variants
default
~/theme main ls -l ports total 5 drwxr-xr-x 2 j3w1 j3w1 4096 Sep 6 09:12 alacritty drwx------ 2 j3w1 j3w1 4096 Sep 6 09:12 gtk -rw-r--r-- 1 j3w1 j3w1 1180 Sep 6 09:12 README.md -rwxr-xr-x 1 j3w1 j3w1 512 Sep 6 09:12 verify.sh lrwxrwxrwx 1 j3w1 j3w1 11 Sep 6 09:12 xresources -> ../tokens/ -rw-r--r-- 1 j3w1 j3w1 20480 Sep 6 09:12 evidence.tar.gz ~/theme main cat ports/gtk/port.json cat: ports/gtk/port.json: No such file or directory ~/theme main npm run validate
<j3w1-terminal id="example-terminal-default"><pre class="terminal terminal-transcript" role="log" aria-label="Shell transcript" tabindex="0"><span class="terminal-line"><span class="terminal-prompt"><span class="terminal-prompt-path"> ~/theme </span><span class="terminal-prompt-arrow terminal-prompt-arrow-path" aria-hidden="true">▶</span><span class="terminal-prompt-branch"> main </span><span class="terminal-prompt-arrow terminal-prompt-arrow-branch" aria-hidden="true">▶</span></span> ls -l ports</span>
<span class="terminal-line">total 5</span>
<span class="terminal-line">drwxr-xr-x 2 j3w1 j3w1 4096 Sep 6 09:12 <span class="terminal-fg-5 terminal-bold">alacritty</span></span>
<span class="terminal-line">drwx------ 2 j3w1 j3w1 4096 Sep 6 09:12 <span class="terminal-fg-5 terminal-bold">gtk</span></span>
<span class="terminal-line">-rw-r--r-- 1 j3w1 j3w1 1180 Sep 6 09:12 <span class="terminal-sel">README.md</span></span>
<span class="terminal-line"><span class="terminal-sel">-rwxr-xr-x 1 j3w1 j3w1 512 Sep 6 09:12 </span><span class="terminal-sel terminal-fg-3">verify.sh</span></span>
<span class="terminal-line">lrwxrwxrwx 1 j3w1 j3w1 11 Sep 6 09:12 <span class="terminal-fg-7">xresources</span> -> <span class="terminal-fg-2">../tokens/</span></span>
<span class="terminal-line">-rw-r--r-- 1 j3w1 j3w1 20480 Sep 6 09:12 <span class="terminal-fg-11">evidence.tar.gz</span></span>
<span class="terminal-line"><span class="terminal-prompt"><span class="terminal-prompt-path"> ~/theme </span><span class="terminal-prompt-arrow terminal-prompt-arrow-path" aria-hidden="true">▶</span><span class="terminal-prompt-branch"> main </span><span class="terminal-prompt-arrow terminal-prompt-arrow-branch" aria-hidden="true">▶</span></span> cat ports/gtk/port.json</span>
<span class="terminal-line terminal-fg-5">cat: ports/gtk/port.json: No such file or directory</span>
<span class="terminal-line terminal-line-cursor"><span class="terminal-prompt"><span class="terminal-prompt-path"> ~/theme </span><span class="terminal-prompt-arrow terminal-prompt-arrow-path" aria-hidden="true">▶</span><span class="terminal-prompt-branch"> main </span><span class="terminal-prompt-arrow terminal-prompt-arrow-branch" aria-hidden="true">▶</span></span> npm run validate<span class="terminal-cursor" aria-hidden="true"> </span></span></pre></j3w1-terminal>ansi-grid
slot normal bold background 0 ✕ 1 ✕ 2 normal bold 3 normal bold 4 ✕ 5 normal bold 6 ✕ 7 normal bold 8 ✕ 9 ✕ 10 ✕ 11 normal bold 12 ✕ 13 ✕ 14 ✕ 15 ✕ ✕ fails 4.5:1 on the terminal background; the extended profile reassigns the slots
<j3w1-terminal id="example-terminal-ansi-grid"><pre class="terminal terminal-ansi-grid" aria-label="The sixteen ANSI slots as normal and bold foregrounds and as backgrounds; a cross marks a slot that fails 4.5 to 1 on the terminal background" tabindex="0"><span class="terminal-line"><span class="terminal-label">slot normal bold background</span></span>
<span class="terminal-line"><span class="terminal-label"> 0</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-0 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-0 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-0 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label"> 1</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-1 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-1 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-1 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label"> 2</span> <span class="terminal-fg-2">normal</span> <span class="terminal-fg-2 terminal-bold">bold</span> <span class="terminal-bg-2 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label"> 3</span> <span class="terminal-fg-3">normal</span> <span class="terminal-fg-3 terminal-bold">bold</span> <span class="terminal-bg-3 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label"> 4</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-4 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-4 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-4 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label"> 5</span> <span class="terminal-fg-5">normal</span> <span class="terminal-fg-5 terminal-bold">bold</span> <span class="terminal-bg-5 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label"> 6</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-6 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-6 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-6 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label"> 7</span> <span class="terminal-fg-7">normal</span> <span class="terminal-fg-7 terminal-bold">bold</span> <span class="terminal-bg-7 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label"> 8</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-8 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-8 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-8 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label"> 9</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-9 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-9 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-9 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label">10</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-10 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-10 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-10 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label">11</span> <span class="terminal-fg-11">normal</span> <span class="terminal-fg-11 terminal-bold">bold</span> <span class="terminal-bg-11 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label">12</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-12 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-12 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-12 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label">13</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-13 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-13 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-13 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label">14</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-14 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-14 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-14 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line"><span class="terminal-label">15</span> <span class="terminal-fail">✕</span> <span class="terminal-fg-15 terminal-swatch" aria-hidden="true"></span> <span class="terminal-fg-15 terminal-swatch" aria-hidden="true"></span> <span class="terminal-bg-15 terminal-swatch-bg" aria-hidden="true"></span></span>
<span class="terminal-line terminal-line-cursor"><span class="terminal-label">✕ fails 4.5:1 on the terminal background; </span><span class="terminal-sel">the extended profile reassigns the slots</span><span class="terminal-cursor" aria-hidden="true"> </span></span></pre></j3w1-terminal>attributes
bold Warm-black surfaces, rose text. dim Warm-black surfaces, rose text. italic Warm-black surfaces, rose text. underline Warm-black surfaces, rose text. inverse Warm-black surfaces, rose text. strike Warm-black surfaces, rose text. selected Warm-black surfaces, rose text.
<j3w1-terminal id="example-terminal-attributes"><pre class="terminal terminal-attributes" aria-label="Terminal text attributes" tabindex="0"><span class="terminal-line"><span class="terminal-label">bold </span><span class="terminal-bold">Warm-black surfaces, rose text.</span></span>
<span class="terminal-line"><span class="terminal-label">dim </span><span class="terminal-dim">Warm-black surfaces, rose text.</span></span>
<span class="terminal-line"><span class="terminal-label">italic </span><span class="terminal-italic">Warm-black surfaces, rose text.</span></span>
<span class="terminal-line"><span class="terminal-label">underline </span><span class="terminal-underline">Warm-black surfaces, rose text.</span></span>
<span class="terminal-line"><span class="terminal-label">inverse </span><span class="terminal-inverse">Warm-black surfaces, rose text.</span></span>
<span class="terminal-line"><span class="terminal-label">strike </span><span class="terminal-strike">Warm-black surfaces, rose text.</span></span>
<span class="terminal-line terminal-line-cursor"><span class="terminal-label">selected </span><span class="terminal-sel">Warm-black surfaces, rose text.</span><span class="terminal-cursor" aria-hidden="true"> </span></span></pre></j3w1-terminal>Install and register
Use the exact version. If npm publication is pending, install the release tarball from the installation guide.
npm install --save-exact @j3w1/ui@1.1.0import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/terminal.css';
import '@j3w1/ui/register/terminal';Insert the maintained markup above after loading these imports. Its native children provide accessible names and form behavior; the empty custom tag alone does not create a control.
Copy the complete implementation
npx --package=@j3w1/ui@1.1.0 j3w1-ui copy terminal --out ./vendor/j3w1/terminalThe CLI verifies every file before writing and refuses overwrites. Serve the output over HTTP and open index.html. Keep its modules, CSS, tokens and licence notices together.
Public API
attributes
| Name | Type / signature | Meaning |
|---|---|---|
disabled | CustomEvent | Disable the native controls owned by this instance. |
loading | CustomEvent | Mark the primary control busy and prevent duplicate activation. |
properties
| Name | Type / signature | Meaning |
|---|---|---|
disabled | boolean | Delegates disabled state to native children. |
name | string | Native control name; application form keys remain explicit. |
methods
| Name | Type / signature | Meaning |
|---|---|---|
refresh | (): void | Reconnect behavior after replacing native child structure. |
focus | (options?: FocusOptions): void | Focus the first usable native control. |
setText | (text: string): void | Replace the bounded read-only text view; no code or shell execution occurs. |
events
| Name | Type / signature | Meaning |
|---|---|---|
j3w1-action | CustomEvent | Request a developer-view action; editing and execution belong to the host. |
Dependencies and verification
Registered components: none. Style dependencies: none.
Package presence establishes an available implementation. Actual passes depend on the tested artifact and environment. Read specification execution evidence; read packed-consumer evidence; inspect the complete state matrix.
Full implementation manifest, API and token dependency closure
Canonical specification
Purpose
The reference for terminal text: the surface, the default foreground, the
cursor, the selection, the six attributes and the sixteen slots the
workstation froze in Xresources. The slots are the origin of the theme and
are carried exactly; what a program does with a slot is that program’s
choice, and the theme documents where a choice fails rather than quietly
fixing it.
Anatomy
Root .terminal (the <pre>) with a variant class .terminal-transcript,
.terminal-ansi-grid or .terminal-attributes. Parts .terminal-<part>:
-line, -prompt with -prompt-path, -prompt-branch and -prompt-arrow,
-cursor, -sel, -label, -fail (the ✕), and the attributes -bold,
-dim, -italic, -underline, -inverse, -strike. Slot classes are
.terminal-fg-0 … .terminal-fg-15 and .terminal-bg-0 … .terminal-bg-15,
each a single role variable color.terminal.ansi.0 … color.terminal.ansi.15,
so the profile switch on the specimen recolours the grid without touching
the markup. The foreground is color.terminal.fg on color.terminal.bg;
the prompt path segment is color.terminal.selection-text on
color.terminal.ansi.4 and the branch segment color.terminal.bg on
color.terminal.ansi.3, the two agnoster backgrounds the workstation used.
States
| State | Visual | Non-colour channel |
|---|---|---|
| default | text on color.terminal.bg; the cursor cell hollow, a 1px color.terminal.cursor outline; no ring | the hollow cursor |
| focus-visible | container ring 2px color.interaction.focus.ring-container at −3px; the cursor solid color.terminal.cursor with color.terminal.bg text | the ring; the cursor fills |
| selected | the run filled color.terminal.selection-bg with color.terminal.selection-text; slot colours inside the run give way to the selection text | the fill spans whole cells; the emulator exposes the selection |
| busy | a command is running: the cursor is a solid static block at the end of the output; the transcript is aria-busy | aria-busy; the cursor shape; no blink |
| current | the cursor line filled color.code.current-line across its width; the cursor as in focus | the row fill; the cursor cell |
The cursor never blinks in the reference. A host keeps the user’s own blink setting and stops blinking under reduced motion; the theme never turns it on.
Keyboard
The emulator and the shell own every key, including Tab, Escape and the selection modifiers. The reference transcript is a single focus stop that consumes nothing. The theme draws the ring when the host reports focus, the fill when the host reports a selection, and the block cursor where the host puts it.
Accessibility
The transcript is role=log so new output is announced politely; the grid
and the attribute sheet are plain <pre> elements with a label. The sixteen
slots are exact in every profile: slots 2, 3, 5, 7 and 11 reach 4.5:1 on the
terminal background; slots 1, 4, 6, 8, 9, 10, 12, 13 and 14 do not
(1.86:1–4.43:1), and the grid marks each of them with a ✕ after its number
so the failure is visible, not implied. Two more are marked on the same
evidence: slot 15 measures 4.45:1 and slot 0 is the background itself. The
extended overlay reassigns the slots to a semantic sixteen that all reach
4.5:1; the site’s profile control shows the grid under it. The background
row is legible only with a foreground the program chooses: with the default
foreground only slots 0 and 8 pass, which is why the row is shown and not
declared as a contract. Two escape families bypass the slots entirely and
are outside the theme: bold-as-bright, which substitutes slots 8–15 for 0–7
and must be off for the slots to hold, and 256-colour or 24-bit sequences,
which carry their own values. Attributes are attributes: dim uses
color.text.muted (5.81:1) rather than a slot, inverse swaps foreground and
background (8.65:1), and bold, italic, underline and strikethrough are text
styles a screen reader can expose.
Portability
Every emulator with a sixteen-slot palette can hold these values byte for
byte; the port’s evidence records whether bold-as-bright is off and whether
the cursor and selection keys exist. Programs that pick slot 4 or 12 for
directories inherit the documented failure; a port may recommend LS_COLORS
or a prompt configuration but never changes the slots to compensate. The
cursor shape (block, bar, underline) is the user’s setting; the theme only
supplies its colour.
Non-examples
Normalising the heritage slots so every one reaches 4.5:1 and calling it
heritage-ansi. A blinking cursor in the reference. A cursor that is a
glowing bar. Bold rendered as bright, which silently swaps the slots. A
purple or cyan slot borrowed from another scheme. Wrapping the transcript at
narrow widths and breaking the prompt segments. A selection drawn as a ring
instead of a fill. Rounded prompt segments or a gradient prompt.