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