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
23 changes: 19 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,29 @@ All notable changes to the **Alone** theme will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [2.0.0] - 2026-08-18

### Changed — Internal: verifier v2, tests, CI (no palette changes)
### Changed — Palette retune (visible look change)

- **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 new perceptual checks report as **warnings** in this release (the current palette misses several — comments Lc 16, ANSI blue/cyan ΔE 5.2, Variables/Parameter under CVD); they become hard failures with the 2.0.0 retune. Each check's severity is a one-line `POLICY` entry.
The first palette change since 1.0. Everything below was made in `themes/_src/variants/*.yaml` and mirrored into the four `terminal/` files; the verifier's perceptual checks (APCA floors, CVD confusability, ANSI ΔE2000, tight-gap ΔE2000, whole-theme wavelength scan) are now **hard failures** and the shipped palette passes all of them. Numbers below are for Alone / Alone Focused against `#0C0A09`; Alone Soft received the same transforms scaled to its dimmer range.

- **Neutrals lose blue-subpixel drive.** The foreground/operator/punctuation grays kept a residual blue channel that lit the display's short-wavelength subpixel for every character on screen. Each neutral was shifted at (near-)constant L\* by pulling the B channel down 10–20 hex and warming the hue: foreground / variables / ANSI white `#C4B8A4→#C8B89A`, operators `#D4C8B8→#D8C8A8`, brightest text / ANSI bright-white `#E8DCD0→#EDDCC4`, mid grays `#9A9080→#9D9078`, `#8A8278→#8D8271`, `#7A7268→#7C7262`, dim UI gray `#5C544A→#5E5446`.
- **Comments up to the readable floor.** `#5C544A→#6E665B` (APCA Lc 16 → 23, WCAG 2.7:1 → 3.5:1) for comments, CodeLens and ANSI bright-black; doc comments `#6B635A→#787062`; line numbers `#4A4540→#56504A`. Still clearly de-emphasised, no longer below the "non-essential text" floor. Soft comments `#4A433B→#625A50` (Lc 18).
- **Ghost text (inline suggestions) no longer identical to comments.** Foreground `#5C544A→#6B635A` plus a faint translucent backing (`editorGhostText.background: #1E191580`, Soft `#18151280`) so a suggestion reads as "proposed", not "commented out". (The italic slant on ghost text is VS Code's own CSS and cannot be changed by a theme.)
- **Accent solid fills dimmed.** `badge.background`, `activityBarBadge.background`, `statusBarItem.remoteBackground` and `extensionBadge.remoteBackground` `#D4A048→#A87C34` — the bright gold rectangles were the largest lit areas in the UI; the dimmer fill still carries Lc 39 for its dark label. Buttons, focus border and cursor keep `#D4A048`.
- **`*.defaultLibrary` becomes a real step.** `variable.defaultLibrary`, `property.defaultLibrary` and `this`/`self`/`super` `#B89860→#B08C50` — one L\* step below Types instead of a near-duplicate.
- **Numbers `#E0A850→#DEA64E`** (L\* 72.5 → 71.8) so Variables→Numbers clears the 3 L\* tight-gap floor without touching the foreground.
- **Parameters `#BCA890→#B8AA9C`.** Separated from Variables on the yellow–blue axis (which red-green-deficient readers retain) instead of the red-green axis; protan/deutan ΔE2000 vs Variables 4.7 → 6.6.
- **Soft Functions `#9A6D53→#976D56`** (ΔE 1.2 from before) so Soft's Types/Functions pair clears the CVD floor; Standard Functions unchanged.
- **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.

### 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.
- **README tables are now rendered by the verifier.** The L\* ladder, Syntax Colors table, bracket list, contrast table (now WCAG **and** APCA) and a new ANSI table live between `<!-- verify:<name>:start/end -->` markers; `node scripts/verify-palette.mjs --write-readme` re-renders them, and the default run fails on drift.
- **Colour math extracted** to `scripts/lib/color.mjs` (sRGB/XYZ/Lab, WCAG, APCA 0.0.98G-4, CIEDE2000, CVD matrices, dominant wavelength) and the generator's substitution/validation rules to `scripts/lib/build.mjs`, so both are unit-testable. `build-themes.mjs` output is byte-identical.
- **Tests** (`npm test`, `node:test`): colour-math sanity (21:1, L\* 100, APCA ±106/108, ΔE2000 red/green ≈ 86.6, sRGB primaries' λd), generator edge cases (bare vs interpolated tokens, unknown/unused tokens, non-object variant roots, path-escaping filenames), build determinism, committed-JSON freshness, `$schema` presence, v1.2.0 snapshot parity (skippable with `PALETTE_CHANGED=1`), and a verifier smoke run.
- **Tests** (`npm test`, `node:test`): colour-math sanity (21:1, L\* 100, APCA ±106/108, ΔE2000 red/green ≈ 86.6, sRGB primaries' λd), generator edge cases (bare vs interpolated tokens, unknown/unused tokens, non-object variant roots, path-escaping filenames), build determinism, committed-JSON freshness, `$schema` presence, v1.2.0 snapshot structural coverage, and a verifier smoke run.
- **CI** (`.github/workflows/ci.yml`): Node 22 + 24 — `npm ci` → build → `git diff --exit-code themes/` → verify → test → `vsce package` (VSIX uploaded as an artifact). Dependabot for npm and GitHub Actions, monthly.
- `@vscode/vsce` added as a devDependency; `npm run package` builds the VSIX.

Expand Down
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,19 @@ On calibrated OLED and miniLED displays, subtle color differences disappear. **A
```text
L* 81 ███████████████████████████ Operators
L* 75 █████████████████████████ Variables
L* 73 ████████████████████████ Numbers
L* 72 ████████████████████████ Numbers
L* 68 ███████████████████████ Keywords (bold)
L* 65 ██████████████████████ Types
L* 61 ████████████████████ Functions
L* 58 ███████████████████ Strings (italic)
L* 55 ██████████████████ Special
L* 48 ████████████████ Punctuation
L* 36 ████████████ Comments (italic)
L* 49 ████████████████ Punctuation
L* 44 ███████████████ Comments (italic)
```

<!-- verify:ladder:end -->

The ladder is monotonic descending. The warm-only palette can't deliver large gaps across all ten tiers — Operators (L\* 81) down to Comments (L\* 36) is a ~45-unit range. The largest gaps cluster at the top and bottom (Operators→Variables 5.9, Special→Punctuation 6.7, Punctuation→Comments 12.3); the middle tiers run in the ~3 L\* range and rely on font style (italic strings/comments/interfaces/`defaultLibrary`, bold keywords/escapes) and hue (gold vs olive vs dusty-rose) to carry the differentiation that lightness alone can't. The ladder above is rendered by `scripts/verify-palette.mjs` from the live theme files; the verifier hard-fails on out-of-order roles and warns on any adjacent gap below 3 L\* (or ΔE2000 below 4).
The ladder is monotonic descending. The warm-only palette can't deliver large gaps across all ten tiers — the whole run from Operators to Comments spans under 40 L\*. The largest gaps sit at the top and bottom (Operators→Variables, Special→Punctuation, Punctuation→Comments); the middle tiers run in the 3–4 L\* range and rely on font style (italic strings/comments/interfaces/`defaultLibrary`, bold keywords/escapes) and hue (gold vs olive vs dusty-rose) to carry the differentiation that lightness alone can't. The ladder above is rendered by `scripts/verify-palette.mjs` from the live theme files (exact per-rung L\* and gaps are in its section 1 output); the verifier hard-fails on out-of-order roles and on any adjacent gap below 3 L\* or ΔE2000 below 4.

---

Expand All @@ -76,9 +76,9 @@ The ladder is monotonic descending. The warm-only palette can't deliver large ga

| Element | Hex | Style |
| -------------------- | --------- | ------------------ |
| Operators | `#D4C8B8` | Normal |
| Variables | `#C4B8A4` | Normal |
| Numbers | `#E0A850` | Normal |
| Operators | `#D8C8A8` | Normal |
| Variables | `#C8B89A` | Normal |
| Numbers | `#DEA64E` | Normal |
| Keywords | `#C8A040` | **Bold** |
| Types | `#BC9858` | Normal |
| Interface/Type-param | `#BC9858` | _Italic_ |
Expand All @@ -87,7 +87,7 @@ The ladder is monotonic descending. The warm-only palette can't deliver large ga
| Strings | `#9A8B60` | _Italic_ |
| Escapes | `#D4B088` | **Bold** |
| Regex / decorators | `#A87878` | _Italic_ |
| Comments | `#5C544A` | _Italic_ |
| Comments | `#6E665B` | _Italic_ |
| Errors | `#D46A66` | **Bold** underline |

<!-- verify:syntax-colors:end -->
Expand Down Expand Up @@ -300,22 +300,22 @@ Matching terminal themes are included in the `terminal/` directory:
| **Alacritty** | `terminal/alone.toml` | Import in your `alacritty.toml` config |
| **Windows Terminal** | `terminal/alone-windows-terminal.json` | Add scheme to `settings.json` |

All terminal themes use the same warm color palette with intentionally muted blue/cyan (replaced with warm grays).
All terminal themes use the same warm color palette. The blue and cyan slots carry no short-wavelength light: blue is a warm gray (`#9C948E`) and cyan is the terracotta used for functions (`#C08868`) — two hues a red-green-deficient reader can still tell apart (ΔE2000 ≥ 10 across all eight normal slots), instead of the two near-identical grays that shipped before 2.0.0. Programs that print blue-on-black (`ls`, `grep`, `man`) stay readable (blue Lc 45 against the terminal background).

The sixteen ANSI slots (as shipped in the VS Code theme and mirrored in the terminal files):

<!-- verify:ansi:start -->

| Slot | Hex | L\* | Bright slot | Hex | L\* |
| ------- | --------- | --- | ------------- | --------- | --- |
| Black | `#0C0A09` | 3 | BrightBlack | `#5C544A` | 36 |
| Black | `#0C0A09` | 3 | BrightBlack | `#6E665B` | 44 |
| Red | `#B85450` | 48 | BrightRed | `#D46A66` | 57 |
| Green | `#9A8B60` | 58 | BrightGreen | `#C4B078` | 72 |
| Yellow | `#D4A048` | 69 | BrightYellow | `#E8B850` | 77 |
| Blue | `#8B8178` | 55 | BrightBlue | `#A89A8C` | 64 |
| Blue | `#9C948E` | 62 | BrightBlue | `#B2AAA3` | 70 |
| Magenta | `#A87878` | 55 | BrightMagenta | `#C89088` | 65 |
| Cyan | `#9A8B7A` | 59 | BrightCyan | `#B8A898` | 70 |
| White | `#C4B8A4` | 75 | BrightWhite | `#E8DCD0` | 88 |
| Cyan | `#C08868` | 61 | BrightCyan | `#CEA284` | 70 |
| White | `#C8B89A` | 75 | BrightWhite | `#EDDCC4` | 89 |

<!-- verify:ansi:end -->

Expand Down Expand Up @@ -350,14 +350,14 @@ Key contrast ratios against the editor background (`#0C0A09`):

| Element | Color | WCAG | WCAG level | APCA Lc |
| --------- | --------- | ------ | ---------- | ------- |
| Operators | `#D4C8B8` | 12.0:1 | AAA | 74 |
| Variables | `#C4B8A4` | 10.1:1 | AAA | 65 |
| Numbers | `#E0A850` | 9.3:1 | AAA | 61 |
| Operators | `#D8C8A8` | 12.0:1 | AAA | 74 |
| Variables | `#C8B89A` | 10.1:1 | AAA | 65 |
| Numbers | `#DEA64E` | 9.1:1 | AAA | 60 |
| Keywords | `#C8A040` | 8.1:1 | AAA | 54 |
| Types | `#BC9858` | 7.3:1 | AAA | 49 |
| Functions | `#C08868` | 6.6:1 | AA | 45 |
| Strings | `#9A8B60` | 5.9:1 | AA | 40 |
| Comments | `#5C544A` | 2.7:1 | — | 16 |
| Comments | `#6E665B` | 3.5:1 | AA (large) | 23 |

<!-- verify:contrast:end -->

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "alone",
"displayName": "Alone",
"description": "A theme for those who thrive coding alone in the dark. The ultimate expression of vision science—protect your dark adaptation during extended sessions.",
"version": "1.3.1",
"version": "2.0.0",
"publisher": "crypticpy",
"author": {
"name": "Chris",
Expand Down
17 changes: 9 additions & 8 deletions scripts/verify-palette.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* Discovers every variant under themes/_src/variants/*.yaml, loads the
* corresponding built JSON from themes/, and runs these checks. Each check
* has a severity in POLICY below — `fail` exits non-zero, `warn` is reported
* but does not fail the run. (v2 introduced the perceptual checks as
* warnings; they flip to `fail` once the palette meets them.)
* but does not fail the run. Since the 2.0.0 retune every check is `fail`;
* demote one to `warn` only while a deliberate palette change is in flight.
*
* 1. L* ladder (standard variant) — the ten headline roles descend in the
* documented order. Out-of-order → fail. Adjacent gaps below
Expand Down Expand Up @@ -56,15 +56,16 @@ const README = path.join(ROOT, 'README.md');
const WRITE_README = process.argv.includes('--write-readme');

// ─── Policy & thresholds ─────────────────────────────────────────────
// Severity per check. Flip a `warn` to `fail` once the palette meets it.
// Severity per check. All hard since 2.0.0; demote to `warn` only while a
// deliberate palette change is in flight.
const POLICY = {
ladderOrder: 'fail',
tightGap: 'warn',
apca: 'warn',
cvd: 'warn',
ansi: 'warn',
tightGap: 'fail',
apca: 'fail',
cvd: 'fail',
ansi: 'fail',
wavelengthBand: 'fail',
wavelengthScan: 'warn',
wavelengthScan: 'fail',
parity: 'fail',
readme: 'fail',
};
Expand Down
16 changes: 8 additions & 8 deletions terminal/alone-windows-terminal.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
{
"name": "Alone",
"background": "#0C0A09",
"foreground": "#C4B8A4",
"foreground": "#C8B89A",
"cursorColor": "#E8B850",
"selectionBackground": "#D4A048",
"black": "#0C0A09",
"red": "#B85450",
"green": "#9A8B60",
"yellow": "#D4A048",
"blue": "#8B8178",
"blue": "#9C948E",
"purple": "#A87878",
"cyan": "#9A8B7A",
"white": "#C4B8A4",
"brightBlack": "#5C544A",
"cyan": "#C08868",
"white": "#C8B89A",
"brightBlack": "#6E665B",
"brightRed": "#D46A66",
"brightGreen": "#C4B078",
"brightYellow": "#E8B850",
"brightBlue": "#A89A8C",
"brightBlue": "#B2AAA3",
"brightPurple": "#C89088",
"brightCyan": "#B8A898",
"brightWhite": "#E8DCD0"
"brightCyan": "#CEA284",
"brightWhite": "#EDDCC4"
}
20 changes: 10 additions & 10 deletions terminal/alone.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# A warm, earthy terminal color scheme

# Basic colors
foreground #C4B8A4
foreground #C8B89A
background #0C0A09
selection_foreground #0C0A09
selection_background #D4A048
Expand All @@ -14,26 +14,26 @@ color0 #0C0A09
color1 #B85450
color2 #9A8B60
color3 #D4A048
color4 #8B8178
color4 #9C948E
color5 #A87878
color6 #9A8B7A
color7 #C4B8A4
color6 #C08868
color7 #C8B89A

# Bright colors
color8 #5C544A
color8 #6E665B
color9 #D46A66
color10 #C4B078
color11 #E8B850
color12 #A89A8C
color12 #B2AAA3
color13 #C89088
color14 #B8A898
color15 #E8DCD0
color14 #CEA284
color15 #EDDCC4

# URL color
url_color #D4A048

# Tab bar colors
active_tab_foreground #0C0A09
active_tab_background #D4A048
inactive_tab_foreground #C4B8A4
inactive_tab_background #5C544A
inactive_tab_foreground #C8B89A
inactive_tab_background #6E665B
Loading
Loading