j3w1 / theme

j3w1 / theme4.0.0

j3w1 / command

  • SPEC Overview
  • SPEC Foundations
  • SPEC Components
  • SPEC Patterns
  • SPEC Tokens
  • SPEC Tools
  • SPEC Workbench
  • SPEC Form builder
  • SPEC Task kit
  • SPEC Recipes
  • SPEC Figma bridge
  • SPEC Report an issue
  • SPEC Implement
  • SPEC For agents
  • SPEC Ports
  • SPEC Releases
  • SPEC Specification
  • DEMO Vue application demo

Code editor

The editor surface, gutter, caret, current line, selection, bracket match and monochrome syntax roles that every code-editing or code-viewing host maps onto.

stable · light DOM · 4.0.0. Light DOM retains static content, native semantics, label relationships and host composition without duplicating controls.

Live variants

default

// 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;
Markup
<j3w1-code-editor id="example-code-editor-default"><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">&gt;</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></j3w1-code-editor>

markup

<!doctype html>
<!-- window frame specimen -->
<html lang="en">
  <head>
    <title>j3w1 &mdash; theme</title>
  </head>
  <body class="frame" data-density="compact">
    <h1>Window frame</h1>
    <marquee>obsolete</marquee>
    <p>Focus is a ring; selection is a fill.</p>
  </body>
</html><
Markup
<j3w1-code-editor id="example-code-editor-markup"><div class="code-editor" role="textbox" aria-multiline="true" aria-readonly="true" aria-label="frame.html, 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-punct">&lt;!</span><span class="code-editor-kw">doctype</span> <span class="code-editor-attr">html</span><span class="code-editor-punct">&gt;</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-cm">&lt;!-- window frame specimen --&gt;</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-punct">&lt;</span><span class="code-editor-tag">html</span> <span class="code-editor-attr">lang</span><span class="code-editor-op">=</span><span class="code-editor-str">"en"</span><span class="code-editor-punct">&gt;</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-indent">  </span><span class="code-editor-punct">&lt;</span><span class="code-editor-tag">head</span><span class="code-editor-punct">&gt;</span></span></span>
<span class="code-editor-line code-editor-line-current"><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-indent">  </span><span class="code-editor-punct">&lt;</span><span class="code-editor-tag">title</span><span class="code-editor-punct">&gt;</span>j3w1 <span class="code-editor-esc">&amp;mdash;</span> theme<span class="code-editor-punct">&lt;/</span><span class="code-editor-tag">title</span><span class="code-editor-punct">&gt;</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">6</span><span class="code-editor-text"><span class="code-editor-indent">  </span><span class="code-editor-punct">&lt;/</span><span class="code-editor-tag">head</span><span class="code-editor-punct">&gt;</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-punct">&lt;</span><span class="code-editor-tag">body</span> <span class="code-editor-attr">class</span><span class="code-editor-op">=</span><span class="code-editor-str">"frame"</span> <span class="code-editor-attr">data-density</span><span class="code-editor-op">=</span><span class="code-editor-str">"compact"</span><span class="code-editor-punct">&gt;</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-indent">  </span><span class="code-editor-indent">  </span><span class="code-editor-punct code-editor-bracket">&lt;</span><span class="code-editor-tag">h1</span><span class="code-editor-punct code-editor-bracket">&gt;</span><span class="code-editor-heading">Window frame</span><span class="code-editor-punct">&lt;/</span><span class="code-editor-tag">h1</span><span class="code-editor-punct">&gt;</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-indent">  </span><span class="code-editor-punct">&lt;</span><span class="code-editor-tag code-editor-deprecated">marquee</span><span class="code-editor-punct">&gt;</span>obsolete<span class="code-editor-punct">&lt;/</span><span class="code-editor-tag code-editor-deprecated">marquee</span><span class="code-editor-punct">&gt;</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-indent">  </span><span class="code-editor-punct">&lt;</span><span class="code-editor-tag">p</span><span class="code-editor-punct">&gt;</span><span class="code-editor-sel">Focus is a ring; selection is a fill.</span><span class="code-editor-punct">&lt;/</span><span class="code-editor-tag">p</span><span class="code-editor-punct">&gt;</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-indent">  </span><span class="code-editor-sel"><span class="code-editor-punct">&lt;/</span><span class="code-editor-tag">body</span><span class="code-editor-punct">&gt;</span></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">12</span><span class="code-editor-text"><span class="code-editor-punct">&lt;/</span><span class="code-editor-tag">html</span><span class="code-editor-punct">&gt;</span><span class="code-editor-invalid">&lt;</span></span></span></pre>
</div></j3w1-code-editor>

