@africode/core 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/AFRICODE_FRAMEWORK_GUIDE.md +707 -0
  2. package/LICENSE +623 -0
  3. package/README.md +442 -0
  4. package/bin/africode.js +73 -0
  5. package/bin/africode.js.1758507140 +343 -0
  6. package/bin/cli.ts +83 -0
  7. package/bin/create-africode.js +158 -0
  8. package/bin/scaffold.ts +219 -0
  9. package/components/accordion.js +183 -0
  10. package/components/alert.js +131 -0
  11. package/components/auth.js +172 -0
  12. package/components/avatar.js +117 -0
  13. package/components/badge.js +104 -0
  14. package/components/base.d.ts +139 -0
  15. package/components/base.js +184 -0
  16. package/components/button.js +164 -0
  17. package/components/card.js +137 -0
  18. package/components/cultural-card.js +243 -0
  19. package/components/divider.js +83 -0
  20. package/components/dropdown.js +171 -0
  21. package/components/error-boundary.js +155 -0
  22. package/components/form.js +131 -0
  23. package/components/grid.js +273 -0
  24. package/components/hero.js +138 -0
  25. package/components/icon.js +36 -0
  26. package/components/index.js +57 -0
  27. package/components/input.js +256 -0
  28. package/components/kanga-card.js +185 -0
  29. package/components/language-switcher.js +108 -0
  30. package/components/loader.js +80 -0
  31. package/components/modal.js +262 -0
  32. package/components/motion.js +84 -0
  33. package/components/navbar.js +236 -0
  34. package/components/pattern-showcase.js +225 -0
  35. package/components/progress.js +134 -0
  36. package/components/react.js +111 -0
  37. package/components/section.js +54 -0
  38. package/components/select.js +322 -0
  39. package/components/sidebar.js +180 -0
  40. package/components/skeleton.js +85 -0
  41. package/components/table.js +181 -0
  42. package/components/tabs.js +202 -0
  43. package/components/theme-toggle.js +82 -0
  44. package/components/toast.js +139 -0
  45. package/components/tooltip.js +167 -0
  46. package/core/a2ui-schema-manager.js +344 -0
  47. package/core/a2ui.js +431 -0
  48. package/core/bun-runtime.js +799 -0
  49. package/core/cli/commands/add.js +23 -0
  50. package/core/cli/commands/audit.js +58 -0
  51. package/core/cli/commands/build.js +137 -0
  52. package/core/cli/commands/create-plugin.js +241 -0
  53. package/core/cli/commands/dev.js +228 -0
  54. package/core/cli/commands/lint.js +23 -0
  55. package/core/cli/commands/test.js +34 -0
  56. package/core/cli/migrator.js +71 -0
  57. package/core/cli/ui.js +46 -0
  58. package/core/compliance.js +628 -0
  59. package/core/config.js +263 -0
  60. package/core/db-advanced.js +481 -0
  61. package/core/db.js +284 -0
  62. package/core/enhanced-hmr.js +404 -0
  63. package/core/errors.js +222 -0
  64. package/core/file-router.js +290 -0
  65. package/core/heartbeat.js +64 -0
  66. package/core/hmr-client.js +204 -0
  67. package/core/hmr.js +196 -0
  68. package/core/html.d.ts +116 -0
  69. package/core/html.js +160 -0
  70. package/core/hydration.js +52 -0
  71. package/core/lipa-namba-journey.js +572 -0
  72. package/core/motion.js +106 -0
  73. package/core/nida-cig-middleware.js +455 -0
  74. package/core/patterns.d.ts +124 -0
  75. package/core/patterns.js +833 -0
  76. package/core/plugins/index.js +312 -0
  77. package/core/router.js +387 -0
  78. package/core/sdk-client.js +62 -0
  79. package/core/sdk.d.ts +133 -0
  80. package/core/sdk.js +123 -0
  81. package/core/seo.js +76 -0
  82. package/core/server/auth-endpoints.js +339 -0
  83. package/core/server/auth.js +180 -0
  84. package/core/server/csrf.js +206 -0
  85. package/core/server/db.js +39 -0
  86. package/core/server/middleware.js +324 -0
  87. package/core/server/rate-limit.js +238 -0
  88. package/core/server/render.js +69 -0
  89. package/core/server/router.js +120 -0
  90. package/core/shim.js +28 -0
  91. package/core/state.d.ts +86 -0
  92. package/core/state.js +242 -0
  93. package/core/store.d.ts +122 -0
  94. package/core/store.js +61 -0
  95. package/core/validation.d.ts +233 -0
  96. package/core/validation.js +590 -0
  97. package/core/websocket.js +639 -0
  98. package/dist/africode.js +2905 -0
  99. package/dist/africode.js.map +61 -0
  100. package/dist/build-info.json +23 -0
  101. package/dist/components.js +2888 -0
  102. package/dist/components.js.map +58 -0
  103. package/dist/styles/africanity.css +322 -0
  104. package/dist/styles/typography.css +141 -0
  105. package/docs/IDE-Guide.md +50 -0
  106. package/package.json +110 -0
  107. package/src/index.ts +196 -0
  108. package/styles/africanity.css +322 -0
  109. package/styles/typography.css +141 -0
  110. package/templates/starter/.env.example +15 -0
  111. package/templates/starter/africode.config.js +40 -0
  112. package/templates/starter/package.json +14 -0
  113. package/templates/starter/src/pages/index.html +46 -0
  114. package/templates/starter/src/pages/index.js +32 -0
  115. package/templates/starter/src/styles/main.css +4 -0
  116. package/templates/starter-3d/.env.example +7 -0
  117. package/templates/starter-3d/africode.config.js +29 -0
  118. package/templates/starter-3d/components/af-model-viewer.js +125 -0
  119. package/templates/starter-3d/package.json +15 -0
  120. package/templates/starter-3d/src/pages/index.html +46 -0
  121. package/templates/starter-3d/src/pages/index.js +50 -0
  122. package/templates/starter-3d/src/styles/main.css +4 -0
  123. package/templates/starter-react/.env.example +15 -0
  124. package/templates/starter-react/africode.config.js +40 -0
  125. package/templates/starter-react/package.json +16 -0
  126. package/templates/starter-react/src/pages/index.html +46 -0
  127. package/templates/starter-react/src/pages/index.js +68 -0
  128. package/templates/starter-react/src/styles/main.css +4 -0
  129. package/templates/starter-tailwind/.env.example +15 -0
  130. package/templates/starter-tailwind/africode.config.js +40 -0
  131. package/templates/starter-tailwind/package.json +20 -0
  132. package/templates/starter-tailwind/src/pages/index.html +46 -0
  133. package/templates/starter-tailwind/src/pages/index.js +37 -0
  134. package/templates/starter-tailwind/src/styles/main.css +4 -0
  135. package/templates/starter-tailwind/src/styles/tailwind.css +1 -0
  136. package/templates/starter-tailwind/src/tailwind-loader.js +30 -0
