Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ Thumbs.db
*.log
*.zip
.claude/

# sample files for theme preview are tracked even though *.log is ignored
!samples/demo.log
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ The first palette change since 1.0. Everything below was made in `themes/_src/va
- **ANSI blue and cyan.** Blue is now a warm gray `#9C948E` (was `#8B8178`, Lc 36 → 45 — `ls`, `grep`, `man` output on black is readable again) and cyan is the terracotta already used for functions, `#C08868` (was `#9A8B7A`). The two former slots were near-identical warm grays (ΔE2000 5.2, indistinguishable under CVD); every pair among the eight normal slots is now ≥ ΔE2000 10 (min 13.6). Bright slots follow: `#A89A8C→#B2AAA3`, `#B8A898→#CEA284`. Black/red/green/yellow/magenta unchanged. Kitty, iTerm2, Alacritty (normal + dim) and Windows Terminal files updated to match.
- **`themes/_snapshot/`** stays as the immutable v1.2.0 reference; the pipeline test now checks structural coverage — every snapshot colour key, tokenColors rule (name/scope/fontStyle) and semantic selector is still present and styled the same, additions allowed — rather than hex equality.

### Added — Scope coverage (all variants, no new hexes)

New `tokenColors` rules and `semanticTokenColors` selectors in `themes/_src/base.yaml`, each bound to an existing role token so every variant inherits it and key parity holds:

- **Diffs / patches**: `markup.inserted` / `markup.deleted` / `markup.changed` take the git-decoration added/deleted/modified colours; `meta.diff.header` (`---`/`+++`/`index`) in doc-comment gray; `meta.diff.range` (`@@ … @@`) in keyword gold, non-bold. `samples/demo.diff` added.
- **Log files**: `token.info-token` / `token.warn-token` / `token.error-token` / `token.debug-token` take the debug-console info/warning/error/source colours (error bold). `samples/demo.log` added.
- **Preprocessor**: `keyword.control.directive` + `punctuation.definition.directive` (so `#` is coloured with `include`/`define`) in keyword gold bold; `entity.name.function.preprocessor` / `entity.name.function.macro` in the macro colour, bold (matches Rust macros).
- **ALL_CAPS constants**: `variable.other.constant`, `constant.other.caps`, `variable.other.enummember` in the constants colour (previously fell through to plain variables).
- **Labels**: `entity.name.label`, `entity.name.goto-label` in the semantic `label` colour.
- **Markdown strikethrough**: `markup.strikethrough` gets `strikethrough` + the deprecated gray.
- **Support variables** (`document`, `window`, `process`, `console`…): `support.variable*` in the `defaultLibrary` colour, italic — same treatment as semantic `*.defaultLibrary`.
- **Semantic selectors**: `selfParameter` / `clsParameter` (= `this`/`self`/`super`), `magicFunction` (= Python magic methods), `builtinConstant` and `boolean` (= number/boolean colour), `builtinType` (= `type.defaultLibrary`, italic), `lifetime`, `attribute`, `derive` (= Rust lifetime/attribute colours, italic), `formatSpecifier` (= f-string braces), `escapeSequence` (= escapes, bold), `event` (= property).
- The pipeline test now checks that everything the v1.2.0 snapshot styled is still styled the same way (additions allowed, drops/restyles fail).

### Changed — Internal: verifier v2, tests, CI

