Color-by-temporal-change + colorize-last invariant (levers 3 & 9) - #37
Merged
Conversation
This was referenced Jun 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the temporal-color art-direction lever (#29) on top of the colorize-last invariant fix (#28). Closes #28, closes #29.
Global default OFF — a bare run, the
Organicdefault, and all existing presets/saved-configs are byte-identical to before. The feature only activates when a user passes--temporal-color > 0(or selects a future showcase preset).What changed
Lever 9 — colorize-last invariant
palette::colorize_subpixel: a single shared colorize pass now used by every output (TUI frame buffer, GIF, WebM, headless print, frame capture, and PNG save).mapping = Noneand so skipped intensity-mapping (and would have skipped all new color levers). Saved stills now match the live look.Lever 3 — color-by-temporal-change
temporal_lagbuffer and emits a raw signeddiff = trail − lag(positive = growing front, ~0 = settled vein, negative = decaying tail). Allocated only when temporal is enabled.AuxCell.signed_diff(sign preserved), normalized by the white-point in the colorizer, then modulated:huemode — rotate the base OKLch hue bytanh(k·diff_norm)·max_shift(front/tail rotate opposite directions).accentmode — blend toward the palette's hot end in OKLch (Bleuje-style; most dramatic).--temporal-color <0..1>,--temporal-lag <frames>,--temporal-mode <hue|accent>, plus RuntimeState fields and saved-config persistence (#[serde(default)]so old TOML loads unchanged).Known limitation
Loading a saved config with
temporal_color > 0does not re-enable the sim computation live (temporal stays off until restart with the flag). This fails safe (base colors, never wrong) and mirrors the existing trail-age/delta/gradient CLI-only-at-startup behavior; the proper fix belongs with the config live-apply / cache-sync refactor, not this change.Test plan
cargo fmt --checkcargo clippy --all-targets --all-features -- -D warningscargo test(774 lib + integration + doc)cargo test --test visual_regression— 47 pass; all 46 pre-existing goldens unchanged, 1 new temporal-on golden added-S --preset organic --temporal-color 0.8 --temporal-mode accentcolors the growing front;--temporal-color 0is unchangedgto save a PNG (with a non-default--intensity-mapping) and confirm it matches the screen--temporal-colordiffers