code wiki / _hdl_build / nx_ui_contrast.nx
nx_ui_contrast.nx source
↩ module page · 99 lines · 5238 B
1// nx_ui_contrast.nx -- QUANTITATIVE layer of the judging system: MEASURED WCAG contrast (not technique presence).
2// Extracts --nx-color-ink / --nx-color-bg from each emitted page's :root and computes the ACCURATE WCAG 2.x
3// contrast ratio via nx_brand_guard (fx_pow sRGB gamma, matches the WCAG reference). AA>=4.50:1, AAA>=7.00:1.
4// Composes nx_brand_guard (-> its nx_syscalls layer; no nx_syscalls_x86_64 dup). Helpers uc_*-prefixed to avoid
5// any collision with the brand_guard/brand_tokens/fx import chain. In _hdl_build/ beside nx_brand_guard so the
6// import resolves. license_tier: ORIGINAL expect_exit: 0
7import "nx_brand_guard.nx"
8const K_MAGIC_262144: i64 = 262144
9
10func uc_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8) { n=n+1 } sys_write(1,s,n); return 0 }
11func uc_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m-(m/10)*10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 }
12func uc_len(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8) { n=n+1 } return n }
13
14func uc_find(hay: *u8, n: i64, pat: *u8) -> i64 {
15 let pl: i64 = uc_len(pat)
16 if pl==0 { return 0-1 }
17 var i: i64=0
18 while i+pl<=n {
19 var j: i64=0; var ok: i64=1
20 while j<pl { if hay[i+j]!=pat[j] { ok=0; j=pl } else { j=j+1 } }
21 if ok==1 { return i }
22 i=i+1
23 }
24 return 0-1
25}
26func uc_slurp(path: *u8, buf: *u8, cap: i64) -> i64 {
27 let fd: i64 = sys_openat_rd(path)
28 if fd < 0 { return 0 }
29 var total: i64 = 0
30 var nrd: i64 = sys_read(fd, buf, cap)
31 while nrd > 0 { total = total + nrd; if total >= cap { nrd = 0 } else { nrd = sys_read(fd, ((buf as i64)+total) as *u8, cap-total) } }
32 sys_close(fd)
33 return total
34}
35func uc_ext(buf: *u8, n: i64, key: *u8, out: *u8) -> i64 {
36 let p: i64 = uc_find(buf, n, key)
37 if p < 0 { out[0]=0 as u8; return 0 }
38 var i: i64 = p + uc_len(key)
39 var gg: i64 = 1
40 while gg==1 { if i<n { if buf[i]==(32 as u8) { i=i+1 } else { gg=0 } } else { gg=0 } }
41 var o: i64 = 0
42 gg = 1
43 while gg==1 {
44 if i>=n { gg=0 }
45 else {
46 let c: i64 = buf[i] as i64
47 if c==59 { gg=0 } else { if c==32 { gg=0 } else { if c==125 { gg=0 } else { out[o]=buf[i]; o=o+1; i=i+1 } } }
48 }
49 }
50 out[o]=0 as u8
51 if out[0]==(35 as u8) { return 1 }
52 return 0
53}
54func uc_white(h: *u8) -> i64 { h[0]=35 as u8; h[1]=102 as u8; h[2]=102 as u8; h[3]=102 as u8; h[4]=102 as u8; h[5]=102 as u8; h[6]=102 as u8; h[7]=0 as u8; return 0 }
55
56func uc_grade(name: *u8, path: *u8, buf: *u8, cap: i64, tot: *i64) -> i64 {
57 let n: i64 = uc_slurp(path, buf, cap)
58 uc_puts(" " as *u8); uc_puts(name); uc_puts(": " as *u8)
59 if n<=0 { uc_puts("(missing)\n" as *u8); return 0 }
60 let ink: *u8 = sys_mmap(16)
61 let bg: *u8 = sys_mmap(16)
62 uc_ext(buf, n, "--nx-color-ink:" as *u8, ink)
63 let hb: i64 = uc_ext(buf, n, "--nx-color-bg:" as *u8, bg)
64 if hb==0 { uc_white(bg) }
65 if ink[0]!=(35 as u8) { uc_puts("(no ink token)\n" as *u8); return 0 }
66 let c: i64 = bg_contrast_hex_x100(ink, bg)
67 uc_puts("ink " as *u8); uc_puts(ink); uc_puts(" on bg " as *u8); uc_puts(bg); uc_puts(" = " as *u8)
68 if c<0 { uc_puts("parse-fail\n" as *u8); return 0 }
69 let f: i64 = c - (c/100)*100
70 uc_num(c/100); uc_puts("." as *u8)
71 if f<10 { uc_puts("0" as *u8) }
72 uc_num(f); uc_puts(":1 " as *u8)
73 tot[1]=tot[1]+1
74 if c>=700 { uc_puts("AAA (exceeds a11y floor)\n" as *u8); tot[0]=tot[0]+1 } else { if c>=450 { uc_puts("AA\n" as *u8); tot[0]=tot[0]+1 } else { uc_puts("BELOW AA -- FAIL\n" as *u8) } }
75 return 0
76}
77
78func main() -> i64 {
79 let cap: i64 = K_MAGIC_262144
80 let buf: *u8 = sys_mmap(cap)
81 let tot: *i64 = sys_mmap(16) as *i64
82 tot[0]=0; tot[1]=0
83 uc_puts("=== nx_ui_contrast -- MEASURED WCAG contrast (accurate fx_pow, via nx_brand_guard) ===\n" as *u8)
84 uc_puts("real benchmark: ink vs bg from each page's :root. AA>=4.50:1, AAA>=7.00:1. Quality, not presence.\n" as *u8)
85 uc_grade("award " as *u8, "web_assets/lds_award.html" as *u8, buf, cap, tot)
86 uc_grade("connect " as *u8, "web_assets/lds_connect.html" as *u8, buf, cap, tot)
87 uc_grade("youth " as *u8, "web_assets/lds_youth.html" as *u8, buf, cap, tot)
88 uc_grade("reconnect" as *u8, "web_assets/lds_reconnect.html" as *u8, buf, cap, tot)
89 uc_grade("games " as *u8, "web_assets/games.html" as *u8, buf, cap, tot)
90 uc_grade("wiki " as *u8, "knowledge/wiki_pages/feedback-additive-not-guards.html" as *u8, buf, cap, tot)
91 uc_puts("--- " as *u8); uc_num(tot[0]); uc_puts(" / " as *u8); uc_num(tot[1]); uc_puts(" pages meet >= AA contrast (measured) ---\n" as *u8)
92 let nc: i64 = bg_contrast_hex_x100("#8a8a8a" as *u8, "#9a9a9a" as *u8)
93 let nf: i64 = nc - (nc/100)*100
94 uc_puts(" NEG-CONTROL #8a8a8a on #9a9a9a = " as *u8); uc_num(nc/100); uc_puts("." as *u8)
95 if nf<10 { uc_puts("0" as *u8) }
96 uc_num(nf); uc_puts(":1 -> " as *u8)
97 if nc<450 { uc_puts("correctly BELOW AA (math discriminates)\n" as *u8) } else { uc_puts("FAIL (math too lenient)\n" as *u8) }
98 return 0
99}