@aglyn/plugins-ai 1.0.0-beta.285 → 1.0.0-beta.287

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 (210) hide show
  1. package/package.json +17 -17
  2. package/src/lib/assets/site-styles/nonprofit.webp +0 -0
  3. package/src/lib/assets/site-styles/professional.webp +0 -0
  4. package/src/lib/assets/site-styles/store.webp +0 -0
  5. package/src/lib/assets/site-styles/trades.webp +0 -0
  6. package/src/lib/components/ai-theme-proposal-card.component.js +12 -3
  7. package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -1
  8. package/src/lib/declarations.js +5 -2
  9. package/src/lib/declarations.js.map +1 -1
  10. package/src/lib/declarations.server.js +12 -0
  11. package/src/lib/declarations.server.js.map +1 -1
  12. package/src/lib/jobs/ai-build-capabilities.d.ts +3 -1
  13. package/src/lib/jobs/ai-build-capabilities.js +27 -2
  14. package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
  15. package/src/lib/jobs/ai-image-reads.d.ts +59 -0
  16. package/src/lib/jobs/ai-image-reads.js +138 -0
  17. package/src/lib/jobs/ai-image-reads.js.map +1 -0
  18. package/src/lib/jobs/ai-job-build-step.d.ts +29 -0
  19. package/src/lib/jobs/ai-job-build-step.js +83 -12
  20. package/src/lib/jobs/ai-job-build-step.js.map +1 -1
  21. package/src/lib/jobs/ai-job-duplicate-step.d.ts +2 -1
  22. package/src/lib/jobs/ai-job-duplicate-step.js +6 -6
  23. package/src/lib/jobs/ai-job-duplicate-step.js.map +1 -1
  24. package/src/lib/jobs/ai-job-import-step.d.ts +4 -2
  25. package/src/lib/jobs/ai-job-import-step.js +15 -11
  26. package/src/lib/jobs/ai-job-import-step.js.map +1 -1
  27. package/src/lib/jobs/ai-job-insight-step.d.ts +10 -0
  28. package/src/lib/jobs/ai-job-insight-step.js +23 -5
  29. package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
  30. package/src/lib/jobs/ai-job-layout-language.js +2 -1
  31. package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
  32. package/src/lib/jobs/ai-job-media-step.d.ts +2 -1
  33. package/src/lib/jobs/ai-job-media-step.js +6 -8
  34. package/src/lib/jobs/ai-job-media-step.js.map +1 -1
  35. package/src/lib/jobs/ai-job-navigation-step.d.ts +2 -1
  36. package/src/lib/jobs/ai-job-navigation-step.js +7 -9
  37. package/src/lib/jobs/ai-job-navigation-step.js.map +1 -1
  38. package/src/lib/jobs/ai-job-page-language.js +7 -1
  39. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  40. package/src/lib/jobs/ai-job-page-sections.js +16 -3
  41. package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
  42. package/src/lib/jobs/ai-job-page-step.js +9 -1
  43. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  44. package/src/lib/jobs/ai-job-plan-step.d.ts +30 -8
  45. package/src/lib/jobs/ai-job-plan-step.js +78 -13
  46. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  47. package/src/lib/jobs/ai-job-privacy-step.d.ts +4 -2
  48. package/src/lib/jobs/ai-job-privacy-step.js +14 -15
  49. package/src/lib/jobs/ai-job-privacy-step.js.map +1 -1
  50. package/src/lib/jobs/ai-job-products-step.js +5 -3
  51. package/src/lib/jobs/ai-job-products-step.js.map +1 -1
  52. package/src/lib/jobs/ai-job-settings-step.d.ts +2 -1
  53. package/src/lib/jobs/ai-job-settings-step.js +7 -8
  54. package/src/lib/jobs/ai-job-settings-step.js.map +1 -1
  55. package/src/lib/jobs/ai-job-site-content.d.ts +34 -1
  56. package/src/lib/jobs/ai-job-site-content.js +67 -8
  57. package/src/lib/jobs/ai-job-site-content.js.map +1 -1
  58. package/src/lib/jobs/ai-job-site-datasets.d.ts +53 -3
  59. package/src/lib/jobs/ai-job-site-datasets.js +298 -30
  60. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  61. package/src/lib/jobs/ai-job-site-step.js +6 -3
  62. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  63. package/src/lib/jobs/ai-job-site-store-pages.js +3 -3
  64. package/src/lib/jobs/ai-job-site-store-pages.js.map +1 -1
  65. package/src/lib/jobs/ai-job-tracking-step.d.ts +2 -1
  66. package/src/lib/jobs/ai-job-tracking-step.js +7 -8
  67. package/src/lib/jobs/ai-job-tracking-step.js.map +1 -1
  68. package/src/lib/jobs/ai-jobs-beat.d.ts +11 -7
  69. package/src/lib/jobs/ai-jobs-beat.js +18 -8
  70. package/src/lib/jobs/ai-jobs-beat.js.map +1 -1
  71. package/src/lib/jobs/ai-jobs-notify.d.ts +66 -1
  72. package/src/lib/jobs/ai-jobs-notify.js +136 -3
  73. package/src/lib/jobs/ai-jobs-notify.js.map +1 -1
  74. package/src/lib/jobs/ai-layout-stock-photos.d.ts +59 -4
  75. package/src/lib/jobs/ai-layout-stock-photos.js +897 -81
  76. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  77. package/src/lib/jobs/ai-product-image.d.ts +14 -0
  78. package/src/lib/jobs/ai-product-image.js +73 -21
  79. package/src/lib/jobs/ai-product-image.js.map +1 -1
  80. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +9 -1
  81. package/src/lib/jobs/ai-theme-brand-inputs.js +28 -2
  82. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
  83. package/src/lib/jobs/fixtures/ai-site-agl4065-datasets.d.ts +175 -0
  84. package/src/lib/jobs/fixtures/ai-site-agl4065-datasets.js +601 -0
  85. package/src/lib/jobs/fixtures/ai-site-agl4065-datasets.js.map +1 -0
  86. package/src/lib/jobs/fixtures/ai-site-agl4065-pages.d.ts +46 -0
  87. package/src/lib/jobs/fixtures/ai-site-agl4065-pages.js +2862 -0
  88. package/src/lib/jobs/fixtures/ai-site-agl4065-pages.js.map +1 -0
  89. package/src/lib/jobs/fixtures/ai-site-agl4065-plans.d.ts +74 -0
  90. package/src/lib/jobs/fixtures/ai-site-agl4065-plans.js +888 -0
  91. package/src/lib/jobs/fixtures/ai-site-agl4065-plans.js.map +1 -0
  92. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-judge.d.ts +29 -0
  93. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-judge.js +81 -0
  94. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-judge.js.map +1 -0
  95. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-recordings.d.ts +87 -0
  96. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-recordings.js +225 -0
  97. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-recordings.js.map +1 -0
  98. package/src/lib/layout-language/ai-layout-compiler.d.ts +11 -0
  99. package/src/lib/layout-language/ai-layout-compiler.js +194 -18
  100. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  101. package/src/lib/layout-language/ai-layout-copy.d.ts +37 -0
  102. package/src/lib/layout-language/ai-layout-copy.js +383 -3
  103. package/src/lib/layout-language/ai-layout-copy.js.map +1 -1
  104. package/src/lib/layout-language/ai-layout-design.d.ts +19 -0
  105. package/src/lib/layout-language/ai-layout-design.js +31 -11
  106. package/src/lib/layout-language/ai-layout-design.js.map +1 -1
  107. package/src/lib/layout-language/ai-layout-listings.d.ts +7 -1
  108. package/src/lib/layout-language/ai-layout-listings.js +9 -1
  109. package/src/lib/layout-language/ai-layout-listings.js.map +1 -1
  110. package/src/lib/layout-language/ai-layout-pictures.d.ts +30 -0
  111. package/src/lib/layout-language/ai-layout-pictures.js +131 -3
  112. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  113. package/src/lib/layout-language/ai-layout-storefront.d.ts +18 -4
  114. package/src/lib/layout-language/ai-layout-storefront.js +100 -20
  115. package/src/lib/layout-language/ai-layout-storefront.js.map +1 -1
  116. package/src/lib/model/ai-build-job.d.ts +7 -0
  117. package/src/lib/model/ai-build-job.js +36 -7
  118. package/src/lib/model/ai-build-job.js.map +1 -1
  119. package/src/lib/model/ai-build-plan.d.ts +28 -4
  120. package/src/lib/model/ai-build-plan.js +49 -9
  121. package/src/lib/model/ai-build-plan.js.map +1 -1
  122. package/src/lib/model/ai-build-progress.js +3 -1
  123. package/src/lib/model/ai-build-progress.js.map +1 -1
  124. package/src/lib/model/ai-job-notice.d.ts +8 -0
  125. package/src/lib/model/ai-job-notice.js +33 -0
  126. package/src/lib/model/ai-job-notice.js.map +1 -1
  127. package/src/lib/model/ai-job-plan-lines.d.ts +2 -1
  128. package/src/lib/model/ai-job-plan-lines.js +6 -1
  129. package/src/lib/model/ai-job-plan-lines.js.map +1 -1
  130. package/src/lib/model/ai-jobs.types.d.ts +8 -0
  131. package/src/lib/model/ai-jobs.types.js.map +1 -1
  132. package/src/lib/model/ai-permissions.d.ts +13 -0
  133. package/src/lib/model/ai-permissions.js +29 -1
  134. package/src/lib/model/ai-permissions.js.map +1 -1
  135. package/src/lib/model/ai-products.d.ts +18 -0
  136. package/src/lib/model/ai-products.js +32 -0
  137. package/src/lib/model/ai-products.js.map +1 -1
  138. package/src/lib/model/ai-site-inspiration.d.ts +3 -2
  139. package/src/lib/model/ai-site-inspiration.js +3 -2
  140. package/src/lib/model/ai-site-inspiration.js.map +1 -1
  141. package/src/lib/plugin.js +4 -13
  142. package/src/lib/plugin.js.map +1 -1
  143. package/src/lib/providers/anthropic.js +9 -2
  144. package/src/lib/providers/anthropic.js.map +1 -1
  145. package/src/lib/providers/catalog.js +14 -5
  146. package/src/lib/providers/catalog.js.map +1 -1
  147. package/src/lib/providers/contract.d.ts +24 -1
  148. package/src/lib/providers/contract.js.map +1 -1
  149. package/src/lib/providers/routing.js +5 -2
  150. package/src/lib/providers/routing.js.map +1 -1
  151. package/src/lib/runtime/ai-dataset-generation.d.ts +99 -1
  152. package/src/lib/runtime/ai-dataset-generation.js +251 -3
  153. package/src/lib/runtime/ai-dataset-generation.js.map +1 -1
  154. package/src/lib/runtime/ai-dev-replay.d.ts +1 -0
  155. package/src/lib/runtime/ai-dev-replay.js +4 -2
  156. package/src/lib/runtime/ai-dev-replay.js.map +1 -1
  157. package/src/lib/runtime/ai-doctrine-validators.d.ts +47 -3
  158. package/src/lib/runtime/ai-doctrine-validators.js +343 -27
  159. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  160. package/src/lib/runtime/ai-doctrine.js +8 -2
  161. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  162. package/src/lib/runtime/ai-icon-library.d.ts +27 -1
  163. package/src/lib/runtime/ai-icon-library.js +30 -3
  164. package/src/lib/runtime/ai-icon-library.js.map +1 -1
  165. package/src/lib/runtime/ai-products-generation.d.ts +11 -1
  166. package/src/lib/runtime/ai-products-generation.js +51 -4
  167. package/src/lib/runtime/ai-products-generation.js.map +1 -1
  168. package/src/lib/runtime/assist-answer-cache.d.ts +2 -0
  169. package/src/lib/runtime/assist-answer-cache.js +5 -2
  170. package/src/lib/runtime/assist-answer-cache.js.map +1 -1
  171. package/src/lib/server/ai-allotments.js +7 -2
  172. package/src/lib/server/ai-allotments.js.map +1 -1
  173. package/src/lib/server/ai-experiment-versions.js +5 -5
  174. package/src/lib/server/ai-experiment-versions.js.map +1 -1
  175. package/src/lib/server/ai-host-permissions-roster.d.ts +25 -0
  176. package/src/lib/server/ai-host-permissions-roster.js +33 -0
  177. package/src/lib/server/ai-host-permissions-roster.js.map +1 -0
  178. package/src/lib/server/ai-host-permissions.js +8 -6
  179. package/src/lib/server/ai-host-permissions.js.map +1 -1
  180. package/src/lib/server/ai-image-reads-route.d.ts +17 -0
  181. package/src/lib/server/ai-image-reads-route.js +106 -0
  182. package/src/lib/server/ai-image-reads-route.js.map +1 -0
  183. package/src/lib/server/ai-seo-apply.js +5 -5
  184. package/src/lib/server/ai-seo-apply.js.map +1 -1
  185. package/src/lib/server/ai-site-import-route.js +7 -4
  186. package/src/lib/server/ai-site-import-route.js.map +1 -1
  187. package/src/lib/server/assist-build.js +1 -0
  188. package/src/lib/server/assist-build.js.map +1 -1
  189. package/src/lib/server/assist-chat.d.ts +11 -7
  190. package/src/lib/server/assist-chat.js +185 -48
  191. package/src/lib/server/assist-chat.js.map +1 -1
  192. package/src/lib/server/assist-docs-query.d.ts +51 -0
  193. package/src/lib/server/assist-docs-query.js +57 -0
  194. package/src/lib/server/assist-docs-query.js.map +1 -0
  195. package/src/lib/server/assist-jobs-context.d.ts +102 -0
  196. package/src/lib/server/assist-jobs-context.js +227 -0
  197. package/src/lib/server/assist-jobs-context.js.map +1 -0
  198. package/src/lib/server/assist-view-context.d.ts +8 -4
  199. package/src/lib/server/assist-view-context.js +12 -7
  200. package/src/lib/server/assist-view-context.js.map +1 -1
  201. package/src/lib/server.js +12 -0
  202. package/src/lib/server.js.map +1 -1
  203. package/src/lib/tools/ai-dataset-tool.d.ts +11 -1
  204. package/src/lib/tools/ai-dataset-tool.js +24 -7
  205. package/src/lib/tools/ai-dataset-tool.js.map +1 -1
  206. package/src/lib/tools/ai-duplicate-resource-tool.js +5 -6
  207. package/src/lib/tools/ai-duplicate-resource-tool.js.map +1 -1
  208. package/src/lib/components/ai-collaborator-permissions-column.component.d.ts +0 -32
  209. package/src/lib/components/ai-collaborator-permissions-column.component.js +0 -132
  210. package/src/lib/components/ai-collaborator-permissions-column.component.js.map +0 -1
