code wiki / _hdl_build / nx_brand_tokens.nx
nx_brand_tokens.nx source
↩ module page · 321 lines · 14403 B
1// nx_brand_tokens.nx -- R1 of the S-class BRAND arc: the DESIGN-TOKEN SSOT (single source of truth).
2// Operator 2026-06-21: "we need real s class nike/coca-cola brand management exceed tools ... users + developers
3// + ai-users + local-llm able to manage in lots of ways to NOT lock in." Design tokens are LITERALLY what a
4// Nike/Coca-Cola brand system is built on: color/type/space/radius/motion captured ONCE as portable DATA, then
5// every surface consumes them -- so re-branding is a data edit, not a code edit, and the brand is diffable /
6// versionable / editable by ANY actor (human, dev, AI, local-LLM) = no vendor lock-in BY CONSTRUCTION.
7//
8// FORMAT (the .brand DATA, line-based, pipe-delimited, mirrors the proven .site idiom):
9// token|<group>|<name>|<value> e.g. token|color|primary|#0b2545
10// EMIT: a W3C-DTCG-spirit CSS custom-properties block :root{ --nx-<group>-<name>: <value>; ... }
11// that nx_web_builder/wb_doc_open will consume via var(--nx-*) (R1b) so a token swap re-themes with NO code change.
12//
13// SOVEREIGNTY + INJECTION SAFE BY CONSTRUCTION (rule 12 boundary defense): bt_value_safe REJECTS any value
14// carrying a CSS-structural breakout char ({ } ; < >) or a third-party-fetch / comment substring (script, src=,
15// url(, /*) -> no <script>, no external fetch, no CSS rule-injection can pass, in ANY brand. group/name are
16// ident-checked (alnum + '-') so the custom-property name itself can never be broken. Library (no main).
17// 100% sovereign (nx_cc->nxasm, no gcc/JS). license_tier: ORIGINAL
18import "nx_syscalls.nx"
19
20func bt_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
21
22// naive substring search: index of needle in hay[0..hlen), or -1.
23func bt_find(hay: *u8, hlen: i64, needle: *u8, nlen: i64) -> i64 {
24 if nlen == 0 { return 0 - 1 }
25 var i: i64 = 0
26 while i + nlen <= hlen {
27 var j: i64 = 0
28 var ok: i64 = 1
29 while j < nlen { if hay[i+j] != needle[j] { ok = 0; break } j = j + 1 }
30 if ok == 1 { return i }
31 i = i + 1
32 }
33 return 0 - 1
34}
35
36// append a nul-terminated string into out at pos (bounded); return new pos.
37func bt_app(out: *u8, pos: i64, cap: i64, s: *u8) -> i64 {
38 var p: i64 = pos
39 var i: i64 = 0
40 while s[i] != (0 as u8) { if p < cap { out[p] = s[i]; p = p + 1 } i = i + 1 }
41 return p
42}
43// append n bytes of a (non-terminated) slice into out at pos (bounded); return new pos.
44func bt_app_n(out: *u8, pos: i64, cap: i64, s: *u8, n: i64) -> i64 {
45 var p: i64 = pos
46 var i: i64 = 0
47 while i < n { if p < cap { out[p] = s[i]; p = p + 1 } i = i + 1 }
48 return p
49}
50
51// is text[s..e) byte-equal to lit[0..litlen)?
52func bt_slice_eq(text: *u8, s: i64, e: i64, lit: *u8, litlen: i64) -> i64 {
53 if (e - s) != litlen { return 0 }
54 var i: i64 = 0
55 while i < litlen { if text[s+i] != lit[i] { return 0 } i = i + 1 }
56 return 1
57}
58
59// a group/name must be an ident: [A-Za-z0-9-] and non-empty (so --nx-<g>-<n> can't be broken).
60func bt_ident_safe(s: *u8, n: i64) -> i64 {
61 if n <= 0 { return 0 }
62 var i: i64 = 0
63 while i < n {
64 let c: i64 = s[i] as i64
65 var okc: i64 = 0
66 if c >= 97 { if c <= 122 { okc = 1 } } // a-z
67 if c >= 65 { if c <= 90 { okc = 1 } } // A-Z
68 if c >= 48 { if c <= 57 { okc = 1 } } // 0-9
69 if c == 45 { okc = 1 } // '-'
70 if okc == 0 { return 0 }
71 i = i + 1
72 }
73 return 1
74}
75
76// a token VALUE must carry NO CSS-structural breakout + NO third-party-fetch/comment substring.
77func bt_value_safe(s: *u8, n: i64) -> i64 {
78 if n <= 0 { return 0 }
79 var i: i64 = 0
80 while i < n {
81 let c: i64 = s[i] as i64
82 if c == 123 { return 0 } // '{'
83 if c == 125 { return 0 } // '}'
84 if c == 59 { return 0 } // ';'
85 if c == 60 { return 0 } // '<'
86 if c == 62 { return 0 } // '>'
87 i = i + 1
88 }
89 if bt_find(s, n, "script" as *u8, 6) >= 0 { return 0 }
90 if bt_find(s, n, "src=" as *u8, 4) >= 0 { return 0 }
91 if bt_find(s, n, "url(" as *u8, 4) >= 0 { return 0 }
92 if bt_find(s, n, "/*" as *u8, 2) >= 0 { return 0 }
93 return 1
94}
95
96// parse a .brand DATA blob -> a :root{ --nx-* } CSS custom-properties block into out (bounded).
97// returns bytes written (excluding nul), or -1 if NO valid token was emitted. out is always finalized+nul-term.
98func bt_emit_root_buf(text: *u8, n: i64, out: *u8, cap: i64) -> i64 {
99 var p: i64 = 0
100 p = bt_app(out, p, cap, ":root{\n" as *u8)
101 var emitted: i64 = 0
102 let pipes: *i64 = sys_mmap(64) as *i64
103 var i: i64 = 0
104 while i < n {
105 // line = [i, le)
106 var le: i64 = i
107 while le < n { if text[le] == (10 as u8) { break } le = le + 1 }
108 // collect up to 3 pipe positions in the line
109 var np: i64 = 0
110 var k: i64 = i
111 while k < le {
112 if text[k] == (124 as u8) { if np < 3 { pipes[np] = k; np = np + 1 } }
113 k = k + 1
114 }
115 if np == 3 {
116 let f0s: i64 = i; let f0e: i64 = pipes[0]
117 let f1s: i64 = pipes[0] + 1; let f1e: i64 = pipes[1]
118 let f2s: i64 = pipes[1] + 1; let f2e: i64 = pipes[2]
119 let f3s: i64 = pipes[2] + 1; let f3e: i64 = le
120 if bt_slice_eq(text, f0s, f0e, "token" as *u8, 5) == 1 {
121 let glen: i64 = f1e - f1s
122 let nlen: i64 = f2e - f2s
123 let vlen: i64 = f3e - f3s
124 if bt_ident_safe(text + f1s, glen) == 1 {
125 if bt_ident_safe(text + f2s, nlen) == 1 {
126 if bt_value_safe(text + f3s, vlen) == 1 {
127 p = bt_app(out, p, cap, " --nx-" as *u8)
128 p = bt_app_n(out, p, cap, text + f1s, glen)
129 p = bt_app(out, p, cap, "-" as *u8)
130 p = bt_app_n(out, p, cap, text + f2s, nlen)
131 p = bt_app(out, p, cap, ": " as *u8)
132 p = bt_app_n(out, p, cap, text + f3s, vlen)
133 p = bt_app(out, p, cap, ";\n" as *u8)
134 emitted = emitted + 1
135 }
136 }
137 }
138 }
139 }
140 i = le + 1
141 }
142 p = bt_app(out, p, cap, "}\n" as *u8)
143 var tp: i64 = p
144 if tp >= cap { tp = cap - 1 }
145 out[tp] = 0 as u8
146 if emitted == 0 { return 0 - 1 }
147 return p
148}
149
150// emit straight to an fd (the path nx_web_builder/wb_doc_open will call in R1b).
151func bt_emit_root_fd(text: *u8, n: i64, fd: i64) -> i64 {
152 let cap: i64 = 65536
153 let out: *u8 = sys_mmap(cap)
154 let w: i64 = bt_emit_root_buf(text, n, out, cap)
155 if w < 0 { return w }
156 sys_write(fd, out, w)
157 return w
158}
159
160// the DEFAULT Nishi starter brand (the current andelinwest navy/amber palette captured AS DATA, plus a real
161// type/space/radius/motion scale). This is the seed brand any actor edits/overrides -- not hardcoded CSS anymore.
162func bt_default_brand() -> *u8 {
163 return "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, -apple-system, Segoe UI, sans-serif\ntoken|font|size-base|16px\ntoken|font|leading|1.6\ntoken|font|h1|2rem\ntoken|font|h2|1.4rem\ntoken|space|1|8px\ntoken|space|2|16px\ntoken|space|3|24px\ntoken|space|4|40px\ntoken|radius|md|8px\ntoken|radius|sm|6px\ntoken|motion|fast|150ms\ntoken|motion|ease|cubic-bezier(.2,.7,.2,1)\n" as *u8
164}
165
166// emit the default brand's :root block into a buffer.
167func bt_default_emit(out: *u8, cap: i64) -> i64 {
168 let d: *u8 = bt_default_brand()
169 return bt_emit_root_buf(d, bt_len(d), out, cap)
170}
171
172// look up a single token's VALUE by group+name; copy into out (nul-terminated), return its length, or -1 if not
173// found. The reusable token getter every actor (R2 enforce, R4 dev/AI/LLM management) resolves a brand through.
174func bt_lookup(text: *u8, n: i64, group: *u8, name: *u8, out: *u8, cap: i64) -> i64 {
175 let glen: i64 = bt_len(group)
176 let nlen: i64 = bt_len(name)
177 let pipes: *i64 = sys_mmap(64) as *i64
178 var i: i64 = 0
179 while i < n {
180 var le: i64 = i
181 while le < n { if text[le] == (10 as u8) { break } le = le + 1 }
182 var np: i64 = 0
183 var k: i64 = i
184 while k < le { if text[k] == (124 as u8) { if np < 3 { pipes[np] = k; np = np + 1 } } k = k + 1 }
185 if np == 3 {
186 let f1s: i64 = pipes[0] + 1; let f1e: i64 = pipes[1]
187 let f2s: i64 = pipes[1] + 1; let f2e: i64 = pipes[2]
188 let f3s: i64 = pipes[2] + 1; let f3e: i64 = le
189 if bt_slice_eq(text, i, pipes[0], "token" as *u8, 5) == 1 {
190 if bt_slice_eq(text, f1s, f1e, group, glen) == 1 {
191 if bt_slice_eq(text, f2s, f2e, name, nlen) == 1 {
192 let vlen: i64 = f3e - f3s
193 var w: i64 = 0
194 while w < vlen { if w < cap - 1 { out[w] = text[f3s + w] } w = w + 1 }
195 var tp: i64 = vlen
196 if tp > cap - 1 { tp = cap - 1 }
197 out[tp] = 0 as u8
198 return vlen
199 }
200 }
201 }
202 }
203 i = le + 1
204 }
205 return 0 - 1
206}
207
208// emit one "token|<group>|<name>|<value>\n" line into out at pos; return new pos. (6 args -- avoids the >6 lane.)
209func bt_emit_token_line(out: *u8, pos: i64, cap: i64, group: *u8, name: *u8, value: *u8) -> i64 {
210 var q: i64 = pos
211 q = bt_app(out, q, cap, "token|" as *u8)
212 q = bt_app(out, q, cap, group)
213 q = bt_app(out, q, cap, "|" as *u8)
214 q = bt_app(out, q, cap, name)
215 q = bt_app(out, q, cap, "|" as *u8)
216 q = bt_app(out, q, cap, value)
217 q = bt_app(out, q, cap, "\n" as *u8)
218 return q
219}
220// produce a NEW .brand with token (group/name)=value: UPDATE in place if present, else APPEND. Validates group/
221// name (ident-safe) + value (sovereignty-safe); returns new length, or -1 if any is unsafe. PURE (base untouched)
222// = the reversibility primitive every actor's brand edit goes through (R4).
223func bt_set(text: *u8, n: i64, group: *u8, name: *u8, value: *u8, out: *u8, cap: i64) -> i64 {
224 let glen: i64 = bt_len(group)
225 let nlen: i64 = bt_len(name)
226 let vlen: i64 = bt_len(value)
227 if bt_ident_safe(group, glen) == 0 { return 0 - 1 }
228 if bt_ident_safe(name, nlen) == 0 { return 0 - 1 }
229 if bt_value_safe(value, vlen) == 0 { return 0 - 1 }
230 let pipes: *i64 = sys_mmap(64) as *i64
231 var p: i64 = 0
232 var found: i64 = 0
233 var i: i64 = 0
234 while i < n {
235 var le: i64 = i
236 while le < n { if text[le] == (10 as u8) { break } le = le + 1 }
237 var np: i64 = 0
238 var k: i64 = i
239 while k < le { if text[k] == (124 as u8) { if np < 3 { pipes[np] = k; np = np + 1 } } k = k + 1 }
240 var ismatch: i64 = 0
241 if np == 3 {
242 if bt_slice_eq(text, i, pipes[0], "token" as *u8, 5) == 1 {
243 if bt_slice_eq(text, pipes[0]+1, pipes[1], group, glen) == 1 {
244 if bt_slice_eq(text, pipes[1]+1, pipes[2], name, nlen) == 1 { ismatch = 1 }
245 }
246 }
247 }
248 if ismatch == 1 {
249 p = bt_emit_token_line(out, p, cap, group, name, value)
250 found = 1
251 } else {
252 var c: i64 = i
253 while c < le { if p < cap { out[p] = text[c]; p = p + 1 } c = c + 1 }
254 if p < cap { out[p] = 10 as u8; p = p + 1 }
255 }
256 i = le + 1
257 }
258 if found == 0 { p = bt_emit_token_line(out, p, cap, group, name, value) }
259 var tp: i64 = p
260 if tp > cap - 1 { tp = cap - 1 }
261 out[tp] = 0 as u8
262 return p
263}
264
265// R8: emit a DARK-mode override block from `dark|<group>|<name>|<value>` lines:
266// @media(prefers-color-scheme:dark){ :root{ --nx-<group>-<name>: <value>; ... } }
267// returns bytes written, or 0 if the brand has NO dark tokens (so the caller emits nothing = backward-compatible).
268// Same ident/value safety as bt_emit_root_buf (sovereignty + no CSS breakout, by construction).
269func bt_emit_dark_root_buf(text: *u8, n: i64, out: *u8, cap: i64) -> i64 {
270 var p: i64 = 0
271 p = bt_app(out, p, cap, "@media(prefers-color-scheme:dark){:root{\n" as *u8)
272 var emitted: i64 = 0
273 let pipes: *i64 = sys_mmap(64) as *i64
274 var i: i64 = 0
275 while i < n {
276 var le: i64 = i
277 while le < n { if text[le] == (10 as u8) { break } le = le + 1 }
278 var np: i64 = 0
279 var k: i64 = i
280 while k < le { if text[k] == (124 as u8) { if np < 3 { pipes[np] = k; np = np + 1 } } k = k + 1 }
281 if np == 3 {
282 if bt_slice_eq(text, i, pipes[0], "dark" as *u8, 4) == 1 {
283 let f1s: i64 = pipes[0] + 1; let f1e: i64 = pipes[1]
284 let f2s: i64 = pipes[1] + 1; let f2e: i64 = pipes[2]
285 let f3s: i64 = pipes[2] + 1; let f3e: i64 = le
286 let glen: i64 = f1e - f1s
287 let nlen: i64 = f2e - f2s
288 let vlen: i64 = f3e - f3s
289 if bt_ident_safe(text + f1s, glen) == 1 {
290 if bt_ident_safe(text + f2s, nlen) == 1 {
291 if bt_value_safe(text + f3s, vlen) == 1 {
292 p = bt_app(out, p, cap, " --nx-" as *u8)
293 p = bt_app_n(out, p, cap, text + f1s, glen)
294 p = bt_app(out, p, cap, "-" as *u8)
295 p = bt_app_n(out, p, cap, text + f2s, nlen)
296 p = bt_app(out, p, cap, ": " as *u8)
297 p = bt_app_n(out, p, cap, text + f3s, vlen)
298 p = bt_app(out, p, cap, ";\n" as *u8)
299 emitted = emitted + 1
300 }
301 }
302 }
303 }
304 }
305 i = le + 1
306 }
307 p = bt_app(out, p, cap, "}}\n" as *u8)
308 var tp: i64 = p
309 if tp > cap - 1 { tp = cap - 1 }
310 out[tp] = 0 as u8
311 if emitted == 0 { return 0 }
312 return p
313}
314func bt_emit_dark_fd(text: *u8, n: i64, fd: i64) -> i64 {
315 let cap: i64 = 65536
316 let out: *u8 = sys_mmap(cap)
317 let w: i64 = bt_emit_dark_root_buf(text, n, out, cap)
318 if w <= 0 { return 0 }
319 sys_write(fd, out, w)
320 return w
321}