folded

export function title(container) {
  const name = container.name ?? "untitled";
  if (label.length > MAX_LENGTH) { ⋯ }
  return escape(label); /* escape() is deprecated */
}
Markup
<j3w1-code-editor id="example-code-editor-folded"><div class="code-editor" role="textbox" aria-multiline="true" aria-readonly="true" aria-label="title.js with a folded region, read-only" tabindex="0">
  <pre class="code-editor-pre"><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 code-editor-line-current"><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><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"><span class="code-editor-fold-gutter">›</span>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">&gt;</span> <span class="code-editor-const">MAX_LENGTH</span><span class="code-editor-punct">)</span> <span class="code-editor-punct">{</span></span> <span class="code-editor-fold" role="img" aria-label="3 folded lines">⋯</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-sel"><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> <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 class="code-editor-ws" aria-hidden="true" data-whitespace="·"></span></span></span></pre>
</div></j3w1-code-editor>

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.0
import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/code-editor.css';
import '@j3w1/ui/register/code-editor';

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.

Vue SFC, React, Astro and plain HTML integration →

Copy the complete implementation

npx --package=@j3w1/ui@4.0.0 j3w1-ui copy code-editor --out ./vendor/j3w1/code-editor

The 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

NameType / signatureMeaning
disabledCustomEventDisable the native controls owned by this instance.
loadingCustomEventMark the primary control busy and prevent duplicate activation.

properties

NameType / signatureMeaning
disabledbooleanDelegates disabled state to native children.
namestringNative control name; application form keys remain explicit.

methods

NameType / signatureMeaning
refresh(): voidReconnect behavior after replacing native child structure.
focus(options?: FocusOptions): voidFocus the first usable native control.
setText(text: string): voidReplace the bounded read-only text view; no code or shell execution occurs.

events

NameType / signatureMeaning
j3w1-actionCustomEventRequest 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

Code editor code-editor

  • Family: Developer interfaces
  • Maturity: stable
  • Priority: R1
  • Since: 0.1.0
  • Custom widget: presentation of <pre> inside role=textbox with aria-multiline and aria-readonly; a real editor is a host surface — APG pattern
  • specified
  • demonstrated
  • test implemented

The editor surface, gutter, caret, current line, selection, bracket match and monochrome syntax roles that every code-editing or code-viewing host maps onto.

Report an issue with this component

Tokens

Focus a role to inspect its values; follow its link for persistent usage and source details.