@@ -0,0 +1,833 @@
1
+ /**
2
+ * AfriCode Procedural SVG Pattern Engine
3
+ *
4
+ * Generates lightweight, on-the-fly SVG patterns inspired by
5
+ * African textiles from across the continent:
6
+ *
7
+ * EAST AFRICA: Maasai Shuka, Kanga, Kitenge, Hadzabe
8
+ * WEST AFRICA: Ghana Kente, Adinkra, Nigeria Aso-Oke, Ankara
9
+ * SOUTHERN AFRICA: Ndebele, Zulu, Swazi/Eswatini, Xhosa
10
+ *
11
+ * @module core/patterns
12
+ */
13
+
14
+ /**
15
+ * Generate a polygon with n sides
16
+ * Based on the mathematical formula:
17
+ * x_i = cx + r * cos(2πi/n)
18
+ * y_i = cy + r * sin(2πi/n)
19
+ */
20
+ export function generatePolygon(n, r, cx = 50, cy = 50) {
21
+ const points = [];
22
+ for (let i = 0; i < n; i++) {
23
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
24
+ const x = cx + r * Math.cos(angle);
25
+ const y = cy + r * Math.sin(angle);
26
+ points.push(`${x.toFixed(2)},${y.toFixed(2)}`);
27
+ }
28
+ return points.join(' ');
29
+ }
30
+
31
+ // ============================================
32
+ // EAST AFRICAN PATTERNS
33
+ // ============================================
34
+
35
+ /**
36
+ * Generate Maasai Shuka tartan pattern (Tanzania/Kenya)
37
+ * Traditional red checkered blanket with overlapping stripes
38
+ */
39
+ export function generateShuka({
40
+ primaryColor = '#FF0000',
41
+ secondaryColor = '#000000',
42
+ backgroundColor = '#8B0000',
43
+ stripeWidth = 4,
44
+ size = 40
45
+ } = {}) {
46
+ const svg = `
47
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
48
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
49
+ <rect x="0" y="0" width="${size}" height="${stripeWidth}" fill="${primaryColor}" opacity="0.8"/>
50
+ <rect x="0" y="${size / 2 - stripeWidth / 2}" width="${size}" height="${stripeWidth}" fill="${secondaryColor}" opacity="0.6"/>
51
+ <rect x="0" y="${size - stripeWidth}" width="${size}" height="${stripeWidth}" fill="${primaryColor}" opacity="0.8"/>
52
+ <rect x="0" y="0" width="${stripeWidth}" height="${size}" fill="${primaryColor}" opacity="0.5"/>
53
+ <rect x="${size / 2 - stripeWidth / 2}" y="0" width="${stripeWidth}" height="${size}" fill="${secondaryColor}" opacity="0.4"/>
54
+ <rect x="${size - stripeWidth}" y="0" width="${stripeWidth}" height="${size}" fill="${primaryColor}" opacity="0.5"/>
55
+ </svg>
56
+ `;
57
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
58
+ }
59
+
60
+ /**
61
+ * Generate Hadzabe pattern (Tanzania)
62
+ * Inspired by cave paintings and natural earth tones
63
+ * Hunter-gatherer tribe with ancient artistic traditions
64
+ */
65
+ export function generateHadzabe({
66
+ earthColor = '#8B4513',
67
+ ochreColor = '#CD853F',
68
+ charcoalColor = '#2F2F2F',
69
+ size = 50
70
+ } = {}) {
71
+ const svg = `
72
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
73
+ <rect width="${size}" height="${size}" fill="${earthColor}"/>
74
+ <!-- Cave art inspired figures -->
75
+ <circle cx="${size * 0.3}" cy="${size * 0.3}" r="${size * 0.08}" fill="${ochreColor}"/>
76
+ <line x1="${size * 0.3}" y1="${size * 0.38}" x2="${size * 0.3}" y2="${size * 0.6}" stroke="${charcoalColor}" stroke-width="2"/>
77
+ <line x1="${size * 0.2}" y1="${size * 0.45}" x2="${size * 0.4}" y2="${size * 0.45}" stroke="${charcoalColor}" stroke-width="2"/>
78
+ <!-- Animal figure -->
79
+ <ellipse cx="${size * 0.7}" cy="${size * 0.5}" rx="${size * 0.15}" ry="${size * 0.08}" fill="${ochreColor}"/>
80
+ <line x1="${size * 0.6}" y1="${size * 0.58}" x2="${size * 0.6}" y2="${size * 0.7}" stroke="${charcoalColor}" stroke-width="2"/>
81
+ <line x1="${size * 0.8}" y1="${size * 0.58}" x2="${size * 0.8}" y2="${size * 0.7}" stroke="${charcoalColor}" stroke-width="2"/>
82
+ <!-- Dots like ancient markings -->
83
+ <circle cx="${size * 0.15}" cy="${size * 0.8}" r="3" fill="${ochreColor}"/>
84
+ <circle cx="${size * 0.85}" cy="${size * 0.2}" r="3" fill="${ochreColor}"/>
85
+ </svg>
86
+ `;
87
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
88
+ }
89
+
90
+ /**
91
+ * Generate Kanga border pattern (Tanzania/Kenya)
92
+ */
93
+ export function generateKangaBorder({
94
+ primaryColor = '#1EB53A', // Simple Green (Tanzania)
95
+ accentColor = '#FCD116', // Gold
96
+ size = 30
97
+ } = {}) {
98
+ const svg = `
99
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
100
+ <rect width="${size}" height="${size}" fill="${primaryColor}"/>
101
+ <!-- Pindo (Border) Motifs: Cashew/Triangle -->
102
+ <path d="M0,0 L${size / 2},${size / 2} L0,${size} Z" fill="${accentColor}"/>
103
+ <path d="M${size},0 L${size / 2},${size / 2} L${size},${size} Z" fill="${accentColor}"/>
104
+ <circle cx="${size / 2}" cy="${size / 2}" r="${size * 0.15}" fill="none" stroke="${accentColor}" stroke-width="2"/>
105
+ </svg>
106
+ `;
107
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
108
+ }
109
+
110
+ /**
111
+ * Generate Kanga traditional Swahili cloth pattern (East Africa)
112
+ */
113
+ export function generateKanga({
114
+ primaryColor = '#FF6B00',
115
+ secondaryColor = '#002B5C',
116
+ backgroundColor = '#FFFFFF',
117
+ size = 40
118
+ } = {}) {
119
+ const svg = `
120
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
121
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
122
+ <!-- Border pattern -->
123
+ <rect x="0" y="0" width="${size}" height="${size * 0.1}" fill="${primaryColor}"/>
124
+ <rect x="0" y="${size * 0.9}" width="${size}" height="${size * 0.1}" fill="${primaryColor}"/>
125
+ <rect x="0" y="0" width="${size * 0.1}" height="${size}" fill="${primaryColor}"/>
126
+ <rect x="${size * 0.9}" y="0" width="${size * 0.1}" height="${size}" fill="${primaryColor}"/>
127
+ <!-- Center motif -->
128
+ <circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.15}" fill="${secondaryColor}"/>
129
+ <text x="${size * 0.5}" y="${size * 0.55}" text-anchor="middle" fill="${primaryColor}" font-size="${size * 0.08}">KANGA</text>
130
+ </svg>
131
+ `;
132
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
133
+ }
134
+
135
+ /**
136
+ * Generate Kuba Border pattern (Congo)
137
+ */
138
+ export function generateKubaBorder({
139
+ primaryColor = '#8B4513',
140
+ secondaryColor = '#DAA520',
141
+ backgroundColor = '#F5F5DC',
142
+ size = 30
143
+ } = {}) {
144
+ const svg = `
145
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
146
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
147
+ <!-- Kuba geometric border -->
148
+ <polygon points="0,0 ${size * 0.3},0 0,${size * 0.3}" fill="${primaryColor}"/>
149
+ <polygon points="${size},0 ${size * 0.7},0 ${size},${size * 0.3}" fill="${primaryColor}"/>
150
+ <polygon points="0,${size} ${size * 0.3},${size} 0,${size * 0.7}" fill="${primaryColor}"/>
151
+ <polygon points="${size},${size} ${size * 0.7},${size} ${size},${size * 0.7}" fill="${primaryColor}"/>
152
+ <!-- Center diamond -->
153
+ <polygon points="${size * 0.5},${size * 0.3} ${size * 0.7},${size * 0.5} ${size * 0.5},${size * 0.7} ${size * 0.3},${size * 0.5}" fill="${secondaryColor}"/>
154
+ </svg>
155
+ `;
156
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
157
+ }
158
+
159
+ /**
160
+ * Generate Zulu Beads pattern (South Africa)
161
+ */
162
+ export function generateZuluBeads({
163
+ primaryColor = '#FF0000',
164
+ secondaryColor = '#000000',
165
+ accentColor = '#FFFFFF',
166
+ size = 40
167
+ } = {}) {
168
+ const svg = `
169
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
170
+ <rect width="${size}" height="${size}" fill="${accentColor}"/>
171
+ <!-- Bead pattern -->
172
+ <circle cx="${size * 0.2}" cy="${size * 0.2}" r="${size * 0.08}" fill="${primaryColor}"/>
173
+ <circle cx="${size * 0.5}" cy="${size * 0.2}" r="${size * 0.08}" fill="${secondaryColor}"/>
174
+ <circle cx="${size * 0.8}" cy="${size * 0.2}" r="${size * 0.08}" fill="${primaryColor}"/>
175
+ <circle cx="${size * 0.2}" cy="${size * 0.5}" r="${size * 0.08}" fill="${secondaryColor}"/>
176
+ <circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.08}" fill="${primaryColor}"/>
177
+ <circle cx="${size * 0.8}" cy="${size * 0.5}" r="${size * 0.08}" fill="${secondaryColor}"/>
178
+ <circle cx="${size * 0.2}" cy="${size * 0.8}" r="${size * 0.08}" fill="${primaryColor}"/>
179
+ <circle cx="${size * 0.5}" cy="${size * 0.8}" r="${size * 0.08}" fill="${secondaryColor}"/>
180
+ <circle cx="${size * 0.8}" cy="${size * 0.8}" r="${size * 0.08}" fill="${primaryColor}"/>
181
+ </svg>
182
+ `;
183
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
184
+ }
185
+
186
+ /**
187
+ * Generate Maasai Shield pattern (Kenya/Tanzania)
188
+ */
189
+ export function generateMasaiShield({
190
+ primaryColor = '#8B0000',
191
+ secondaryColor = '#FFD700',
192
+ backgroundColor = '#654321',
193
+ size = 50
194
+ } = {}) {
195
+ const svg = `
196
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
197
+ <ellipse cx="${size * 0.5}" cy="${size * 0.5}" rx="${size * 0.4}" ry="${size * 0.45}" fill="${backgroundColor}"/>
198
+ <!-- Shield patterns -->
199
+ <ellipse cx="${size * 0.5}" cy="${size * 0.3}" rx="${size * 0.2}" ry="${size * 0.15}" fill="${primaryColor}"/>
200
+ <rect x="${size * 0.4}" y="${size * 0.5}" width="${size * 0.2}" height="${size * 0.3}" fill="${secondaryColor}"/>
201
+ <!-- Decorative lines -->
202
+ <line x1="${size * 0.3}" y1="${size * 0.2}" x2="${size * 0.7}" y2="${size * 0.2}" stroke="${primaryColor}" stroke-width="3"/>
203
+ <line x1="${size * 0.3}" y1="${size * 0.8}" x2="${size * 0.7}" y2="${size * 0.8}" stroke="${primaryColor}" stroke-width="3"/>
204
+ </svg>
205
+ `;
206
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
207
+ }
208
+
209
+ /**
210
+ * Generate Ndebele Paint house pattern (South Africa)
211
+ */
212
+ export function generateNdebelePaint({
213
+ primaryColor = '#FF1493',
214
+ secondaryColor = '#00FF00',
215
+ accentColor = '#FFFF00',
216
+ backgroundColor = '#FFFFFF',
217
+ size = 50
218
+ } = {}) {
219
+ const svg = `
220
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
221
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
222
+ <!-- Ndebele geometric patterns -->
223
+ <polygon points="${size * 0.2},${size * 0.2} ${size * 0.4},${size * 0.2} ${size * 0.3},${size * 0.4}" fill="${primaryColor}"/>
224
+ <polygon points="${size * 0.6},${size * 0.2} ${size * 0.8},${size * 0.2} ${size * 0.7},${size * 0.4}" fill="${secondaryColor}"/>
225
+ <polygon points="${size * 0.2},${size * 0.6} ${size * 0.4},${size * 0.6} ${size * 0.3},${size * 0.8}" fill="${accentColor}"/>
226
+ <polygon points="${size * 0.6},${size * 0.6} ${size * 0.8},${size * 0.6} ${size * 0.7},${size * 0.8}" fill="${primaryColor}"/>
227
+ <!-- Center design -->
228
+ <circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.15}" fill="${secondaryColor}"/>
229
+ <rect x="${size * 0.45}" y="${size * 0.45}" width="${size * 0.1}" height="${size * 0.1}" fill="${accentColor}"/>
230
+ </svg>
231
+ `;
232
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
233
+ }
234
+
235
+ /**
236
+ * Generate Kitenge floral pattern (East Africa)
237
+ */
238
+ export function generateKitenge({
239
+ primaryColor = '#00A3DD',
240
+ secondaryColor = '#FCD116',
241
+ backgroundColor = '#1EB53A',
242
+ size = 50
243
+ } = {}) {
244
+ const svg = `
245
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
246
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
247
+ <circle cx="${size * 0.25}" cy="${size * 0.25}" r="${size * 0.2}" fill="${primaryColor}" opacity="0.8"/>
248
+ <circle cx="${size * 0.75}" cy="${size * 0.75}" r="${size * 0.2}" fill="${primaryColor}" opacity="0.8"/>
249
+ <circle cx="${size * 0.25}" cy="${size * 0.25}" r="${size * 0.1}" fill="${secondaryColor}"/>
250
+ <circle cx="${size * 0.75}" cy="${size * 0.75}" r="${size * 0.1}" fill="${secondaryColor}"/>
251
+ <circle cx="${size * 0.75}" cy="${size * 0.25}" r="${size * 0.08}" fill="${secondaryColor}" opacity="0.6"/>
252
+ <circle cx="${size * 0.25}" cy="${size * 0.75}" r="${size * 0.08}" fill="${secondaryColor}" opacity="0.6"/>
253
+ </svg>
254
+ `;
255
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
256
+ }
257
+
258
+ // ============================================
259
+ // WEST AFRICAN PATTERNS
260
+ // ============================================
261
+
262
+ /**
263
+ * Generate Ghana Kente cloth pattern
264
+ * Royal cloth of the Ashanti people with geometric strips
265
+ * Colors: Gold (royalty), Green (harvest), Red (blood/sacrifice)
266
+ */
267
+ export function generateKente({
268
+ colors = ['#FFD700', '#228B22', '#DC143C', '#000000'],
269
+ size = 60
270
+ } = {}) {
271
+ const [gold, green, red, black] = colors;
272
+ const stripe = size / 6;
273
+
274
+ const svg = `
275
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
276
+ <rect width="${size}" height="${size}" fill="${black}"/>
277
+ <!-- Horizontal bands -->
278
+ <rect x="0" y="0" width="${size}" height="${stripe}" fill="${gold}"/>
279
+ <rect x="0" y="${stripe}" width="${size}" height="${stripe}" fill="${green}"/>
280
+ <rect x="0" y="${stripe * 2}" width="${size}" height="${stripe}" fill="${red}"/>
281
+ <rect x="0" y="${stripe * 3}" width="${size}" height="${stripe}" fill="${gold}"/>
282
+ <rect x="0" y="${stripe * 4}" width="${size}" height="${stripe}" fill="${green}"/>
283
+ <rect x="0" y="${stripe * 5}" width="${size}" height="${stripe}" fill="${red}"/>
284
+ <!-- Vertical accents -->
285
+ <rect x="${size * 0.2}" y="0" width="3" height="${size}" fill="${black}" opacity="0.5"/>
286
+ <rect x="${size * 0.4}" y="0" width="3" height="${size}" fill="${black}" opacity="0.5"/>
287
+ <rect x="${size * 0.6}" y="0" width="3" height="${size}" fill="${black}" opacity="0.5"/>
288
+ <rect x="${size * 0.8}" y="0" width="3" height="${size}" fill="${black}" opacity="0.5"/>
289
+ <!-- Kente squares -->
290
+ <rect x="${size * 0.1}" y="${size * 0.1}" width="${size * 0.15}" height="${size * 0.15}" fill="${gold}" stroke="${black}" stroke-width="1"/>
291
+ <rect x="${size * 0.75}" y="${size * 0.75}" width="${size * 0.15}" height="${size * 0.15}" fill="${red}" stroke="${black}" stroke-width="1"/>
292
+ </svg>
293
+ `;
294
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
295
+ }
296
+
297
+ /**
298
+ * Generate Ghana Adinkra symbols pattern
299
+ * Philosophical symbols of the Akan people
300
+ * Each symbol represents concepts like wisdom, strength, unity
301
+ */
302
+ export function generateAdinkra({
303
+ symbolColor = '#000000',
304
+ backgroundColor = '#CD853F',
305
+ size = 50
306
+ } = {}) {
307
+ // Gye Nyame symbol (Supremacy of God) simplified
308
+ const svg = `
309
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
310
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
311
+ <!-- Sankofa-inspired heart shape (go back and get it) -->
312
+ <path d="M${size * 0.5} ${size * 0.2}
313
+ C${size * 0.3} ${size * 0.1} ${size * 0.15} ${size * 0.3} ${size * 0.25} ${size * 0.5}
314
+ L${size * 0.5} ${size * 0.8}
315
+ L${size * 0.75} ${size * 0.5}
316
+ C${size * 0.85} ${size * 0.3} ${size * 0.7} ${size * 0.1} ${size * 0.5} ${size * 0.2}"
317
+ fill="none" stroke="${symbolColor}" stroke-width="3"/>
318
+ <!-- Spiral detail -->
319
+ <circle cx="${size * 0.35}" cy="${size * 0.45}" r="${size * 0.08}" fill="none" stroke="${symbolColor}" stroke-width="2"/>
320
+ <circle cx="${size * 0.65}" cy="${size * 0.45}" r="${size * 0.08}" fill="none" stroke="${symbolColor}" stroke-width="2"/>
321
+ </svg>
322
+ `;
323
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
324
+ }
325
+
326
+ /**
327
+ * Generate Nigeria Aso-Oke pattern (Yoruba)
328
+ * Hand-woven cloth with intricate strip patterns
329
+ * Traditional for special occasions
330
+ */
331
+ export function generateAsoOke({
332
+ colors = ['#4B0082', '#FFD700', '#FFFFFF'],
333
+ size = 50
334
+ } = {}) {
335
+ const [indigo, gold, white] = colors;
336
+ const stripe = size / 10;
337
+
338
+ const svg = `
339
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
340
+ <rect width="${size}" height="${size}" fill="${indigo}"/>
341
+ <!-- Horizontal stripes -->
342
+ <rect x="0" y="${stripe}" width="${size}" height="${stripe * 0.5}" fill="${gold}"/>
343
+ <rect x="0" y="${stripe * 3}" width="${size}" height="${stripe * 0.5}" fill="${white}"/>
344
+ <rect x="0" y="${stripe * 5}" width="${size}" height="${stripe * 0.5}" fill="${gold}"/>
345
+ <rect x="0" y="${stripe * 7}" width="${size}" height="${stripe * 0.5}" fill="${white}"/>
346
+ <rect x="0" y="${stripe * 9}" width="${size}" height="${stripe * 0.5}" fill="${gold}"/>
347
+ <!-- Vertical accent lines -->
348
+ <rect x="${size * 0.48}" y="0" width="${stripe * 0.4}" height="${size}" fill="${gold}" opacity="0.7"/>
349
+ <!-- Diamond motifs -->
350
+ <polygon points="${size * 0.25},${size * 0.3} ${size * 0.35},${size * 0.5} ${size * 0.25},${size * 0.7} ${size * 0.15},${size * 0.5}"
351
+ fill="${gold}" stroke="${white}" stroke-width="1"/>
352
+ <polygon points="${size * 0.75},${size * 0.3} ${size * 0.85},${size * 0.5} ${size * 0.75},${size * 0.7} ${size * 0.65},${size * 0.5}"
353
+ fill="${gold}" stroke="${white}" stroke-width="1"/>
354
+ </svg>
355
+ `;
356
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
357
+ }
358
+
359
+ /**
360
+ * Generate Nigeria Ankara/African wax print pattern
361
+ * Bold, colorful designs popular across Africa
362
+ */
363
+ export function generateAnkara({
364
+ primaryColor = '#FF6B00',
365
+ secondaryColor = '#00A86B',
366
+ accentColor = '#FFD700',
367
+ backgroundColor = '#FFFFFF',
368
+ size = 60
369
+ } = {}) {
370
+ const svg = `
371
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
372
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
373
+ <!-- Bold circular motifs -->
374
+ <circle cx="${size * 0.3}" cy="${size * 0.3}" r="${size * 0.25}" fill="${primaryColor}"/>
375
+ <circle cx="${size * 0.3}" cy="${size * 0.3}" r="${size * 0.15}" fill="${secondaryColor}"/>
376
+ <circle cx="${size * 0.3}" cy="${size * 0.3}" r="${size * 0.08}" fill="${accentColor}"/>
377
+
378
+ <circle cx="${size * 0.8}" cy="${size * 0.8}" r="${size * 0.2}" fill="${secondaryColor}"/>
379
+ <circle cx="${size * 0.8}" cy="${size * 0.8}" r="${size * 0.1}" fill="${primaryColor}"/>
380
+
381
+ <!-- Connecting lines -->
382
+ <line x1="${size * 0.45}" y1="${size * 0.45}" x2="${size * 0.65}" y2="${size * 0.65}"
383
+ stroke="${primaryColor}" stroke-width="4"/>
384
+
385
+ <!-- Small dots -->
386
+ <circle cx="${size * 0.1}" cy="${size * 0.8}" r="${size * 0.05}" fill="${accentColor}"/>
387
+ <circle cx="${size * 0.9}" cy="${size * 0.2}" r="${size * 0.05}" fill="${accentColor}"/>
388
+ </svg>
389
+ `;
390
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
391
+ }
392
+
393
+ // ============================================
394
+ // CENTRAL & NORTH AFRICAN PATTERNS
395
+ // ============================================
396
+
397
+ /**
398
+ * Generate Bogolanfini (Mud Cloth) pattern (Mali)
399
+ * Geometric abstract designs in earth tones
400
+ */
401
+ export function generateBogolan({
402
+ primaryColor = '#000000',
403
+ secondaryColor = '#FFFFFF',
404
+ accentColor = '#8B4513',
405
+ size = 60
406
+ } = {}) {
407
+ const svg = `
408
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
409
+ <rect width="${size}" height="${size}" fill="${primaryColor}"/>
410
+ <!-- Zigzags -->
411
+ <polyline points="0,${size * 0.2} ${size * 0.25},0 ${size * 0.5},${size * 0.2} ${size * 0.75},0 ${size},${size * 0.2}"
412
+ fill="none" stroke="${secondaryColor}" stroke-width="3"/>
413
+ <polyline points="0,${size * 0.8} ${size * 0.25},${size} ${size * 0.5},${size * 0.8} ${size * 0.75},${size} ${size},${size * 0.8}"
414
+ fill="none" stroke="${secondaryColor}" stroke-width="3"/>
415
+ <!-- Crosses -->
416
+ <line x1="${size * 0.25}" y1="${size * 0.4}" x2="${size * 0.25}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
417
+ <line x1="${size * 0.15}" y1="${size * 0.5}" x2="${size * 0.35}" y2="${size * 0.5}" stroke="${secondaryColor}" stroke-width="2"/>
418
+ <line x1="${size * 0.75}" y1="${size * 0.4}" x2="${size * 0.75}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
419
+ <line x1="${size * 0.65}" y1="${size * 0.5}" x2="${size * 0.85}" y2="${size * 0.5}" stroke="${secondaryColor}" stroke-width="2"/>
420
+ <!-- Dots -->
421
+ <circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.08}" fill="${accentColor}"/>
422
+ </svg>
423
+ `;
424
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
425
+ }
426
+
427
+ /**
428
+ * Generate Kuba Shoowa pattern (DRC)
429
+ * Complex interlocking geometric shapes
430
+ */
431
+ export function generateKuba({
432
+ primaryColor = '#D2B48C',
433
+ secondaryColor = '#3E2723',
434
+ size = 60
435
+ } = {}) {
436
+ const svg = `
437
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
438
+ <rect width="${size}" height="${size}" fill="${primaryColor}"/>
439
+ <!-- Interlocking diamonds/rectangles -->
440
+ <rect x="${size * 0.1}" y="${size * 0.1}" width="${size * 0.3}" height="${size * 0.3}" fill="${secondaryColor}"/>
441
+ <rect x="${size * 0.6}" y="${size * 0.6}" width="${size * 0.3}" height="${size * 0.3}" fill="${secondaryColor}"/>
442
+ <rect x="${size * 0.6}" y="${size * 0.1}" width="${size * 0.3}" height="${size * 0.3}"
443
+ fill="none" stroke="${secondaryColor}" stroke-width="4"/>
444
+ <rect x="${size * 0.1}" y="${size * 0.6}" width="${size * 0.3}" height="${size * 0.3}"
445
+ fill="none" stroke="${secondaryColor}" stroke-width="4"/>
446
+ <!-- Center lines -->
447
+ <line x1="${size * 0.4}" y1="${size * 0.5}" x2="${size * 0.6}" y2="${size * 0.5}" stroke="${secondaryColor}" stroke-width="2"/>
448
+ <line x1="${size * 0.5}" y1="${size * 0.4}" x2="${size * 0.5}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
449
+ </svg>
450
+ `;
451
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
452
+ }
453
+
454
+ /**
455
+ * Generate Imigongo pattern (Rwanda)
456
+ * Spiral/Geometric ridges traditionally made from cow dung
457
+ */
458
+ export function generateImigongo({
459
+ primaryColor = '#000000',
460
+ secondaryColor = '#FFFFFF',
461
+ accentColor = '#B22222',
462
+ size = 60
463
+ } = {}) {
464
+ const svg = `
465
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
466
+ <rect width="${size}" height="${size}" fill="${secondaryColor}"/>
467
+ <!-- Spiral/Diamond Motif -->
468
+ <path d="M${size * 0.5} ${size * 0.1}
469
+ L${size * 0.9} ${size * 0.5}
470
+ L${size * 0.5} ${size * 0.9}
471
+ L${size * 0.1} ${size * 0.5} Z"
472
+ fill="${primaryColor}"/>
473
+ <path d="M${size * 0.5} ${size * 0.3}
474
+ L${size * 0.7} ${size * 0.5}
475
+ L${size * 0.5} ${size * 0.7}
476
+ L${size * 0.3} ${size * 0.5} Z"
477
+ fill="${secondaryColor}"/>
478
+ <circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.1}" fill="${accentColor}"/>
479
+ </svg>
480
+ `;
481
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
482
+ }
483
+
484
+ /**
485
+ * Generate Ethiopian Tibeb pattern
486
+ * Vibrant woven geometric borders
487
+ */
488
+ export function generateTibeb({
489
+ colors = ['#009E60', '#FCDD09', '#EF3340'], // Ethiopian flag colors
490
+ backgroundColor = '#FFFFFF',
491
+ size = 40
492
+ } = {}) {
493
+ const [c1, c2, c3] = colors;
494
+ const svg = `
495
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
496
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
497
+ <!-- Diamond Chain -->
498
+ <polygon points="${size * 0.5},0 ${size},${size * 0.5} ${size * 0.5},${size} 0,${size * 0.5}"
499
+ fill="${c1}" opacity="0.2"/>
500
+ <polygon points="${size * 0.5},${size * 0.2} ${size * 0.8},${size * 0.5} ${size * 0.5},${size * 0.8} ${size * 0.2},${size * 0.5}"
501
+ fill="${c2}"/>
502
+ <rect x="${size * 0.4}" y="${size * 0.4}" width="${size * 0.2}" height="${size * 0.2}" fill="${c3}"/>
503
+ <!-- Side accents -->
504
+ <line x1="0" y1="0" x2="0" y2="${size}" stroke="${c1}" stroke-width="4"/>
505
+ <line x1="${size}" y1="0" x2="${size}" y2="${size}" stroke="${c1}" stroke-width="4"/>
506
+ </svg>
507
+ `;
508
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
509
+ }
510
+
511
+ // ============================================
512
+ // SOUTHERN AFRICAN PATTERNS
513
+ // ============================================
514
+
515
+ /**
516
+ * Generate Ndebele geometric mural pattern (South Africa)
517
+ */
518
+ export function generateNdebele({
519
+ colors = ['#FFD700', '#4169E1', '#FF69B4', '#228B22'],
520
+ size = 60,
521
+ strokeWidth = 2
522
+ } = {}) {
523
+ const [c1, c2, c3, c4] = colors;
524
+ const svg = `
525
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
526
+ <rect width="${size}" height="${size}" fill="#FFFFFF"/>
527
+ <rect x="${strokeWidth}" y="${strokeWidth}"
528
+ width="${size - strokeWidth * 2}" height="${size - strokeWidth * 2}"
529
+ fill="none" stroke="#000000" stroke-width="${strokeWidth}"/>
530
+ <rect x="${size * 0.15}" y="${size * 0.15}" width="${size * 0.35}" height="${size * 0.35}"
531
+ fill="${c1}" stroke="#000000" stroke-width="${strokeWidth / 2}"/>
532
+ <rect x="${size * 0.5}" y="${size * 0.15}" width="${size * 0.35}" height="${size * 0.35}"
533
+ fill="${c2}" stroke="#000000" stroke-width="${strokeWidth / 2}"/>
534
+ <rect x="${size * 0.15}" y="${size * 0.5}" width="${size * 0.35}" height="${size * 0.35}"
535
+ fill="${c3}" stroke="#000000" stroke-width="${strokeWidth / 2}"/>
536
+ <rect x="${size * 0.5}" y="${size * 0.5}" width="${size * 0.35}" height="${size * 0.35}"
537
+ fill="${c4}" stroke="#000000" stroke-width="${strokeWidth / 2}"/>
538
+ <polygon points="${size / 2},${size * 0.3} ${size * 0.7},${size / 2} ${size / 2},${size * 0.7} ${size * 0.3},${size / 2}"
539
+ fill="#FFFFFF" stroke="#000000" stroke-width="${strokeWidth}"/>
540
+ </svg>
541
+ `;
542
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
543
+ }
544
+
545
+ /**
546
+ * Generate Zulu beadwork pattern (South Africa)
547
+ * Traditional "love letter" beadwork with symbolic colors
548
+ * Colors carry deep meaning in Zulu courtship
549
+ */
550
+ export function generateZulu({
551
+ colors = ['#FFFFFF', '#000000', '#FF0000', '#00A86B', '#FFD700'],
552
+ size = 50
553
+ } = {}) {
554
+ const [white, black, red, green, gold] = colors;
555
+ const bead = size / 10;
556
+
557
+ const svg = `
558
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
559
+ <rect width="${size}" height="${size}" fill="${black}"/>
560
+ <!-- Triangle pattern (isivivane - sacred cairn) -->
561
+ <polygon points="${size * 0.5},${size * 0.1} ${size * 0.9},${size * 0.9} ${size * 0.1},${size * 0.9}"
562
+ fill="none" stroke="${white}" stroke-width="2"/>
563
+ <polygon points="${size * 0.5},${size * 0.25} ${size * 0.75},${size * 0.75} ${size * 0.25},${size * 0.75}"
564
+ fill="${red}"/>
565
+ <!-- Beadwork dots -->
566
+ <circle cx="${size * 0.5}" cy="${size * 0.35}" r="${bead}" fill="${white}"/>
567
+ <circle cx="${size * 0.35}" cy="${size * 0.6}" r="${bead}" fill="${green}"/>
568
+ <circle cx="${size * 0.65}" cy="${size * 0.6}" r="${bead}" fill="${gold}"/>
569
+ <circle cx="${size * 0.5}" cy="${size * 0.8}" r="${bead}" fill="${white}"/>
570
+ <!-- Border dots -->
571
+ <circle cx="${size * 0.1}" cy="${size * 0.1}" r="${bead * 0.7}" fill="${red}"/>
572
+ <circle cx="${size * 0.9}" cy="${size * 0.1}" r="${bead * 0.7}" fill="${green}"/>
573
+ </svg>
574
+ `;
575
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
576
+ }
577
+
578
+ /**
579
+ * Generate Swazi/Eswatini pattern
580
+ * Inspired by Ligwalagwala (purple-crested turaco) and royal patterns
581
+ * Traditional shields and ceremonial designs
582
+ */
583
+ export function generateSwazi({
584
+ colors = ['#3E5EB9', '#FECD00', '#B10C0C', '#FFFFFF'],
585
+ size = 50
586
+ } = {}) {
587
+ const [blue, gold, red, white] = colors;
588
+
589
+ const svg = `
590
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
591
+ <rect width="${size}" height="${size}" fill="${blue}"/>
592
+ <!-- Shield shape (central to Eswatini culture) -->
593
+ <ellipse cx="${size * 0.5}" cy="${size * 0.45}" rx="${size * 0.35}" ry="${size * 0.4}"
594
+ fill="${gold}" stroke="${red}" stroke-width="3"/>
595
+ <!-- Inner pattern -->
596
+ <ellipse cx="${size * 0.5}" cy="${size * 0.45}" rx="${size * 0.2}" ry="${size * 0.25}"
597
+ fill="${red}"/>
598
+ <!-- Feather accents -->
599
+ <line x1="${size * 0.5}" y1="${size * 0.05}" x2="${size * 0.5}" y2="${size * 0.2}"
600
+ stroke="${white}" stroke-width="3"/>
601
+ <line x1="${size * 0.4}" y1="${size * 0.08}" x2="${size * 0.45}" y2="${size * 0.15}"
602
+ stroke="${white}" stroke-width="2"/>
603
+ <line x1="${size * 0.6}" y1="${size * 0.08}" x2="${size * 0.55}" y2="${size * 0.15}"
604
+ stroke="${white}" stroke-width="2"/>
605
+ <!-- Spear points -->
606
+ <polygon points="${size * 0.1},${size * 0.3} ${size * 0.05},${size * 0.5} ${size * 0.15},${size * 0.5}" fill="${white}"/>
607
+ <polygon points="${size * 0.9},${size * 0.3} ${size * 0.85},${size * 0.5} ${size * 0.95},${size * 0.5}" fill="${white}"/>
608
+ </svg>
609
+ `;
610
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
611
+ }
612
+
613
+ /**
614
+ * Generate Xhosa pattern (South Africa)
615
+ * Inspired by traditional Xhosa beadwork and blanket designs
616
+ * Known for bold geometric patterns
617
+ */
618
+ export function generateXhosa({
619
+ primaryColor = '#FFFFFF',
620
+ accentColor = '#00A86B',
621
+ backgroundColor = '#1a1a2e',
622
+ size = 50
623
+ } = {}) {
624
+ const svg = `
625
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
626
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
627
+ <!-- Horizontal bands -->
628
+ <rect x="0" y="${size * 0.2}" width="${size}" height="${size * 0.1}" fill="${primaryColor}"/>
629
+ <rect x="0" y="${size * 0.7}" width="${size}" height="${size * 0.1}" fill="${primaryColor}"/>
630
+ <!-- Vertical bands -->
631
+ <rect x="${size * 0.2}" y="0" width="${size * 0.1}" height="${size}" fill="${accentColor}"/>
632
+ <rect x="${size * 0.7}" y="0" width="${size * 0.1}" height="${size}" fill="${accentColor}"/>
633
+ <!-- Central diamond -->
634
+ <polygon points="${size * 0.5},${size * 0.35} ${size * 0.65},${size * 0.5} ${size * 0.5},${size * 0.65} ${size * 0.35},${size * 0.5}"
635
+ fill="${accentColor}" stroke="${primaryColor}" stroke-width="2"/>
636
+ <!-- Corner triangles -->
637
+ <polygon points="0,0 ${size * 0.15},0 0,${size * 0.15}" fill="${accentColor}"/>
638
+ <polygon points="${size},0 ${size * 0.85},0 ${size},${size * 0.15}" fill="${accentColor}"/>
639
+ <polygon points="0,${size} ${size * 0.15},${size} 0,${size * 0.85}" fill="${accentColor}"/>
640
+ <polygon points="${size},${size} ${size * 0.85},${size} ${size},${size * 0.85}" fill="${accentColor}"/>
641
+ </svg>
642
+ `;
643
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
644
+ }
645
+
646
+ /**
647
+ * Apply pattern as background to an element
648
+ */
649
+ export function applyPattern(element, patternUrl) {
650
+ element.style.backgroundImage = `url("${patternUrl}")`;
651
+ element.style.backgroundRepeat = 'repeat';
652
+ }
653
+
654
+ // ============================================
655
+ // NORTH AFRICAN PATTERNS
656
+ // ============================================
657
+
658
+ /**
659
+ * Generate Berber pattern (North Africa)
660
+ * Geometric designs inspired by Amazigh rugs and tattoos
661
+ * Symbols of protection, fertility, and nature
662
+ */
663
+ export function generateBerber({
664
+ primaryColor = '#8B0000', // Deep red
665
+ secondaryColor = '#000000',
666
+ accentColor = '#FFD700',
667
+ backgroundColor = '#F5F5DC', // Beige/Wool
668
+ size = 60
669
+ } = {}) {
670
+ const svg = `
671
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
672
+ <rect width="${size}" height="${size}" fill="${backgroundColor}"/>
673
+ <!-- Lozenge (Diamond) - universal protective symbol -->
674
+ <polygon points="${size * 0.5},${size * 0.1} ${size * 0.9},${size * 0.5} ${size * 0.5},${size * 0.9} ${size * 0.1},${size * 0.5}"
675
+ fill="${primaryColor}" stroke="${secondaryColor}" stroke-width="2"/>
676
+ <!-- Inner geometric details -->
677
+ <line x1="${size * 0.5}" y1="${size * 0.1}" x2="${size * 0.5}" y2="${size * 0.9}" stroke="${accentColor}" stroke-width="2"/>
678
+ <line x1="${size * 0.1}" y1="${size * 0.5}" x2="${size * 0.9}" y2="${size * 0.5}" stroke="${accentColor}" stroke-width="2"/>
679
+ <!-- X symbols (Fibula/Cross) -->
680
+ <line x1="${size * 0.4}" y1="${size * 0.4}" x2="${size * 0.6}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
681
+ <line x1="${size * 0.6}" y1="${size * 0.4}" x2="${size * 0.4}" y2="${size * 0.6}" stroke="${secondaryColor}" stroke-width="2"/>
682
+ </svg>
683
+ `;
684
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
685
+ }
686
+
687
+ /**
688
+ * Generate Adire Oniko (Yoruba Indigo) pattern
689
+ * Resist-dyed circles and ripples
690
+ * "Tie and dye" technique simulation
691
+ */
692
+ export function generateAdire({
693
+ primaryColor = '#4B0082', // Indigo
694
+ secondaryColor = '#8A2BE2', // Light Indigo
695
+ accentColor = '#FFFFFF',
696
+ size = 50
697
+ } = {}) {
698
+ const svg = `
699
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
700
+ <rect width="${size}" height="${size}" fill="${primaryColor}"/>
701
+ <!-- Resist circles (Oniko) -->
702
+ <circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.35}" fill="none" stroke="${secondaryColor}" stroke-width="3"/>
703
+ <circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.25}" fill="none" stroke="${accentColor}" stroke-width="2" stroke-dasharray="4 2"/>
704
+ <circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.1}" fill="${accentColor}" opacity="0.8"/>
705
+ <!-- Corner ripples -->
706
+ <path d="M0,0 Q${size * 0.2},0 ${size * 0.2},${size * 0.2} Q0,${size * 0.2} 0,0" fill="${secondaryColor}"/>
707
+ <path d="M${size},${size} Q${size * 0.8},${size} ${size * 0.8},${size * 0.8} Q${size},${size * 0.8} ${size},${size}" fill="${secondaryColor}"/>
708
+ </svg>
709
+ `;
710
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
711
+ }
712
+
713
+ // Export all generators
714
+ export default {
715
+ // East Africa
716
+ generatePolygon,
717
+ generateShuka,
718
+ generateHadzabe,
719
+ generateKanga,
720
+ generateKangaBorder,
721
+ generateKitenge,
722
+ generateMasaiShield,
723
+ generateTibeb, // Ethiopia
724
+ generateImigongo, // Rwanda
725
+ // West Africa
726
+ generateKente,
727
+ generateAdinkra,
728
+ generateAsoOke,
729
+ generateAnkara,
730
+ generateBogolan, // Mali/West
731
+ generateAdire, // Nigeria (Indigo)
732
+ // Central Africa
733
+ generateKuba, // DRC
734
+ generateKubaBorder,
735
+ // North Africa
736
+ generateBerber, // Amazigh
737
+ // Southern Africa
738
+ generateNdebele,
739
+ generateNdebelePaint,
740
+ generateZulu,
741
+ generateZuluBeads,
742
+ generateSwazi,
743
+ generateXhosa,
744
+ // Utilities
745
+ applyPattern,
746
+ // Tech Patterns
747
+ generateTuareg,
748
+ generateGeez,
749
+ generateBoli,
750
+ generateCircuit,
751
+ circuit: generateCircuit
752
+ };
753
+
754
+ /**
755
+ * Generate Tuareg Indigo pattern (Sahara/Berber)
756
+ * Inspired by the "Blue Men of the Sahara" and their geometric silver jewelry/stars
757
+ */
758
+ export function generateTuareg({
759
+ primaryColor = '#2D3D6B', // Tuareg Indigo
760
+ secondaryColor = '#6B8CC7', // Sky Blue
761
+ accentColor = '#FFFFFF', // Silver/White
762
+ size = 60
763
+ } = {}) {
764
+ const svg = `
765
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
766
+ <rect width="${size}" height="${size}" fill="${primaryColor}"/>
767
+ <!-- Southern Cross / Tuareg Star -->
768
+ <path d="M${size * 0.5} 0 L${size * 0.6} ${size * 0.4} L${size} ${size * 0.5} L${size * 0.6} ${size * 0.6} L${size * 0.5} ${size} L${size * 0.4} ${size * 0.6} L0 ${size * 0.5} L${size * 0.4} ${size * 0.4} Z"
769
+ fill="none" stroke="${accentColor}" stroke-width="2"/>
770
+ <circle cx="${size * 0.5}" cy="${size * 0.5}" r="${size * 0.1}" fill="${secondaryColor}"/>
771
+ </svg>
772
+ `;
773
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
774
+ }
775
+
776
+ /**
777
+ * Generate Ge'ez Script pattern (Ethiopia/Eritrea)
778
+ * Abstract calligraphic strokes inspired by one of the world's oldest scripts
779
+ */
780
+ export function generateGeez({
781
+ inkColor = '#3A2E2C',
782
+ parchmentColor = '#F4E4BC',
783
+ size = 50
784
+ } = {}) {
785
+ const svg = `
786
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
787
+ <rect width="${size}" height="${size}" fill="${parchmentColor}"/>
788
+ <path d="M${size * 0.2} ${size * 0.2} L${size * 0.4} ${size * 0.2} M${size * 0.3} ${size * 0.2} L${size * 0.3} ${size * 0.5} Q${size * 0.4} ${size * 0.6} ${size * 0.2} ${size * 0.7}"
789
+ fill="none" stroke="${inkColor}" stroke-width="3" stroke-linecap="round"/>
790
+ <path d="M${size * 0.6} ${size * 0.3} C${size * 0.8} ${size * 0.3} ${size * 0.8} ${size * 0.6} ${size * 0.6} ${size * 0.6} L${size * 0.8} ${size * 0.8}"
791
+ fill="none" stroke="${inkColor}" stroke-width="3" stroke-linecap="round"/>
792
+ </svg>
793
+ `;
794
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
795
+ }
796
+
797
+ /**
798
+ * Generate Boli pattern (Mali/Bambara)
799
+ * Abstract organic shapes inspired by mud-based ritual objects
800
+ */
801
+ export function generateBoli({
802
+ clayColor = '#4E342E',
803
+ earthColor = '#3E2723',
804
+ accentColor = '#BCAAA4',
805
+ size = 60
806
+ } = {}) {
807
+ const svg = `
808
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
809
+ <rect width="${size}" height="${size}" fill="${earthColor}"/>
810
+ <path d="M${size * 0.2} ${size * 0.5} Q${size * 0.3} ${size * 0.2} ${size * 0.5} ${size * 0.3} T${size * 0.8} ${size * 0.5} Q${size * 0.7} ${size * 0.8} ${size * 0.5} ${size * 0.7} T${size * 0.2} ${size * 0.5}"
811
+ fill="${clayColor}" stroke="${accentColor}" stroke-width="2"/>
812
+ </svg>
813
+ `;
814
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
815
+ }
816
+
817
+ export function generateCircuit({
818
+ primaryColor = '#334155',
819
+ secondaryColor = '#1e293b',
820
+ size = 100
821
+ } = {}) {
822
+ const svg = `
823
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 100 100">
824
+ <rect width="100" height="100" fill="${secondaryColor}"/>
825
+ <path d="M10 10 H90 V90 H10 Z" fill="none" stroke="${primaryColor}" stroke-width="0.5" opacity="0.3"/>
826
+ <path d="M20 20 V50 H50 V80 H80" fill="none" stroke="${primaryColor}" stroke-width="1"/>
827
+ <circle cx="20" cy="20" r="2" fill="${primaryColor}"/>
828
+ <circle cx="80" cy="80" r="2" fill="${primaryColor}"/>
829
+ <circle cx="50" cy="50" r="1.5" fill="${primaryColor}"/>
830
+ </svg>
831
+ `;
832
+ return `data:image/svg+xml,${encodeURIComponent(svg.trim())}`;
833
+ }