@aglyn/plugins-ai 1.0.0-beta.231 → 1.0.0-beta.232

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 (220) hide show
  1. package/package.json +17 -17
  2. package/src/lib/activity/ai-activity-actions.js +8 -4
  3. package/src/lib/activity/ai-activity-actions.js.map +1 -1
  4. package/src/lib/components/ai-job-follow.component.js +1 -0
  5. package/src/lib/components/ai-job-follow.component.js.map +1 -1
  6. package/src/lib/components/ai-job-links.js +13 -0
  7. package/src/lib/components/ai-job-links.js.map +1 -1
  8. package/src/lib/components/ai-jobs-list-page.component.js +1 -0
  9. package/src/lib/components/ai-jobs-list-page.component.js.map +1 -1
  10. package/src/lib/components/ai-media-create.component.d.ts +20 -7
  11. package/src/lib/components/ai-media-create.component.js +107 -55
  12. package/src/lib/components/ai-media-create.component.js.map +1 -1
  13. package/src/lib/components/ai-seo-fields-card.component.js +1 -0
  14. package/src/lib/components/ai-seo-fields-card.component.js.map +1 -1
  15. package/src/lib/components/ai-site-memory-card.component.d.ts +32 -0
  16. package/src/lib/components/ai-site-memory-card.component.js +187 -0
  17. package/src/lib/components/ai-site-memory-card.component.js.map +1 -0
  18. package/src/lib/components/ai-site-start-card.component.js +80 -77
  19. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  20. package/src/lib/components/ai-theme-proposal-card.component.js +4 -0
  21. package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -1
  22. package/src/lib/components/ai-usage-strip.component.js +1 -0
  23. package/src/lib/components/ai-usage-strip.component.js.map +1 -1
  24. package/src/lib/components/assist-panel.component.d.ts +10 -0
  25. package/src/lib/components/assist-panel.component.js +119 -9
  26. package/src/lib/components/assist-panel.component.js.map +1 -1
  27. package/src/lib/components/assist-signals-page.component.js +2 -0
  28. package/src/lib/components/assist-signals-page.component.js.map +1 -1
  29. package/src/lib/components/billing-ai-allotments.component.js +3 -0
  30. package/src/lib/components/billing-ai-allotments.component.js.map +1 -1
  31. package/src/lib/components/billing-ai-top-users.component.js +1 -0
  32. package/src/lib/components/billing-ai-top-users.component.js.map +1 -1
  33. package/src/lib/components/billing-assist-overage-card.component.js +2 -0
  34. package/src/lib/components/billing-assist-overage-card.component.js.map +1 -1
  35. package/src/lib/components/member-ai-usage-card.component.js +10 -0
  36. package/src/lib/components/member-ai-usage-card.component.js.map +1 -1
  37. package/src/lib/components/staff-org-ai-card.component.js +1 -0
  38. package/src/lib/components/staff-org-ai-card.component.js.map +1 -1
  39. package/src/lib/components/staff-org-ai-conversations.component.d.ts +23 -0
  40. package/src/lib/components/staff-org-ai-conversations.component.js +346 -0
  41. package/src/lib/components/staff-org-ai-conversations.component.js.map +1 -0
  42. package/src/lib/jobs/ai-build-capabilities.d.ts +13 -1
  43. package/src/lib/jobs/ai-build-capabilities.js +101 -7
  44. package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
  45. package/src/lib/jobs/ai-business-profile-prefill.d.ts +29 -0
  46. package/src/lib/jobs/ai-business-profile-prefill.js +85 -0
  47. package/src/lib/jobs/ai-business-profile-prefill.js.map +1 -0
  48. package/src/lib/jobs/ai-job-build-step.js +3 -1
  49. package/src/lib/jobs/ai-job-build-step.js.map +1 -1
  50. package/src/lib/jobs/ai-job-edit-step.d.ts +225 -0
  51. package/src/lib/jobs/ai-job-edit-step.js +631 -0
  52. package/src/lib/jobs/ai-job-edit-step.js.map +1 -0
  53. package/src/lib/jobs/ai-job-insight-step.js +21 -4
  54. package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
  55. package/src/lib/jobs/ai-job-layout-language.d.ts +8 -3
  56. package/src/lib/jobs/ai-job-layout-language.js +8 -2
  57. package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
  58. package/src/lib/jobs/ai-job-layout-step.js +7 -6
  59. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  60. package/src/lib/jobs/ai-job-logic-step.d.ts +20 -0
  61. package/src/lib/jobs/ai-job-logic-step.js +87 -6
  62. package/src/lib/jobs/ai-job-logic-step.js.map +1 -1
  63. package/src/lib/jobs/ai-job-page-language.d.ts +52 -7
  64. package/src/lib/jobs/ai-job-page-language.js +72 -9
  65. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  66. package/src/lib/jobs/ai-job-page-step.js +12 -2
  67. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  68. package/src/lib/jobs/ai-job-plan-step.d.ts +19 -5
  69. package/src/lib/jobs/ai-job-plan-step.js +54 -20
  70. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  71. package/src/lib/jobs/ai-job-site-content.d.ts +163 -0
  72. package/src/lib/jobs/ai-job-site-content.js +443 -0
  73. package/src/lib/jobs/ai-job-site-content.js.map +1 -0
  74. package/src/lib/jobs/ai-job-site-look.d.ts +112 -0
  75. package/src/lib/jobs/ai-job-site-look.js +322 -0
  76. package/src/lib/jobs/ai-job-site-look.js.map +1 -0
  77. package/src/lib/jobs/ai-job-site-step.d.ts +26 -5
  78. package/src/lib/jobs/ai-job-site-step.js +163 -24
  79. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  80. package/src/lib/jobs/ai-jobs-notify.d.ts +6 -1
  81. package/src/lib/jobs/ai-jobs-notify.js +15 -3
  82. package/src/lib/jobs/ai-jobs-notify.js.map +1 -1
  83. package/src/lib/layout-language/ai-layout-compiler.d.ts +9 -0
  84. package/src/lib/layout-language/ai-layout-compiler.js +120 -33
  85. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  86. package/src/lib/layout-language/ai-layout-frame.js +5 -4
  87. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  88. package/src/lib/layout-language/ai-layout-language.d.ts +12 -5
  89. package/src/lib/layout-language/ai-layout-language.js +92 -9
  90. package/src/lib/layout-language/ai-layout-language.js.map +1 -1
  91. package/src/lib/layout-language/ai-layout-pictures.d.ts +144 -0
  92. package/src/lib/layout-language/ai-layout-pictures.js +214 -0
  93. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -0
  94. package/src/lib/layout-language/ai-layout-store.d.ts +2 -0
  95. package/src/lib/layout-language/ai-layout-store.js +7 -1
  96. package/src/lib/layout-language/ai-layout-store.js.map +1 -1
  97. package/src/lib/model/ai-build-progress.js +4 -1
  98. package/src/lib/model/ai-build-progress.js.map +1 -1
  99. package/src/lib/model/ai-edit-job.d.ts +109 -0
  100. package/src/lib/model/ai-edit-job.js +157 -0
  101. package/src/lib/model/ai-edit-job.js.map +1 -0
  102. package/src/lib/model/ai-job-activity.js +1 -0
  103. package/src/lib/model/ai-job-activity.js.map +1 -1
  104. package/src/lib/model/ai-jobs.types.d.ts +3 -1
  105. package/src/lib/model/ai-jobs.types.js.map +1 -1
  106. package/src/lib/model/ai-logic-job.d.ts +18 -1
  107. package/src/lib/model/ai-logic-job.js +24 -3
  108. package/src/lib/model/ai-logic-job.js.map +1 -1
  109. package/src/lib/model/ai-media-credits.d.ts +8 -4
  110. package/src/lib/model/ai-media-credits.js +11 -4
  111. package/src/lib/model/ai-media-credits.js.map +1 -1
  112. package/src/lib/model/ai-media-kinds.d.ts +68 -0
  113. package/src/lib/model/ai-media-kinds.js +98 -0
  114. package/src/lib/model/ai-media-kinds.js.map +1 -0
  115. package/src/lib/model/ai-site-build-progress.d.ts +4 -0
  116. package/src/lib/model/ai-site-build-progress.js +28 -11
  117. package/src/lib/model/ai-site-build-progress.js.map +1 -1
  118. package/src/lib/model/ai-site-context.d.ts +111 -0
  119. package/src/lib/model/ai-site-context.js +222 -0
  120. package/src/lib/model/ai-site-context.js.map +1 -0
  121. package/src/lib/model/ai-site-job.d.ts +10 -2
  122. package/src/lib/model/ai-site-job.js +12 -5
  123. package/src/lib/model/ai-site-job.js.map +1 -1
  124. package/src/lib/model/ai-site-kinds.d.ts +164 -0
  125. package/src/lib/model/ai-site-kinds.js +1942 -0
  126. package/src/lib/model/ai-site-kinds.js.map +1 -0
  127. package/src/lib/model/ai-site-look.d.ts +150 -0
  128. package/src/lib/model/ai-site-look.js +1236 -0
  129. package/src/lib/model/ai-site-look.js.map +1 -0
  130. package/src/lib/model/ai-site-memory.d.ts +80 -0
  131. package/src/lib/model/ai-site-memory.js +171 -0
  132. package/src/lib/model/ai-site-memory.js.map +1 -0
  133. package/src/lib/model/ai-site-start.d.ts +10 -1
  134. package/src/lib/model/ai-site-start.js +16 -2
  135. package/src/lib/model/ai-site-start.js.map +1 -1
  136. package/src/lib/model/assist-follow-up.d.ts +92 -0
  137. package/src/lib/model/assist-follow-up.js +128 -0
  138. package/src/lib/model/assist-follow-up.js.map +1 -0
  139. package/src/lib/plugin-config.js +2 -0
  140. package/src/lib/plugin-config.js.map +1 -1
  141. package/src/lib/plugin.js +20 -1
  142. package/src/lib/plugin.js.map +1 -1
  143. package/src/lib/providers/anthropic.d.ts +9 -1
  144. package/src/lib/providers/anthropic.js +143 -9
  145. package/src/lib/providers/anthropic.js.map +1 -1
  146. package/src/lib/providers/catalog.d.ts +37 -7
  147. package/src/lib/providers/catalog.js +103 -11
  148. package/src/lib/providers/catalog.js.map +1 -1
  149. package/src/lib/providers/contract.d.ts +29 -0
  150. package/src/lib/providers/contract.js.map +1 -1
  151. package/src/lib/providers/image-contract.d.ts +22 -1
  152. package/src/lib/providers/image-contract.js +40 -1
  153. package/src/lib/providers/image-contract.js.map +1 -1
  154. package/src/lib/providers/image-endpoints.d.ts +24 -0
  155. package/src/lib/providers/image-endpoints.js +28 -0
  156. package/src/lib/providers/image-endpoints.js.map +1 -0
  157. package/src/lib/providers/model-choice.js +23 -2
  158. package/src/lib/providers/model-choice.js.map +1 -1
  159. package/src/lib/providers/routing.js +18 -0
  160. package/src/lib/providers/routing.js.map +1 -1
  161. package/src/lib/providers/vertex-image-endpoint.d.ts +48 -0
  162. package/src/lib/providers/vertex-image-endpoint.js +80 -0
  163. package/src/lib/providers/vertex-image-endpoint.js.map +1 -0
  164. package/src/lib/providers/vertex-image.d.ts +13 -27
  165. package/src/lib/providers/vertex-image.js +15 -42
  166. package/src/lib/providers/vertex-image.js.map +1 -1
  167. package/src/lib/runtime/ai-blog-post-generation.d.ts +62 -0
  168. package/src/lib/runtime/ai-blog-post-generation.js +89 -0
  169. package/src/lib/runtime/ai-blog-post-generation.js.map +1 -0
  170. package/src/lib/runtime/ai-dev-env.d.ts +53 -0
  171. package/src/lib/runtime/ai-dev-env.js +72 -0
  172. package/src/lib/runtime/ai-dev-env.js.map +1 -0
  173. package/src/lib/runtime/ai-dev-replay.d.ts +116 -0
  174. package/src/lib/runtime/ai-dev-replay.js +313 -0
  175. package/src/lib/runtime/ai-dev-replay.js.map +1 -0
  176. package/src/lib/runtime/ai-doctrine.js +5 -1
  177. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  178. package/src/lib/runtime/ai-eval-live.js +4 -0
  179. package/src/lib/runtime/ai-eval-live.js.map +1 -1
  180. package/src/lib/runtime/ai-eval.d.ts +13 -1
  181. package/src/lib/runtime/ai-eval.js +84 -1
  182. package/src/lib/runtime/ai-eval.js.map +1 -1
  183. package/src/lib/runtime/ai-live-batch.d.ts +45 -0
  184. package/src/lib/runtime/ai-live-batch.js +89 -0
  185. package/src/lib/runtime/ai-live-batch.js.map +1 -0
  186. package/src/lib/runtime/ai-runtime.js +46 -2
  187. package/src/lib/runtime/ai-runtime.js.map +1 -1
  188. package/src/lib/runtime/site-context.d.ts +58 -0
  189. package/src/lib/runtime/site-context.js +127 -0
  190. package/src/lib/runtime/site-context.js.map +1 -0
  191. package/src/lib/server/ai-admin-conversations.d.ts +22 -0
  192. package/src/lib/server/ai-admin-conversations.js +197 -0
  193. package/src/lib/server/ai-admin-conversations.js.map +1 -0
  194. package/src/lib/server/ai-media-image.d.ts +5 -5
  195. package/src/lib/server/ai-media-image.js +25 -11
  196. package/src/lib/server/ai-media-image.js.map +1 -1
  197. package/src/lib/server/ai-media-raster-prompt.d.ts +34 -0
  198. package/src/lib/server/ai-media-raster-prompt.js +53 -0
  199. package/src/lib/server/ai-media-raster-prompt.js.map +1 -0
  200. package/src/lib/server/assist-chat.d.ts +11 -0
  201. package/src/lib/server/assist-chat.js +57 -18
  202. package/src/lib/server/assist-chat.js.map +1 -1
  203. package/src/lib/server/assist-edit-applied.js +16 -3
  204. package/src/lib/server/assist-edit-applied.js.map +1 -1
  205. package/src/lib/server/assist-view-context.d.ts +19 -1
  206. package/src/lib/server/assist-view-context.js +38 -1
  207. package/src/lib/server/assist-view-context.js.map +1 -1
  208. package/src/lib/server.js +10 -0
  209. package/src/lib/server.js.map +1 -1
  210. package/src/lib/subprocessors.js +17 -1
  211. package/src/lib/subprocessors.js.map +1 -1
  212. package/src/lib/tools/ai-blog-post-tool.d.ts +60 -0
  213. package/src/lib/tools/ai-blog-post-tool.js +175 -0
  214. package/src/lib/tools/ai-blog-post-tool.js.map +1 -0
  215. package/src/lib/usage/assist-usage.d.ts +3 -0
  216. package/src/lib/usage/assist-usage.js +4 -2
  217. package/src/lib/usage/assist-usage.js.map +1 -1
  218. package/src/lib/usage/staff-org-ai-conversations.d.ts +103 -0
  219. package/src/lib/usage/staff-org-ai-conversations.js +152 -0
  220. package/src/lib/usage/staff-org-ai-conversations.js.map +1 -0
