code wiki / _hdl_build / nx_site_archetype.nx
nx_site_archetype.nx source
↩ module page · 964 lines · 53249 B
1// nx_site_archetype.nx -- R5 of the SITE FACTORY: COMPOSE whole, award-tier, WCAG-AAA, responsive sites from
2// the pattern corpus that nx_tpl_ingest (R4) built. For each archetype PRESENT in the corpus it emits a distinct
3// full page (varied section set + theme + hero, one shared design system) through the gorgeous nx_sclass_kit v2 --
4// so every page is s-class + accessible + sovereign BY CONSTRUCTION (0 JS, 0 trackers, own tokens). Plus a GALLERY
5// index that shows the range at a glance. This is the "get our generator going -> SOTA aesthetics + breadth" rung:
6// consumed template STRUCTURE (R4) -> generated gorgeous sites (R5).
7// usage: nx_site_archetype <template-dir> <corpus-prefix> <docroot> <domain>
8// emits: <docroot>/index.html (gallery) + <docroot>/<archetype>.html (one per corpus archetype) + sitemap + robots
9// Corpus-driven: walks the source templates, recomputes each content-addressed key, and confirms membership in the
10// seg_store corpus (ss_hget) before composing -> the archetype SET comes from the corpus, not hardcoded.
11// license_tier: ORIGINAL
12import "nx_sclass_kit.nx"
13import "nx_tpl_ingest.nx"
14import "nx_kit2.nx"
15const SA_MAGIC_131072: i64 = 131072
16const SA_MAGIC_1024: i64 = 1024
17const SA_MAGIC_262144: i64 = 262144
18
19const SA_ICON: *u8 = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2l3 7h7l-5.5 4 2 7L12 16l-6.5 4 2-7L2 9h7z\"/></svg>"
20
21// R5b requirements/content: a loaded .req file (line-oriented "<archetype>|<field>|<value>", \n->\0 in place)
22// overrides the built-in default copy so a real brief fills in real words. 0 = none loaded (use defaults).
23static SA_REQ: i64 = 0
24static SA_REQN: i64 = 0
25static SA_NPAT: i64 = 0 // measured distinct patterns in the corpus (shown on the gallery, honest number)
26static SA_NVAR: i64 = 0 // variations emitted this run (per-pattern seq-driven pages; gate-readable)
27const SA_VARCAP: i64 = 40 // budget guard: max variation pages per run (fail-fast, never unbounded)
28// R-SITESHAPE nav hook: when set (label-ptr array, href-ptr array, count) the seq-composer emits the
29// SITE'S OWN nav instead of the default Gallery/Live-site pair. 0 = default (variations unaffected).
30static SA_WNAV: i64 = 0
31static SA_WHREF: i64 = 0
32static SA_WNAVN: i64 = 0
33// R-BRICKS compose hooks: SA_STOREH = open corpus handle for part: queries (0 = none); SA_GRIDN = one-shot
34// item-count override for sa_grid6 (0 = default 6). Consumed bricks drive section richness.
35static SA_STOREH: i64 = 0
36static SA_GRIDN: i64 = 0
37
38func sa_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
39func sa_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
40func sa_cat(out: *u8, o: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){out[o]=s[i]; o=o+1; i=i+1} return o }
41func sa_catn(d: *u8, o: i64, v: i64) -> i64 {
42 var m: i64=v; var oo: i64=o
43 if m<0 { d[oo]=45 as u8; oo=oo+1; m=0-m }
44 var nd: i64=1; var t: i64=m
45 while t>=10 { nd=nd+1; t=t/10 }
46 var i: i64=nd-1
47 while i>=0 { d[oo+i]=(48+(m%10)) as u8; m=m/10; i=i-1 }
48 return oo+nd
49}
50// look up "<archname>|<key>|<value>" in the loaded .req; return a NUL-terminated pointer to <value>, or 0.
51func sa_req_find(arch: i64, key: *u8) -> *u8 {
52 if SA_REQ == 0 { return 0 as *u8 }
53 let buf: *u8 = SA_REQ as *u8
54 let n: i64 = SA_REQN
55 let pfx: *u8 = sys_mmap(96)
56 var po: i64 = ti_arch_name(arch, pfx)
57 pfx[po] = 124 as u8; po = po + 1
58 po = sa_cat(pfx, po, key)
59 pfx[po] = 124 as u8; po = po + 1
60 pfx[po] = 0 as u8
61 let pl: i64 = po
62 var i: i64 = 0
63 while i < n {
64 var m: i64 = 1
65 var j: i64 = 0
66 while j < pl { if (buf[i + j] as i64) != (pfx[j] as i64) { m = 0; j = pl } else { j = j + 1 } }
67 if m == 1 { return (buf as i64 + i + pl) as *u8 }
68 var s: i64 = 1
69 while s == 1 { if i >= n { s = 0 } else { if (buf[i] as i64) == 0 { i = i + 1; s = 0 } else { i = i + 1 } } }
70 }
71 return 0 as *u8
72}
73// count the corpus's "pat:" pattern records (ss_doc_count counts only "doc:" keys -- our keys differ)
74func sa_pat_count(h: *i64) -> i64 {
75 let ns: i64 = h[0]
76 var n: i64 = 0
77 var s: i64 = 0
78 while s < ns {
79 let kb: *u8 = h[1 + 8 * s] as *u8
80 if h[2 + 8 * s] >= 8 {
81 let m9: i64 = ss_r32(kb, 4)
82 var e9: i64 = 0
83 while e9 < m9 {
84 let eo: i64 = 8 + 4 * m9 + ss_r32(kb, 8 + 4 * e9)
85 if (kb[eo] as i64) == 1 {
86 let kl9: i64 = ss_r32(kb, eo + 1)
87 if kl9 >= 4 {
88 if kb[eo + 5] == (112 as u8) { if kb[eo + 6] == (97 as u8) { if kb[eo + 7] == (116 as u8) { if kb[eo + 8] == (58 as u8) {
89 n = n + 1
90 } } } }
91 }
92 }
93 e9 = e9 + 1
94 }
95 }
96 s = s + 1
97 }
98 return n
99}
100
101// R-BRICKS: median heads-count of the consumed part: bricks of `kind`, clamped 3..6. 0 = no bricks.
102// Walks the corpus key blobs (sa_pat_count pattern), fetches each part: record, matches "kind|<kind>\n",
103// parses its "heads|" metric -- so section richness comes from what real templates actually did.
104func sa_brick_n(kind: *u8) -> i64 {
105 if SA_STOREH == 0 { return 0 }
106 let h: *i64 = SA_STOREH as *i64
107 let needle: *u8 = sys_mmap(64)
108 var no: i64 = sa_cat(needle, 0, "kind|" as *u8)
109 no = sa_cat(needle, no, kind)
110 needle[no] = 10 as u8
111 needle[no + 1] = 0 as u8
112 let nlen: i64 = no + 1
113 let keyb: *u8 = sys_mmap(64)
114 let pbox: *i64 = sys_mmap(16) as *i64
115 let lbox: *i64 = sys_mmap(16) as *i64
116 let vals: *i64 = sys_mmap(32 * 8) as *i64
117 var nv: i64 = 0
118 let ns: i64 = h[0]
119 var s: i64 = 0
120 while s < ns {
121 let kb: *u8 = h[1 + 8 * s] as *u8
122 if h[2 + 8 * s] >= 8 {
123 let m9: i64 = ss_r32(kb, 4)
124 var e9: i64 = 0
125 while e9 < m9 {
126 let eo: i64 = 8 + 4 * m9 + ss_r32(kb, 8 + 4 * e9)
127 if (kb[eo] as i64) == 1 {
128 let kl9: i64 = ss_r32(kb, eo + 1)
129 if kl9 >= 6 { if kl9 < 48 {
130 if kb[eo + 5] == (112 as u8) { if kb[eo + 6] == (97 as u8) { if kb[eo + 7] == (114 as u8) { if kb[eo + 8] == (116 as u8) { if kb[eo + 9] == (58 as u8) {
131 var kc: i64 = 0
132 while kc < kl9 { keyb[kc] = kb[eo + 5 + kc]; kc = kc + 1 }
133 keyb[kc] = 0 as u8
134 if ss_hget(h, keyb, pbox, lbox) == 1 {
135 let rp: *u8 = pbox[0] as *u8
136 let rl: i64 = lbox[0]
137 // match kind
138 var km: i64 = 0
139 var i: i64 = 0
140 while i + nlen <= rl {
141 var j: i64 = 0
142 var ok: i64 = 1
143 while j < nlen { if (rp[i + j] as i64) != (needle[j] as i64) { ok = 0; j = nlen } else { j = j + 1 } }
144 if ok == 1 { km = 1; i = rl } else { i = i + 1 }
145 }
146 if km == 1 { if nv < 32 {
147 // parse heads|N
148 let hn2: *u8 = "heads|" as *u8
149 var hp: i64 = 0 - 1
150 var i2: i64 = 0
151 while i2 + 6 <= rl {
152 var j2: i64 = 0
153 var ok2: i64 = 1
154 while j2 < 6 { if (rp[i2 + j2] as i64) != (hn2[j2] as i64) { ok2 = 0; j2 = 6 } else { j2 = j2 + 1 } }
155 if ok2 == 1 { hp = i2 + 6; i2 = rl } else { i2 = i2 + 1 }
156 }
157 if hp >= 0 {
158 var v: i64 = 0
159 var d: i64 = hp
160 var sc: i64 = 1
161 while sc == 1 {
162 if d >= rl { sc = 0 } else {
163 let c: i64 = rp[d] as i64
164 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); d = d + 1 } else { sc = 0 } } else { sc = 0 }
165 }
166 }
167 vals[nv] = v
168 nv = nv + 1
169 }
170 } }
171 }
172 } } } } }
173 } }
174 }
175 e9 = e9 + 1
176 }
177 }
178 s = s + 1
179 }
180 if nv == 0 { return 0 }
181 // insertion sort + median
182 var a: i64 = 1
183 while a < nv {
184 let cv: i64 = vals[a]
185 var b: i64 = a - 1
186 var go: i64 = 1
187 while go == 1 { if b < 0 { go = 0 } else { if vals[b] > cv { vals[b+1] = vals[b]; b = b - 1 } else { go = 0 } } }
188 vals[b+1] = cv
189 a = a + 1
190 }
191 var med: i64 = vals[nv / 2]
192 if med < 3 { med = 3 }
193 if med > 6 { med = 6 }
194 return med
195}
196
197// req string or default
198func sa_rs(arch: i64, key: *u8, def: *u8) -> *u8 {
199 let v: *u8 = sa_req_find(arch, key)
200 if (v as i64) != 0 { return v }
201 return def
202}
203// grid-item override: "<sectionid>.<n>.t" / "<sectionid>.<n>.b"
204func sa_ritem(arch: i64, id: *u8, n: i64, suf: *u8, def: *u8) -> *u8 {
205 let key: *u8 = sys_mmap(96)
206 var o: i64 = sa_cat(key, 0, id)
207 key[o] = 46 as u8; o = o + 1
208 o = sa_catn(key, o, n)
209 key[o] = 46 as u8; o = o + 1
210 o = sa_cat(key, o, suf)
211 key[o] = 0 as u8
212 return sa_rs(arch, key, def)
213}
214// load a .req requirements file ("<archetype>|<key>|<value>" lines): \n/\r -> \0 in place, remember it.
215func sa_req_load(path: *u8) -> i64 {
216 let szp: *i64 = sys_mmap(16) as *i64
217 let raw: *u8 = ss_readall(path, szp)
218 if (raw as i64) == 0 { return 0 - 1 }
219 let n: i64 = szp[0]
220 var i: i64 = 0
221 var lines: i64 = 0
222 while i < n {
223 if (raw[i] as i64) == 10 { raw[i] = 0 as u8; lines = lines + 1 }
224 if (raw[i] as i64) == 13 { raw[i] = 0 as u8 }
225 i = i + 1
226 }
227 raw[n] = 0 as u8
228 SA_REQ = raw as i64
229 SA_REQN = n
230 return lines
231}
232
233func sa_theme(arch: i64) -> i64 {
234 if arch==2 { return 0 }
235 if arch==4 { return 0 }
236 if arch==6 { return 0 }
237 if arch==9 { return 0 }
238 return 1
239}
240// display name (page title + gallery card)
241func sa_disp(arch: i64) -> *u8 {
242 if arch==1 { return "Landing page" as *u8 }
243 if arch==2 { return "Online store" as *u8 }
244 if arch==3 { return "Social network" as *u8 }
245 if arch==4 { return "Media library" as *u8 }
246 if arch==5 { return "Resume / portfolio" as *u8 }
247 if arch==6 { return "Family hub" as *u8 }
248 if arch==8 { return "Portfolio" as *u8 }
249 if arch==9 { return "Photo gallery" as *u8 }
250 if arch==10 { return "Blog / magazine" as *u8 }
251 return "Brochure" as *u8
252}
253// content strings by (archetype, field). field: 0 eyebrow 1 hero-pre 2 hero-grad 3 lede 4 hint 5 cta1 6 cta-h2 7 cta-p 8 footer
254// A loaded .req overrides any field: "<archname>|<key>|<value>" with key in
255// eyebrow/heropre/herograd/lede/hint/cta1/ctah2/ctap/footer (R5b requirements compiler).
256func sa_s(arch: i64, field: i64) -> *u8 {
257 if SA_REQ != 0 {
258 var k: *u8 = "eyebrow" as *u8
259 if field == 1 { k = "heropre" as *u8 }
260 if field == 2 { k = "herograd" as *u8 }
261 if field == 3 { k = "lede" as *u8 }
262 if field == 4 { k = "hint" as *u8 }
263 if field == 5 { k = "cta1" as *u8 }
264 if field == 6 { k = "ctah2" as *u8 }
265 if field == 7 { k = "ctap" as *u8 }
266 if field == 8 { k = "footer" as *u8 }
267 let rv: *u8 = sa_req_find(arch, k)
268 if (rv as i64) != 0 { return rv }
269 }
270 if arch==1 {
271 if field==0 { return "Landing" as *u8 }
272 if field==1 { return "Ship your idea" as *u8 }
273 if field==2 { return "in a weekend" as *u8 }
274 if field==3 { return "A conversion-first landing page: a bold hero, the proof, the plan, and one clear call to action." as *u8 }
275 if field==4 { return "Free to start -- no card required." as *u8 }
276 if field==5 { return "Get started" as *u8 }
277 if field==6 { return "Ready when you are" as *u8 }
278 if field==7 { return "One short step to launch. Everything accessible, fast, and yours." as *u8 }
279 return "Composed by the Nishi Site Factory." as *u8
280 }
281 if arch==2 {
282 if field==0 { return "Store" as *u8 }
283 if field==1 { return "Everything you need" as *u8 }
284 if field==2 { return "in one place" as *u8 }
285 if field==3 { return "A storefront built to convert: featured products, trust signals, and a frictionless path to checkout." as *u8 }
286 if field==4 { return "Free shipping over 50." as *u8 }
287 if field==5 { return "Start shopping" as *u8 }
288 if field==6 { return "Your cart is waiting" as *u8 }
289 if field==7 { return "Secure checkout, honest pricing, no dark patterns." as *u8 }
290 return "Composed by the Nishi Site Factory." as *u8
291 }
292 if arch==3 {
293 if field==0 { return "Community" as *u8 }
294 if field==1 { return "Find your" as *u8 }
295 if field==2 { return "people" as *u8 }
296 if field==3 { return "A social space with a feed, profiles, and groups -- private by default, no ads, no tracking." as *u8 }
297 if field==4 { return "Two-adults rule, no adult DMs." as *u8 }
298 if field==5 { return "Join free" as *u8 }
299 if field==6 { return "Better conversations start here" as *u8 }
300 if field==7 { return "You own your data. We sell nothing." as *u8 }
301 return "Composed by the Nishi Site Factory." as *u8
302 }
303 if arch==4 {
304 if field==0 { return "Library" as *u8 }
305 if field==1 { return "Watch anything" as *u8 }
306 if field==2 { return "anytime" as *u8 }
307 if field==3 { return "A media library that streams your collection -- browse, watch, and download, on any screen." as *u8 }
308 if field==4 { return "Your library, zero ads." as *u8 }
309 if field==5 { return "Start watching" as *u8 }
310 if field==6 { return "Press play" as *u8 }
311 if field==7 { return "Thousands of titles, one sovereign server." as *u8 }
312 return "Composed by the Nishi Site Factory." as *u8
313 }
314 if arch==5 {
315 if field==0 { return "Portfolio" as *u8 }
316 if field==1 { return "Jordan Rivera" as *u8 }
317 if field==2 { return "Product Designer" as *u8 }
318 if field==3 { return "A resume and portfolio: experience, selected work, and the skills that back it up." as *u8 }
319 if field==4 { return "Open to new projects." as *u8 }
320 if field==5 { return "Get in touch" as *u8 }
321 if field==6 { return "Let us build something" as *u8 }
322 if field==7 { return "Tell me about your project and I will reply within a day." as *u8 }
323 return "Composed by the Nishi Site Factory." as *u8
324 }
325 if arch==6 {
326 if field==0 { return "Hub" as *u8 }
327 if field==1 { return "Your family" as *u8 }
328 if field==2 { return "in one hub" as *u8 }
329 if field==3 { return "One place for your apps, photos, and tools -- fast, private, and made for every screen." as *u8 }
330 if field==4 { return "Everything, nothing tracked." as *u8 }
331 if field==5 { return "Open the hub" as *u8 }
332 if field==6 { return "All of it, one tap away" as *u8 }
333 if field==7 { return "Your apps and memories, always at hand." as *u8 }
334 return "Composed by the Nishi Site Factory." as *u8
335 }
336 if arch==8 {
337 if field==0 { return "Portfolio" as *u8 }
338 if field==1 { return "Selected" as *u8 }
339 if field==2 { return "work" as *u8 }
340 if field==3 { return "A portfolio: a bold intro, selected projects, and a clear way to get in touch." as *u8 }
341 if field==4 { return "Open to new work." as *u8 }
342 if field==5 { return "See the work" as *u8 }
343 if field==6 { return "Let us collaborate" as *u8 }
344 if field==7 { return "Tell me about your project and I will reply within a day." as *u8 }
345 return "Composed by the Nishi Site Factory." as *u8
346 }
347 if arch==9 {
348 if field==0 { return "Gallery" as *u8 }
349 if field==1 { return "Moments" as *u8 }
350 if field==2 { return "in focus" as *u8 }
351 if field==3 { return "A photo gallery: a clean grid that lets the images lead." as *u8 }
352 if field==4 { return "Prints available." as *u8 }
353 if field==5 { return "View the gallery" as *u8 }
354 if field==6 { return "Want a print" as *u8 }
355 if field==7 { return "Reach out for prints, licensing, or a shoot." as *u8 }
356 return "Composed by the Nishi Site Factory." as *u8
357 }
358 if arch==10 {
359 if field==0 { return "Blog" as *u8 }
360 if field==1 { return "Ideas worth" as *u8 }
361 if field==2 { return "sharing" as *u8 }
362 if field==3 { return "A blog and magazine: a strong lead story and a clean, readable stream of posts." as *u8 }
363 if field==4 { return "New posts weekly." as *u8 }
364 if field==5 { return "Start reading" as *u8 }
365 if field==6 { return "Never miss a post" as *u8 }
366 if field==7 { return "Subscribe and get new stories in your inbox." as *u8 }
367 return "Composed by the Nishi Site Factory." as *u8
368 }
369 if field==0 { return "Welcome" as *u8 }
370 if field==1 { return "A better way" as *u8 }
371 if field==2 { return "to work with us" as *u8 }
372 if field==3 { return "A clean brochure site: who we are, what we do, and how to reach us." as *u8 }
373 if field==4 { return "Trusted by our community." as *u8 }
374 if field==5 { return "Contact us" as *u8 }
375 if field==6 { return "Let us talk" as *u8 }
376 if field==7 { return "Reach out and we will get right back to you." as *u8 }
377 return "Composed by the Nishi Site Factory." as *u8
378}
379
380// "/factory/<archetype>.html" into out (archetype = lowercase name from ti_arch_name)
381func sa_href(out: *u8, arch: i64) -> i64 {
382 var o: i64 = sa_cat(out, 0, "/factory/" as *u8)
383 let nm: *u8 = sys_mmap(32)
384 ti_arch_name(arch, nm)
385 o = sa_cat(out, o, nm)
386 o = sa_cat(out, o, ".html" as *u8)
387 out[o]=0 as u8
388 return o
389}
390
391// ---- reusable content sections (award-tier via the kit) ----
392func sa_features(buf: *u8, o: i64, tag: *u8, h2: *u8, sub: *u8, t0: *u8, b0: *u8, t1: *u8, b1: *u8, t2: *u8, b2: *u8) -> i64 {
393 var x: i64 = sk_section_open(buf, o, "features" as *u8, tag, h2, sub)
394 x = sk_card(buf, x, SA_ICON, t0, b0)
395 x = sk_card(buf, x, SA_ICON, t1, b1)
396 x = sk_card(buf, x, SA_ICON, t2, b2)
397 x = sk_section_close(buf, x)
398 return x
399}
400func sa_proof(buf: *u8, o: i64, h2: *u8, sub: *u8, n0: *u8, q0: *u8, n1: *u8, q1: *u8, n2: *u8, q2: *u8) -> i64 {
401 var x: i64 = sk_trust_open(buf, o, "Proof" as *u8, h2, sub)
402 x = sk_trust_item(buf, x, n0, q0)
403 x = sk_trust_item(buf, x, n1, q1)
404 x = sk_trust_item(buf, x, n2, q2)
405 x = sk_trust_close(buf, x)
406 return x
407}
408func sa_grid6(buf: *u8, o: i64, arch: i64, id: *u8, tag: *u8, h2: *u8, sub: *u8, label: *u8) -> i64 {
409 var x: i64 = sk_section_open(buf, o, id, tag, h2, sub)
410 let nm: *u8 = sys_mmap(64)
411 var n6: i64 = 6
412 if SA_GRIDN > 0 { n6 = SA_GRIDN }
413 var i: i64 = 0
414 while i < n6 {
415 var e: i64 = sa_cat(nm, 0, label)
416 nm[e] = 32 as u8; e = e + 1
417 nm[e] = (49 + i) as u8; e = e + 1
418 nm[e] = 0 as u8
419 // R5b: real copy from the .req when provided ("<id>.<n>.t" / "<id>.<n>.b"); default otherwise.
420 let ct: *u8 = sa_ritem(arch, id, i + 1, "t" as *u8, nm)
421 let cb: *u8 = sa_ritem(arch, id, i + 1, "b" as *u8, "Composed from the corpus pattern -- swap in real content via requirements." as *u8)
422 x = sk_card(buf, x, SA_ICON, ct, cb)
423 i = i + 1
424 }
425 x = sk_section_close(buf, x)
426 return x
427}
428
429// build "<heropre> <herograd>" headline into a scratch buffer
430func sa_headline(arch: i64) -> *u8 {
431 let hl: *u8 = sys_mmap(256)
432 var o: i64 = sa_cat(hl, 0, sa_s(arch, 1))
433 hl[o] = 32 as u8; o = o + 1
434 o = sa_cat(hl, o, sa_s(arch, 2))
435 hl[o] = 0 as u8
436 return hl
437}
438// EDITORIAL / newspaper design (nx_kit2 ke_*) -- for BLOG
439func sa_recipe_editorial(arch: i64, brand: *u8, title: *u8, buf: *u8) -> i64 {
440 var o: i64 = ke_open(buf, 0, title, brand)
441 let body: *u8 = sa_rs(arch, "leadbody" as *u8, "<p>This edition is composed end to end by a sovereign organ -- no content system, no template marketplace, no third-party stylesheet. The layout was learned from real open templates; the words come from a plain requirements file.</p><p>What you are reading is proof that a generator can produce a finished page, not a wireframe. Every section was placed by the same pipeline, and each can be re-themed without touching a line of markup.</p>" as *u8)
442 o = ke_lead(buf, o, sa_s(arch, 0), sa_headline(arch), sa_s(arch, 3), "By the Editors", body)
443 o = ke_more_open(buf, o, "More stories" as *u8)
444 var i: i64 = 1
445 while i <= 4 {
446 let t: *u8 = sa_ritem(arch, "posts" as *u8, i, "t" as *u8, "A dispatch from the pipeline" as *u8)
447 let d: *u8 = sa_ritem(arch, "posts" as *u8, i, "b" as *u8, "Placed by the generator -- fill it from the requirements file." as *u8)
448 let m: *u8 = sa_ritem(arch, "posts" as *u8, i, "m" as *u8, "Generated" as *u8)
449 o = ke_item(buf, o, t, d, m)
450 i = i + 1
451 }
452 o = ke_more_close(buf, o)
453 o = ke_sub(buf, o, sa_s(arch, 6), sa_s(arch, 7), sa_s(arch, 5), "/" as *u8)
454 o = ke_close(buf, o, brand, sa_s(arch, 8))
455 return o
456}
457// DARK FULL-BLEED GALLERY design (nx_kit2 kg_*) -- for GALLERY + PORTFOLIO
458func sa_recipe_gallery(arch: i64, secid: *u8, brand: *u8, title: *u8, buf: *u8) -> i64 {
459 var o: i64 = kg_open(buf, 0, title, brand)
460 o = kg_head(buf, o, sa_s(arch, 0), sa_headline(arch), sa_s(arch, 3))
461 o = kg_grid_open(buf, o)
462 var i: i64 = 1
463 while i <= 6 {
464 let cap: *u8 = sa_ritem(arch, secid, i, "t" as *u8, "Untitled" as *u8)
465 let sub: *u8 = sa_ritem(arch, secid, i, "b" as *u8, "Add a caption in the requirements file." as *u8)
466 o = kg_tile(buf, o, i, cap, sub)
467 i = i + 1
468 }
469 o = kg_grid_close(buf, o)
470 o = kg_cta(buf, o, sa_s(arch, 6), sa_s(arch, 7), sa_s(arch, 5), "/" as *u8)
471 o = kg_close(buf, o, brand, sa_s(arch, 8))
472 return o
473}
474
475// SHOP design (nx_kit2 ks_*) -- for ECOMMERCE
476func sa_recipe_shop(arch: i64, brand: *u8, title: *u8, buf: *u8) -> i64 {
477 var o: i64 = ks_open(buf, 0, title, brand)
478 o = ks_promo(buf, o, sa_headline(arch), sa_s(arch, 3))
479 o = ks_grid_open(buf, o, "Featured products" as *u8)
480 var i: i64 = 1
481 while i <= 6 {
482 let n: *u8 = sa_ritem(arch, "products" as *u8, i, "t" as *u8, "Featured product" as *u8)
483 let d: *u8 = sa_ritem(arch, "products" as *u8, i, "b" as *u8, "A well-made thing -- add details in the requirements file." as *u8)
484 let p: *u8 = sa_ritem(arch, "products" as *u8, i, "p" as *u8, "$24" as *u8)
485 o = ks_prod(buf, o, i, n, d, p)
486 i = i + 1
487 }
488 o = ks_grid_close(buf, o)
489 o = ks_trust(buf, o, "over $50" as *u8, "30-day, no questions" as *u8, "sovereign TLS 1.3" as *u8)
490 o = ks_close(buf, o, brand, sa_s(arch, 8))
491 return o
492}
493
494// SOCIAL FEED design (nx_kit2 kf_*) -- for SOCIAL
495func sa_recipe_social(arch: i64, brand: *u8, title: *u8, buf: *u8) -> i64 {
496 var o: i64 = kf_open(buf, 0, title, brand)
497 o = kf_composer(buf, o, sa_rs(arch, "composer" as *u8, "Share something with the family" as *u8))
498 var i: i64 = 1
499 while i <= 4 {
500 let a: *u8 = sa_ritem(arch, "feed" as *u8, i, "a" as *u8, "A community member" as *u8)
501 let m: *u8 = sa_ritem(arch, "feed" as *u8, i, "m" as *u8, "today" as *u8)
502 let t: *u8 = sa_ritem(arch, "feed" as *u8, i, "b" as *u8, "A post placed by the generator -- fill it from the requirements file." as *u8)
503 o = kf_post(buf, o, i, a, m, t)
504 i = i + 1
505 }
506 o = kf_aside_open(buf, o, sa_s(arch, 3))
507 i = 1
508 while i <= 3 {
509 let n: *u8 = sa_ritem(arch, "follow" as *u8, i, "t" as *u8, "A neighbor" as *u8)
510 o = kf_follow(buf, o, i, n)
511 i = i + 1
512 }
513 o = kf_close(buf, o, brand, sa_s(arch, 8))
514 return o
515}
516// MEDIA STREAMER design (nx_kit2 km_*) -- for MEDIA
517func sa_recipe_media(arch: i64, brand: *u8, title: *u8, buf: *u8) -> i64 {
518 var o: i64 = km_open(buf, 0, title, brand)
519 o = km_billboard(buf, o, sa_s(arch, 0),
520 sa_rs(arch, "billt" as *u8, "The Long Season" as *u8),
521 sa_rs(arch, "billm" as *u8, "2026 · Documentary · 96 min · 4K" as *u8),
522 sa_rs(arch, "billsub" as *u8, "The 4K remaster of the farm documentary the whole family quotes -- restored frame by frame on the sovereign pipeline." as *u8),
523 sa_rs(arch, "billplay" as *u8, "Play" as *u8))
524 o = km_shelf_open(buf, o, sa_rs(arch, "shelf1" as *u8, "New this week" as *u8))
525 var i: i64 = 1
526 while i <= 6 {
527 let n: *u8 = sa_ritem(arch, "library" as *u8, i, "t" as *u8, "Untitled" as *u8)
528 let s: *u8 = sa_ritem(arch, "library" as *u8, i, "s" as *u8, "In your library" as *u8)
529 o = km_poster(buf, o, i, n, s)
530 i = i + 1
531 }
532 o = km_shelf_close(buf, o)
533 o = km_shelf_open(buf, o, sa_rs(arch, "shelf2" as *u8, "Continue watching" as *u8))
534 i = 1
535 while i <= 6 {
536 let n2: *u8 = sa_ritem(arch, "library" as *u8, 7 - i, "t" as *u8, "Untitled" as *u8)
537 o = km_poster(buf, o, i + 6, n2, "Pick up where you left off" as *u8)
538 i = i + 1
539 }
540 o = km_shelf_close(buf, o)
541 o = km_close(buf, o, brand, sa_s(arch, 8))
542 return o
543}
544// HUB DASHBOARD design (nx_kit2 kd_*) -- for HUB
545func sa_recipe_hub(arch: i64, brand: *u8, title: *u8, buf: *u8) -> i64 {
546 var o: i64 = kd_open(buf, 0, title, brand)
547 o = kd_greet(buf, o, sa_rs(arch, "greet" as *u8, "Good evening." as *u8), sa_s(arch, 3))
548 o = kd_deck_open(buf, o)
549 var i: i64 = 1
550 while i <= 6 {
551 let n: *u8 = sa_ritem(arch, "apps" as *u8, i, "t" as *u8, "An app" as *u8)
552 let b: *u8 = sa_ritem(arch, "apps" as *u8, i, "b" as *u8, "One tap away." as *u8)
553 let h: *u8 = sa_ritem(arch, "apps" as *u8, i, "h" as *u8, "/" as *u8)
554 o = kd_tile(buf, o, i, n, b, h)
555 i = i + 1
556 }
557 o = kd_deck_close(buf, o)
558 o = kd_strip(buf, o, "your data never leaves the house" as *u8, "a supervisor watches every service" as *u8, "phone, desktop, TV" as *u8)
559 o = kd_close(buf, o, brand, sa_s(arch, 8))
560 return o
561}
562
563// ---- PER-PATTERN (seq-driven) composition: the CONSUMED template's section ORDER shapes the page ----
564// idx-th '>'-separated token of a seq string -> out (NUL-term). returns len, 0 = past end.
565func sa_tok_at(seq: *u8, idx: i64, out: *u8) -> i64 {
566 var t: i64 = 0
567 var i: i64 = 0
568 while t < idx {
569 var go: i64 = 1
570 while go == 1 {
571 if seq[i] == (0 as u8) { out[0] = 0 as u8; return 0 }
572 if seq[i] == (62 as u8) { go = 0 }
573 i = i + 1
574 }
575 t = t + 1
576 }
577 if seq[i] == (0 as u8) { out[0] = 0 as u8; return 0 }
578 var o: i64 = 0
579 while seq[i] != (0 as u8) {
580 if seq[i] == (62 as u8) { out[o] = 0 as u8; return o }
581 out[o] = seq[i]
582 o = o + 1
583 i = i + 1
584 }
585 out[o] = 0 as u8
586 return o
587}
588func sa_tokeq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while 1 == 1 { if (a[i] as i64) != (b[i] as i64) { return 0 } if a[i] == (0 as u8) { return 1 } i = i + 1 } return 1 }
589// compose a page whose SECTION ORDER follows the consumed pattern's seq (kit1 marketing grammar; the
590// archetype's content fills the sections). hero is always the title carrier; hd/nav/ft live in the shell.
591func sa_recipe_seq(arch: i64, seq: *u8, theme: i64, brand: *u8, title: *u8, buf: *u8) -> i64 {
592 var brandhref: *u8 = "/factory/" as *u8
593 if SA_WNAVN > 0 { brandhref = "/" as *u8 }
594 var o: i64 = sk_open_site(buf, 0, title, brand, theme, brandhref)
595 if SA_WNAVN > 0 {
596 let nl: *i64 = SA_WNAV as *i64
597 let nh: *i64 = SA_WHREF as *i64
598 var ni: i64 = 0
599 while ni < SA_WNAVN { o = sk_nav_item(buf, o, nl[ni] as *u8, nh[ni] as *u8); ni = ni + 1 }
600 } else {
601 o = sk_nav_item(buf, o, "Gallery" as *u8, "/factory/" as *u8)
602 o = sk_nav_item(buf, o, "Live site" as *u8, "/" as *u8)
603 }
604 o = sk_header_close(buf, o)
605 o = sk_hero(buf, o, sa_s(arch,0), sa_s(arch,1), sa_s(arch,2), sa_s(arch,3), sa_s(arch,5), "/" as *u8, "See the gallery" as *u8, "/factory/" as *u8, sa_s(arch,4))
606 let tok: *u8 = sys_mmap(32)
607 let done: *i64 = sys_mmap(16 * 8) as *i64
608 var d: i64 = 0
609 while d < 16 { done[d] = 0; d = d + 1 }
610 var ti: i64 = 0
611 var run: i64 = 1
612 while run == 1 {
613 let tl: i64 = sa_tok_at(seq, ti, tok)
614 ti = ti + 1
615 if tl == 0 { run = 0 } else {
616 if sa_tokeq(tok, "feat" as *u8) == 1 { if done[0] == 0 { done[0] = 1
617 o = sa_features(buf, o, "Features" as *u8, "What you get" as *u8, "Composed in the order the consumed template used." as *u8, "Fast" as *u8, "Static-fast pages, no framework tax." as *u8, "Accessible" as *u8, "WCAG-AAA contrast, keyboard-first." as *u8, "Sovereign" as *u8, "No third-party CSS, JS, or trackers." as *u8) } }
618 if sa_tokeq(tok, "proof" as *u8) == 1 { if done[1] == 0 { done[1] = 1
619 o = sa_proof(buf, o, "Trusted" as *u8, "What people say." as *u8, "A builder" as *u8, "Shipped in an afternoon." as *u8, "A designer" as *u8, "It just looks right." as *u8, "An engineer" as *u8, "Zero JS and it flies." as *u8) } }
620 if sa_tokeq(tok, "price" as *u8) == 1 { if done[2] == 0 { done[2] = 1
621 o = sk_section_open(buf, o, "price" as *u8, "Pricing" as *u8, "Simple, honest pricing" as *u8, "Start free -- upgrade when it pays for itself." as *u8)
622 o = sk_card(buf, o, SA_ICON, "Free" as *u8, "Everything to launch one site." as *u8)
623 o = sk_card(buf, o, SA_ICON, "Pro" as *u8, "Custom domain and every archetype." as *u8)
624 o = sk_card(buf, o, SA_ICON, "Team" as *u8, "Shared workspace and roles." as *u8)
625 o = sk_section_close(buf, o) } }
626 if sa_tokeq(tok, "gal" as *u8) == 1 { if done[3] == 0 { done[3] = 1
627 SA_GRIDN = sa_brick_n("gal" as *u8)
628 o = sa_grid6(buf, o, arch, "gallery" as *u8, "Gallery" as *u8, "From the collection" as *u8, "A grid placed exactly where the source template placed its gallery." as *u8, "Piece" as *u8)
629 SA_GRIDN = 0 } }
630 if sa_tokeq(tok, "vid" as *u8) == 1 { if done[4] == 0 { done[4] = 1
631 SA_GRIDN = sa_brick_n("vid" as *u8)
632 o = sa_grid6(buf, o, arch, "media" as *u8, "Media" as *u8, "Watch and listen" as *u8, "Media cards in the source template's position." as *u8, "Clip" as *u8)
633 SA_GRIDN = 0 } }
634 if sa_tokeq(tok, "faq" as *u8) == 1 { if done[5] == 0 { done[5] = 1
635 o = sk_section_open(buf, o, "faq" as *u8, "FAQ" as *u8, "Questions, answered" as *u8, "The things people ask most." as *u8)
636 o = sk_card(buf, o, SA_ICON, "Is it really no-JS" as *u8, "Yes -- every page works with scripting off." as *u8)
637 o = sk_card(buf, o, SA_ICON, "Is it accessible" as *u8, "AAA contrast, skip links, semantic landmarks." as *u8)
638 o = sk_card(buf, o, SA_ICON, "Can I self-host" as *u8, "It is your markup on your server." as *u8)
639 o = sk_section_close(buf, o) } }
640 if sa_tokeq(tok, "form" as *u8) == 1 { if done[6] == 0 { done[6] = 1
641 o = sk_search(buf, o, "/search" as *u8, "Search this site" as *u8) } }
642 if sa_tokeq(tok, "cta" as *u8) == 1 { if done[7] == 0 { done[7] = 1
643 o = sk_cta(buf, o, sa_s(arch,0), sa_s(arch,6), sa_s(arch,7), sa_s(arch,5), "/" as *u8, "Back to gallery" as *u8, "/factory/" as *u8) } }
644 }
645 }
646 o = sk_close(buf, o, "Composed per-pattern: the section order above is the CONSUMED template's own information architecture." as *u8, brand)
647 return o
648}
649
650// compose ONE whole archetype page; returns byte length. Distinct DESIGN SYSTEM per archetype family.
651func sa_recipe(arch: i64, brand: *u8, title: *u8, buf: *u8) -> i64 {
652 if arch == 10 { return sa_recipe_editorial(arch, brand, title, buf) }
653 if arch == 2 { return sa_recipe_shop(arch, brand, title, buf) }
654 if arch == 3 { return sa_recipe_social(arch, brand, title, buf) }
655 if arch == 4 { return sa_recipe_media(arch, brand, title, buf) }
656 if arch == 6 { return sa_recipe_hub(arch, brand, title, buf) }
657 if arch == 9 { return sa_recipe_gallery(arch, "gallery" as *u8, brand, title, buf) }
658 if arch == 8 { return sa_recipe_gallery(arch, "work" as *u8, brand, title, buf) }
659 let theme: i64 = sa_theme(arch)
660 var o: i64 = sk_open_site(buf, 0, title, brand, theme, "/factory/" as *u8)
661 o = sk_nav_item(buf, o, "Gallery" as *u8, "/factory/" as *u8)
662 o = sk_nav_item(buf, o, "Live site" as *u8, "/" as *u8)
663 o = sk_header_close(buf, o)
664 o = sk_hero(buf, o, sa_s(arch,0), sa_s(arch,1), sa_s(arch,2), sa_s(arch,3), sa_s(arch,5), "/" as *u8, "See the gallery" as *u8, "/factory/" as *u8, sa_s(arch,4))
665 if arch==1 {
666 o = sa_features(buf, o, "Features" as *u8, "Everything you need to launch" as *u8, "Fast, accessible, and yours." as *u8, "Blazing fast" as *u8, "Static-fast pages, no framework tax." as *u8, "Accessible" as *u8, "WCAG-AAA contrast, keyboard-first." as *u8, "Sovereign" as *u8, "No third-party CSS, JS, or trackers." as *u8)
667 o = sa_proof(buf, o, "Loved by builders" as *u8, "What early users say." as *u8, "A founder" as *u8, "Launched in an afternoon." as *u8, "A designer" as *u8, "It just looks right." as *u8, "An engineer" as *u8, "Zero JS and it flies." as *u8)
668 o = sk_section_open(buf, o, "pricing" as *u8, "Pricing" as *u8, "Simple, honest pricing" as *u8, "Start free. Upgrade when it pays for itself." as *u8)
669 o = sk_card(buf, o, SA_ICON, "Free" as *u8, "Everything to launch one site." as *u8)
670 o = sk_card(buf, o, SA_ICON, "Pro" as *u8, "Custom domain and more archetypes." as *u8)
671 o = sk_card(buf, o, SA_ICON, "Team" as *u8, "Shared workspace and roles." as *u8)
672 o = sk_section_close(buf, o)
673 o = sk_section_open(buf, o, "faq" as *u8, "FAQ" as *u8, "Questions, answered" as *u8, "The things people ask most." as *u8)
674 o = sk_card(buf, o, SA_ICON, "Is it really no-JS" as *u8, "Yes -- every page is static and works with scripting off." as *u8)
675 o = sk_card(buf, o, SA_ICON, "Is it accessible" as *u8, "AAA contrast, skip links, and semantic landmarks by default." as *u8)
676 o = sk_card(buf, o, SA_ICON, "Can I self-host" as *u8, "Yes -- it is your markup on your server." as *u8)
677 o = sk_section_close(buf, o)
678 }
679 if arch==2 {
680 o = sa_grid6(buf, o, arch, "products" as *u8, "Shop" as *u8, "Featured products" as *u8, "Handpicked and ready to ship." as *u8, "Product" as *u8)
681 o = sa_proof(buf, o, "Trusted checkout" as *u8, "Why shoppers stay." as *u8, "Secure" as *u8, "Sovereign TLS, no card stored." as *u8, "Honest" as *u8, "Prices with no dark patterns." as *u8, "Fast" as *u8, "Pages load instantly." as *u8)
682 }
683 if arch==3 {
684 o = sa_features(buf, o, "How it works" as *u8, "A kinder social space" as *u8, "Built for real connection." as *u8, "A real feed" as *u8, "Chronological, no engagement bait." as *u8, "Private groups" as *u8, "Share with the people you choose." as *u8, "No ads" as *u8, "You are not the product." as *u8)
685 o = sa_proof(buf, o, "A safer community" as *u8, "Safety by construction." as *u8, "Two-adults rule" as *u8, "No one is ever alone with a minor." as *u8, "No adult DMs" as *u8, "Youth spaces are protected." as *u8, "You own it" as *u8, "Export or delete anytime." as *u8)
686 }
687 if arch==4 {
688 o = sa_grid6(buf, o, arch, "library" as *u8, "Library" as *u8, "Browse the library" as *u8, "Your collection, beautifully organized." as *u8, "Title" as *u8)
689 o = sa_features(buf, o, "Anywhere" as *u8, "Watch on any screen" as *u8, "Responsive by construction." as *u8, "Any device" as *u8, "Phone, tablet, desktop, TV." as *u8, "Download" as *u8, "Take it offline." as *u8, "No ads" as *u8, "Just your library." as *u8)
690 }
691 if arch==5 {
692 o = sa_features(buf, o, "Experience" as *u8, "Where I have worked" as *u8, "A decade of shipping product." as *u8, "Lead Designer" as *u8, "Owned end-to-end design systems." as *u8, "Senior Designer" as *u8, "Shipped flagship features." as *u8, "Designer" as *u8, "Where it all started." as *u8)
693 o = sa_grid6(buf, o, arch, "work" as *u8, "Portfolio" as *u8, "Selected work" as *u8, "A few things I am proud of." as *u8, "Project" as *u8)
694 o = sa_proof(buf, o, "Skills and endorsements" as *u8, "What colleagues say." as *u8, "Systems" as *u8, "Design systems and tokens." as *u8, "Research" as *u8, "Turns users into insight." as *u8, "Craft" as *u8, "Pixel-tight and accessible." as *u8)
695 }
696 if arch==6 {
697 o = sa_grid6(buf, o, arch, "apps" as *u8, "Apps" as *u8, "Everything in one place" as *u8, "Your family hub, one tap away." as *u8, "App" as *u8)
698 }
699 if arch==7 {
700 o = sa_features(buf, o, "What we do" as *u8, "How we help" as *u8, "Clear services, no jargon." as *u8, "Consult" as *u8, "We listen first." as *u8, "Deliver" as *u8, "We ship on time." as *u8, "Support" as *u8, "We stay with you." as *u8)
701 o = sa_proof(buf, o, "Our promise" as *u8, "Why clients trust us." as *u8, "Honest" as *u8, "Plain talk, fair prices." as *u8, "Local" as *u8, "We know our community." as *u8, "Proven" as *u8, "Years of happy clients." as *u8)
702 }
703 if arch==8 {
704 o = sa_grid6(buf, o, arch, "work" as *u8, "Portfolio" as *u8, "Selected work" as *u8, "A few projects I am proud of." as *u8, "Project" as *u8)
705 o = sa_proof(buf, o, "About" as *u8, "How I work." as *u8, "Discovery" as *u8, "I start by understanding the problem." as *u8, "Craft" as *u8, "Accessible, pixel-tight, fast." as *u8, "Delivery" as *u8, "Shipped and supported." as *u8)
706 }
707 if arch==9 {
708 o = sa_grid6(buf, o, arch, "gallery" as *u8, "Gallery" as *u8, "Recent work" as *u8, "A clean grid that lets the images lead." as *u8, "Shot" as *u8)
709 o = sa_features(buf, o, "Details" as *u8, "About the collection" as *u8, "Shot and edited in-house." as *u8, "Originals" as *u8, "Every frame is our own." as *u8, "Prints" as *u8, "Museum-grade paper." as *u8, "Licensing" as *u8, "Simple, fair terms." as *u8)
710 }
711 if arch==10 {
712 o = sk_section_open(buf, o, "posts" as *u8, "Blog" as *u8, "Latest posts" as *u8, "Stories, notes, and the occasional deep dive." as *u8)
713 o = sk_card(buf, o, SA_ICON, "A lead story" as *u8, "The piece we most want you to read this week." as *u8)
714 o = sk_card(buf, o, SA_ICON, "A short note" as *u8, "Quick thoughts between the longer pieces." as *u8)
715 o = sk_card(buf, o, SA_ICON, "A deep dive" as *u8, "Where we go long on something that matters." as *u8)
716 o = sk_section_close(buf, o)
717 o = sa_proof(buf, o, "About" as *u8, "Who writes here." as *u8, "Independent" as *u8, "No sponsors, no tracking." as *u8, "Regular" as *u8, "New posts every week." as *u8, "Yours" as *u8, "Read on any device." as *u8)
718 }
719 o = sk_cta(buf, o, sa_s(arch,0), sa_s(arch,6), sa_s(arch,7), sa_s(arch,5), "/" as *u8, "Back to gallery" as *u8, "/factory/" as *u8)
720 o = sk_close(buf, o, sa_s(arch,8), brand)
721 return o
722}
723
724// "v-<archname>-<key-digits<=10>" (flat basename -> publishable in the content namespace). returns len.
725func sa_vname(arch: i64, key: *u8, out: *u8) -> i64 {
726 var o: i64 = sa_cat(out, 0, "v-" as *u8)
727 let nm: *u8 = sys_mmap(32)
728 ti_arch_name(arch, nm)
729 o = sa_cat(out, o, nm)
730 out[o] = 45 as u8; o = o + 1
731 var i: i64 = 4 // key = "pat:<digits>"
732 var n: i64 = 0
733 while n < 10 { if key[i] == (0 as u8) { n = 10 } else { out[o] = key[i]; o = o + 1; i = i + 1; n = n + 1 } }
734 out[o] = 0 as u8
735 return o
736}
737
738// the GALLERY index: one card per corpus archetype + one card per consumed PATTERN (structural variations)
739func sa_gallery_index(codes: *i64, ncodes: i64, vk: *i64, vs: *i64, va: *i64, nv: i64, brand: *u8, buf: *u8) -> i64 {
740 var o: i64 = sk_open_site(buf, 0, "Nishi Site Factory -- generated archetypes" as *u8, brand, 1, "/factory/" as *u8)
741 o = sk_nav_item(buf, o, "Live site" as *u8, "/" as *u8)
742 o = sk_header_close(buf, o)
743 let lede: *u8 = sys_mmap(512)
744 var lo: i64 = sa_cat(lede, 0, "Every card is a whole, responsive, WCAG-AAA page composed by a sovereign organ from " as *u8)
745 if SA_NPAT > 0 { lo = sa_catn(lede, lo, SA_NPAT); lo = sa_cat(lede, lo, " distinct structural patterns consumed from real open templates" as *u8) }
746 else { lo = sa_cat(lede, lo, "a deduped corpus of template structure" as *u8) }
747 lo = sa_cat(lede, lo, " -- no third-party CSS, zero JS, zero trackers." as *u8)
748 lede[lo] = 0 as u8
749 o = sk_hero(buf, o, "Site Factory" as *u8, "Sites generated" as *u8, "from consumed structure" as *u8, lede, "Browse archetypes" as *u8, "/factory/" as *u8, "Back to nishifamily" as *u8, "/" as *u8, "Sovereign, accessible, award-tier by construction." as *u8)
750 o = sk_section_open(buf, o, "archetypes" as *u8, "Generated" as *u8, "Archetype gallery" as *u8, "Distinct layouts, one design system -- click into any." as *u8)
751 let hrefbuf: *u8 = sys_mmap(128)
752 var i: i64 = 0
753 while i < ncodes {
754 let a: i64 = codes[i]
755 sa_href(hrefbuf, a)
756 o = sk_card_link(buf, o, SA_ICON, sa_disp(a), sa_s(a,3), hrefbuf)
757 i = i + 1
758 }
759 o = sk_section_close(buf, o)
760 if nv > 0 {
761 o = sk_section_open(buf, o, "variations" as *u8, "Per-pattern" as *u8, "Structural variations" as *u8, "One page per consumed pattern -- each follows its SOURCE template's own section order, so the corpus visibly shapes the layout." as *u8)
762 let vhref: *u8 = sys_mmap(128)
763 let vbody: *u8 = sys_mmap(320)
764 let vtitle: *u8 = sys_mmap(160)
765 var vi: i64 = 0
766 while vi < nv {
767 var ho: i64 = sa_cat(vhref, 0, "/factory/" as *u8)
768 ho = sa_cat(vhref, ho, vk[vi] as *u8)
769 ho = sa_cat(vhref, ho, ".html" as *u8)
770 vhref[ho] = 0 as u8
771 var bo: i64 = sa_cat(vbody, 0, "Section flow: " as *u8)
772 bo = sa_cat(vbody, bo, vs[vi] as *u8)
773 vbody[bo] = 0 as u8
774 var to2: i64 = sa_cat(vtitle, 0, sa_disp(va[vi]))
775 to2 = sa_cat(vtitle, to2, " pattern" as *u8)
776 vtitle[to2] = 0 as u8
777 o = sk_card_link(buf, o, SA_ICON, vtitle, vbody, vhref)
778 vi = vi + 1
779 }
780 o = sk_section_close(buf, o)
781 }
782 o = sk_cta(buf, o, "Sovereign" as *u8, "Consume templates, generate sites" as *u8, "This gallery was emitted by nx_site_archetype from a content-addressed corpus built by nx_tpl_ingest." as *u8, "Back to nishifamily" as *u8, "/" as *u8, "Refresh" as *u8, "/factory/" as *u8)
783 o = sk_close(buf, o, "Generated by the Nishi Site Factory (nx_site_archetype) from the R4 pattern corpus." as *u8, brand)
784 return o
785}
786
787// walk the source templates, confirm corpus membership, compose a page per distinct archetype + the gallery
788func sa_run(tpldir: *u8, corpusprefix: *u8, docroot: *u8, domain: *u8) -> i64 {
789 sys_mkdir(docroot, 0x1ed)
790 let hh: *i64 = ss_open(corpusprefix)
791 if (hh as i64) != 0 { SA_NPAT = sa_pat_count(hh); SA_STOREH = hh as i64 }
792 let pbox: *i64 = sys_mmap(16) as *i64
793 let lbox: *i64 = sys_mmap(16) as *i64
794 let seen: *i64 = sys_mmap(16 * 8) as *i64
795 var si: i64 = 0
796 while si < 16 { seen[si] = 0; si = si + 1 }
797 let codes: *i64 = sys_mmap(16 * 8) as *i64
798 var ncodes: i64 = 0
799 // per-PATTERN variation capture (budget-guarded at SA_VARCAP; dedup by content-addressed key)
800 let vkeys: *u8 = sys_mmap(SA_VARCAP * TI_KEYW)
801 let vkp: *i64 = sys_mmap(SA_VARCAP * 8) as *i64
802 let vsp: *i64 = sys_mmap(SA_VARCAP * 8) as *i64
803 let vap: *i64 = sys_mmap(SA_VARCAP * 8) as *i64
804 let vseqarena: *u8 = sys_mmap(SA_VARCAP * 200)
805 var nvar: i64 = 0
806 let dbuf: *u8 = sys_mmap(SA_MAGIC_131072)
807 let path: *u8 = sys_mmap(SA_MAGIC_1024)
808 let key: *u8 = sys_mmap(64)
809 let seq: *u8 = sys_mmap(256)
810 let szp: *i64 = sys_mmap(16) as *i64
811 let fd: i64 = sys_openat_rd(tpldir)
812 if fd < 0 { sa_w("site-archetype: cannot open tpldir " as *u8); sa_w(tpldir); sa_w("\n" as *u8); return 0 - 1 }
813 var go: i64 = 1
814 while go == 1 {
815 let nr: i64 = sys_getdents64(fd, dbuf, SA_MAGIC_131072)
816 if nr <= 0 { go = 0 } else {
817 var off: i64 = 0
818 while off < nr {
819 let recd: *u8 = (dbuf as i64 + off) as *u8
820 let ty: i64 = dirent_type(recd)
821 let nm: *u8 = dirent_name(recd)
822 off = off + dirent_reclen(recd)
823 if ty != 4 {
824 var ishtml: i64 = 0
825 if ti_suffix(nm, ".html" as *u8) == 1 { ishtml = 1 }
826 if ti_suffix(nm, ".htm" as *u8) == 1 { ishtml = 1 }
827 if ishtml == 1 {
828 var po: i64 = sa_cat(path, 0, tpldir)
829 po = sa_cat(path, po, "/" as *u8)
830 po = sa_cat(path, po, nm)
831 path[po] = 0 as u8
832 let raw: *u8 = ss_readall(path, szp)
833 let rn: i64 = szp[0]
834 if rn >= 40 {
835 if ti_find_ci(raw, 0, rn, "<" as *u8) >= 0 {
836 let arch: i64 = ti_classify(raw, rn)
837 ti_seq(raw, rn, seq)
838 ti_mkkey(arch, seq, key)
839 var present: i64 = 1
840 if (hh as i64) != 0 { present = 0; if ss_hget(hh, key, pbox, lbox) == 1 { present = 1 } }
841 if present == 1 { if arch >= 1 { if arch <= 10 {
842 if seen[arch] == 0 {
843 seen[arch] = 1
844 codes[ncodes] = arch
845 ncodes = ncodes + 1
846 }
847 // capture EVERY distinct pattern (not just first-per-archetype) for the
848 // per-pattern variation pages; fail-fast at the SA_VARCAP budget.
849 if nvar < SA_VARCAP { if ti_seen(vkeys, nvar, key) == 0 {
850 let kdst: *u8 = (vkeys as i64 + nvar * TI_KEYW) as *u8
851 var kk: i64 = 0
852 while key[kk] != (0 as u8) { kdst[kk] = key[kk]; kk = kk + 1 }
853 kdst[kk] = 0 as u8
854 let sdst: *u8 = (vseqarena as i64 + nvar * 200) as *u8
855 var sk2: i64 = 0
856 while seq[sk2] != (0 as u8) { if sk2 < 198 { sdst[sk2] = seq[sk2] } sk2 = sk2 + 1 }
857 if sk2 > 198 { sk2 = 198 }
858 sdst[sk2] = 0 as u8
859 vkp[nvar] = kdst as i64
860 vsp[nvar] = sdst as i64
861 vap[nvar] = arch
862 nvar = nvar + 1
863 } }
864 } } }
865 }
866 }
867 }
868 }
869 }
870 }
871 }
872 sys_close(fd)
873 // compose one page per present archetype
874 let buf: *u8 = sys_mmap(SA_MAGIC_262144)
875 let pathb: *u8 = sys_mmap(512)
876 let nmb: *u8 = sys_mmap(64)
877 let titleb: *u8 = sys_mmap(160)
878 var i: i64 = 0
879 while i < ncodes {
880 let a: i64 = codes[i]
881 ti_arch_name(a, nmb)
882 var t: i64 = sa_cat(titleb, 0, sa_disp(a))
883 t = sa_cat(titleb, t, " -- Nishi Site Factory" as *u8)
884 titleb[t] = 0 as u8
885 let o: i64 = sa_recipe(a, "Nishi" as *u8, titleb, buf)
886 var pp: i64 = sa_cat(pathb, 0, docroot)
887 pp = sa_cat(pathb, pp, "/" as *u8)
888 pp = sa_cat(pathb, pp, nmb)
889 pp = sa_cat(pathb, pp, ".html" as *u8)
890 pathb[pp] = 0 as u8
891 let pfd: i64 = sys_openat_wr(pathb, 0x1a4)
892 if pfd >= 0 { sys_write(pfd, buf, o); sys_close(pfd) }
893 i = i + 1
894 }
895 // per-pattern VARIATION pages: each follows its consumed template's own section order (seq-driven).
896 // Flat "v-<arch>-<hash>.html" basenames so every page publishes through the content namespace.
897 let vnarena: *u8 = sys_mmap(SA_VARCAP * 40)
898 let vnp: *i64 = sys_mmap(SA_VARCAP * 8) as *i64
899 var wv: i64 = 0
900 while wv < nvar {
901 let vn: *u8 = (vnarena as i64 + wv * 40) as *u8
902 sa_vname(vap[wv], vkp[wv] as *u8, vn)
903 vnp[wv] = vn as i64
904 var vt: i64 = sa_cat(titleb, 0, sa_disp(vap[wv]))
905 vt = sa_cat(titleb, vt, " -- pattern variation" as *u8)
906 titleb[vt] = 0 as u8
907 let vo: i64 = sa_recipe_seq(vap[wv], vsp[wv] as *u8, wv % 2, "Nishi" as *u8, titleb, buf)
908 var vp: i64 = sa_cat(pathb, 0, docroot)
909 vp = sa_cat(pathb, vp, "/" as *u8)
910 vp = sa_cat(pathb, vp, vn)
911 vp = sa_cat(pathb, vp, ".html" as *u8)
912 pathb[vp] = 0 as u8
913 let vfd: i64 = sys_openat_wr(pathb, 0x1a4)
914 if vfd >= 0 { sys_write(vfd, buf, vo); sys_close(vfd) }
915 wv = wv + 1
916 }
917 SA_NVAR = nvar
918 // gallery index
919 let go2: i64 = sa_gallery_index(codes, ncodes, vnp, vsp, vap, nvar, "Nishi" as *u8, buf)
920 var ip: i64 = sa_cat(pathb, 0, docroot); ip = sa_cat(pathb, ip, "/index.html" as *u8); pathb[ip]=0 as u8
921 let ifd: i64 = sys_openat_wr(pathb, 0x1a4)
922 if ifd >= 0 { sys_write(ifd, buf, go2); sys_close(ifd) }
923 // sitemap.xml
924 var so: i64 = sa_cat(buf, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n" as *u8)
925 so = sa_cat(buf, so, "<url><loc>https://" as *u8); so = sa_cat(buf, so, domain); so = sa_cat(buf, so, "/factory/</loc><priority>1.0</priority></url>\n" as *u8)
926 i = 0
927 while i < ncodes {
928 ti_arch_name(codes[i], nmb)
929 so = sa_cat(buf, so, "<url><loc>https://" as *u8); so = sa_cat(buf, so, domain); so = sa_cat(buf, so, "/factory/" as *u8); so = sa_cat(buf, so, nmb); so = sa_cat(buf, so, ".html</loc><priority>0.8</priority></url>\n" as *u8)
930 i = i + 1
931 }
932 so = sa_cat(buf, so, "</urlset>\n" as *u8)
933 var mp: i64 = sa_cat(pathb, 0, docroot); mp = sa_cat(pathb, mp, "/sitemap.xml" as *u8); pathb[mp]=0 as u8
934 let mfd: i64 = sys_openat_wr(pathb, 0x1a4)
935 if mfd >= 0 { sys_write(mfd, buf, so); sys_close(mfd) }
936 // robots.txt
937 var ro: i64 = sa_cat(buf, 0, "User-agent: *\nAllow: /\nSitemap: https://" as *u8); ro = sa_cat(buf, ro, domain); ro = sa_cat(buf, ro, "/factory/sitemap.xml\n" as *u8)
938 var rp: i64 = sa_cat(pathb, 0, docroot); rp = sa_cat(pathb, rp, "/robots.txt" as *u8); pathb[rp]=0 as u8
939 let rfd: i64 = sys_openat_wr(pathb, 0x1a4)
940 if rfd >= 0 { sys_write(rfd, buf, ro); sys_close(rfd) }
941 sa_w("SITE-ARCHETYPE OK: gallery + " as *u8)
942 let cb: *u8 = sys_mmap(16); var ci: i64=0; var m: i64=ncodes; if m==0 { cb[0]=48 as u8; ci=1 } var tb: *u8=sys_mmap(16); var k: i64=0; while m>0 { tb[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } while k>0 { cb[ci]=tb[k-1]; ci=ci+1; k=k-1 } cb[ci]=0 as u8
943 sa_w(cb); sa_w(" archetype pages + " as *u8)
944 let vb: *u8 = sys_mmap(28)
945 let ve: i64 = sa_catn(vb, 0, nvar)
946 sys_write(1, vb, ve)
947 sa_w(" pattern variations -> " as *u8); sa_w(docroot); sa_w("\n" as *u8)
948 return ncodes
949}
950
951func main(argc: i64, argv: *i64) -> i64 {
952 if argc < 5 { sa_w("usage: nx_site_archetype <template-dir> <corpus-prefix> <docroot> <domain> [reqfile]\n" as *u8); return 2 }
953 let tpldir: *u8 = argv[1] as *u8
954 let prefix: *u8 = argv[2] as *u8
955 let docroot: *u8 = argv[3] as *u8
956 let domain: *u8 = argv[4] as *u8
957 if argc >= 6 {
958 let rl: i64 = sa_req_load(argv[5] as *u8)
959 if rl < 0 { sa_w("site-archetype: cannot read reqfile\n" as *u8); return 1 }
960 }
961 let rc: i64 = sa_run(tpldir, prefix, docroot, domain)
962 if rc < 0 { return 1 }
963 return 0
964}