code wiki / _hdl_build / nx_media_theme.nx

nx_media_theme.nx

buildroot/runtime/_hdl_build/nx_media_theme.nx

16652 B328 linesdepth 6pulls 8 transitivereach 0 importersview sourcekind tooltopic media
docsdependenciesstructsconstsfunctions

about

nx_media_theme.nx -- SOVEREIGN READING-SURFACE THEME ENGINE for /gallery + /library. Closes the TEN media.matrix rows that all name this organ (operator buy-off 2026-07-14: harsh plain white, no dark theme, clunky): light+dark theme, sunlight/outdoor readability, ambient adaptation, mobile legibility, anti-glare surface, warm night shift, flicker/refresh comfort, paper-like feel, reading typography, blue-light reduction. NOT A STUB. media.matrix's own axis says a symbol on disk is NECESSARY-NOT-SUFFICIENT, so this organ is built to be MEASURED, not greppable: every palette is a token row that mt_contrast() scores through the estate's WCAG kernel, and every claim it makes is a number its gate can refuse. DRY (rule 15) -- this organ INVENTS NOTHING THE ESTATE ALREADY OWNS: * WCAG math -> nx_uiq_color.nx (uiq_parse_color / uiq_ratio100 / uiq_lum). That file's header declares itself THE ONE WCAG 2.x relative-luminance + contrast-ratio implementation and carries a D001 migrate-on-touch note. A second luminance kernel here would be the exact duplication that note exists to prevent -- and would have been the FOURTH copy in this estate. * data format + parser + safety -> nx_brand_tokens.nx (bt_slice_eq / bt_value_safe / bt_app / bt_emit_root_buf). * mode vocabulary + hex values -> nx_night_grade.nx 6-theme SSOT (migrated from night_themes.tsv). light/sepia/ dark/night bg+fg are BYTE-FAITHFUL to it, so its already-measured blue-emission assertions still hold here instead of new ones being asserted. * override idiom -> data-theme, matching nishi_ds.css and nx_papers_index.nx. Not a new attribute. DATA-DRIVEN (rule 11): every palette value, threshold and floor is a named const or a row in MT_PALETTE_S. OVERRIDE SEMANTICS -- the user wins in BOTH directions. The OS default rides prefers-color-scheme, but it is scoped :root:not([data-theme]), so once a user picks a mode the media query CANNOT win. A bare @media block cannot express OS-dark + user-picks-light. HONEST LIMITS -- stated, not papered over: * Reflective/paper-like and matte/anti-glare are PHYSICAL display properties the web cannot set. This ships the controllable proxy: a paper palette and a capped peak luminance (sepia bg #f4ecd8, not #ffffff). It does not make glass matte. * Flicker-free is a panel property (PWM / e-ink). The controllable parts are motion and the first-paint flash; both are handled (prefers-reduced-motion, and color-scheme so the UA paints the correct base colour BEFORE first paint instead of flashing white). * Ambient-light auto-adaptation is DELEGATED to the OS signal. A real AmbientLightSensor lane is NOT implemented and is NOT claimed -- that matrix row stays _ABSENT_. Usage: nx_media_theme [--css | --table | --contrast <mode> | --kat] (default --css)

dependencies 3 imports · 0 importers

nx_syscalls.nx nx_brand_tokens.nx nx_uiq_color.nx nx_media_theme.nx

imports: nx_syscalls.nxnx_brand_tokens.nxnx_uiq_color.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main mt_palette mt_palette_len bt_len sys_write sys_exit mt_selftest mt_palette ↻ mt_palette_len ↻ mt_w sys_write ↻ bt_len ↻ uiq_ratio100 uiq_lum nx_f64_mul nx_f64_classify nx_f64_exp_field nx_f64_mant_field nx_f64_sign nx_f64_mant_field ↻ nx_f64_exp_field ↻ _f64_round_pack uiq_f64c nx_f64_div nx_f64_classify ↻ nx_f64_sign ↻ nx_f64_mant_field ↻ nx_f64_exp_field ↻ _f64_round_pack ↻ nx_i64_to_f64 _f64_round_pack ↻ uiq_srgb_lin uiq_f64c ↻ nx_f64_div ↻ nx_f64_add nx_f64_classify ↻ nx_f64_sign ↻ nx_f64_mant_field ↻ nx_f64_exp_field ↻ _f64_round_pack ↻

structs

none

consts

