code wiki / _hdl_build / nx_brand_dark_gate.nx
nx_brand_dark_gate.nx source
↩ module page · 78 lines · 4724 B
1// nx_brand_dark_gate.nx -- R8 gate: dark-mode colour system. A brand with `dark|...` tokens emits a
2// @media(prefers-color-scheme:dark){:root{...}} override; a brand WITHOUT them emits nothing (backward-compatible).
3// BOTH light and dark must pass WCAG AA. Sovereignty + determinism hold. 100% sovereign. expect_exit: 0
4import "nx_syscalls.nx"
5import "nx_sitegate_emit_lib.nx"
6import "nx_brand_tokens.nx"
7import "nx_brand_guard.nx"
8import "nx_web_builder.nx"
9
10
11func g_has(s: *u8, n: i64, lit: *u8) -> i64 { if bt_find(s, n, lit, bt_len(lit)) >= 0 { return 1 } return 0 }
12func inband8(v: i64, lo: i64, hi: i64) -> i64 { if v < lo { return 0 } if v > hi { return 0 } return 1 }
13
14func main() -> i64 {
15 let tot: *i64 = sys_mmap(32) as *i64
16 tot[0]=0; tot[1]=0
17 let cap: i64 = 65536
18 let a: *u8 = sys_mmap(cap)
19 gw("=== nx_brand_dark_gate -- R8 dark-mode colour system (prefers-color-scheme token layer) ===\n" as *u8)
20
21 // a dark-capable brand: light tokens + dark overrides
22 let dk: *u8 = "token|color|primary|#0b2545\ntoken|color|accent|#e8a534\ntoken|color|accent-ink|#0b2545\ntoken|color|hero|#13315c\ntoken|color|ink|#16202e\ntoken|color|bg|#ffffff\ntoken|color|muted|#eef3f8\ntoken|color|line|#cdd7e3\ntoken|font|sans|system-ui\ntoken|font|size-base|16px\ntoken|font|leading|1.6\ntoken|font|h1|2rem\ntoken|font|h2|1.4rem\ntoken|radius|md|8px\ntoken|radius|sm|6px\ntoken|motion|fast|150ms\ntoken|motion|ease|ease\ndark|color|bg|#0b1220\ndark|color|ink|#e6edf3\ndark|color|primary|#9ec1ff\ndark|color|muted|#161f2e\ndark|color|line|#2a3850\n" as *u8
23 let dn: i64 = bt_len(dk)
24
25 // D1: dark brand emits the @media dark override
26 let w1: i64 = bt_emit_dark_root_buf(dk, dn, a, cap)
27 var t1: i64 = 0
28 if w1 > 0 {
29 if g_has(a, w1, "@media(prefers-color-scheme:dark){:root{" as *u8) == 1 {
30 if g_has(a, w1, "--nx-color-bg: #0b1220" as *u8) == 1 { if g_has(a, w1, "--nx-color-ink: #e6edf3" as *u8) == 1 { t1 = 1 } }
31 }
32 }
33 t_row("D1 dark brand emits @media(prefers-color-scheme:dark) override block" as *u8, t1, tot)
34
35 // D2: default brand (no dark tokens) emits NOTHING (backward-compatible)
36 let w2: i64 = bt_emit_dark_root_buf(bt_default_brand(), bt_len(bt_default_brand()), a, cap)
37 t_row("D2 brand WITHOUT dark tokens emits nothing (w==0, zero regression)" as *u8, inband8(w2, 0, 0), tot)
38
39 // D3: a BUILT page carries BOTH the light :root and the dark @media block
40 let fd: i64 = sys_openat_wr("/tmp/nx_dark.html" as *u8, 0x1a4)
41 wb_doc_open_branded(fd, "Dark" as *u8, dk, dn)
42 wb_w(fd, "<p>x</p>\n" as *u8)
43 wb_doc_close(fd)
44 sys_close(fd)
45 let lp: *i64 = sys_mmap(16) as *i64
46 let pg: *u8 = sys_read_file("/tmp/nx_dark.html" as *u8, lp)
47 let pn: i64 = lp[0]
48 var t3: i64 = 0
49 if g_has(pg, pn, "--nx-color-bg: #ffffff" as *u8) == 1 { if g_has(pg, pn, "@media(prefers-color-scheme:dark)" as *u8) == 1 { if g_has(pg, pn, "--nx-color-bg: #0b1220" as *u8) == 1 { t3 = 1 } } }
50 t_row("D3 built page has BOTH light :root (#ffffff) AND dark override (#0b1220)" as *u8, t3, tot)
51
52 // D4 + D5: BOTH modes meet WCAG AA
53 let aa_light: i64 = bg_contrast_hex_x100("#16202e" as *u8, "#ffffff" as *u8)
54 let aa_dark: i64 = bg_contrast_hex_x100("#e6edf3" as *u8, "#0b1220" as *u8)
55 gw(" light ink/bg=" as *u8); gn(aa_light); gw(" (x100) dark ink/bg=" as *u8); gn(aa_dark); gw(" (x100)\n" as *u8)
56 t_row("D4 dark mode ink/bg meets WCAG AA" as *u8, inband8(aa_dark, 450, 999999), tot)
57 t_row("D5 light mode ink/bg meets WCAG AA" as *u8, inband8(aa_light, 450, 999999), tot)
58
59 // D6: sovereignty -- a hostile dark value is rejected, a good sibling survives
60 let bad: *u8 = "dark|color|bg|#0b1220\ndark|color|x|<script>alert\n" as *u8
61 let w6: i64 = bt_emit_dark_root_buf(bad, bt_len(bad), a, cap)
62 var t6: i64 = 0
63 if w6 > 0 { if g_has(a, w6, "--nx-color-bg: #0b1220" as *u8) == 1 { if g_has(a, w6, "script" as *u8) == 0 { t6 = 1 } } }
64 t_row("D6 sovereignty: hostile dark value rejected, good sibling survives" as *u8, t6, tot)
65
66 // D7: determinism
67 let b: *u8 = sys_mmap(cap)
68 let e1: i64 = bt_emit_dark_root_buf(dk, dn, a, cap)
69 let e2: i64 = bt_emit_dark_root_buf(dk, dn, b, cap)
70 var t7: i64 = 0
71 if e1 == e2 { if e1 > 0 { var eq: i64 = 1; var i: i64 = 0; while i < e1 { if a[i] != b[i] { eq = 0 } i = i + 1 } t7 = eq } }
72 t_row("D7 determinism: dark block emits byte-identical" as *u8, t7, tot)
73
74 gw("\nrows pass=" as *u8); gn(tot[0]); gw(" fail=" as *u8); gn(tot[1]); gw("\n" as *u8)
75 if tot[1] == 0 { gw("VERDICT=GREEN -- dark-mode colour system: AA in both modes, additive, sovereign\n" as *u8); return 0 }
76 gw("VERDICT=RED\n" as *u8)
77 return 1
78}