@@ -1,4 +1,5 @@
1
1
  import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
2
3
  /**
3
4
  * @license
4
5
  * Copyright 2026 Aglyn LLC
@@ -67,7 +68,8 @@ const componentOf = (targets, id)=>{
67
68
  },
68
69
  formSection: formSectionOf(sections, plan, targets),
69
70
  pageIcon: pageIconOf(sections),
70
- formsPlaced: new Set()
71
+ formsPlaced: new Set(),
72
+ itemIds: plan.sections.map(()=>[])
71
73
  };
72
74
  const roots = plan.sections.map((_, index)=>{
73
75
  var _sections_index;
@@ -84,7 +86,8 @@ const componentOf = (targets, id)=>{
84
86
  },
85
87
  sectionRoots: roots,
86
88
  scrollTo: page.scrollTo,
87
- settled: page.settled
89
+ settled: page.settled,
90
+ itemIds: page.itemIds
88
91
  };
89
92
  }
90
93
  /** The first icon the design names anywhere, else a sparkle: what an empty picture shows. */ function pageIconOf(sections) {
@@ -104,7 +107,7 @@ const componentOf = (targets, id)=>{
104
107
  // ── A section ─────────────────────────────────────────────────────────────
105
108
  function compileSection(page, raw, index) {
106
109
  var _raw_band, _ref;
107
- var _page_plan_sections_index_name, _page_plan_sections_index, _page_options_sectionIds;
110
+ var _placedHere_, _page_plan_sections_index_name, _page_plan_sections_index, _page_options_sectionIds;
108
111
  const at = `sections[${index}]`;
109
112
  const band = settleBand(page, (_raw_band = raw.band) != null ? _raw_band : 'plain', at);
110
113
  const scope = {
@@ -154,6 +157,29 @@ function compileSection(page, raw, index) {
154
157
  weight: (_ref = cols == null ? void 0 : cols[position]) != null ? _ref : 1
155
158
  };
156
159
  }).filter((entry)=>entry.column.length);
160
+ // A row whose columns each place the same component, one instance a
161
+ // column or more, is that component's group of cards: the compiler lays
162
+ // its instances out once, rather than one like Grid a column (rule 1).
163
+ // Row by row, as the columns showed them: the first of each column, then the second.
164
+ const deepest = Math.max(0, ...filled.map((entry)=>entry.column.length));
165
+ const placedHere = Array.from({
166
+ length: deepest
167
+ }, (_, row)=>filled.flatMap((entry)=>entry.column[row] ? [
168
+ entry.column[row]
169
+ ] : [])).flat();
170
+ const repeated = ((_placedHere_ = placedHere[0]) == null ? void 0 : _placedHere_.kind) === 'component' ? componentOf(page.targets, placedHere[0].to) : null;
171
+ if (filled.length >= 2 && repeated && placedHere.every((block)=>block.kind === 'component' && block.to === repeated.id)) {
172
+ head.push({
173
+ kind: 'cards',
174
+ to: repeated.id,
175
+ items: placedHere.map((block)=>componentItem(block, repeated.props))
176
+ });
177
+ page.settled.push({
178
+ at,
179
+ what: `${placedHere.length} ${repeated.name} instances in ${filled.length} columns drawn as one group`
180
+ });
181
+ filled = [];
182
+ }
157
183
  // A row whose columns each hold only one kind of group — a card a column —
158
184
  // is that group, laid out by the compiler rather than column by column.
159
185
  const groups = filled.flatMap((entry)=>entry.column);
@@ -292,6 +318,30 @@ function compileSection(page, raw, index) {
292
318
  container
293
319
  ], 'section', (_ref = (_page_options_sectionIds = page.options.sectionIds) == null ? void 0 : _page_options_sectionIds[index]) != null ? _ref : sectionIdOf(index));
294
320
  }