@@ -99,7 +99,10 @@ function formSectionOf(sections, plan, targets) {
99
99
  pictures: 0,
100
100
  features: 0,
101
101
  splitAt: -2,
102
- quotesOnly: []
102
+ quotesOnly: [],
103
+ drawnBands: [],
104
+ bare: 0,
105
+ rhythm: 0
103
106
  };
104
107
  const roots = plan.sections.map((_, index)=>{
105
108
  var _sections_index;
@@ -136,12 +139,58 @@ function formSectionOf(sections, plan, targets) {
136
139
  return AI_ICON_LIBRARY.sparkle;
137
140
  }
138
141
  // ── A section ─────────────────────────────────────────────────────────────
139
- function compileSection(page, raw, index) {
140
- var _raw_band, _ref, _page_targets_listings, _ref1;
141
- var _raw_blocks_find, _page_plan_sections_index, _placedHere_, _page_plan_sections_index_name, _page_plan_sections_index1, _page_options_sectionIds;
142
+ /** The listings whose element shows each record's picture: products, posts and events (AGL-4065). */ const PICTURED_LISTINGS = new Set([
143
+ 'products',
144
+ 'posts',
145
+ 'events'
146
+ ]);
147
+ /**
148
+ * A section drawn, and what the next one reads of it (AGL-4065): the band it
149
+ * was drawn in, and whether it showed a picture — its own, a stand-in, a
150
+ * record's photo or a listing that shows its records' pictures.
151
+ */ function compileSection(page, raw, index) {
152
+ var _page, _drawnBands, _page_targets_listings, _page_bare;
153
+ const scope = sectionScope(page, raw, index);
154
+ const id = drawSection(page, raw, index, scope);
155
+ (_drawnBands = (_page = page).drawnBands) != null ? _drawnBands : _page.drawnBands = [];
156
+ page.drawnBands[index] = scope.band;
157
+ const listed = aiLayoutListingAt((_page_targets_listings = page.targets.listings) != null ? _page_targets_listings : [], page.targets.pageId, index);
158
+ const pictured = !!listed && PICTURED_LISTINGS.has(listed.listing.kind) || holdsPicture(page.tree, id);
159
+ page.bare = pictured ? 0 : ((_page_bare = page.bare) != null ? _page_bare : 0) + 1;
160
+ return id;
161
+ }
162
+ /** Whether a compiled part holds an Image anywhere under it. */ function holdsPicture(tree, id) {
163
+ var _node_nodes;
164
+ const node = tree.nodes[id];
165
+ if (!node) return false;
166
+ return node.componentId === 'image' || ((_node_nodes = node.nodes) != null ? _node_nodes : []).some((child)=>holdsPicture(tree, child));
167
+ }
168
+ /**
169
+ * The band a section is drawn in where the site's design keeps a rhythm
170
+ * (AGL-4065): on a `plain` rhythm one ground, every soft band plain; on an
171
+ * `alternate` rhythm the model's bands, except a plain or soft band that
172
+ * would meet the same band above it, which takes the other. Brand and dark
173
+ * bands, and the first section's, are the model's.
174
+ */ function rhythmBand(page, index, band) {
175
+ var _page_drawnBands;
176
+ if (!page.design || index === 0 || band !== 'plain' && band !== 'soft') return band;
177
+ if (page.design.choices.bandRhythm === 'plain') return 'plain';
178
+ const above = (_page_drawnBands = page.drawnBands) == null ? void 0 : _page_drawnBands[index - 1];
179
+ if (above !== band) return band;
180
+ return band === 'plain' ? 'soft' : 'plain';
181
+ }
182
+ function sectionScope(page, raw, index) {
183
+ var _raw_band, _ref;
184
+ var _page_design, _raw_blocks_find, _page_plan_sections_index;
142
185
  const at = `sections[${index}]`;
143
- const band = settleBand(page, (_raw_band = raw.band) != null ? _raw_band : 'plain', at);
144
- const scope = {
186
+ const asked = (_raw_band = raw.band) != null ? _raw_band : 'plain';
187
+ const ruled = rhythmBand(page, index, asked);
188
+ if (ruled !== asked) page.settled.push({
189
+ at: `${at}.band`,
190
+ what: `drawn ${ruled}: the page's ${(_page_design = page.design) == null ? void 0 : _page_design.choices.bandRhythm} band rhythm`
191
+ });
192
+ const band = settleBand(page, ruled, at);
193
+ return {
145
194
  page,
146
195
  index,
147
196
  at,
@@ -164,6 +213,11 @@ function compileSection(page, raw, index) {
164
213
  })
165
214
  ].join(' ')
166
215
  };
216
+ }
217
+ function drawSection(page, raw, index, scope) {
218
+ var _page_targets_listings, _ref;
219
+ var _placedHere_, _page_plan_sections_index_name, _page_plan_sections_index, _page_options_sectionIds;
220
+ const { at, band } = scope;
167
221
  // A quote is a gap the owner fills, and a published page shows no gap (AGL-3660).
168
222
  const blocks = placePlanned(scope, raw).filter((block)=>{
169
223
  if (block.kind !== 'quotes') return true;
@@ -185,8 +239,11 @@ function compileSection(page, raw, index) {
185
239
  // through the element that keeps them, around the words the design gave it (AGL-3676).
186
240
  const listed = aiLayoutListingAt((_page_targets_listings = page.targets.listings) != null ? _page_targets_listings : [], page.targets.pageId, index);
187
241
  if (listed) return listingSection(scope, blocks, listed);
188
- // The site's design draws the sections it has an arrangement for (AGL-3660).
242
+ // The site's design draws the sections it has an arrangement for (AGL-3660),
243
+ // the third band in a row with no picture beside one (AGL-4065).
189
244
  if (page.design) {
245
+ const beside = rhythmSection(scope, raw, blocks);
246
+ if (beside) return beside;
190
247
  const designed = designSection(scope, raw, blocks);
191
248
  if (designed) return designed;
192
249
  }
@@ -336,13 +393,13 @@ function compileSection(page, raw, index) {
336
393
  }
337
394
  }
338
395
  if (!parts.length) {
339
- var _page_plan_sections_index2;
396
+ var _page_plan_sections_index1;
340
397
  // Nothing the design gave this section could be shown: it keeps its
341
398
  // place on the page under the name its plan gives it.
342
399
  const fallback = compileFlow(scope, [
343
400
  {
344
401
  kind: 'heading',
345
- text: ((_page_plan_sections_index2 = page.plan.sections[index]) == null ? void 0 : _page_plan_sections_index2.name) || page.plan.title
402
+ text: ((_page_plan_sections_index1 = page.plan.sections[index]) == null ? void 0 : _page_plan_sections_index1.name) || page.plan.title
346
403
  }
347
404
  ], 'full');
348
405
  if (fallback) parts.push(fallback);
@@ -364,7 +421,7 @@ function compileSection(page, raw, index) {
364
421
  }, [
365
422
  content
366
423
  ], 'container');
367
- const name = ((_page_plan_sections_index1 = page.plan.sections[index]) == null ? void 0 : (_page_plan_sections_index_name = _page_plan_sections_index1.name) == null ? void 0 : _page_plan_sections_index_name.trim()) || `Section ${index + 1}`;
424
+ const name = ((_page_plan_sections_index = page.plan.sections[index]) == null ? void 0 : (_page_plan_sections_index_name = _page_plan_sections_index.name) == null ? void 0 : _page_plan_sections_index_name.trim()) || `Section ${index + 1}`;
368
425
  return tree.add('section', _extends({
369
426
  element: 'section',
370
427
  ariaLabel: sectionLabel(name, index, page.options.language)
@@ -372,7 +429,7 @@ function compileSection(page, raw, index) {
372
429
  colorScheme: 'dark'
373
430
  } : {}), bandSx(band), [
374
431
  container
375
- ], 'section', (_ref1 = (_page_options_sectionIds = page.options.sectionIds) == null ? void 0 : _page_options_sectionIds[index]) != null ? _ref1 : sectionIdOf(index));
432
+ ], 'section', (_ref = (_page_options_sectionIds = page.options.sectionIds) == null ? void 0 : _page_options_sectionIds[index]) != null ? _ref : sectionIdOf(index));
376
433
  }
377
434
  /**
378
435
  * A component block's prop values as a card item: its title-like prop as the
@@ -2203,6 +2260,119 @@ function instances(scope, placed, items, perRow) {
2203
2260
  container
2204
2261
  ], bandSx(scope.band), scope.band === 'dark');
2205
2262
  }
2263
+ /** The most sections a page sets beside a photo for being the third in a row with none (AGL-4065). */ const AI_LAYOUT_RHYTHM_MOST = 2;
2264
+ /** What the compiler notes of a section it set beside a photo for the page's rhythm (AGL-4065). */ export const AI_LAYOUT_RHYTHM_NOTE = 'drawn beside a photo: third text-only band';
2265
+ /**
2266
+ * NO THREE TEXT-ONLY BANDS IN A ROW (AGL-4065). The booth-kit trades homes
2267
+ * of 2026-10-25 stacked their middles as bands of words with no picture —
2268
+ * Holeshot Moto Repair's numbered steps, its repair list and its reasons to
2269
+ * trust the shop, one under another. On a page drawn with a design, whose
2270
+ * stand-in pictures the stock library fills, a section that would be the
2271
+ * third in a row to show no picture is set beside one instead: its words
2272
+ * and its items in one half, a photo of its heading's subject in the other,
2273
+ * the side turning as the design's own photo-led sections turn. At most
2274
+ * twice a page, and only where the page has a picture left.
2275
+ *
2276
+ * A section of words or of one group of cards or lines qualifies. Steps,
2277
+ * questions and figures read best as text and stay so; a section with a
2278
+ * picture, a form, a component or a row of columns of its own is drawn as
2279
+ * designed; a group the design draws as pictures, articles or a menu
2280
+ * already is one; and the page's closing call to action is the design's to
2281
+ * draw (`coverClose`). `null` leaves the section to the design.
2282
+ */ function rhythmSection(scope, raw, blocks) {
2283
+ var _page_bare, _page_rhythm, _ref, _scope_words, _page_rhythm1;
2284
+ var _group_items;
2285
+ const { page, index } = scope;
2286
+ const design = page.design;
2287
+ if (!design || index === 0 || ((_page_bare = page.bare) != null ? _page_bare : 0) < 2 || ((_page_rhythm = page.rhythm) != null ? _page_rhythm : 0) >= AI_LAYOUT_RHYTHM_MOST || picturesLeft(page) < 1) return null;
2288
+ if (raw.cols && raw.cols.length >= 2) return null;
2289
+ const words = blocks.filter((block)=>WORD_KINDS.has(block.kind));
2290
+ const groups = blocks.filter((block)=>!WORD_KINDS.has(block.kind));
2291
+ if (groups.length > 1 || !words.some((block)=>speaksHeading(scope, block))) return null;
2292
+ const group = groups[0];
2293
+ if (group && (group.kind !== 'cards' && group.kind !== 'list' || group.to || ((_ref = (_group_items = group.items) == null ? void 0 : _group_items.length) != null ? _ref : 0) > 6)) return null;
2294
+ if ((group == null ? void 0 : group.kind) === 'cards' && group.style !== 'quiet' && aiLayoutGroupVariant(design.input, design.choices, (_scope_words = scope.words) != null ? _scope_words : '') !== design.choices.group) return null;
2295
+ const last = index === page.plan.sections.length - 1;
2296
+ if (last && words.some((block)=>block.kind === 'button')) return null;
2297
+ if (!group) {
2298
+ var _page_rhythm2;
2299
+ // A section of words the design already sets beside a photo needs no rule.
2300
+ if (!words.some((block)=>block.kind === 'text' || block.kind === 'lede') || design.choices.features && page.features < 2) return null;
2301
+ page.rhythm = ((_page_rhythm2 = page.rhythm) != null ? _page_rhythm2 : 0) + 1;
2302
+ page.settled.push({
2303
+ at: scope.at,
2304
+ what: AI_LAYOUT_RHYTHM_NOTE
2305
+ });
2306
+ return feature(scope, words);
2307
+ }
2308
+ page.rhythm = ((_page_rhythm1 = page.rhythm) != null ? _page_rhythm1 : 0) + 1;
2309
+ page.settled.push({
2310
+ at: scope.at,
2311
+ what: AI_LAYOUT_RHYTHM_NOTE
2312
+ });
2313
+ return featureGroup(scope, words, group);
2314
+ }
2315
+ /**
2316
+ * A section's words and its one group beside a picture of its subject
2317
+ * (AGL-4065): the words over the items in the wider half, the photo at 4:3
2318
+ * in the other, on the side the design's photo-led sections turn to next.
2319
+ */ function featureGroup(scope, words, group) {
2320
+ const { page } = scope;
2321
+ const design = page.design;
2322
+ const left = design.choices.featureLeft !== (page.features % 2 === 1);
2323
+ page.features += 1;
2324
+ scope.centered = false;
2325
+ // The heading and its words open the half, the group under them, any button last.
2326
+ const flow = compileFlow(scope, [
2327
+ ...words.filter((block)=>block.kind !== 'button'),
2328
+ group,
2329
+ ...words.filter((block)=>block.kind === 'button')
2330
+ ], 'half');
2331
+ const photo = designPicture(scope, {
2332
+ alt: standInAlt(scope),
2333
+ given: false
2334
+ }, {
2335
+ aspectRatio: '4 / 3',
2336
+ borderRadius: 2
2337
+ });
2338
+ const row = designRow(scope, left ? [
2339
+ {
2340
+ id: photo,
2341
+ size: 'xs:12 md:5'
2342
+ },
2343
+ {
2344
+ id: flow,
2345
+ size: 'xs:12 md:7'
2346
+ }
2347
+ ] : [
2348
+ {
2349
+ id: flow,
2350
+ size: 'xs:12 md:7'
2351
+ },
2352
+ {
2353
+ id: photo,
2354
+ size: 'xs:12 md:5'
2355
+ }
2356
+ ], '8');
2357
+ const container = page.tree.add('muiContainer', {
2358
+ maxWidth: 'lg'
2359
+ }, {
2360
+ py: _extends({}, SECTION_PADDING)
2361
+ }, [
2362
+ row
2363
+ ], 'container');
2364
+ return designedRoot(scope, [
2365
+ container
2366
+ ], bandSx(scope.band), scope.band === 'dark');
2367
+ }
2368
+ /**
2369
+ * The variant a designed group's item title takes (AGL-4065): the heading
2370
+ * style it names, or — where the site's seed sets its titles as labels — the
2371
+ * theme's own overline, spaced capitals over the item's words.
2372
+ */ function itemTitleVariant(scope, heading) {
2373
+ var _scope_page_design;
2374
+ return ((_scope_page_design = scope.page.design) == null ? void 0 : _scope_page_design.choices.headingCase) === 'caps' ? 'overline' : heading;
2375
+ }
2206
2376
  /** A heading beside its items: the words in a narrow column, the items ruled in the wide one. */ function splitSection(scope, head, group, tail) {
2207
2377
  const { page } = scope;
2208
2378
  scope.centered = false;
@@ -2296,7 +2466,7 @@ function instances(scope, placed, items, perRow) {
2296
2466
  }, null, [
2297
2467
  item.title.trim() ? tree.add('muiTypography', {
2298
2468
  children: aiLayoutWords(item.title, 'itemTitle', facts, scope.page.options.language),
2299
- variant: 'h5',
2469
+ variant: itemTitleVariant(scope, 'h5'),
2300
2470
  component: itemElement(scope)
2301
2471
  }, null, null, 'title') : null,
2302
2472
  item.text.trim() ? tree.add('muiTypography', {
@@ -2330,7 +2500,7 @@ function instances(scope, placed, items, perRow) {
2330
2500
  const ids = items.map((item)=>tree.add('muiStack', {
2331
2501
  spacing: '1'
2332
2502
  }, null, [
2333
- title(item),
2503
+ title(item, itemTitleVariant(scope, 'h5')),
2334
2504
  words(item)
2335
2505
  ], 'ruled'));
2336
2506
  return ruledList(scope, noted(scope, ids), 'ruledItems');
@@ -2344,7 +2514,7 @@ function instances(scope, placed, items, perRow) {
2344
2514
  }, {
2345
2515
  pt: 2.5
2346
2516
  }, [
2347
- title(item),
2517
+ title(item, itemTitleVariant(scope, 'h5')),
2348
2518
  words(item)
2349
2519
  ], 'ruledWords')
2350
2520
  ], 'ruled'));
@@ -2816,13 +2986,19 @@ function listingSection(scope, blocks, placed) {
2816
2986
  * A storefront's reasons to buy as open columns, each led by an icon over its
2817
2987
  * title and words (AGL-3676): the icon the design named for it, else one its
2818
2988
  * words suggest (shipping a truck, returns the arrows, small batch the hand),
2819
- * never the same twice in a row. One style key an element, so a row repeats
2820
- * no multi-key inline style (rule 16).
2989
+ * else one neutral icon along the row; a row of places ("Areas we serve")
2990
+ * shows the place marker for every place (AGL-4065). One style key an
2991
+ * element, so a row repeats no multi-key inline style (rule 16).
2821
2992
  */ function iconColumns(scope, items, room) {
2993
+ var _scope_words;
2822
2994
  const { page } = scope;
2823
2995
  const tree = page.tree;
2824
2996
  const facts = page.targets.facts;
2825
- const iconWords = aiStorefrontItemIcons(items, (word)=>!!aiIconOfWord(word));
2997
+ const iconWords = aiStorefrontItemIcons(items, (word)=>!!aiIconOfWord(word), _extends({
2998
+ section: (_scope_words = scope.words) != null ? _scope_words : ''
2999
+ }, page.design ? {
3000
+ kind: page.design.input.kind
3001
+ } : {}));
2826
3002
  const perRow = across(items.length, room, 'cards');
2827
3003
  const textAlign = scope.centered ? {
2828
3004
  align: 'center'
@@ -2845,7 +3021,7 @@ function listingSection(scope, blocks, placed) {
2845
3021
  }, accent(scope), null, 'icon'),
2846
3022
  item.title.trim() ? tree.add('muiTypography', _extends({
2847
3023
  children: aiLayoutWords(item.title, 'itemTitle', facts, scope.page.options.language),
2848
- variant: 'h6',
3024
+ variant: itemTitleVariant(scope, 'h6'),
2849
3025
  component: itemElement(scope)
2850
3026
  }, textAlign), null, null, 'title') : null,
2851
3027
  item.text.trim() ? tree.add('muiTypography', _extends({