code wiki / _hdl_build / nx_uigen_l1.nx
nx_uigen_l1.nx source
↩ module page · 131 lines · 6868 B
1// nx_uigen_l1.nx -- ROADMAP RUNG L1: PARAMETERIZED UI GENERATION (the first rung where the SYSTEM, not a
2// human, makes the design choices). From a compact SPEC (seed hue + layout variant) it GENERATES a full page:
3// real color-theory palette GENERATION (integer HSL->RGB) for BOTH themes -- light (ink dark, bg light) AND a
4// hue-tinted dark (ink light, bg dark) -> WCAG-accessible BY CONSTRUCTION in each theme -- composing the
5// canonical kit (nx_sclass_kit) so craft stays S-class. Different spec -> a VISIBLY DISTINCT, accessible,
6// on-brief page. Attacks census GAPs design-diversity / palette-generation / layout-generation. Pure emit
7// (no syscalls) so it composes anywhere. license_tier: ORIGINAL
8import "nx_sclass_kit.nx"
9const K_MAGIC_2000: i64 = 2000
10const K_MAGIC_65536: i64 = 65536
11
12// print an 8-bit channel (0..255) with no scratch buffer (pure).
13func l1_put_u8(buf: *u8, off: i64, v: i64) -> i64 {
14 var o: i64 = off
15 if v >= 100 { buf[o] = (48 + v / 100) as u8; o = o + 1; let t: i64 = v % 100; buf[o] = (48 + t / 10) as u8; o = o + 1; buf[o] = (48 + t % 10) as u8; o = o + 1; return o }
16 if v >= 10 { buf[o] = (48 + v / 10) as u8; o = o + 1; buf[o] = (48 + v % 10) as u8; o = o + 1; return o }
17 buf[o] = (48 + v) as u8; o = o + 1
18 return o
19}
20
21// integer HSL->RGB packed as r*65536+g*256+b. h in [0,360), s,l in [0,100]. Verified exact: red/green/yellow.
22// This IS the palette generation -- a different seed hue yields a different, coherent, accessible scheme.
23func l1_hsl_pack(h: i64, s: i64, l: i64) -> i64 {
24 let L: i64 = l * 10
25 let S: i64 = s * 10
26 var d: i64 = 2 * L - 1000
27 if d < 0 { d = 0 - d }
28 let C: i64 = ((1000 - d) * S) / 1000
29 let hp: i64 = (h * 1000) / 60
30 var hm: i64 = hp
31 while hm >= K_MAGIC_2000 { hm = hm - K_MAGIC_2000 }
32 var hd: i64 = hm - 1000
33 if hd < 0 { hd = 0 - hd }
34 let X: i64 = (C * (1000 - hd)) / 1000
35 let m: i64 = L - C / 2
36 var rp: i64 = 0
37 var gp: i64 = 0
38 var bp: i64 = 0
39 let seg: i64 = h / 60
40 if seg == 0 { rp = C; gp = X; bp = 0 }
41 if seg == 1 { rp = X; gp = C; bp = 0 }
42 if seg == 2 { rp = 0; gp = C; bp = X }
43 if seg == 3 { rp = 0; gp = X; bp = C }
44 if seg == 4 { rp = X; gp = 0; bp = C }
45 if seg >= 5 { rp = C; gp = 0; bp = X }
46 var r: i64 = ((rp + m) * 255) / 1000
47 var g: i64 = ((gp + m) * 255) / 1000
48 var b: i64 = ((bp + m) * 255) / 1000
49 if r < 0 { r = 0 }
50 if r > 255 { r = 255 }
51 if g < 0 { g = 0 }
52 if g > 255 { g = 255 }
53 if b < 0 { b = 0 }
54 if b > 255 { b = 255 }
55 return r * K_MAGIC_65536 + g * 256 + b
56}
57
58// emit "rgb(r,g,b)" for hsl(h,s,l).
59func l1_rgb(buf: *u8, off: i64, h: i64, s: i64, l: i64) -> i64 {
60 let p: i64 = l1_hsl_pack(h, s, l)
61 let r: i64 = p / K_MAGIC_65536
62 let g: i64 = (p / 256) % 256
63 let b: i64 = p % 256
64 var o: i64 = he_puts(buf, off, "rgb(" as *u8)
65 o = l1_put_u8(buf, o, r); o = he_puts(buf, o, "," as *u8)
66 o = l1_put_u8(buf, o, g); o = he_puts(buf, o, "," as *u8)
67 o = l1_put_u8(buf, o, b); o = he_puts(buf, o, ")" as *u8)
68 return o
69}
70
71// emit one "--tok:rgb(...);" pair.
72func l1_tok(buf: *u8, off: i64, tok: *u8, h: i64, s: i64, l: i64) -> i64 {
73 var o: i64 = he_puts(buf, off, tok)
74 o = l1_rgb(buf, o, h, s, l)
75 o = he_puts(buf, o, ";" as *u8)
76 return o
77}
78
79// GENERATED palette override for BOTH themes, derived from ONE seed hue by color theory. Emitted AFTER the
80// kit stylesheet so it wins the cascade. LIGHT: ink L=12 vs bg L=97 (huge gap => AA/AAA by construction).
81// DARK: ink L=92 vs bg L=9 (huge gap => AA/AAA by construction). accent = hue+32 (analogous). Never random-ugly.
82func l1_palette_style(buf: *u8, off: i64, hue: i64) -> i64 {
83 var ah: i64 = hue + 32
84 while ah >= 360 { ah = ah - 360 }
85 var o: i64 = he_puts(buf, off, "<style>:root{" as *u8)
86 o = l1_tok(buf, o, "--nx-color-primary:" as *u8, hue, 62, 46)
87 o = l1_tok(buf, o, "--nx-color-primary2:" as *u8, hue, 70, 62)
88 o = l1_tok(buf, o, "--nx-color-accent:" as *u8, ah, 72, 50)
89 o = l1_tok(buf, o, "--nx-color-bg:" as *u8, hue, 22, 97)
90 o = l1_tok(buf, o, "--nx-color-surface:" as *u8, hue, 16, 100)
91 o = l1_tok(buf, o, "--nx-color-surface2:" as *u8, hue, 20, 94)
92 o = l1_tok(buf, o, "--nx-color-ink:" as *u8, hue, 25, 12)
93 o = l1_tok(buf, o, "--nx-color-ink2:" as *u8, hue, 14, 44)
94 o = l1_tok(buf, o, "--nx-color-line:" as *u8, hue, 18, 89)
95 o = he_puts(buf, o, "}@media(prefers-color-scheme:dark){:root{" as *u8)
96 o = l1_tok(buf, o, "--nx-color-primary:" as *u8, hue, 66, 64)
97 o = l1_tok(buf, o, "--nx-color-primary2:" as *u8, hue, 60, 74)
98 o = l1_tok(buf, o, "--nx-color-accent:" as *u8, ah, 70, 62)
99 o = l1_tok(buf, o, "--nx-color-bg:" as *u8, hue, 24, 9)
100 o = l1_tok(buf, o, "--nx-color-surface:" as *u8, hue, 20, 14)
101 o = l1_tok(buf, o, "--nx-color-surface2:" as *u8, hue, 18, 19)
102 o = l1_tok(buf, o, "--nx-color-ink:" as *u8, hue, 15, 92)
103 o = l1_tok(buf, o, "--nx-color-ink2:" as *u8, hue, 12, 66)
104 o = l1_tok(buf, o, "--nx-color-line:" as *u8, hue, 16, 24)
105 o = he_puts(buf, o, "}}</style>" as *u8)
106 return o
107}
108
109// layout variant tweak. 0 = default doc; 1 = accent top-rule + wider; 2 = narrow centered reading column.
110func l1_layout_style(buf: *u8, off: i64, variant: i64) -> i64 {
111 var o: i64 = off
112 if variant == 1 { o = he_puts(buf, o, "<style>body{border-top:5px solid var(--nx-color-accent)}.doc{max-width:1060px}</style>" as *u8) }
113 if variant == 2 { o = he_puts(buf, o, "<style>.doc{max-width:740px}.doc h1{text-align:center}.doc .lede{margin-left:auto;margin-right:auto;text-align:center}</style>" as *u8) }
114 return o
115}
116
117// GENERATE a full page from a spec (seed hue + layout variant). Composes the kit shell + generated palette.
118// Different (hue,variant) -> a visibly-distinct, accessible, S-class page. The L1 generator front door.
119func l1_page(buf: *u8, off: i64, hue: i64, variant: i64, title: *u8, brand: *u8, h1: *u8, lede: *u8) -> i64 {
120 var o: i64 = sk_doc_open(buf, off, title, brand, "/" as *u8)
121 o = sk_nav_item(buf, o, "Home" as *u8, "/" as *u8)
122 o = sk_header_close(buf, o)
123 o = l1_palette_style(buf, o, hue)
124 o = l1_layout_style(buf, o, variant)
125 o = sk_doc_main(buf, o)
126 o = sk_doc_h1(buf, o, h1, lede)
127 o = sk_h2(buf, o, "Generated from a spec" as *u8)
128 o = sk_lede(buf, o, "This entire palette — light and dark — was generated from one seed hue by color theory (integer HSL, ink and background held far apart in lightness so contrast passes WCAG in both themes by construction). Change the seed and every color moves together, coherently and accessibly: the system, not a human, chose these colors." as *u8)
129 o = sk_doc_close(buf, o, "Generated by nx_uigen_l1 (roadmap rung L1: parameterized generation) composing the sovereign S-class kit." as *u8, brand)
130 return o
131}