321
+ /**
322
+ * A component block's prop values as a card item: its title-like prop as the
323
+ * title and its text-like prop as the text, which `instanceValues` writes
324
+ * back into the same props.
325
+ */ function componentItem(block, props) {
326
+ var _block_items, _block_items1;
327
+ // An item that names no prop is the card itself, written as a cards item.
328
+ const own = ((_block_items = block.items) != null ? _block_items : []).find((item)=>!(item.title in props) && (item.title.trim() || item.text.trim()));
329
+ if (own && !((_block_items1 = block.items) != null ? _block_items1 : []).some((item)=>item.title in props)) return {
330
+ title: own.title,
331
+ text: own.text
332
+ };
333
+ const value = (pattern)=>{
334
+ var _ref, _block_items;
335
+ var _find;
336
+ return (_ref = (_find = ((_block_items = block.items) != null ? _block_items : []).find((item)=>item.title in props && pattern.test(item.title) && item.text.trim())) == null ? void 0 : _find.text) != null ? _ref : '';
337
+ };
338
+ const title = value(/title|name|heading|label|question|figure|value/i) || block.text || '';
339
+ const text = value(/text|description|body|summary|copy|answer|detail|caption/i);
340
+ return {
341
+ title,
342
+ text
343
+ };
344
+ }
295
345
  /** A band the page has room for: past two brand or two dark bands, a soft one instead. */ function settleBand(page, band, at) {
296
346
  if (band !== 'brand' && band !== 'dark') return band;
297
347
  if (page.strong[band] >= AI_LAYOUT_MAX_STRONG_BANDS) {
@@ -357,6 +407,7 @@ function compileSection(page, raw, index) {
357
407
  } : {}));
