| 4 |
4 |
|
//! MNW web server. Themes are authored by **intent** ("human design"): colors are
|
| 5 |
5 |
|
//! declared by role (surface / content / action / status / line / category), not
|
| 6 |
6 |
|
//! by hue. This crate is the single place that resolves an authored theme into a
|
| 7 |
|
- |
//! full set of intent tokens — including the derived interactive states
|
| 8 |
|
- |
//! (hover/active/selection/row-stripe/contrast) that each app used to recompute
|
| 9 |
|
- |
//! itself — and emits them as CSS variables or RGB tuples.
|
|
7 |
+ |
//! full set of intent tokens, including the derived interactive states
|
|
8 |
+ |
//! (hover/active/selection/row-stripe/contrast), and emits them as CSS
|
|
9 |
+ |
//! variables or RGB tuples. No app recomputes them itself.
|
| 10 |
10 |
|
//!
|
| 11 |
11 |
|
//! Theme file shape:
|
| 12 |
12 |
|
//! ```text
|
| 482 |
482 |
|
/// or dark, since red is the theme's danger tone either way, which is exactly
|
| 483 |
483 |
|
/// why the four achromatic slots are not in this table.
|
| 484 |
484 |
|
///
|
| 485 |
|
- |
/// Lifted from Alloy's `skelgen` on 2026-07-31, which had folded three
|
| 486 |
|
- |
/// disagreeing hand-maintained copies into one and is the reason the
|
| 487 |
|
- |
/// arrangement is trusted. It moved here so a program that paints its own
|
| 488 |
|
- |
/// palette at runtime, rather than reading a generated config, resolves the
|
| 489 |
|
- |
/// same slots. Slot 14 was the one the copies disagreed on and is
|
| 490 |
|
- |
/// `category.six`, which both the Linux console table and the retired
|
| 491 |
|
- |
/// `vtrgb.py` had.
|
|
485 |
+ |
/// Here rather than in each consumer, so a program that paints its own palette
|
|
486 |
+ |
/// at runtime resolves the same slots as one reading a generated config. Slot
|
|
487 |
+ |
/// 14 is `category.six`.
|
| 492 |
488 |
|
const CHROMATIC: [(usize, &str); 12] = [
|
| 493 |
489 |
|
(1, "status.danger"),
|
| 494 |
490 |
|
(2, "status.success"),
|
| 776 |
772 |
|
/// Resolve an authored theme into the full intent token set.
|
| 777 |
773 |
|
///
|
| 778 |
774 |
|
/// 1. Copy each present base intent from the authored colors.
|
| 779 |
|
- |
/// 2. Compute the derived interactive states from the base intents, using the
|
| 780 |
|
- |
/// same math the apps used to apply individually (so output is identical).
|
|
775 |
+ |
/// 2. Compute the derived interactive states from the base intents, so every
|
|
776 |
+ |
/// consumer gets identical output.
|
| 781 |
777 |
|
///
|
| 782 |
778 |
|
/// Each derived token is emitted only when its source intents exist, mirroring
|
| 783 |
779 |
|
/// the skip-missing behavior of the rest of the crate.
|
| 1224 |
1220 |
|
Mono,
|
| 1225 |
1221 |
|
/// Body and UI text: everything that is not mono or brand. [`FONT_SANS`].
|
| 1226 |
1222 |
|
Sans,
|
| 1227 |
|
- |
/// The brand / display tier. No house default, per `cdf8ac09`.
|
|
1223 |
+ |
/// The brand / display tier. No house default.
|
| 1228 |
1224 |
|
Display,
|
| 1229 |
1225 |
|
}
|
| 1230 |
1226 |
|
|
| 3104 |
3100 |
|
// cannot hold a bevel, not that it is wrong. Shrinking the list is the fix;
|
| 3105 |
3101 |
|
// growing it is a regression in the theme, not in this derivation.
|
| 3106 |
3102 |
|
//
|
| 3107 |
|
- |
// tokyonight left the list on 2026-08-15, and it is the only entry that could
|
| 3108 |
|
- |
// leave without a judgment call about someone else's palette. Its page and
|
| 3109 |
|
- |
// raised were the identical hex, so it had no ramp at all rather than a
|
| 3110 |
|
- |
// shallow one, and the fix is upstream's own `bg_highlight` (#292e42, 0.079
|
| 3111 |
|
- |
// above the page) rather than a color we picked. The other nineteen are
|
| 3112 |
|
- |
// shallow ramps in published palettes, which is a different claim, and they
|
| 3113 |
|
- |
// stay deferred until every app is migrated and eyeballed.
|
|
3103 |
+ |
// An entry leaves this list only when the fix is upstream's own, never a
|
|
3104 |
+ |
// color we picked. The remaining entries are shallow ramps in published
|
|
3105 |
+ |
// palettes, deferred until every app is migrated and eyeballed.
|
| 3114 |
3106 |
|
#[test]
|
| 3115 |
3107 |
|
fn raised_is_distinct_from_page() {
|
| 3116 |
3108 |
|
// Below this, a raised surface and the page under it are one surface to
|
| 4308 |
4300 |
|
|
| 4309 |
4301 |
|
#[test]
|
| 4310 |
4302 |
|
fn the_house_themes_measure_high() {
|
| 4311 |
|
- |
// The two we author. Measured 2026-08-28: goingson 6.18/7.01 and
|
| 4312 |
|
- |
// audiofiles 6.80/4.78 against page and sunken. A change that drops
|
| 4313 |
|
- |
// either below AA is a regression in a theme we control, which is
|
| 4314 |
|
- |
// exactly what this crate now knows how to see.
|
|
4303 |
+ |
// The two we author. A change that drops either below AA is a
|
|
4304 |
+ |
// regression in a theme we control.
|
| 4315 |
4305 |
|
//
|
| 4316 |
4306 |
|
// `high-contrast` is deliberately not in this list. It measures
|
| 4317 |
4307 |
|
// 4.89/3.53 and therefore reads as Standard: its muted text misses AA
|