Skip to main content

max / makeover

Assert that a raised surface lifts off the page under it The three degeneracy tests each measure a derived color against the face it came from, so nothing measured the face against the page it sits on. makenot.work passed all three and still could not hold a bevel, and goingson and audiofiles needed the same re-ramp before it, so the gap was a missing assertion rather than three accidents. Adds `raised_is_distinct_from_page` beside its siblings, with the threshold picked against the ramps already ruled on: 0.024 oklab L was invisible, 0.036 was rejected as marginal, 0.058 was accepted, and goingson and audiofiles sit at 0.119 and 0.065. The line goes at 0.05, in the gap between every ramp judged inadequate and every one judged adequate. The theme files quote CIE L* on 0 to 100 and this compares oklab L on 0 to 1, which are close to a factor of 116 apart. Twenty of the thirty-one shipped themes fail, all of them imports. Whether any gets re-ramped is a separate decision: an imported palette that cannot hold a bevel is not thereby wrong, and a nord that is not nord is worth less than a nord that bevels weakly.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-03 00:02 UTC
Signed with PGP, not checked
Commit: a39822d0bd712642a410e35bba34f782ebd75573
Parent: 04f8207
1 file changed, +70 insertions, -0 deletions
M src/lib.rs +70
@@ -1876,6 +1876,76 @@
1876 1876 );
1877 1877 }
1878 1878
1879 + // The three tests above each measure a derived color against the face it was
1880 + // derived from, so a theme can pass all of them and still have nothing lift
1881 + // off anything: the face itself sits on the page, and that relationship is
1882 + // the one a bevel needs in order to read as an object rather than as a
1883 + // rectangle with decorated edges. makenot.work passed all three and could
1884 + // not hold a bevel, which is what this covers.
1885 + //
1886 + // The threshold is picked against the ramps already ruled on rather than
1887 + // against a round number. makenot.work shipped at 0.024 and was invisible,
1888 + // was tried at 0.036 and rejected as marginal on badges and chips, and was
1889 + // accepted at 0.058; goingson and audiofiles sit at 0.119 and 0.065. Every
1890 + // ramp judged inadequate is below 0.036 and every one judged adequate is
1891 + // above 0.058, so the line goes in the gap between them. Note the unit: this
1892 + // is oklab L on 0 to 1, not the CIE L* on 0 to 100 that the theme files quote
1893 + // in their comments, and the two are not interchangeable.
1894 + //
1895 + // Most of the list is imported palettes, which were authored for syntax
1896 + // highlighting and owe our depth model nothing. Failing here says a theme
1897 + // cannot hold a bevel, not that it is wrong. Shrinking the list is the fix;
1898 + // growing it is a regression in the theme, not in this derivation.
1899 + #[test]
1900 + fn raised_is_distinct_from_page() {
1901 + // Below this, a raised surface and the page under it are one surface to
1902 + // a reader, whichever direction the theme ramps in.
1903 + const MIN_DELTA_L: f32 = 0.05;
1904 + const CANNOT_LIFT_OFF_THE_PAGE: &[&str] = &[
1905 + "akari-dawn",
1906 + "akari-night",
1907 + "ayu-light",
1908 + "ayu-mirage",
1909 + "catppuccin-latte",
1910 + "catppuccin-mocha",
1911 + "dawnfox",
1912 + "dracula",
1913 + "everforest",
1914 + "flatwhite",
1915 + "gruvbox-light",
1916 + "neobrute",
1917 + "one-dark",
1918 + "oxocarbon-dark",
1919 + "oxocarbon-light",
1920 + "poimandres",
1921 + "rosepine",
1922 + "rosepine-dawn",
1923 + "solarized-dark",
1924 + "tokyonight",
1925 + ];
1926 +
1927 + let mut flat: Vec<String> = Vec::new();
1928 + for (id, source) in embedded_themes() {
1929 + let theme = parse_theme_str(id, source, false).unwrap();
1930 + let t = resolve(&theme);
1931 + let (Some(page), Some(raised)) = (
1932 + t.hex("surface-page").and_then(Rgb::from_hex),
1933 + t.hex("surface-raised").and_then(Rgb::from_hex),
1934 + ) else {
1935 + continue;
1936 + };
1937 + if (raised.to_oklab().l - page.to_oklab().l).abs() < MIN_DELTA_L {
1938 + flat.push(id.to_string());
1939 + }
1940 + }
1941 + flat.sort();
1942 +
1943 + assert_eq!(
1944 + flat, CANNOT_LIFT_OFF_THE_PAGE,
1945 + "themes whose raised surface is too close to the page to lift off it"
1946 + );
1947 + }
1948 +
1879 1949 // What the bevel pair does on a sixteen-color terminal, measured across the
1880 1950 // shipped set rather than assumed. Two results, both load-bearing for a
1881 1951 // consumer that has to render one there.