PartRoleValueUse
root.bgcolor.code.bgapproveduse#000000D-041 code.bg: color.primitive.ink.0.
root.bordercolor.border.controlapproveduse#c81a1aD-041 owner correction: red control and floating-frame borders, distinct from rose text.
root.ringcolor.interaction.focus.ring-containerobserveduse#ffa2a7Focus colour for containers and explicitly mapped filled controls (D-015); component rules determine ring geometry.
gutter.bgcolor.code.gutter-bgapproveduse#000000D-041 code.gutter-bg: color.primitive.ink.0.
gutter.rulecolor.code.gutter-ruleapproveduse#482b2bD-041 code.gutter-rule: color.primitive.modern.divider.
gutter.bg-read-onlycolor.surface.sunkenapproveduse#000000Reading and detail panes set below the canvas.
line-number.textcolor.code.line-numberapproveduse#bd787dD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
line-number.text-activecolor.code.line-number-activeapproveduse#e99499D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
line.bg-currentcolor.code.current-lineapproveduse#0d0707D-041 code.current-line: color.primitive.modern.panel.
caret.bgcolor.code.caretapproveduse#ffa2a7D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
selection.bgcolor.code.selection-bgobserveduse#420f0cEditor selection background (muted text stays 4.71:1).
selection.bg-inactivecolor.interaction.selection.inactive-bgobserveduse#420f0cSelection while the container is not focused.
selection.text-inactivecolor.interaction.selection.inactive-textapproveduse#e99499D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
bracket.outlinecolor.code.bracket-matchobserveduse#e53935Matching bracket 1px border.
indent.guidecolor.code.indent-guideapproveduse#482b2bD-041 code.indent-guide: color.primitive.modern.divider.
whitespace.textcolor.code.whitespaceapproveduse#986f72D-041 code.whitespace: color.primitive.modern.control.
fold.textcolor.text.mutedapproveduse#d4868bD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
fold.bordercolor.border.controlapproveduse#c81a1aD-041 owner correction: red control and floating-frame borders, distinct from rose text.
syntax.keywordcolor.code.syntax.keywordapproveduse#c7a0e8D-041 code.syntax.keyword: color.primitive.modern.violet.
syntax.stringcolor.code.syntax.stringapproveduse#82d9a0D-041 code.syntax.string: color.primitive.modern.green.
syntax.commentcolor.code.syntax.commentapproveduse#bd787dD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
syntax.numbercolor.code.syntax.numberapproveduse#e5c07bD-041 code.syntax.number: color.primitive.modern.amber.
syntax.constantcolor.code.syntax.constantapproveduse#e5c07bD-041 code.syntax.constant: color.primitive.modern.amber.
syntax.functioncolor.code.syntax.functionapproveduse#82b4ffD-041 code.syntax.function: color.primitive.modern.blue.
syntax.variablecolor.code.syntax.variableapproveduse#e99499D-041 rose coding text reduces glare while syntax hues distinguish meaning.
syntax.typecolor.code.syntax.typeapproveduse#78d4d4D-041 code.syntax.type: color.primitive.modern.cyan.
syntax.operatorcolor.code.syntax.operatorapproveduse#e99499D-041 rose coding text reduces glare while syntax hues distinguish meaning.
syntax.punctuationcolor.code.syntax.punctuationapproveduse#d4868bD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
syntax.propertycolor.code.syntax.propertyapproveduse#78d4d4D-041 code.syntax.property: color.primitive.modern.cyan.
syntax.headingcolor.code.syntax.headingapproveduse#f4eeeeD-041 code.syntax.heading: color.primitive.modern.bright.
syntax.tagcolor.code.syntax.tagapproveduse#f07178D-041 code.syntax.tag: color.primitive.modern.red.
syntax.attributecolor.code.syntax.attributeapproveduse#e5c07bD-041 code.syntax.attribute: color.primitive.modern.amber.
syntax.escapecolor.code.syntax.escapeapproveduse#e5c07bD-041 code.syntax.escape: color.primitive.modern.amber.
syntax.invalidcolor.code.syntax.invalidapproveduse#f07178D-041 code.syntax.invalid: color.primitive.modern.red.
syntax.deprecatedcolor.code.syntax.deprecatedapproveduse#bd787dD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.

State matrix

Every declared state and combination, statically rendered; the default cell is live. Sizes: compact, comfortable (switch with the density control above).

StateJavaScriptMarkupFolded region
default
// 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;
<!doctype html>
<!-- window frame specimen -->
<html lang="en">
  <head>
    <title>j3w1 &mdash; theme</title>
  </head>
  <body class="frame" data-density="compact">
    <h1>Window frame</h1>
    <marquee>obsolete</marquee>
    <p>Focus is a ring; selection is a fill.</p>
  </body>
