i3 window frame
The workstation frame; an i3 bar with workspaces and Chinese i3status labels above the terminal and code-editor components as tiled, tabbed or floating windows behind i3 title bars.
stable · light DOM · 4.0.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
// Compose the window title of the focused container. import { Container } from "./tree.js"; const MAX_LENGTH = 48; export function title(container) { const name = container.name ?? "untitled…"; let label = `${name} (${container.children.length})`; if (label.length > MAX_LENGTH) { label = label.slice(0, MAX_LENGTH) + "…"; } return escape(label); /* escape() is deprecated */ } const broken = 0x1G;
Workspace 2 is empty.
Workspace 3 is empty.
<j3w1-i3-window-frame id="example-i3-window-frame-default"><div class="i3-window-frame" role="region" aria-label="Workstation, workspace 1: theme, tiled">
<div class="i3-window-frame-bar" role="group" aria-label="i3 bar">
<div class="i3-window-frame-workspaces" role="tablist" aria-label="Workspaces">
<button class="i3-window-frame-workspace" type="button" role="tab" aria-selected="true" tabindex="0" id="example-i3-window-frame-default-workspace-tab-0" aria-controls="example-i3-window-frame-default-workspace-panel-0">1:theme</button>
<button class="i3-window-frame-workspace i3-window-frame-workspace-demo-target" type="button" role="tab" aria-selected="false" tabindex="-1" id="example-i3-window-frame-default-workspace-tab-1" aria-controls="example-i3-window-frame-default-workspace-panel-1">2:reference</button>
<button class="i3-window-frame-workspace i3-window-frame-workspace-urgent" type="button" role="tab" aria-selected="false" tabindex="-1" id="example-i3-window-frame-default-workspace-tab-2" aria-controls="example-i3-window-frame-default-workspace-panel-2">3:ports<span class="i3-window-frame-urgent-mark">!<span class="sr-only"> urgent</span></span></button>
</div>
<div class="i3-window-frame-status" role="group" lang="zh" aria-label="状态">
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 处理器 12%</span>
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 内存储器 3.1G</span>
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 局域网 up</span>
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 电池 87%</span>
<time class="i3-window-frame-block i3-window-frame-clock" datetime="2026-09-06T14:32:07">09月06号 14时32分07秒</time>
</div>
</div>
<section role="tabpanel" id="example-i3-window-frame-default-workspace-panel-0" aria-labelledby="example-i3-window-frame-default-workspace-tab-0"><div class="i3-window-frame-area">
<div class="i3-window-frame-window i3-window-frame-focused" role="group" aria-label="Terminal window, focused" tabindex="0">
<div class="i3-window-frame-title">~/theme — zsh</div>
<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>
</div>
<div class="i3-window-frame-window" role="group" aria-label="Editor window" tabindex="0">
<div class="i3-window-frame-title">title.js — editor</div>
<div class="code-editor" role="textbox" aria-multiline="true" aria-readonly="true" aria-label="title.js, read-only" tabindex="0">
<pre class="code-editor-pre"><span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">1</span><span class="code-editor-text"><span class="code-editor-cm">// Compose the window title of the focused container.</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">2</span><span class="code-editor-text"><span class="code-editor-kw">import</span> <span class="code-editor-punct">{</span> <span class="code-editor-type">Container</span> <span class="code-editor-punct">}</span> <span class="code-editor-kw">from</span> <span class="code-editor-str">"./tree.js"</span><span class="code-editor-punct">;</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">3</span><span class="code-editor-text"><span class="code-editor-kw">const</span> <span class="code-editor-const">MAX_LENGTH</span> <span class="code-editor-op">=</span> <span class="code-editor-num">48</span><span class="code-editor-punct">;</span><span class="code-editor-ws" aria-hidden="true" data-whitespace="··"></span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">4</span><span class="code-editor-text"><span class="code-editor-kw">export</span> <span class="code-editor-kw">function</span> <span class="code-editor-fn">title</span><span class="code-editor-punct code-editor-bracket">(</span><span class="code-editor-var">container</span><span class="code-editor-punct code-editor-bracket">)</span> <span class="code-editor-punct">{</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">5</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">const</span> <span class="code-editor-var">name</span> <span class="code-editor-op">=</span> <span class="code-editor-var">container</span><span class="code-editor-punct">.</span><span class="code-editor-prop">name</span> <span class="code-editor-op">??</span> <span class="code-editor-str">"untitled<span class="code-editor-esc">…</span>"</span><span class="code-editor-punct">;</span></span></span>
<span class="code-editor-line code-editor-line-current"><span class="code-editor-ln" aria-hidden="true">6</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">let</span> <span class="code-editor-var">label</span> <span class="code-editor-op">=</span> <span class="code-editor-str">`${</span><span class="code-editor-var">name</span><span class="code-editor-str">} (${</span><span class="code-editor-var">container</span><span class="code-editor-punct">.</span><span class="code-editor-prop">children</span><span class="code-editor-punct">.</span><span class="code-editor-prop">length</span><span class="code-editor-str">})`</span><span class="code-editor-punct">;</span><span class="code-editor-caret" aria-hidden="true"></span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">7</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">if</span> <span class="code-editor-punct">(</span><span class="code-editor-sel"><span class="code-editor-var">label</span><span class="code-editor-punct">.</span><span class="code-editor-prop">length</span> <span class="code-editor-op">></span> <span class="code-editor-const">MAX_LENGTH</span><span class="code-editor-punct">)</span> <span class="code-editor-punct">{</span></span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">8</span><span class="code-editor-text"><span class="code-editor-sel"><span class="code-editor-indent"> </span><span class="code-editor-indent"> </span><span class="code-editor-var">label</span> <span class="code-editor-op">=</span> <span class="code-editor-var">label</span><span class="code-editor-punct">.</span><span class="code-editor-fn">slice</span><span class="code-editor-punct">(</span><span class="code-editor-num">0</span><span class="code-editor-punct">,</span> <span class="code-editor-const">MAX_LENGTH</span><span class="code-editor-punct">)</span></span> <span class="code-editor-op">+</span> <span class="code-editor-str">"…"</span><span class="code-editor-punct">;</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">9</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-punct">}</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">10</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">return</span> <span class="code-editor-fn code-editor-deprecated">escape</span><span class="code-editor-punct">(</span><span class="code-editor-var">label</span><span class="code-editor-punct">);</span> <span class="code-editor-cm">/* escape() is deprecated */</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">11</span><span class="code-editor-text"><span class="code-editor-punct">}</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">12</span><span class="code-editor-text"><span class="code-editor-kw">const</span> <span class="code-editor-var">broken</span> <span class="code-editor-op">=</span> <span class="code-editor-num">0x1</span><span class="code-editor-invalid">G</span><span class="code-editor-punct">;</span></span></span></pre>
</div>
</div>
</div></section>
<section role="tabpanel" id="example-i3-window-frame-default-workspace-panel-1" aria-labelledby="example-i3-window-frame-default-workspace-tab-1" hidden=""><p>Workspace 2 is empty.</p></section><section role="tabpanel" id="example-i3-window-frame-default-workspace-panel-2" aria-labelledby="example-i3-window-frame-default-workspace-tab-2" hidden=""><p>Workspace 3 is empty.</p></section></div></j3w1-i3-window-frame>tabbed
~/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
// Compose the window title of the focused container. import { Container } from "./tree.js"; const MAX_LENGTH = 48; export function title(container) { const name = container.name ?? "untitled…"; let label = `${name} (${container.children.length})`; if (label.length > MAX_LENGTH) { label = label.slice(0, MAX_LENGTH) + "…"; } return escape(label); /* escape() is deprecated */ } const broken = 0x1G;
Workspace 2 is empty.
Workspace 3 is empty.
<j3w1-i3-window-frame id="example-i3-window-frame-tabbed"><div class="i3-window-frame" role="region" aria-label="Workstation, workspace 1: theme, tabbed">
<div class="i3-window-frame-bar" role="group" aria-label="i3 bar">
<div class="i3-window-frame-workspaces" role="tablist" aria-label="Workspaces">
<button class="i3-window-frame-workspace" type="button" role="tab" aria-selected="true" tabindex="0" id="example-i3-window-frame-tabbed-workspace-tab-0" aria-controls="example-i3-window-frame-tabbed-workspace-panel-0">1:theme</button>
<button class="i3-window-frame-workspace i3-window-frame-workspace-demo-target" type="button" role="tab" aria-selected="false" tabindex="-1" id="example-i3-window-frame-tabbed-workspace-tab-1" aria-controls="example-i3-window-frame-tabbed-workspace-panel-1">2:reference</button>
<button class="i3-window-frame-workspace i3-window-frame-workspace-urgent" type="button" role="tab" aria-selected="false" tabindex="-1" id="example-i3-window-frame-tabbed-workspace-tab-2" aria-controls="example-i3-window-frame-tabbed-workspace-panel-2">3:ports<span class="i3-window-frame-urgent-mark">!<span class="sr-only"> urgent</span></span></button>
</div>
<div class="i3-window-frame-status" role="group" lang="zh" aria-label="状态">
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 处理器 12%</span>
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 内存储器 3.1G</span>
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 局域网 up</span>
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 电池 87%</span>
<time class="i3-window-frame-block i3-window-frame-clock" datetime="2026-09-06T14:32:07">09月06号 14时32分07秒</time>
</div>
</div>
<section role="tabpanel" id="example-i3-window-frame-tabbed-workspace-panel-0" aria-labelledby="example-i3-window-frame-tabbed-workspace-tab-0"><div class="i3-window-frame-area">
<div class="i3-window-frame-container i3-window-frame-focused" role="group" aria-label="Tabbed container, focused" tabindex="0">
<div class="i3-window-frame-tabs" role="tablist" aria-label="Windows in the container">
<button class="i3-window-frame-tab" type="button" role="tab" id="example-i3-window-frame-tabbed-i3-tab-terminal" aria-selected="true" aria-controls="example-i3-window-frame-tabbed-i3-panel-terminal" tabindex="0">~/theme — zsh</button>
<button class="i3-window-frame-tab" type="button" role="tab" id="example-i3-window-frame-tabbed-i3-tab-editor" aria-selected="false" aria-controls="example-i3-window-frame-tabbed-i3-panel-editor" tabindex="-1">title.js — editor</button>
</div>
<div class="i3-window-frame-panel" role="tabpanel" id="example-i3-window-frame-tabbed-i3-panel-terminal" aria-labelledby="example-i3-window-frame-tabbed-i3-tab-terminal">
<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>
</div>
<div class="i3-window-frame-panel" role="tabpanel" id="example-i3-window-frame-tabbed-i3-panel-editor" aria-labelledby="example-i3-window-frame-tabbed-i3-tab-editor" hidden="">
<div class="code-editor" role="textbox" aria-multiline="true" aria-readonly="true" aria-label="title.js, read-only" tabindex="0">
<pre class="code-editor-pre"><span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">1</span><span class="code-editor-text"><span class="code-editor-cm">// Compose the window title of the focused container.</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">2</span><span class="code-editor-text"><span class="code-editor-kw">import</span> <span class="code-editor-punct">{</span> <span class="code-editor-type">Container</span> <span class="code-editor-punct">}</span> <span class="code-editor-kw">from</span> <span class="code-editor-str">"./tree.js"</span><span class="code-editor-punct">;</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">3</span><span class="code-editor-text"><span class="code-editor-kw">const</span> <span class="code-editor-const">MAX_LENGTH</span> <span class="code-editor-op">=</span> <span class="code-editor-num">48</span><span class="code-editor-punct">;</span><span class="code-editor-ws" aria-hidden="true" data-whitespace="··"></span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">4</span><span class="code-editor-text"><span class="code-editor-kw">export</span> <span class="code-editor-kw">function</span> <span class="code-editor-fn">title</span><span class="code-editor-punct code-editor-bracket">(</span><span class="code-editor-var">container</span><span class="code-editor-punct code-editor-bracket">)</span> <span class="code-editor-punct">{</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">5</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">const</span> <span class="code-editor-var">name</span> <span class="code-editor-op">=</span> <span class="code-editor-var">container</span><span class="code-editor-punct">.</span><span class="code-editor-prop">name</span> <span class="code-editor-op">??</span> <span class="code-editor-str">"untitled<span class="code-editor-esc">…</span>"</span><span class="code-editor-punct">;</span></span></span>
<span class="code-editor-line code-editor-line-current"><span class="code-editor-ln" aria-hidden="true">6</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">let</span> <span class="code-editor-var">label</span> <span class="code-editor-op">=</span> <span class="code-editor-str">`${</span><span class="code-editor-var">name</span><span class="code-editor-str">} (${</span><span class="code-editor-var">container</span><span class="code-editor-punct">.</span><span class="code-editor-prop">children</span><span class="code-editor-punct">.</span><span class="code-editor-prop">length</span><span class="code-editor-str">})`</span><span class="code-editor-punct">;</span><span class="code-editor-caret" aria-hidden="true"></span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">7</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">if</span> <span class="code-editor-punct">(</span><span class="code-editor-sel"><span class="code-editor-var">label</span><span class="code-editor-punct">.</span><span class="code-editor-prop">length</span> <span class="code-editor-op">></span> <span class="code-editor-const">MAX_LENGTH</span><span class="code-editor-punct">)</span> <span class="code-editor-punct">{</span></span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">8</span><span class="code-editor-text"><span class="code-editor-sel"><span class="code-editor-indent"> </span><span class="code-editor-indent"> </span><span class="code-editor-var">label</span> <span class="code-editor-op">=</span> <span class="code-editor-var">label</span><span class="code-editor-punct">.</span><span class="code-editor-fn">slice</span><span class="code-editor-punct">(</span><span class="code-editor-num">0</span><span class="code-editor-punct">,</span> <span class="code-editor-const">MAX_LENGTH</span><span class="code-editor-punct">)</span></span> <span class="code-editor-op">+</span> <span class="code-editor-str">"…"</span><span class="code-editor-punct">;</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">9</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-punct">}</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">10</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">return</span> <span class="code-editor-fn code-editor-deprecated">escape</span><span class="code-editor-punct">(</span><span class="code-editor-var">label</span><span class="code-editor-punct">);</span> <span class="code-editor-cm">/* escape() is deprecated */</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">11</span><span class="code-editor-text"><span class="code-editor-punct">}</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">12</span><span class="code-editor-text"><span class="code-editor-kw">const</span> <span class="code-editor-var">broken</span> <span class="code-editor-op">=</span> <span class="code-editor-num">0x1</span><span class="code-editor-invalid">G</span><span class="code-editor-punct">;</span></span></span></pre>
</div>
</div>
</div>
</div></section>
<section role="tabpanel" id="example-i3-window-frame-tabbed-workspace-panel-1" aria-labelledby="example-i3-window-frame-tabbed-workspace-tab-1" hidden=""><p>Workspace 2 is empty.</p></section><section role="tabpanel" id="example-i3-window-frame-tabbed-workspace-panel-2" aria-labelledby="example-i3-window-frame-tabbed-workspace-tab-2" hidden=""><p>Workspace 3 is empty.</p></section></div></j3w1-i3-window-frame>floating
~/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
// Compose the window title of the focused container. import { Container } from "./tree.js"; const MAX_LENGTH = 48; export function title(container) { const name = container.name ?? "untitled…"; let label = `${name} (${container.children.length})`; if (label.length > MAX_LENGTH) { label = label.slice(0, MAX_LENGTH) + "…"; } return escape(label); /* escape() is deprecated */ } const broken = 0x1G;
Workspace 2 is empty.
Workspace 3 is empty.
<j3w1-i3-window-frame id="example-i3-window-frame-floating"><div class="i3-window-frame" role="region" aria-label="Workstation, workspace 1: theme, with a floating window">
<div class="i3-window-frame-bar" role="group" aria-label="i3 bar">
<div class="i3-window-frame-workspaces" role="tablist" aria-label="Workspaces">
<button class="i3-window-frame-workspace" type="button" role="tab" aria-selected="true" tabindex="0" id="example-i3-window-frame-floating-workspace-tab-0" aria-controls="example-i3-window-frame-floating-workspace-panel-0">1:theme</button>
<button class="i3-window-frame-workspace i3-window-frame-workspace-demo-target" type="button" role="tab" aria-selected="false" tabindex="-1" id="example-i3-window-frame-floating-workspace-tab-1" aria-controls="example-i3-window-frame-floating-workspace-panel-1">2:reference</button>
<button class="i3-window-frame-workspace i3-window-frame-workspace-urgent" type="button" role="tab" aria-selected="false" tabindex="-1" id="example-i3-window-frame-floating-workspace-tab-2" aria-controls="example-i3-window-frame-floating-workspace-panel-2">3:ports<span class="i3-window-frame-urgent-mark">!<span class="sr-only"> urgent</span></span></button>
</div>
<div class="i3-window-frame-status" role="group" lang="zh" aria-label="状态">
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 处理器 12%</span>
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 内存储器 3.1G</span>
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 局域网 up</span>
<span class="i3-window-frame-block"><span class="i3-window-frame-glyph" aria-hidden="true"></span> 电池 87%</span>
<time class="i3-window-frame-block i3-window-frame-clock" datetime="2026-09-06T14:32:07">09月06号 14时32分07秒</time>
</div>
</div>
<section role="tabpanel" id="example-i3-window-frame-floating-workspace-panel-0" aria-labelledby="example-i3-window-frame-floating-workspace-tab-0"><div class="i3-window-frame-area i3-window-frame-area-floating">
<div class="i3-window-frame-window" role="group" aria-label="Terminal window" tabindex="0">
<div class="i3-window-frame-title">~/theme — zsh</div>
<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>
</div>
<div class="i3-window-frame-window i3-window-frame-floating i3-window-frame-focused" role="group" aria-label="Editor window, floating, focused" tabindex="0">
<div class="i3-window-frame-title">title.js — editor</div>
<div class="code-editor" role="textbox" aria-multiline="true" aria-readonly="true" aria-label="title.js, read-only" tabindex="0">
<pre class="code-editor-pre"><span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">1</span><span class="code-editor-text"><span class="code-editor-cm">// Compose the window title of the focused container.</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">2</span><span class="code-editor-text"><span class="code-editor-kw">import</span> <span class="code-editor-punct">{</span> <span class="code-editor-type">Container</span> <span class="code-editor-punct">}</span> <span class="code-editor-kw">from</span> <span class="code-editor-str">"./tree.js"</span><span class="code-editor-punct">;</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">3</span><span class="code-editor-text"><span class="code-editor-kw">const</span> <span class="code-editor-const">MAX_LENGTH</span> <span class="code-editor-op">=</span> <span class="code-editor-num">48</span><span class="code-editor-punct">;</span><span class="code-editor-ws" aria-hidden="true" data-whitespace="··"></span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">4</span><span class="code-editor-text"><span class="code-editor-kw">export</span> <span class="code-editor-kw">function</span> <span class="code-editor-fn">title</span><span class="code-editor-punct code-editor-bracket">(</span><span class="code-editor-var">container</span><span class="code-editor-punct code-editor-bracket">)</span> <span class="code-editor-punct">{</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">5</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">const</span> <span class="code-editor-var">name</span> <span class="code-editor-op">=</span> <span class="code-editor-var">container</span><span class="code-editor-punct">.</span><span class="code-editor-prop">name</span> <span class="code-editor-op">??</span> <span class="code-editor-str">"untitled<span class="code-editor-esc">…</span>"</span><span class="code-editor-punct">;</span></span></span>
<span class="code-editor-line code-editor-line-current"><span class="code-editor-ln" aria-hidden="true">6</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">let</span> <span class="code-editor-var">label</span> <span class="code-editor-op">=</span> <span class="code-editor-str">`${</span><span class="code-editor-var">name</span><span class="code-editor-str">} (${</span><span class="code-editor-var">container</span><span class="code-editor-punct">.</span><span class="code-editor-prop">children</span><span class="code-editor-punct">.</span><span class="code-editor-prop">length</span><span class="code-editor-str">})`</span><span class="code-editor-punct">;</span><span class="code-editor-caret" aria-hidden="true"></span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">7</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">if</span> <span class="code-editor-punct">(</span><span class="code-editor-sel"><span class="code-editor-var">label</span><span class="code-editor-punct">.</span><span class="code-editor-prop">length</span> <span class="code-editor-op">></span> <span class="code-editor-const">MAX_LENGTH</span><span class="code-editor-punct">)</span> <span class="code-editor-punct">{</span></span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">8</span><span class="code-editor-text"><span class="code-editor-sel"><span class="code-editor-indent"> </span><span class="code-editor-indent"> </span><span class="code-editor-var">label</span> <span class="code-editor-op">=</span> <span class="code-editor-var">label</span><span class="code-editor-punct">.</span><span class="code-editor-fn">slice</span><span class="code-editor-punct">(</span><span class="code-editor-num">0</span><span class="code-editor-punct">,</span> <span class="code-editor-const">MAX_LENGTH</span><span class="code-editor-punct">)</span></span> <span class="code-editor-op">+</span> <span class="code-editor-str">"…"</span><span class="code-editor-punct">;</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">9</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-punct">}</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">10</span><span class="code-editor-text"><span class="code-editor-indent"> </span><span class="code-editor-kw">return</span> <span class="code-editor-fn code-editor-deprecated">escape</span><span class="code-editor-punct">(</span><span class="code-editor-var">label</span><span class="code-editor-punct">);</span> <span class="code-editor-cm">/* escape() is deprecated */</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">11</span><span class="code-editor-text"><span class="code-editor-punct">}</span></span></span>
<span class="code-editor-line"><span class="code-editor-ln" aria-hidden="true">12</span><span class="code-editor-text"><span class="code-editor-kw">const</span> <span class="code-editor-var">broken</span> <span class="code-editor-op">=</span> <span class="code-editor-num">0x1</span><span class="code-editor-invalid">G</span><span class="code-editor-punct">;</span></span></span></pre>
</div>
</div>
</div></section>
<section role="tabpanel" id="example-i3-window-frame-floating-workspace-panel-1" aria-labelledby="example-i3-window-frame-floating-workspace-tab-1" hidden=""><p>Workspace 2 is empty.</p></section><section role="tabpanel" id="example-i3-window-frame-floating-workspace-panel-2" aria-labelledby="example-i3-window-frame-floating-workspace-tab-2" hidden=""><p>Workspace 3 is empty.</p></section></div></j3w1-i3-window-frame>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@4.0.0import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/i3-window-frame.css';
import '@j3w1/ui/register/i3-window-frame';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@4.0.0 j3w1-ui copy i3-window-frame --out ./vendor/j3w1/i3-window-frameThe 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. |
events
| Name | Type / signature | Meaning |
|---|---|---|
j3w1-window-action | CustomEvent | Request a host window action; the browser component does not control OS windows. |
Dependencies and verification
Registered components: none. Style dependencies: terminal, code-editor, tabs.
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
i3 window frame i3-window-frame
The workstation frame; an i3 bar with workspaces and Chinese i3status labels above the terminal and code-editor components as tiled, tabbed or floating windows behind i3 title bars.
Report an issue with this component
Tokens
Focus a role to inspect its values; follow its link for persistent usage and source details.
| Part | Role | Value | Use |
|---|---|---|---|
root.bg | color.surface.desktopobserveduse | #000000 | Behind every window. |
root.border | color.border.defaultapproveduse | #482b2b | D-041 border.default: color.primitive.modern.divider. |
bar.bg | color.surface.chromeapproveduse | #000000 | D-041 surface.chrome: color.primitive.ink.0. |
bar.text | color.text.defaultapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
bar.rule | color.border.dividerapproveduse | #482b2b | D-041 border.divider: color.primitive.modern.divider. |
workspace.text | color.text.defaultapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
workspace.selected-bg | color.interaction.selection.bgapproveduse | #531310 | Selected row, tab, workspace; D-027 recessed the fill, leaving the 2px indicator and the check to carry selection. |
workspace.selected-text | color.interaction.selection.textobserveduse | #f4eeee | Text on the selection. |
workspace.bg-hover | color.interaction.hover.bgapproveduse | #1c1010 | D-041 interaction.hover.bg: color.primitive.modern.hover. |
workspace.ring | color.interaction.focus.ringobserveduse | #e53935 | 1px dashed focus ring on controls and rows. |
workspace.ring-on-selection | color.interaction.focus.ringobserveduse | #e53935 | 1px dashed focus ring on controls and rows. |
workspace.urgent-bg | color.status.danger.fillobserveduse | #dc282e | Danger fill. |
workspace.urgent-text | color.status.danger.on-fillobserveduse | #f9faf9 | Text on the danger fill (4.58:1). |
status.separator | color.text.mutedapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
status.glyph | color.icon.decorativeapproveduse | #986f72 | D-041 icon.decorative: color.primitive.modern.control. |
clock.text | color.text.brightapproveduse | #ffa2a7 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
area.bg | color.surface.desktopobserveduse | #000000 | Behind every window. |
window.bg | color.surface.canvasapproveduse | #000000 | Page and terminal background. |
window.border | color.border.defaultapproveduse | #482b2b | D-041 border.default: color.primitive.modern.divider. |
window.border-focused | color.border.activeobserveduse | #e53935 | Active or focused control border. |
window.ring | color.interaction.focus.ring-containerobserveduse | #ffa2a7 | Focus colour for containers and explicitly mapped filled controls (D-015); component rules determine ring geometry. |
title.bg | color.surface.chromeapproveduse | #000000 | D-041 surface.chrome: color.primitive.ink.0. |
title.text | color.text.mutedapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
title.bg-focused | color.surface.chrome-altapproveduse | #140b0b | D-041 surface.chrome-alt: color.primitive.modern.raised. |
title.text-focused | color.text.brightapproveduse | #ffa2a7 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
tab.indicator | color.border.selected-indicatorobserveduse | #e53935 | 2px indicator bar on the selected tab or nav item. |
tab.indicator-inactive | color.border.selected-indicator-inactiveobserveduse | #9e231f | Indicator bar when the container is not focused. |
floating.border | color.border.overlayapproveduse | #c81a1a | D-041 owner correction: red control and floating-frame borders, distinct from rose text. |
floating.shadow | shadow.floatingobserveduse | 0px 6px 22px 0px rgb(0 0 0 / 55%) | The only shadow: the i3 floating window. |
terminal.bg | color.terminal.bgapproveduse | #000000 | D-041 terminal.bg: color.primitive.ink.0. |
terminal.text | color.terminal.fgapproveduse | #ffa2a7 | D-041: bright rose terminal text for readable black-background shells. |
editor.bg | color.code.bgapproveduse | #000000 | D-041 code.bg: color.primitive.ink.0. |
State matrix
Every declared state and combination, statically rendered; the default cell is live. Sizes: compact, comfortable (switch with the density control above).
| State | Tiled | Tabbed | Floating |
|---|---|---|---|
default | ~/theme — zsh
~/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 title.js — editor
// Compose the window title of the focused container. import { Container } from "./tree.js"; const MAX_LENGTH = 48; export function title(container) { const name = container.name ?? "untitled…"; let label = `${name} (${container.children.length})`; if (label.length > MAX_LENGTH) { label = label.slice(0, MAX_LENGTH) + "…"; } return escape(label); /* escape() is deprecated */ } const broken = 0x1G; | ~/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 // Compose the window title of the focused container. import { Container } from "./tree.js"; const MAX_LENGTH = 48; export function title(container) { const name = container.name ?? "untitled…"; let label = `${name} (${container.children.length})`; if (label.length > MAX_LENGTH) { label = label.slice(0, MAX_LENGTH) + "…"; } return escape(label); /* escape() is deprecated */ } const broken = 0x1G; | ~/theme — zsh
~/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 title.js — editor
// Compose the window title of the focused container. import { Container } from "./tree.js"; const MAX_LENGTH = 48; export function title(container) { const name = container.name ?? "untitled…"; let label = `${name} (${container.children.length})`; if (label.length > MAX_LENGTH) { label = label.slice(0, MAX_LENGTH) + "…"; } return escape(label); /* escape() is deprecated */ } const broken = 0x1G; |
focus-visible | |||
selected | |||
container-inactive | |||
error |
Purpose
The frame the palette was tuned in. It proves that the terminal and code-editor components sit in window chrome drawn from the same roles, and it records the workstation’s geometry as reference metrics. A specimen of composition, not a desktop: only i3 and sway ports draw this frame.
Anatomy
Parts as listed in the anatomy.
States
| State | Visual | Non-colour channel |
|---|---|---|
| default | terminal window focused: color.border.active frame, bright title; editor at rest; workspace 1 filled | the title text; aria-selected |
| focus-visible | 2px color.interaction.focus.ring-container ring at −3px inside the focused window or container; the client draws no second ring | the ring |
| selected | workspace 2 takes the selection fill with color.interaction.selection.text, 1px dashed color.interaction.focus.ring at −2px when focused; workspace 1 at rest | aria-selected |
| container-inactive | no window focused: every frame color.border.default, every title color.text.muted on color.surface.chrome, tab indicator color.border.selected-indicator-inactive, no caret | lightness drop; no caret |
| error | workspace 3 urgent: color.status.danger.fill with color.status.danger.on-fill and a trailing ! | the ! mark; “urgent” read to assistive technology |
The clients keep their own states (the terminal’s busy cursor, the editor’s selection and read-only gutter); only the states the frame adds are declared here.
Keyboard
As in the key table. A window group can hold focus itself, as i3 focuses a container. Nothing traps focus.
Accessibility
The region names its workspace and layout. The workspace tablist is named;
the status group is lang="zh";
its Nerd Font glyphs are aria-hidden, so only the labels are read. Every
window is a named group; the focused and the floating window say so in their
names. Urgency carries the ! mark and a visually hidden “urgent”. Text meets
4.5:1; frames, the ring and the urgent fill 3:1.
Portability
The geometry is recorded so a port of the i3 configuration matches the workstation; any other application keeps its own window manager, bar and gaps.
Non-examples
Rounded corners or a title-bar gradient. A focused window that glows or blurs its neighbours. A shadow under a tiled window. 14/−2 gaps forced into an unrelated application. A red underline instead of the selection fill for the workspace. Traffic-light buttons in the title bar. A translucent bar.
Contrast report
21 declared pairs measured on resolved sRGB values with the WCAG 2.x formula; 0 waived (decorative only), 0 failing. A pass is a design target for the named role, not an application-wide conformance claim.
| Pair | State | Kind | Foreground | Background | Ratio | Min | Result |
|---|---|---|---|---|---|---|---|
| i3-window-frame default text | default | text | color.text.muted #d4868b | color.surface.chrome #000000 | 7.58 | 4.5 | pass |
| i3-window-frame focus-visible text | focus-visible | text | color.text.bright #ffa2a7 | color.surface.chrome-alt #140b0b | 10.14 | 4.5 | pass |
| i3-window-frame focus-visible outline | focus-visible | ui | color.interaction.focus.ring-container #ffa2a7 | color.surface.chrome-alt #140b0b | 10.14 | 3 | pass |
| i3-window-frame selected text | selected | text | color.interaction.selection.text #f4eeee | color.interaction.selection.bg #531310 | 12.47 | 4.5 | pass |
| i3-window-frame container-inactive text | container-inactive | text | color.text.muted #d4868b | color.surface.chrome #000000 | 7.58 | 4.5 | pass |
| i3-window-frame error text | error | text | color.status.danger.on-fill #f9faf9 | color.status.danger.fill #dc282e | 4.58 | 4.5 | pass |
| ring on a selected workspace when focused | selected | ui | color.interaction.focus.ring #e53935 | color.interaction.selection.bg #531310 | 3.38 | 3 | pass |
| workspace names and status text on the bar | — | text | color.text.default #e99499 | color.surface.chrome #000000 | 9.16 | 4.5 | pass |
| clock on the bar | — | text | color.text.bright #ffa2a7 | color.surface.chrome #000000 | 10.98 | 4.5 | pass |
| focused title | — | text | color.text.bright #ffa2a7 | color.surface.chrome-alt #140b0b | 10.14 | 4.5 | pass |
| focused window frame on the desktop | — | ui | color.border.active #e53935 | color.surface.desktop #000000 | 4.97 | 3 | pass |
| floating window frame on the desktop | — | ui | color.border.overlay #c81a1a | color.surface.desktop #000000 | 3.62 | 3 | pass |
| container ring on the window surface | focus-visible | ui | color.interaction.focus.ring-container #ffa2a7 | color.surface.canvas #000000 | 10.98 | 3 | pass |
| ring on a workspace or tab | — | ui | color.interaction.focus.ring #e53935 | color.surface.chrome #000000 | 4.97 | 3 | pass |
| visible-tab indicator on the title row | — | ui | color.border.selected-indicator #e53935 | color.surface.chrome #000000 | 4.97 | 3 | pass |
| urgent fill against the bar | error | ui | color.status.danger.fill #dc282e | color.surface.chrome #000000 | 4.39 | 3 | pass |
| visible-workspace fill against the bar | — | ui | color.interaction.selection.bg #531310 | color.surface.chrome #000000 | 1.47 | 1 | pass |
| inactive tab indicator | container-inactive | ui | color.border.selected-indicator-inactive #9e231f | color.surface.chrome #000000 | 2.71 | 1 | pass |
| unfocused window frames (decorative) | — | ui | color.border.default #482b2b | color.surface.desktop #000000 | 1.66 | 1 | pass |
| status block separators (decorative) | — | ui | color.text.muted #d4868b | color.surface.chrome #000000 | 7.58 | 1 | pass |
| status glyphs (decorative) | — | ui | color.icon.decorative #986f72 | color.surface.chrome #000000 | 4.85 | 1 | pass |
Keys
| Key | Action |
|---|---|
| Tab / Shift+Tab | The workspace tablist (its selected tab is the stop), then each window group, then the client inside it; in the tabbed variant the tab list, then the visible panel's client. |
| Arrow keys | Move between workspaces in the bar and between tabs in a tabbed container; inside a client the client's own contract applies. |
| Enter / Space | Shows the workspace or tab under focus. |
| Mod+h j k l, Mod+1..9 | The window manager's own bindings move focus and switch workspaces on the workstation; the specimen documents them and does not reimplement them. |
For agents
Component JSON ·Implementation brief ·Build a task kit ·
Related: terminal code-editor tabs
Stress fixtures: FX-STATE-MATRIX FX-320 FX-360 FX-ZOOM-200 FX-RM FX-HC FX-I18N FX-RTL FX-DENSITY