358
408
  const lastCol = raw.cols && raw.cols.length >= 2 ? raw.cols.length - 1 : undefined;
359
409
  for (const block of blocks){
410
+ var _block_items;
360
411
  if (block.kind === 'form' && !(block.to && forms.has(block.to))) {
361
412
  var _plannedForms_;
362
413
  const only = page.targets.forms.length === 1 ? page.targets.forms[0].id : undefined;
@@ -367,6 +418,21 @@ function compileSection(page, raw, index) {
367
418
  else delete block.to;
368
419
  }
369
420
  if (block.kind === 'component' && !block.to) block.to = plannedComponents[0];
421
+ // A group whose every item names the same component is that component's
422
+ // placements (AGL-3660): the design put the id on its items, not the block.
423
+ if (AI_LAYOUT_GROUP_KINDS.has(block.kind) && !block.to && ((_block_items = block.items) == null ? void 0 : _block_items.length)) {
424
+ var _block_items_;
425
+ const named = (_block_items_ = block.items[0]) == null ? void 0 : _block_items_.to;
426
+ if (named && componentOf(page.targets, named) && block.items.every((item)=>item.to === named)) {
427
+ block.to = named;
428
+ block.items = block.items.map((_0)=>{
429
+ let { to: _to } = _0, item = _object_without_properties_loose(_0, [
430
+ "to"
431
+ ]);
432
+ return item;
433
+ });
434
+ }
435
+ }
370
436
  }
371
437
  for (const form of plannedForms){
372
438
  if (!blocks.some((block)=>block.kind === 'form' && block.to === form)) {
@@ -387,7 +453,11 @@ function compileSection(page, raw, index) {
387
453
  // A group the design drew where the plan places a component is that component's placements.
388
454
  const group = blocks.find((block)=>AI_LAYOUT_GROUP_KINDS.has(block.kind) && block.kind !== 'faq' && block.kind !== 'list' && !block.to);
389
455
  if (group) {
390
- group.to = component;
456
+ // Every group of that kind the design split over the row's columns, so
457
+ // each item of the row is drawn alike (AGL-3660), never the first alone.
458
+ for (const like of blocks){
459
+ if (like.kind === group.kind && !like.to) like.to = component;
460
+ }
391
461
  continue;
392
462
  }
393
463
  blocks.push(_extends({
@@ -508,7 +578,7 @@ export function compileRow(scope, columns) {
508
578
  spacing: '2',
509
579
  useFlexGap: true,
510
580
  flexWrap: 'wrap'
511
- }, scope.centered && room === 'full' ? {
581
+ }, scope.centered ? {
512
582
  justifyContent: 'center'
513
583
  } : {}), null, buttons, 'actions'));
514
584
  buttons = [];
@@ -658,7 +728,11 @@ function compileButton(scope, block) {
658
728
  children: label
659
729
  }, look, {
660
730
  size: scope.index === 0 || block.style === 'large' ? 'large' : 'medium'
661
- }, destinationProps(destination)), null, null, 'button');
731
+ }, destinationProps(destination)), // Sized to its words, never stretched across the column a Stack would
732
+ // stretch it over (AGL-3660), and aligned with its section.
733
+ {
734
+ alignSelf: scope.centered ? 'center' : 'flex-start'
735
+ }, null, 'button');
662
736
  linkTo(scope, id, destination);