</html><
export function title(container) {
  const name = container.name ?? "untitled";
  if (label.length > MAX_LENGTH) { ⋯ }
  return escape(label); /* escape() is deprecated */
}
focus-visible
selected
selected+container-inactive
current
read-only

Purpose

The reference rendering of source code: the contract a real editor’s theme API is mapped onto. It never edits.

Anatomy

Root .code-editor; parts .code-editor-<part>: -pre, -line, -ln (line number), -text, -indent, -ws (rendered whitespace), -caret, -sel (selection range), -bracket, -fold, -fold-gutter. Syntax spans are .code-editor-<role>: -kw keyword, -str string, -cm comment, -num number, -const constant, -fn function, -var variable, -type, -op operator, -punct punctuation, -prop property, -heading, -tag, -attr attribute, -esc escape, -invalid, -deprecated.

States

StateVisualNon-colour channel
defaultcode on color.code.bg; comments italic; invalid text wavy-underlined in color.code.syntax.invalid; deprecated text struck throughitalic, wavy underline, line-through
focus-visible2px color.interaction.focus.ring-container ring at −3px; 1px color.code.caret bar; caret line filled color.code.current-line across gutter and text, its number color.code.line-number-activethe ring; the caret bar
selectedrange filled color.code.selection-bg; syntax colours keptthe host’s selection is announced; the fill spans line ends
selected+container-inactivesame range in color.interaction.selection.inactive-bg with color.interaction.selection.inactive-text; no caret, no ringlightness drop between the two fills
currentboth characters of the matched pair outlined 1px solid color.code.bracket-matchan outline box, not a colour change
read-onlygutter on color.surface.sunken, same line numbers; dotted gutter rule; no caretaria-readonly; dotted rule; no caret

Precedence: selection under the text, current line under the selection, bracket outline and caret above everything. The caret never blinks in the reference; a host that blinks it follows the user’s cursor-blink setting and stops under reduced motion.

Keyboard

As in the key table. The theme only draws what the host’s keys produce; the read-only reference consumes no key. A host that captures Tab offers Escape, then Tab, and announces it.

Accessibility

Syntax colour is decoration; meaning never rides on colour alone (italic comments, wavy-underlined invalid text, struck-through deprecated text). Selection is a fill and focus a ring, drawn together, never substituting for each other. Every syntax role meets 4.5:1 on color.code.bg. Inside color.code.selection-bg, D-041 also keeps comments and types above 4.5:1. The reference uses semantic syntax hues; the existing code.hued.* roles alias those syntax roles for consumers using the earlier opt-in mapping. Line numbers are text people read and meet the text floor; indent guides, rendered whitespace and the gutter rule are decorative. In forced colours the caret, selection and bracket outline take Highlight; syntax spans keep their text styles.

Portability

The port maps these roles onto the host’s theme API without touching caret behaviour, keyboard handling or selection semantics. No bracket-match outline: bold weight, deviation recorded. No 1px caret: the host’s own caret in color.code.caret. The heritage-ansi and extended profiles change role values only, never the mapping.

Non-examples

Rainbow syntax in the reference, or any hue beyond the three bounded ones (hosts opt into code.hued.*, D-030). A blinking or animated caret in the reference. A selection that turns text white and drops the syntax roles. A current line brighter than the selection. A bracket match as a background fill, which reads as a selection. Line numbers in a decorative colour. A glow, gradient or rounded corner on the box. Removing the host’s focus indicator without drawing the container ring.

Contrast report

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