46const MT_MODE_N: i64 = 5
47const MT_COLOR_N: i64 = 6
48const MT_SCRATCH: i64 = 8192
49const MT_CSSCAP: i64 = 32768
52const MT_FLOOR_READ: i64 = 700
53const MT_FLOOR_UI: i64 = 450
54const MT_FLOOR_SUN: i64 = 2000
55const MT_KAT_BW: i64 = 2100
58const MT_BG_W: i64 = 9
59const MT_FG_W: i64 = 1
60const MT_PERMILLE: i64 = 1000
61const MT_BLUE_NIGHT_MAX: i64 = 250
62const MT_BLUE_CTRL_MIN: i64 = 330
64const MT_ASCII_NL: i64 = 10
65const MT_ASCII_PIPE: i64 = 124
66const MT_ASCII_DASH: i64 = 45
68const MT_PALETTE_S: *u8 = "mode|light|bg|#fbfbf9\nmode|light|surface|#ffffff\nmode|light|text|#1d1d1b\nmode|light|muted|#586274\nmode|light|accent|#2f5fd0\nmode|light|border|#dfe4ec\nmode|light|scheme|light\nmode|dark|bg|#15161a\nmode|dark|surface|#1b1d23\nmode|dark|text|#d8d8d2\nmode|dark|muted|#8b929c\nmode|dark|accent|#5b9dff\nmode|dark|border|#2a2f3a\nmode|dark|scheme|dark\nmode|sepia|bg|#f4ecd8\nmode|sepia|surface|#fbf4e3\nmode|sepia|text|#43391f\nmode|sepia|muted|#6b5d3a\nmode|sepia|accent|#7a3b12\nmode|sepia|border|#e0d4b6\nmode|sepia|scheme|light\nmode|sunlight|bg|#ffffff\nmode|sunlight|surface|#f0f0f0\nmode|sunlight|text|#000000\nmode|sunlight|muted|#262626\nmode|sunlight|accent|#0b3d91\nmode|sunlight|border|#767676\nmode|sunlight|scheme|light\nmode|night|bg|#1a1206\nmode|night|surface|#241809\nmode|night|text|#e8c890\nmode|night|muted|#b39760\nmode|night|accent|#f0a94b\nmode|night|border|#3d2a10\nmode|night|scheme|dark\n" as *u8
70const MT_BASE_S: *u8 = "token|font|body|system-ui, -apple-system, Segoe UI, Roboto, sans-serif\ntoken|font|read|Iowan Old Style, Charter, Palatino, Georgia, serif\ntoken|size|base|16px\ntoken|size|leading|1.65\ntoken|size|measure|68ch\ntoken|size|tap|44px\ntoken|radius|md|10px\n" as *u8
72const MT_ALIAS_S: *u8 = "--bg:var(--nx-color-bg);--fg:var(--nx-color-text);--mut:var(--nx-color-muted);--card:var(--nx-color-surface);--acc:var(--nx-color-accent);--bd:var(--nx-color-border);"
74const MT_SCAFFOLD_S: *u8 = "html{-webkit-text-size-adjust:100%;text-size-adjust:100%}\nbody{margin:0;background:var(--nx-color-bg);color:var(--nx-color-text);font-family:var(--nx-font-body);font-size:16px;font-size:var(--nx-size-base);line-height:1.65;line-height:var(--nx-size-leading)}\n.nx-read{max-width:68ch;max-width:var(--nx-size-measure);margin:0 auto;padding:0 1rem;font-family:var(--nx-font-read);font-size:1.0625rem;line-height:1.7;hyphens:auto;overflow-wrap:break-word}\n.nx-read p{margin:0 0 1.15em}\na{color:var(--nx-color-accent)}\n.nx-muted{color:var(--nx-color-muted)}\n.nx-surface{background:var(--nx-color-surface);border:1px solid var(--nx-color-border);border-radius:10px;border-radius:var(--nx-radius-md)}\nbutton,select,input,textarea,[role=button],.nx-tap{min-height:44px;min-width:44px;min-height:var(--nx-size-tap);min-width:var(--nx-size-tap);font-size:16px;font-size:var(--nx-size-base)}\nimg,video,canvas{max-width:100%;height:auto}\n:focus-visible{outline:3px solid var(--nx-color-accent);outline-offset:2px}\n@media (max-width:600px){.nx-read{font-size:1.125rem;line-height:1.75;padding:0 1.1rem}}\n@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;scroll-behavior:auto !important}}\n"

functions

76func mt_w(s: *u8) -> i64 { sys_write(1, s, bt_len(s)); return 0 }
77func mt_n(v: i64) -> i64
91func mt_mode_name(i: i64) -> *u8
98func mt_color_name(i: i64) -> *u8
106func mt_palette() -> *u8 { return MT_PALETTE_S }
called by 2: mt_selftestmain
107func mt_palette_len() -> i64 { return bt_len(MT_PALETTE_S) }
called by 2: mt_selftestmain calls 1: bt_len
109func mt_slice(text: *u8, n: i64, mode: *u8, token: *u8, box: *i64) -> i64
136func mt_rgb(text: *u8, n: i64, mode: *u8, token: *u8, out: *i64) -> i64
143func mt_contrast(text: *u8, n: i64, mode: *u8, fg: *u8, bg: *u8) -> i64
151func mt_blue_permille(text: *u8, n: i64, mode: *u8) -> i64
162func mt_mode_complete(text: *u8, n: i64, mode: *u8) -> i64
175func mt_distinct(text: *u8, n: i64, mode: *u8, ta: *u8, tb: *u8) -> i64
calls 2: sys_mmapmt_rgb
186func mt_emit_vars(text: *u8, n: i64, mode: *u8, out: *u8, pos: i64, cap: i64) -> i64
213func mt_emit_css(text: *u8, n: i64, out: *u8, cap: i64) -> i64
246func mt_emit_css_fd(text: *u8, n: i64, fd: i64) -> i64
called by 1: main calls 3: sys_mmapmt_emit_csssys_write
254func mt_report_mode(text: *u8, n: i64, mode: *u8) -> i64
271func mt_selftest() -> i64
297func main(argc: i64, argv: *i64) -> i64