| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| |
|
|
|
|
|
|
| |
Export stays a flat palette and import needs no reconstruction, because families are derived from the hex every render rather than stored. A #roundtriptest gate confirms export to import to export is byte-identical, and that the exported palette is still a flat [hex, name] list. Package seeding is unaffected since it reads the same flat palette.
The spec's planned ramp-step warning exemption is dropped after analysis: a generated ramp's steps are a stepL apart, well above the too-similar ΔE threshold, so they never trigger the warning, and exempting same-family pairs would hide genuine near-duplicates that should be flagged (the case #deltatest checks). So the warning stays on the full palette.
README documents color families: the hue grouping and its limitation, the ground strip, the per-column count control and regenerate, removed-step references reading "(gone)", and the removal of the standalone ramp panel. Phase 6, the last phase; the color-families v1 build is code-complete.
|
| |
|
|
|
|
|
|
|
|
| |
neutral cut
Replace gap-based hue clustering and the flat neutral threshold. Chromatic colors now bucket by nearest perceptual hue anchor (red, orange, yellow, green, teal, blue, purple, pink), so adjacent categories stay separate by construction and there's no single-linkage chaining merging them through intermediate tones. The neutral cut is lightness-scaled rather than flat: a color reads as neutral below a chroma that's highest in the mid-tones and tapers toward the light end, so a faint mid gray goes neutral while an equally-faint pale tint keeps its hue.
This fixes the two concrete problems: the grays and steels consolidate into one neutral column, and pale tints (light blues) stay with their hue instead of falling into the grays. What it doesn't fix is hue-adjacent warm colors: this palette's olive-greens sit on top of the golds in OKLCH hue, so they still group together, and a ramp that drifts in hue can split across an anchor boundary. That's a real property of the colors, not a bug, and it's filed for research (a writeup of the problem and the four approaches tried lives outside the repo; the task points to it).
20 family node tests including the yellow/green split and the no-chaining case; suite green.
|
| |
|
|
| |
Craig confirmed the spec Ready. The six phases become tracked tasks under the color-families parent — family model and sort cores, strip rendering, the count control, the ground strip plus ramp-panel retirement, and the warnings/seeding/export/README close-out — all :solo:. Three manual aesthetic checks (hue grouping matches the eye, regenerate-replace reads as deliberate, removed-step references read as "(gone)") go under the Manual testing parent.
|
| |
|
|
|
|
|
|
| |
Resolved both open decisions per Craig: theme.json stays flat, and the standalone ramp panel goes away in favor of the per-strip control. The bigger change is the grouping mechanism: families are now derived from OKLCH hue off the hex, never from a name convention, so renaming a color to anything never moves it between strips.
That pivot designs out the Codex review's two hardest blockers. There's no step-name grammar and no import inference, because grouping isn't name-based. And the palette stays a flat, individually-editable list rather than transferring ownership to family objects, so per-chip rename/remove/edit keep working and there's no ownership contract to invent. Families are a display view over the existing palette.
The rest of the review is folded as written, adapted to the flat model: the ground strip is synthesized from the bg/fg assignments (pinned, editable, de-duped by hex), removed-step references degrade to a visible "(gone)" rather than a silent jump, n=0 is handled without ramp(), and the neutral (0.02) and hue-gap (25) thresholds and sort tie-breakers are pinned. Review file consumed and deleted; dispositions and a responder entry are in the spec.
|
| |
|
|
|
|
| |
The palette panel becomes color families instead of a flat row of chips: a base color plus its tonal ramp, shown as a dark-to-light strip with a per-family symmetric step count (N gives base ±N). Families are live, so changing the count or the base regenerates the strip; regeneration is authoritative. fg and bg share a fixed ground strip, other standalone colors are singletons, and strips sort by hue across the panel with steps sorted by lightness within.
The spec keeps theme.json a flat palette (families derived from the ramp naming on import) and reuses the shipped ramp() and assignment re-point. Two decisions are left open for Craig: flat-vs-structured persistence, and whether the per-family count control should replace the standalone ramp panel. Six phases, each leaving the tree green; the v1 build it extends is cross-linked from the task.
|
| |
|
|
| |
All five build phases plus the README close-out landed; the parent stays open pending the manual aesthetic and real-Emacs-fidelity sign-off.
|
| | |
|
| |
|
|
|
|
| |
The palette-ramps spec is Ready, so its six phases become tracked tasks under a v1 build parent: ramp core, ramp UI, foreground-set/floor/lMax core, worst-case readout, safe-lightness picker, and a README plus test-surface close-out. All six are :solo: — each verifies through node tests or a headless hash-gate plus a screenshot read.
The aesthetic and real-Emacs-fidelity checks that need Craig's eye go under the existing Manual testing parent: does a generated ramp harmonize, does the safe-lightness guidance read clearly, and does a tint the tool calls safe actually keep every token readable behind real syntax.
|
| |
|
|
|
|
|
|
|
|
| |
Resolved both open decisions. The contrast target is WCAG AA by default, with AAA selectable and APCA shown as a diagnostic only. The v1 foreground set is the distinct syntax-assignment hexes plus the default foreground, with locked background-only roles excluded.
Pinned what the review flagged as underspecified: a closed five-face covered set (region, hl-line, highlight, lazy-highlight, isearch), ramp defaults and palette-insertion rules (n/stepL/chromaEase, naming, collisions, clamp display), and explicit-state structured-error contracts for ramp, fgSetFor, floor, and lMax. Package and non-overlay UI cells stay single-pair in v1.
Closed the v1 face set rather than keeping the review's open-ended "any face the buffer renders text over" clause, since an open set reintroduces the gap the foreground-set decision exists to close. Kept throwing for genuine programmer error while returning structured results for bad user input, matching colormath.js.
The spec is implementation-ready. The six implementation tasks get created once Craig confirms the go. Review file consumed and deleted.
|
| |
|
|
| |
Design doc (spec-create workflow) for two coupled v1 features: generating a harmonized tonal ramp from a base color, and a worst-case-contrast readout that caps a background tint at the lightness where every foreground on it stays readable. Cross-linked from the color-harmony task; harmonic fill deferred to vNext.
|
| | |
|
| | |
|
| | |
|
| |
|
|
| |
consistency-check tasks
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
| |
The seeding engine turns the color guide's seed table into executable defaults: a role-to-treatment table, a face-to-role map per tier (syntax, UI, org), and a pure seed() that opens the tool guide-correct and reseeds dupre-revised to the compact mapping. v1 generates the shades with OKLCH, reusing the perceptual-metrics colormath.js core, so it sequences after that feature's Phase 1. todo.org carries the two implementation phases.
|
| | |
|
| |
|
|
| |
The spec adds OKLCH editing, perceptual-lightness and APCA readouts, and a pairwise ΔE distinguishability check to the theme-studio, so it can build deliberately low-contrast themes by metric instead of by eye. The testing strategy extracts the color math into a Node-unit-tested colormath.js core, with the browser hash tests reduced to UI wiring and coverage measured on that core. todo.org carries the five implementation phases and the manual-validation checklist.
|
| | |
|
| |
|
|
| |
F8 is bound globally to cj/main-agenda-display, but ghostel's semi-char mode forwarded it to the terminal program, so it did nothing inside a ghostel buffer. I added F8 to ghostel-keymap-exceptions and rebuilt the semi-char map, which lets it fall through to the global map, the path F10 and the F9 family already take.
|
| |
|
|
| |
The tool authors themes from scratch -- palette, faces across every tier, live preview, export to a loadable deftheme. It never selects among existing themes, so "selector" mis-described it. Renamed the directory, the generated HTML and its title, the design spec, and every reference in the code, README, tests, and todo. No behavior change.
|
| | |
|
| |
|
|
| |
These three no longer fall to the generic face-name list. ghostel renders a mock terminal covering all 19 faces (the 16 ANSI colors, default, and the fake cursor). mu4e renders a headers list, message view, and compose stub covering all 37 of the faces the dupre theme themes; mu4e is absent from the generated inventory, so its face list is curated. dashboard covers all 8. Every face has a real preview element, so the click-to-flash linking works both directions with no fallback.
|
| |
|
|
| |
Clicking a face row now flashes that face in the live-buffer and package previews, and clicking an element in either preview flashes its table row. The syntax tier already did this. UI faces had only preview-to-row, and package faces had neither. The package preview spans and table rows now carry data-face, reusing the same delegated-click handler the mock frame uses. When a face isn't shown in a bespoke preview, the row falls back to flashing its own cell. A fuller org preview that gives every org row a real target is filed as a separate task.
|
| |
|
|
|
|
|
|
|
|
| |
build-theme.el is the last link in the theme-selector pipeline: a theme.json export becomes a single self-contained themes/<name>-theme.el. All four tiers convert: default from assignments.bg/.p, the syntax categories to their font-lock/tree-sitter faces with the bold/italic sets applied, UI passthrough, and package faces with :inherit/:height/weight/slant.
The output is a flat generated deftheme, not the palette/faces/theme trio the hand-authored dupre ships. A theme.json carries resolved per-face hex, not dupre's semantic-mapping layer, so a flat deftheme is the faithful output and never clobbers the curated dupre files.
I omitted the dec (decorator) key: Emacs has no dedicated decorator face and renders decorators with font-lock-type-face, which the type key already owns, so coloring dec independently would clobber types. Decorators follow the type color, as they do in stock Emacs.
20 ERT tests cover the attribute builder, each tier, the dec omission, and an end-to-end convert-and-load with a WCAG-AA assertion on the round-tripped default.
|
| |
|
|
| |
The last link in the tier-3 pipeline, with pointers to the theme.json contract, the existing dupre theme files, and the Elisp/testing conventions so a fresh session can start from the task alone.
|
| |
|
|
|
|
| |
I extended the hash-guarded self-test harness to assert the tier-3 acceptance criteria against the real emitted code, run in headless Chrome: old-JSON import with no packages key, the full package round-trip (fg, bg, bold, italic, inherit, height, source), cleared-state export, unknown-package preservation, and inheritance-cycle termination. All pass. The two DOM-coupled regressions are handled structurally rather than in the harness: updateColor remaps PKGMAP when a palette color is edited, and PKGMAP stores hexes so a deleted palette color leaves package references in the recoverable "(gone)" state.
This closes the tier-3 package-faces milestone: all seven phases plus the test surface have landed.
|
| |
|
|
| |
I rewrote the README to cover what the tool actually is now: the three face tiers (syntax, UI, package) plus the palette, the in-page color picker with its AA/AAA legibility mask, the package-faces section with bespoke org/magit/elfeed previews and the generic fallback, modeled inheritance and relative height (with the note that the font family stays in font-config.el), the theme.json packages schema with inherit/height/source, export-versus-save, and the inventory-refresh command with its loaded-config dependency. It also documents that theme-selector.html is generated.
|
| |
|
|
|
|
| |
I added the hybrid inventory. build-inventory.el, loaded into a running Emacs, queries every installed package's faces grouped by the package that defines them and writes package-inventory.json. generate.py embeds that file and merges each package into the app dropdown as an editable generic app, leaving the bespoke org, magit, and elfeed untouched.
The dropdown now reaches 40 apps: the three bespoke plus 37 inventory packages (643 faces), so any installed package can be themed against the palette with the generic preview. The inventory is a committed data artifact refreshed by reloading the .el, never browser-side discovery, matching the spec's hybrid-and-split decision.
|
| |
|
|
| |
I added renderMagitPreview and renderElfeedPreview. The magit one is a status buffer: head and branch lines, an untracked section, a diff hunk with context, removed, and added lines, and recent commits with hashes, authors, and a keyword and tag. The elfeed one is a search list: the filter line, dated entries with feed, unread and read titles, and tags, plus log lines colored by level. The preview pane dispatches to each app's bespoke renderer, the generic fallback covers everything else, and the pane label now names the app and says whether the preview is bespoke or generic.
|
| |
|
|
| |
I added renderOrgPreview, a mock org document painted live from the org package faces. It exercises the prominent ones in context: document title, headings with their heights, a TODO and a DONE, tags, a scheduled timestamp, a property drawer, inline code and verbatim, a link, a checkbox, a quote, a src block with begin and end lines, and a header-row table. The preview pane now dispatches on the app's preview key, so org-mode gets this bespoke document and every other app keeps the generic face-name list until its own preview lands. It rebuilds on any package-face or palette edit.
|
| |
|
|
|
|
| |
I added the package faces section: an application selector for org-mode, magit, and elfeed, and a face table for the chosen app with a foreground and background dropdown, bold and italic toggles, an inherit dropdown (base faces plus the app's own faces), a relative-height stepper, a live contrast readout on the effective inherit-resolved color, and a per-face reset, plus a per-app reset and a text filter for the large sets.
The right pane shows a generic preview, each face name in its own resolved colors, which the bespoke org/magit/elfeed previews replace in the next phases. The fg/bg dropdown is now a shared colorDropdown helper that the ui-faces table also uses, so there's no forked control. Palette edits propagate to package faces, and import and export carry them through.
|
| |
|
|
|
|
| |
I filled the APPS registry with the complete own-defface sets: 88 org faces including org-agenda, 98 magit, and 13 elfeed, built from embedded face-name lists plus a curated seed-color map. Prominent faces are seeded with palette colors, heading heights, and the fixed-pitch inherits that keep code and tables monospace under variable-pitch prose. The long tail seeds to the default foreground for the user to tune.
Org headings carry their heights, agenda dates and deadlines are colored by role, and magit's diff, branch, and section faces map to the palette's greens, reds, and blues. No UI yet. That's phase 3, and the schema self-test still passes while seeding all 199 faces.
|
| |
|
|
|
|
| |
I folded a relative height field into the tier-3 spec and brought Phase 1's schema in line. A face's height is a float multiplier off the base font (1.3 is 1.3x the running font, never a point size), so it stays portable across fonts and machines, and it's omitted from export at 1.0. The font family itself stays in font-config.el, where it belongs; the theme owns only relative size.
Height is read straight off the face and does not cascade through inherit, because Emacs multiplies float heights along an inherit chain and headings should each size off the body, not compound off the level above. The org starter now seeds heading heights and the fixed-pitch inherits that keep code and tables monospace under variable-pitch prose. The self-test gained a height assertion and still reports PASS.
|