feat(editor): the dark scheme everywhere — the surface, documentation, mode buttons, program windows

The surface turns dark with light labels and cables and a faint light outline
round Java's icons; documentation rectangles become a tint of their colour and
texts are drawn towards light; the mode buttons use Java's pictures freed from
their grey ground (tools/dark-pictures/make.py); native controls follow
color-scheme; the desktop's program windows paint through Java-look tokens
whose light values are Java's own. The exported image and the report keep
Java's colours.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-10 22:27:03 +00:00
co-authored by Claude Opus 5.5
parent 8c4e5049f6
commit ae10ee6c31
17 changed files with 536 additions and 127 deletions
@@ -1,13 +1,14 @@
// How the editor paints a documentation item, against the pixels Java's
// JDocuElement paints (packages/doc/test/documentation.java.json, DocuRun):
// a rectangle in the documentation mode and in the others, its border, the
// text's border; the focused text's frame; where an edge is taken hold of.
// text's border; the focused text's frame; where an edge is taken hold of —
// and the editor's own dark paint, which Java has not.
import { readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import { edgesAt, fontFamily, holdFrame, rectangleBorder, rectangleFill, TEXT_BORDER, FOCUS_BORDER, FOCUS_BAND, textColor } from '../src/canvas/documentationPaint.js';
import { darkRectangleBorder, darkRectangleFill, darkTextColor, edgesAt, fontFamily, holdFrame, rectangleBorder, rectangleFill, TEXT_BORDER, FOCUS_BORDER, FOCUS_BAND, textColor } from '../src/canvas/documentationPaint.js';
type Rgba = [number, number, number, number];
const java = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '../../doc/test/documentation.java.json'), 'utf8')) as {
@@ -40,6 +41,14 @@ describe("Java's paint of the documentation", () => {
expect(textColor({ red: 0, green: 0, blue: 1, alpha: 0.5 })).toBe('rgba(0, 0, 255, 0.5)');
});
it('paints a rectangle in the dark scheme as a tint of its colour, stronger while documenting, and draws a text towards light', () => {
const grey = { red: 0.8, green: 0.8, blue: 0.8, alpha: 1 };
expect(darkRectangleFill(grey, true)).toBe('rgba(204, 204, 204, 0.28)');
expect(darkRectangleFill(grey, false)).toBe('rgba(204, 204, 204, 0.2)');
expect(darkRectangleBorder({ red: 1, green: 0, blue: 0, alpha: 1 })).toBe('rgba(255, 0, 0, 0.7)');
expect(darkTextColor({ red: 0, green: 0, blue: 0, alpha: 1 })).toBe('color-mix(in oklab, rgba(0, 0, 0, 1) 15%, var(--canvas-label))');
});
it("grows a focused text's frame as Java does, and finds the edges a drag takes", () => {
const [x, y, width, height] = java.dropped.textUnfocused.bounds as [number, number, number, number];
const [fx, fy, fw, fh] = java.dropped.text.bounds as [number, number, number, number];