PairStateKindForegroundBackgroundRatioMinResult
code-editor default textdefaulttextcolor.code.syntax.variable #e99499color.code.bg #0000009.164.5pass
code-editor default borderdefaultuicolor.border.control #c81a1acolor.code.bg #0000003.623pass
code-editor focus-visible textfocus-visibletextcolor.code.syntax.variable #e99499color.code.current-line #0d07078.724.5pass
code-editor focus-visible outlinefocus-visibleuicolor.interaction.focus.ring-container #ffa2a7color.code.current-line #0d070710.453pass
code-editor selected textselectedtextcolor.code.syntax.variable #e99499color.code.selection-bg #420f0c7.024.5pass
code-editor selected+container-inactive textselected+container-inactivetextcolor.interaction.selection.inactive-text #e99499color.interaction.selection.inactive-bg #420f0c7.024.5pass
code-editor current textcurrenttextcolor.code.syntax.variable #e99499color.code.bg #0000009.164.5pass
code-editor current bordercurrentuicolor.code.bracket-match #e53935color.code.bg #0000004.973pass
code-editor read-only textread-onlytextcolor.code.line-number #bd787dcolor.surface.sunken #0000006.154.5pass
caret on the current linefocus-visibleuicolor.code.caret #ffa2a7color.code.current-line #0d070710.453pass
bracket-match outline on the editor surfacecurrentuicolor.code.bracket-match #e53935color.code.bg #0000004.973pass
bracket-match outline on the current linecurrentuicolor.code.bracket-match #e53935color.code.current-line #0d07074.733pass
line numbers in the gutter—textcolor.code.line-number #bd787dcolor.code.gutter-bg #0000006.154.5pass
active line number—textcolor.code.line-number-active #e99499color.code.current-line #0d07078.724.5pass
keyword—textcolor.code.syntax.keyword #c7a0e8color.code.bg #0000009.624.5pass
string—textcolor.code.syntax.string #82d9a0color.code.bg #00000012.384.5pass
comment—textcolor.code.syntax.comment #bd787dcolor.code.bg #0000006.154.5pass
number and constant—textcolor.code.syntax.number #e5c07bcolor.code.bg #00000012.164.5pass
function—textcolor.code.syntax.function #82b4ffcolor.code.bg #0000009.924.5pass
type—textcolor.code.syntax.type #78d4d4color.code.bg #00000012.174.5pass
property, heading and invalid text—textcolor.code.syntax.property #78d4d4color.code.bg #00000012.174.5pass
tag—textcolor.code.syntax.tag #f07178color.code.bg #0000007.344.5pass
attribute and escape—textcolor.code.syntax.attribute #e5c07bcolor.code.bg #00000012.164.5pass
deprecated text—textcolor.code.syntax.deprecated #bd787dcolor.code.bg #0000006.154.5pass
comment syntax inside the selectionselectedtextcolor.code.syntax.comment #bd787dcolor.code.selection-bg #420f0c4.714.5pass
type syntax inside the selectionselectedtextcolor.code.syntax.type #78d4d4color.code.selection-bg #420f0c9.324.5pass
muted string text inside the selectionselectedtextcolor.code.syntax.string #82d9a0color.code.selection-bg #420f0c9.494.5pass
keyword and tag text inside the selection (D-029)selectedtextcolor.code.syntax.keyword #c7a0e8color.code.selection-bg #420f0c7.374.5pass
property, heading and invalid text inside the selection (D-029)selectedtextcolor.code.syntax.property #78d4d4color.code.selection-bg #420f0c9.324.5pass
fold marker text—textcolor.text.muted #d4868bcolor.code.bg #0000007.584.5pass
indent guide (decorative)—uicolor.code.indent-guide #482b2bcolor.code.bg #0000001.661pass
rendered whitespace (decorative)—uicolor.code.whitespace #986f72color.code.bg #0000004.851pass
gutter rule (decorative)—uicolor.code.gutter-rule #482b2bcolor.code.bg #0000001.661pass

Keys

KeyAction
(host)The host editor owns every key; the theme changes no binding, no caret behaviour and no selection model.
TabReaches the editor as one stop in the reference; whether Tab inserts or moves focus is the host's rule and is announced by the host.
EscapeIn hosts that trap Tab, Escape must release focus to the next stop; the theme does not provide it.

For agents

Component JSON ·Implementation brief ·Build a task kit ·

Related: diagnostics diff-view terminal

Stress fixtures: FX-STATE-MATRIX FX-320 FX-ZOOM-200 FX-RM FX-HC FX-LONG FX-RTL