- **Verifier v2** (`scripts/verify-palette.mjs`). New checks alongside the L\* ladder, wavelength band, and key parity: an **APCA Lc** column and per-role floors (body 60 / syntax 40 / special 37 / punctuation 28 / comments 22, overridable per variant via `verify.apcaFloors` — Alone Soft declares a scaled set); **ΔE2000** on every tight ladder gap; a **colour-vision-deficiency** table (Viénot protan/deutan/tritan simulation) over the ten most confusable role pairs, passing on ΔE2000 ≥ 5 or a font-style difference; **ANSI** pairwise ΔE2000 among the eight normal terminal slots (≥ 10); and a **whole-theme wavelength scan** — every chromatic hex in every variant, not just the ten headline roles, must have a dominant wavelength ≥ 575 nm. The perceptual checks were introduced as warnings against the 1.3.1 palette (which missed several — comments Lc 16, ANSI blue/cyan ΔE 5.2, Variables/Parameter under CVD) and are hard failures from 2.0.0. Each check's severity is a one-line `POLICY` entry.
Expand Down
13 changes: 13 additions & 0 deletions samples/demo.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/src/palette.ts b/src/palette.ts
index 3f2a1c0..9b7e4d2 100644
--- a/src/palette.ts
+++ b/src/palette.ts
@@ -12,7 +12,9 @@ export const COMMENTS = '#5C544A';
-export const COMMENTS = '#5C544A';
+export const COMMENTS = '#6E665B'; // APCA Lc 23
export const KEYWORDS = '#C8A040';
-export const ANSI_BLUE = '#8B8178';
-export const ANSI_CYAN = '#9A8B7A';
+export const ANSI_BLUE = '#9C948E';
+export const ANSI_CYAN = '#C08868';
export const FOREGROUND = '#C8B89A';
6 changes: 6 additions & 0 deletions samples/demo.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
2026-08-18T01:30:12.004Z [INFO] server listening on :3000
2026-08-18T01:30:12.118Z [DEBUG] loaded 3 theme variants (alone, alone-soft, alone-focused)
2026-08-18T01:30:14.902Z [WARN] slow request GET /api/palette took 1843ms
2026-08-18T01:30:15.007Z [ERROR] verify-palette: README tables out of date
at check (scripts/verify-palette.mjs:412:9)
2026-08-18T01:30:15.010Z [INFO] rebuild complete
134 changes: 134 additions & 0 deletions themes/_src/base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,36 @@ semanticTokenColors:
foreground: ${semanticTokenColors.*.modification.foreground}
"*.async":
italic: true
# ── Coverage additions (2.0.0): every selector below is bound to an existing
# role token so all variants inherit it and key parity is unaffected. ──
selfParameter:
foreground: ${tokenColors.special_variables_this_self_super.settings.foreground}
italic: true
clsParameter:
foreground: ${tokenColors.special_variables_this_self_super.settings.foreground}
italic: true
magicFunction:
foreground: ${tokenColors.python_magic_methods.settings.foreground}
italic: true
builtinConstant: ${tokenColors.boolean_null_constants.settings.foreground}
boolean: ${tokenColors.boolean_null_constants.settings.foreground}
builtinType:
foreground: ${semanticTokenColors.type.defaultLibrary.foreground}
italic: true
lifetime:
foreground: ${tokenColors.rust_lifetime.settings.foreground}
italic: true
attribute:
foreground: ${tokenColors.rust_attributes.settings.foreground}
italic: true
derive:
foreground: ${tokenColors.rust_attributes.settings.foreground}
italic: true
formatSpecifier: ${tokenColors.python_f_string_braces.settings.foreground}
escapeSequence:
foreground: ${tokenColors.escape_characters.settings.foreground}
bold: true
event: ${semanticTokenColors.property}
tokenColors:
- name: Comments
scope:
Expand Down Expand Up @@ -599,6 +629,110 @@ tokenColors:
settings:
foreground: ${tokenColors.invalid_deprecated.settings.foreground}
fontStyle: strikethrough
# ── Coverage additions (2.0.0): diffs, logs, preprocessor, constants,
# labels, strikethrough, support variables. All bound to existing tokens. ──
- name: Diff Inserted
scope:
- markup.inserted
- markup.inserted.diff
- punctuation.definition.inserted.diff
settings:
foreground: ${colors.gitDecoration.addedResourceForeground}
- name: Diff Deleted
scope:
- markup.deleted
- markup.deleted.diff
- punctuation.definition.deleted.diff
settings:
foreground: ${colors.gitDecoration.deletedResourceForeground}
- name: Diff Changed
scope:
- markup.changed
- markup.changed.diff
- punctuation.definition.changed.diff
settings:
foreground: ${colors.gitDecoration.modifiedResourceForeground}
- name: Diff Headers
scope:
- meta.diff.header
- meta.diff.header.from-file
- meta.diff.header.to-file
- meta.diff.index
- punctuation.definition.from-file.diff
- punctuation.definition.to-file.diff
settings:
foreground: ${tokenColors.documentation_comments.settings.foreground}
- name: Diff Ranges
scope:
- meta.diff.range
- punctuation.definition.range.diff
settings:
foreground: ${tokenColors.keywords.settings.foreground}
fontStyle: ""
- name: Log Info
scope:
- token.info-token
settings:
foreground: ${colors.debugConsole.infoForeground}
- name: Log Warning
scope:
- token.warn-token
settings:
foreground: ${colors.debugConsole.warningForeground}
- name: Log Error
scope:
- token.error-token
settings:
foreground: ${colors.debugConsole.errorForeground}
fontStyle: bold
- name: Log Debug
scope:
- token.debug-token
settings:
foreground: ${colors.debugConsole.sourceForeground}
- name: Preprocessor Directives
scope:
- keyword.control.directive
- punctuation.definition.directive
settings:
foreground: ${tokenColors.keywords.settings.foreground}
fontStyle: bold
- name: Preprocessor Macros
scope:
- entity.name.function.preprocessor
- entity.name.function.macro
settings:
foreground: ${tokenColors.rust_macros.settings.foreground}
fontStyle: bold
- name: Constants (ALL_CAPS)
scope:
- variable.other.constant
- constant.other.caps
- variable.other.enummember
settings:
foreground: ${tokenColors.other_constants.settings.foreground}
- name: Labels
scope:
- entity.name.label
- entity.name.goto-label
settings:
foreground: ${semanticTokenColors.label}
- name: Markdown Strikethrough
scope:
- markup.strikethrough
- punctuation.definition.strikethrough.markdown
settings:
foreground: ${tokenColors.invalid_deprecated.settings.foreground}
fontStyle: strikethrough
- name: Support Variables (globals, DOM)
scope:
- support.variable
- support.variable.property
- support.variable.dom
- support.variable.object.process
settings:
foreground: ${semanticTokenColors.variable.defaultLibrary.foreground}
fontStyle: italic
colors:
foreground: ${colors.foreground}
disabledForeground: ${colors.disabledForeground}
Expand Down
Loading
Loading