663
737
  return id;
664
738
  }
@@ -691,7 +765,9 @@ export function destinationProps(destination) {
691
765
  /**
692
766
  * A picture slot: a soft frame at a stock shape showing an icon until the
693
767
  * owner places the picture, which then fills it. Its description is its alt
694
- * text (rule 9), and no source is set: a picture comes from the media library.
768
+ * text (rule 9), and no source is set here: the compiler stays pure, and
769
+ * `ai-layout-pictures.ts` fills the slot with a photo the site serves itself
770
+ * once the page is checked.
695
771
  */ function image(scope, block, room) {
696
772
  var _aiIconOfWord;
697
773
  const { page } = scope;
@@ -729,7 +805,8 @@ export function destinationProps(destination) {
729
805
  alignItems: 'center',
730
806
  justifyContent: 'center',
731
807
  overflow: 'hidden',
732
- borderRadius: 4,
808
+ // In multiples of the theme's corner radius, so a sharp site's frames are sharp.
809
+ borderRadius: 2,
733
810
  bgcolor: 'action.hover',
734
811
  // The frame's shape follows its room, so no two slots of a page share one style.
735
812
  aspectRatio: room === 'full' ? page.images === 1 ? '16 / 9' : '21 / 9' : room === 'half' ? '4 / 3' : page.images === 1 ? '1 / 1' : '3 / 4'
@@ -751,9 +828,12 @@ export function destinationProps(destination) {
751
828
  }, [
752
829
  placed
753
830
  ], 'formContent');
754
- return tree.add('muiCard', {
755
- variant: 'outlined'
756
- }, null, [
831
+ // The card style is the site theme's (AGL-3660), as a card dropped from the
832
+ // drawer takes it; it takes the flow's width, so a centered section never
833
+ // shrinks a form to its button.
834
+ return tree.add('muiCard', null, {
835
+ alignSelf: 'stretch'
836
+ }, [
757
837
  content
758
838
  ], 'formCard');
759
839
  }
@@ -797,6 +877,11 @@ function textProps(props) {
797
877
  return values;
798
878
  }
799
879
  // ── Groups ────────────────────────────────────────────────────────────────
880
+ /** Records the elements that draw a section's repeated items, and hands them back. */ function noted(scope, ids) {
881
+ var _scope_page_itemIds_scope_index;
882
+ if (!scope.frame) (_scope_page_itemIds_scope_index = scope.page.itemIds[scope.index]) == null ? void 0 : _scope_page_itemIds_scope_index.push(...ids);
883
+ return ids;
884
+ }
800
885
  /** How many items sit side by side in a room. */ function across(count, room, kind) {
801
886
  if (room === 'narrow') return 1;
802
887
  if (room === 'half') return count >= 2 && kind === 'stats' ? 2 : 1;
@@ -847,10 +932,17 @@ function itemSize(perRow) {
847
932
  const facts = scope.page.targets.facts;
848
933
  return !!(aiLayoutWords(item.title, 'itemTitle', facts) || aiLayoutWords(item.text, 'itemText', facts));
849
934
  }
850
- /** A group's items with every part that has no words left once cleaned emptied, and wordless items left out. */ function cleanItems(scope, items) {
935
+ /** A group's items with every part that has no words left once cleaned emptied, and wordless items left out. */ /** A title that only names the kind of thing it is: "Card", "Item 2", "Title". */ const AI_LAYOUT_PLACEHOLDER_TITLE = /^(?:card|item|title|heading|placeholder|tile|box|feature|service|post|article|entry)\s*\d*$/i;
936
+ function cleanItems(scope, items) {
851
937
  const facts = scope.page.targets.facts;
938
+ // A title that is only the name or id of what places it — a "Card" item of
939
+ // the Card component (AGL-3660) — is no words a visitor reads.
940
+ const references = new Set(scope.page.targets.components.flatMap((component)=>[
941
+ component.name,
942
+ component.id
943
+ ]).map((name)=>name.trim().toLowerCase()));
852
944
  return items.map((item)=>_extends({}, item, {
853
- title: aiLayoutWords(item.title, 'itemTitle', facts) ? item.title : '',
945
+ title: aiLayoutWords(item.title, 'itemTitle', facts) && !references.has(item.title.trim().toLowerCase()) && !AI_LAYOUT_PLACEHOLDER_TITLE.test(item.title.trim()) ? item.title : '',
854
946
  text: aiLayoutWords(item.text, 'itemText', facts) ? item.text : ''
855
947
  })).filter((item)=>speaks(scope, item));
856
948
  }
@@ -879,13 +971,13 @@ function group(scope, block, room) {
879
971
  if (rule1(scope)) return compactGroup(scope, block, items, perRow);
880
972
  switch(block.kind){
881
973
  case 'steps':
882
- return layOut(scope, items.map((item, position)=>step(scope, item, position)), perRow, '4', 'steps');
974
+ return layOut(scope, noted(scope, items.map((item, position)=>step(scope, item, position))), perRow, '4', 'steps');
883
975
  case 'stats':
884
- return layOut(scope, items.map((item)=>stat(scope, item)), perRow, '4', 'stats');
976
+ return layOut(scope, noted(scope, items.map((item)=>stat(scope, item))), perRow, '4', 'stats');
885
977
  case 'quotes':
886
- return layOut(scope, items.map((item)=>quote(scope, item)), perRow, '3', 'quotes');
978
+ return layOut(scope, noted(scope, items.map((item)=>quote(scope, item))), perRow, '3', 'quotes');
887
979
  default:
888
- return layOut(scope, items.map((item)=>card(scope, block, item)), perRow, '3', 'cards');
980
+ return layOut(scope, noted(scope, items.map((item)=>card(scope, block, item))), perRow, '3', 'cards');
889
981
  }
890
982
  }
891
983
  function instances(scope, placed, items, perRow) {
@@ -898,7 +990,7 @@ function instances(scope, placed, items, perRow) {
898
990
  propValues: values
899
991
  } : {}), null, null, 'instance');
900
992
  });
901
- return layOut(scope, ids, perRow, '3', 'instances');
993
+ return layOut(scope, noted(scope, ids), perRow, '3', 'instances');
902
994
  }
903
995
  /**
904
996
  * A group in its compact form, a title over its text: two elements an item,
@@ -915,7 +1007,7 @@ function instances(scope, placed, items, perRow) {
915
1007
  secondary: text
916
1008
  } : {}), null, null, 'pair');
917
1009
  });
918
- return layOut(scope, pairs, perRow, '3', 'compact');
1010
+ return layOut(scope, noted(scope, pairs), perRow, '3', 'compact');
919
1011
  }
920
1012
  /** A card: an optional icon, its title one level under the section's heading, and its words. */ function card(scope, block, item) {
921
1013
  var _aiIconOfWord;
@@ -950,12 +1042,9 @@ function instances(scope, placed, items, perRow) {
950
1042
  }, [
951
1043
  stack
952
1044
  ], 'cardContent');
953
- return tree.add('muiCard', block.style === 'primary' || block.style === 'large' ? {
954
- variant: 'elevation',
955
- elevation: '2'
956
- } : {
957
- variant: 'outlined'
958
- }, {
1045
+ // Flat, outlined, raised, tinted or ruled is the site theme's card style
1046
+ // (AGL-3660), never a choice stamped on this card.
1047
+ return tree.add('muiCard', null, {
959
1048
  height: '100%'
960
1049
  }, [
961
1050
  content
@@ -1030,9 +1119,7 @@ function instances(scope, placed, items, perRow) {
1030
1119
  }, [
1031
1120
  stack
1032
1121
  ], 'quoteContent');
1033
- return tree.add('muiCard', {
1034
- variant: 'outlined'
1035
- }, {
1122
+ return tree.add('muiCard', null, {
1036
1123
  height: '100%'
1037
1124
  }, [
1038
1125
  content
@@ -1062,7 +1149,7 @@ function instances(scope, placed, items, perRow) {
1062
1149
  });
1063
1150
  return links.length ? tree.add('muiStack', {
1064
1151
  spacing: '1'
1065
- }, null, links, 'links') : null;
1152
+ }, null, noted(scope, links), 'links') : null;
1066
1153
  }
1067
1154
  const lines = cleanItems(scope, (_block_items1 = block.items) != null ? _block_items1 : []).map((item)=>aiLayoutWords([
1068
1155
  item.title,
@@ -1080,7 +1167,7 @@ function instances(scope, placed, items, perRow) {
1080
1167
  ], 'row'));
1081
1168
  return tree.add('muiList', {
1082
1169
  disablePadding: true
1083
- }, null, rows, 'list');
1170
+ }, null, noted(scope, rows), 'list');
1084
1171
  }
1085
1172
  const check = (_aiIconOfWord = aiIconOfWord(block.icon)) != null ? _aiIconOfWord : AI_ICON_LIBRARY.check;
1086
1173
  const rows = lines.map((line)=>tree.add('muiStack', {
@@ -1099,7 +1186,7 @@ function instances(scope, placed, items, perRow) {
1099
1186
  ], 'row'));
1100
1187
  return tree.add('muiStack', {
1101
1188
  spacing: '1.5'
1102
- }, null, rows, 'list');
1189
+ }, null, noted(scope, rows), 'list');
1103
1190
  }
1104
1191
  /** Questions and answers: an accordion each, or question-over-answer pairs where rule 1 holds. */ function faq(scope, block) {
1105
1192
  var _block_items;
@@ -1120,7 +1207,7 @@ function instances(scope, placed, items, perRow) {
1120
1207
  ], 'row'));
1121
1208
  return tree.add('muiList', {
1122
1209
  disablePadding: true
1123
- }, null, rows, 'faq');
1210
+ }, null, noted(scope, rows), 'faq');
1124
1211
  }
1125
1212
  const panels = items.map((item, position)=>tree.add('muiAccordion', _extends({
1126
1213
  disableGutters: true
@@ -1141,7 +1228,7 @@ function instances(scope, placed, items, perRow) {
1141
1228
  ], 'panel'));
1142
1229
  return tree.add('muiStack', {
1143
1230
  spacing: '1.5'
1144
- }, null, panels, 'faq');
1231
+ }, null, noted(scope, panels), 'faq');
1145
1232
  }
1146
1233
  /** The id the compiled page's root is stored under. */ export const AI_LAYOUT_PAGE_ROOT_ID = CANVAS_ROOT_ELEMENT_ID;
1147
1234