@aglyn/plugins-ai 1.0.0-beta.261 → 1.0.0-beta.263

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 (90) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/ai-brief-dialog.component.d.ts +21 -58
  3. package/src/lib/components/ai-brief-dialog.component.js +8 -132
  4. package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
  5. package/src/lib/components/ai-job-follow.component.js +2 -35
  6. package/src/lib/components/ai-job-follow.component.js.map +1 -1
  7. package/src/lib/components/ai-job-plan.component.d.ts +2 -8
  8. package/src/lib/components/ai-job-plan.component.js +13 -74
  9. package/src/lib/components/ai-job-plan.component.js.map +1 -1
  10. package/src/lib/components/ai-template-collection-field.component.d.ts +2 -12
  11. package/src/lib/components/ai-template-collection-field.component.js +13 -10
  12. package/src/lib/components/ai-template-collection-field.component.js.map +1 -1
  13. package/src/lib/components/ai-upsell-dialog.component.d.ts +3 -25
  14. package/src/lib/components/ai-upsell-dialog.component.js +9 -66
  15. package/src/lib/components/ai-upsell-dialog.component.js.map +1 -1
  16. package/src/lib/components/use-ai-job-run.d.ts +3 -8
  17. package/src/lib/components/use-ai-job-run.js +4 -15
  18. package/src/lib/components/use-ai-job-run.js.map +1 -1
  19. package/src/lib/insights/ai-figure-readers.js +15 -5
  20. package/src/lib/insights/ai-figure-readers.js.map +1 -1
  21. package/src/lib/insights/ai-figure-summaries.d.ts +27 -0
  22. package/src/lib/insights/ai-figure-summaries.js +96 -0
  23. package/src/lib/insights/ai-figure-summaries.js.map +1 -0
  24. package/src/lib/insights/ai-insight-digest.d.ts +2 -0
  25. package/src/lib/insights/ai-insight-digest.js +7 -4
  26. package/src/lib/insights/ai-insight-digest.js.map +1 -1
  27. package/src/lib/insights/ai-insight-readers.d.ts +2 -1
  28. package/src/lib/insights/ai-insight-readers.js +11 -26
  29. package/src/lib/insights/ai-insight-readers.js.map +1 -1
  30. package/src/lib/jobs/ai-job-insight-step.d.ts +1 -1
  31. package/src/lib/jobs/ai-job-insight-step.js +5 -3
  32. package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
  33. package/src/lib/jobs/ai-job-page-language.d.ts +2 -0
  34. package/src/lib/jobs/ai-job-page-language.js +23 -2
  35. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  36. package/src/lib/jobs/ai-job-plan-step.d.ts +14 -1
  37. package/src/lib/jobs/ai-job-plan-step.js +44 -9
  38. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  39. package/src/lib/jobs/ai-jobs-notify.d.ts +8 -1
  40. package/src/lib/jobs/ai-jobs-notify.js +44 -2
  41. package/src/lib/jobs/ai-jobs-notify.js.map +1 -1
  42. package/src/lib/jobs/ai-layout-stock-photos.js +11 -1
  43. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  44. package/src/lib/layout-language/ai-layout-compiler.js +18 -7
  45. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  46. package/src/lib/layout-language/ai-layout-promised-copy.d.ts +54 -0
  47. package/src/lib/layout-language/ai-layout-promised-copy.js +104 -0
  48. package/src/lib/layout-language/ai-layout-promised-copy.js.map +1 -0
  49. package/src/lib/model/ai-brief-copy.d.ts +85 -0
  50. package/src/lib/model/ai-brief-copy.js +152 -0
  51. package/src/lib/model/ai-brief-copy.js.map +1 -0
  52. package/src/lib/model/ai-create-view.d.ts +200 -0
  53. package/src/lib/model/ai-create-view.js +263 -0
  54. package/src/lib/model/ai-create-view.js.map +1 -0
  55. package/src/lib/model/ai-insight.d.ts +10 -1
  56. package/src/lib/model/ai-insight.js +16 -39
  57. package/src/lib/model/ai-insight.js.map +1 -1
  58. package/src/lib/model/ai-job-activity.d.ts +24 -0
  59. package/src/lib/model/ai-job-activity.js +52 -1
  60. package/src/lib/model/ai-job-activity.js.map +1 -1
  61. package/src/lib/model/ai-job-notice.d.ts +7 -1
  62. package/src/lib/model/ai-job-notice.js +10 -9
  63. package/src/lib/model/ai-job-notice.js.map +1 -1
  64. package/src/lib/model/ai-job-plan-lines.d.ts +46 -0
  65. package/src/lib/model/ai-job-plan-lines.js +70 -0
  66. package/src/lib/model/ai-job-plan-lines.js.map +1 -0
  67. package/src/lib/model/ai-plan-said-sections.d.ts +81 -0
  68. package/src/lib/model/ai-plan-said-sections.js +168 -0
  69. package/src/lib/model/ai-plan-said-sections.js.map +1 -0
  70. package/src/lib/model/ai-site-job.d.ts +8 -2
  71. package/src/lib/model/ai-site-job.js +7 -1
  72. package/src/lib/model/ai-site-job.js.map +1 -1
  73. package/src/lib/model/ai-template-collections.d.ts +28 -0
  74. package/src/lib/model/ai-template-collections.js +28 -0
  75. package/src/lib/model/ai-template-collections.js.map +1 -0
  76. package/src/lib/model/ai-upsell-copy.d.ts +41 -0
  77. package/src/lib/model/ai-upsell-copy.js +85 -0
  78. package/src/lib/model/ai-upsell-copy.js.map +1 -0
  79. package/src/lib/runtime/ai-doctrine-validators.d.ts +15 -1
  80. package/src/lib/runtime/ai-doctrine-validators.js +96 -3
  81. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  82. package/src/lib/runtime/ai-eval-memory-firestore.js +2 -0
  83. package/src/lib/runtime/ai-eval-memory-firestore.js.map +1 -1
  84. package/src/lib/runtime/ai-palette.generated.js +11 -3
  85. package/src/lib/runtime/ai-palette.generated.js.map +1 -1
  86. package/src/lib/server/ai-create-route.d.ts +32 -0
  87. package/src/lib/server/ai-create-route.js +295 -0
  88. package/src/lib/server/ai-create-route.js.map +1 -0
  89. package/src/lib/server.js +14 -0
  90. package/src/lib/server.js.map +1 -1
@@ -487,6 +487,16 @@ export declare function isAiLinkElement(componentId: unknown): boolean;
487
487
  * a re-ask to inherit the band's contrast text or to set it.
488
488
  */
489
489
  export declare function detectInvisibleLinks(tree: AiDoctrineTree, outputKind: AiOutputKind): AiDoctrineViolation[];
490
+ /**
491
+ * Rule 5, for words on a colored band (AGL-3886). A theme's `text.*` colors
492
+ * are made for its page background: on a band in `primary.main` they are two
493
+ * valid tokens that cannot be read. A live gym site's "How your first week
494
+ * works" band, in an olive brand color, drew each step's words under its
495
+ * title in the muted text color, about 1.6:1. Words whose color is a page
496
+ * text color, and a List Item Text's secondary words left muted, on such a
497
+ * band are refused, with a re-ask for the band's contrast text.
498
+ */
499
+ export declare function detectPageTextOnBands(tree: AiDoctrineTree, outputKind: AiOutputKind): AiDoctrineViolation[];
490
500
  /**
491
501
  * Whether a link's words ask a visitor to get in touch — contact, book, quote,
492
502
  * request, order, pre-order, enquire — which the site's form answers
@@ -820,7 +830,11 @@ export declare function aiSettleCutHeadings(input: unknown): unknown;
820
830
  * which is what the re-ask asks for;
821
831
  * - `link-color-on-band` (5): a link or a button whose words are drawn in its
822
832
  * band's own family is given that family's contrast text as its `sx` color,
823
- * which is what the re-ask asks for.
833
+ * which is what the re-ask asks for;
834
+ * - `page-text-on-band` (5): words on a band in a family's main or dark shade
835
+ * whose `sx` color is a page text color (`text.secondary`) are given the
836
+ * family's contrast text, and a List Item Text's secondary words there take
837
+ * the row's own color (`secondaryColor: inherit`).
824
838
  *
825
839
  * A tree with nothing to settle comes back as the same object, so settling is
826
840
  * idempotent; a node that is changed is copied, never edited in place.
@@ -642,6 +642,15 @@ const COLOR_KEYWORDS = new Set([
642
642
  const LITERAL_COLOR = /#[0-9a-f]{3,8}\b|\b(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\s*\(|\b(?:black|white|red|green|blue|yellow|orange|purple|pink|gray|grey|brown|cyan|magenta|navy|teal|maroon|olive|lime|aqua|silver|gold|indigo|violet|beige|coral|crimson|salmon|tomato|turquoise|khaki|lavender|ivory|azure)\b/i;
643
643
  const LENGTH_WITH_UNIT = /-?\d*\.?\d+\s*(?:px|rem|em|pt|vh|vw|ch)\b/i;
644
644
  const paletteTokens = new Set(AI_SX_TOKENS.palette);
645
+ /**
646
+ * A color written as a value — a hex code or a color function — and never a
647
+ * color WORD. Plan prose names things in words: a photographer's "Blue Ridge
648
+ * elopements" or "Black and white portraits" is a place and a style, not a
649
+ * color, and the live 2026-10-16 guided start was refused for it (AGL-3864).
650
+ */ const LITERAL_COLOR_VALUE = /#[0-9a-f]{3,8}\b|\b(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\s*\(/i;
651
+ /** Whether plan prose writes a color by value: a hex code or a color function. */ function proseHasLiteralColor(value) {
652
+ return typeof value === 'string' && LITERAL_COLOR_VALUE.test(value);
653
+ }
645
654
  /** Whether a value names a color by value rather than by theme token. */ function hasLiteralColor(value) {
646
655
  if (typeof value !== 'string') return false;
647
656
  const parts = value.trim().split(/\s+/).filter((part)=>!paletteTokens.has(part) && !COLOR_KEYWORDS.has(part.toLowerCase()));
@@ -1846,6 +1855,65 @@ const GRID = 'muiGrid';
1846
1855
  }
1847
1856
  ];
1848
1857
  }
1858
+ /** The text colors a theme makes for its page background, which a band in a brand color does not share. */ const PAGE_TEXT_COLORS = new Set([
1859
+ 'text.primary',
1860
+ 'text.secondary',
1861
+ 'text.disabled'
1862
+ ]);
1863
+ /**
1864
+ * The words on a colored band drawn in a color made for the page background:
1865
+ * an element whose `sx` color is a `text.*` token, and a List Item Text's
1866
+ * secondary words, which MUI draws in `text.secondary` unless the element's
1867
+ * `secondaryColor` is `inherit`. A band is one `bandOf` names in a family's
1868
+ * main or dark shade; its light shade sits close to the page, where the
1869
+ * page's text colors still read.
1870
+ */ function pageTextOnBands(tree, outputKind) {
1871
+ if (outputKind === 'email' || outputKind === 'form') return [];
1872
+ const found = [];
1873
+ for (const visit of walkTree(tree)){
1874
+ var _node_sx, _node_props, _node_props1;
1875
+ const { node } = visit;
1876
+ const ownColor = (_node_sx = node.sx) == null ? void 0 : _node_sx['color'];
1877
+ const pageColored = ownColor !== undefined && sxValues(ownColor).some((value)=>typeof value === 'string' && PAGE_TEXT_COLORS.has(value.trim()));
1878
+ const secondary = (_node_props = node.props) == null ? void 0 : _node_props['secondary'];
1879
+ const mutedSecondary = node.componentId === 'muiListItemText' && typeof secondary === 'string' && secondary.trim() !== '' && ((_node_props1 = node.props) == null ? void 0 : _node_props1['secondaryColor']) !== 'inherit';
1880
+ if (!pageColored && !mutedSecondary) continue;
1881
+ const band = bandOf(tree, visit);
1882
+ if (!band || band.token.endsWith('.light')) continue;
1883
+ if (pageColored) found.push(_extends({
1884
+ id: visit.id
1885
+ }, band, {
1886
+ part: 'sx'
1887
+ }));
1888
+ if (mutedSecondary) found.push(_extends({
1889
+ id: visit.id
1890
+ }, band, {
1891
+ part: 'secondary'
1892
+ }));
1893
+ }
1894
+ return found;
1895
+ }
1896
+ /**
1897
+ * Rule 5, for words on a colored band (AGL-3886). A theme's `text.*` colors
1898
+ * are made for its page background: on a band in `primary.main` they are two
1899
+ * valid tokens that cannot be read. A live gym site's "How your first week
1900
+ * works" band, in an olive brand color, drew each step's words under its
1901
+ * title in the muted text color, about 1.6:1. Words whose color is a page
1902
+ * text color, and a List Item Text's secondary words left muted, on such a
1903
+ * band are refused, with a re-ask for the band's contrast text.
1904
+ */ export function detectPageTextOnBands(tree, outputKind) {
1905
+ const hidden = pageTextOnBands(tree, outputKind);
1906
+ if (!hidden.length) return [];
1907
+ const [first] = hidden;
1908
+ return [
1909
+ {
1910
+ rule: 5,
1911
+ code: 'page-text-on-band',
1912
+ message: `Words on a ${first.token} band are drawn in a text color made for the page's background, so they cannot be read. Set their sx color to ${first.family}.contrastText, and give a List Item Text with secondary words on the band "secondaryColor": "inherit".`,
1913
+ nodeIds: unique(hidden.map((entry)=>entry.id))
1914
+ }
1915
+ ];
1916
+ }
1849
1917
  /** A link's words that say it goes home. */ const HOME_WORDS = /\bhome(?:\s?page)?\b/i;
1850
1918
  /** A label's words, lowercase, for comparing one label with another. */ const labelWords = (label)=>label.toLowerCase().split(RegExp("[^\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088F\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5C-\\u0C5D\\u0C60-\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDC-\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C8A\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5-\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183-\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3006\\u3031-\\u3035\\u303B-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7DC\\uA7F1-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD-\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC\\u{10000}-\\u{1000B}\\u{1000D}-\\u{10026}\\u{10028}-\\u{1003A}\\u{1003C}-\\u{1003D}\\u{1003F}-\\u{1004D}\\u{10050}-\\u{1005D}\\u{10080}-\\u{100FA}\\u{10280}-\\u{1029C}\\u{102A0}-\\u{102D0}\\u{10300}-\\u{1031F}\\u{1032D}-\\u{10340}\\u{10342}-\\u{10349}\\u{10350}-\\u{10375}\\u{10380}-\\u{1039D}\\u{103A0}-\\u{103C3}\\u{103C8}-\\u{103CF}\\u{10400}-\\u{1049D}\\u{104B0}-\\u{104D3}\\u{104D8}-\\u{104FB}\\u{10500}-\\u{10527}\\u{10530}-\\u{10563}\\u{10570}-\\u{1057A}\\u{1057C}-\\u{1058A}\\u{1058C}-\\u{10592}\\u{10594}-\\u{10595}\\u{10597}-\\u{105A1}\\u{105A3}-\\u{105B1}\\u{105B3}-\\u{105B9}\\u{105BB}-\\u{105BC}\\u{105C0}-\\u{105F3}\\u{10600}-\\u{10736}\\u{10740}-\\u{10755}\\u{10760}-\\u{10767}\\u{10780}-\\u{10785}\\u{10787}-\\u{107B0}\\u{107B2}-\\u{107BA}\\u{10800}-\\u{10805}\\u{10808}\\u{1080A}-\\u{10835}\\u{10837}-\\u{10838}\\u{1083C}\\u{1083F}-\\u{10855}\\u{10860}-\\u{10876}\\u{10880}-\\u{1089E}\\u{108E0}-\\u{108F2}\\u{108F4}-\\u{108F5}\\u{10900}-\\u{10915}\\u{10920}-\\u{10939}\\u{10940}-\\u{10959}\\u{10980}-\\u{109B7}\\u{109BE}-\\u{109BF}\\u{10A00}\\u{10A10}-\\u{10A13}\\u{10A15}-\\u{10A17}\\u{10A19}-\\u{10A35}\\u{10A60}-\\u{10A7C}\\u{10A80}-\\u{10A9C}\\u{10AC0}-\\u{10AC7}\\u{10AC9}-\\u{10AE4}\\u{10B00}-\\u{10B35}\\u{10B40}-\\u{10B55}\\u{10B60}-\\u{10B72}\\u{10B80}-\\u{10B91}\\u{10C00}-\\u{10C48}\\u{10C80}-\\u{10CB2}\\u{10CC0}-\\u{10CF2}\\u{10D00}-\\u{10D23}\\u{10D4A}-\\u{10D65}\\u{10D6F}-\\u{10D85}\\u{10E80}-\\u{10EA9}\\u{10EB0}-\\u{10EB1}\\u{10EC2}-\\u{10EC7}\\u{10F00}-\\u{10F1C}\\u{10F27}\\u{10F30}-\\u{10F45}\\u{10F70}-\\u{10F81}\\u{10FB0}-\\u{10FC4}\\u{10FE0}-\\u{10FF6}\\u{11003}-\\u{11037}\\u{11071}-\\u{11072}\\u{11075}\\u{11083}-\\u{110AF}\\u{110D0}-\\u{110E8}\\u{11103}-\\u{11126}\\u{11144}\\u{11147}\\u{11150}-\\u{11172}\\u{11176}\\u{11183}-\\u{111B2}\\u{111C1}-\\u{111C4}\\u{111DA}\\u{111DC}\\u{11200}-\\u{11211}\\u{11213}-\\u{1122B}\\u{1123F}-\\u{11240}\\u{11280}-\\u{11286}\\u{11288}\\u{1128A}-\\u{1128D}\\u{1128F}-\\u{1129D}\\u{1129F}-\\u{112A8}\\u{112B0}-\\u{112DE}\\u{11305}-\\u{1130C}\\u{1130F}-\\u{11310}\\u{11313}-\\u{11328}\\u{1132A}-\\u{11330}\\u{11332}-\\u{11333}\\u{11335}-\\u{11339}\\u{1133D}\\u{11350}\\u{1135D}-\\u{11361}\\u{11380}-\\u{11389}\\u{1138B}\\u{1138E}\\u{11390}-\\u{113B5}\\u{113B7}\\u{113D1}\\u{113D3}\\u{11400}-\\u{11434}\\u{11447}-\\u{1144A}\\u{1145F}-\\u{11461}\\u{11480}-\\u{114AF}\\u{114C4}-\\u{114C5}\\u{114C7}\\u{11580}-\\u{115AE}\\u{115D8}-\\u{115DB}\\u{11600}-\\u{1162F}\\u{11644}\\u{11680}-\\u{116AA}\\u{116B8}\\u{11700}-\\u{1171A}\\u{11740}-\\u{11746}\\u{11800}-\\u{1182B}\\u{118A0}-\\u{118DF}\\u{118FF}-\\u{11906}\\u{11909}\\u{1190C}-\\u{11913}\\u{11915}-\\u{11916}\\u{11918}-\\u{1192F}\\u{1193F}\\u{11941}\\u{119A0}-\\u{119A7}\\u{119AA}-\\u{119D0}\\u{119E1}\\u{119E3}\\u{11A00}\\u{11A0B}-\\u{11A32}\\u{11A3A}\\u{11A50}\\u{11A5C}-\\u{11A89}\\u{11A9D}\\u{11AB0}-\\u{11AF8}\\u{11BC0}-\\u{11BE0}\\u{11C00}-\\u{11C08}\\u{11C0A}-\\u{11C2E}\\u{11C40}\\u{11C72}-\\u{11C8F}\\u{11D00}-\\u{11D06}\\u{11D08}-\\u{11D09}\\u{11D0B}-\\u{11D30}\\u{11D46}\\u{11D60}-\\u{11D65}\\u{11D67}-\\u{11D68}\\u{11D6A}-\\u{11D89}\\u{11D98}\\u{11DB0}-\\u{11DDB}\\u{11EE0}-\\u{11EF2}\\u{11F02}\\u{11F04}-\\u{11F10}\\u{11F12}-\\u{11F33}\\u{11FB0}\\u{12000}-\\u{12399}\\u{12480}-\\u{12543}\\u{12F90}-\\u{12FF0}\\u{13000}-\\u{1342F}\\u{13441}-\\u{13446}\\u{13460}-\\u{143FA}\\u{14400}-\\u{14646}\\u{16100}-\\u{1611D}\\u{16800}-\\u{16A38}\\u{16A40}-\\u{16A5E}\\u{16A70}-\\u{16ABE}\\u{16AD0}-\\u{16AED}\\u{16B00}-\\u{16B2F}\\u{16B40}-\\u{16B43}\\u{16B63}-\\u{16B77}\\u{16B7D}-\\u{16B8F}\\u{16D40}-\\u{16D6C}\\u{16E40}-\\u{16E7F}\\u{16EA0}-\\u{16EB8}\\u{16EBB}-\\u{16ED3}\\u{16F00}-\\u{16F4A}\\u{16F50}\\u{16F93}-\\u{16F9F}\\u{16FE0}-\\u{16FE1}\\u{16FE3}\\u{16FF2}-\\u{16FF3}\\u{17000}-\\u{18CD5}\\u{18CFF}-\\u{18D1E}\\u{18D80}-\\u{18DF2}\\u{1AFF0}-\\u{1AFF3}\\u{1AFF5}-\\u{1AFFB}\\u{1AFFD}-\\u{1AFFE}\\u{1B000}-\\u{1B122}\\u{1B132}\\u{1B150}-\\u{1B152}\\u{1B155}\\u{1B164}-\\u{1B167}\\u{1B170}-\\u{1B2FB}\\u{1BC00}-\\u{1BC6A}\\u{1BC70}-\\u{1BC7C}\\u{1BC80}-\\u{1BC88}\\u{1BC90}-\\u{1BC99}\\u{1D400}-\\u{1D454}\\u{1D456}-\\u{1D49C}\\u{1D49E}-\\u{1D49F}\\u{1D4A2}\\u{1D4A5}-\\u{1D4A6}\\u{1D4A9}-\\u{1D4AC}\\u{1D4AE}-\\u{1D4B9}\\u{1D4BB}\\u{1D4BD}-\\u{1D4C3}\\u{1D4C5}-\\u{1D505}\\u{1D507}-\\u{1D50A}\\u{1D50D}-\\u{1D514}\\u{1D516}-\\u{1D51C}\\u{1D51E}-\\u{1D539}\\u{1D53B}-\\u{1D53E}\\u{1D540}-\\u{1D544}\\u{1D546}\\u{1D54A}-\\u{1D550}\\u{1D552}-\\u{1D6A5}\\u{1D6A8}-\\u{1D6C0}\\u{1D6C2}-\\u{1D6DA}\\u{1D6DC}-\\u{1D6FA}\\u{1D6FC}-\\u{1D714}\\u{1D716}-\\u{1D734}\\u{1D736}-\\u{1D74E}\\u{1D750}-\\u{1D76E}\\u{1D770}-\\u{1D788}\\u{1D78A}-\\u{1D7A8}\\u{1D7AA}-\\u{1D7C2}\\u{1D7C4}-\\u{1D7CB}\\u{1DF00}-\\u{1DF1E}\\u{1DF25}-\\u{1DF2A}\\u{1E030}-\\u{1E06D}\\u{1E100}-\\u{1E12C}\\u{1E137}-\\u{1E13D}\\u{1E14E}\\u{1E290}-\\u{1E2AD}\\u{1E2C0}-\\u{1E2EB}\\u{1E4D0}-\\u{1E4EB}\\u{1E5D0}-\\u{1E5ED}\\u{1E5F0}\\u{1E6C0}-\\u{1E6DE}\\u{1E6E0}-\\u{1E6E2}\\u{1E6E4}-\\u{1E6E5}\\u{1E6E7}-\\u{1E6ED}\\u{1E6F0}-\\u{1E6F4}\\u{1E6FE}-\\u{1E6FF}\\u{1E7E0}-\\u{1E7E6}\\u{1E7E8}-\\u{1E7EB}\\u{1E7ED}-\\u{1E7EE}\\u{1E7F0}-\\u{1E7FE}\\u{1E800}-\\u{1E8C4}\\u{1E900}-\\u{1E943}\\u{1E94B}\\u{1EE00}-\\u{1EE03}\\u{1EE05}-\\u{1EE1F}\\u{1EE21}-\\u{1EE22}\\u{1EE24}\\u{1EE27}\\u{1EE29}-\\u{1EE32}\\u{1EE34}-\\u{1EE37}\\u{1EE39}\\u{1EE3B}\\u{1EE42}\\u{1EE47}\\u{1EE49}\\u{1EE4B}\\u{1EE4D}-\\u{1EE4F}\\u{1EE51}-\\u{1EE52}\\u{1EE54}\\u{1EE57}\\u{1EE59}\\u{1EE5B}\\u{1EE5D}\\u{1EE5F}\\u{1EE61}-\\u{1EE62}\\u{1EE64}\\u{1EE67}-\\u{1EE6A}\\u{1EE6C}-\\u{1EE72}\\u{1EE74}-\\u{1EE77}\\u{1EE79}-\\u{1EE7C}\\u{1EE7E}\\u{1EE80}-\\u{1EE89}\\u{1EE8B}-\\u{1EE9B}\\u{1EEA1}-\\u{1EEA3}\\u{1EEA5}-\\u{1EEA9}\\u{1EEAB}-\\u{1EEBB}\\u{20000}-\\u{2A6DF}\\u{2A700}-\\u{2B81D}\\u{2B820}-\\u{2CEAD}\\u{2CEB0}-\\u{2EBE0}\\u{2EBF0}-\\u{2EE5D}\\u{2F800}-\\u{2FA1D}\\u{30000}-\\u{3134A}\\u{31350}-\\u{33479}\\u0030-\\u0039\\u00B2-\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D58-\\u0D5E\\u0D66-\\u0D78\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19\\u{10107}-\\u{10133}\\u{10140}-\\u{10178}\\u{1018A}-\\u{1018B}\\u{102E1}-\\u{102FB}\\u{10320}-\\u{10323}\\u{10341}\\u{1034A}\\u{103D1}-\\u{103D5}\\u{104A0}-\\u{104A9}\\u{10858}-\\u{1085F}\\u{10879}-\\u{1087F}\\u{108A7}-\\u{108AF}\\u{108FB}-\\u{108FF}\\u{10916}-\\u{1091B}\\u{109BC}-\\u{109BD}\\u{109C0}-\\u{109CF}\\u{109D2}-\\u{109FF}\\u{10A40}-\\u{10A48}\\u{10A7D}-\\u{10A7E}\\u{10A9D}-\\u{10A9F}\\u{10AEB}-\\u{10AEF}\\u{10B58}-\\u{10B5F}\\u{10B78}-\\u{10B7F}\\u{10BA9}-\\u{10BAF}\\u{10CFA}-\\u{10CFF}\\u{10D30}-\\u{10D39}\\u{10D40}-\\u{10D49}\\u{10E60}-\\u{10E7E}\\u{10F1D}-\\u{10F26}\\u{10F51}-\\u{10F54}\\u{10FC5}-\\u{10FCB}\\u{11052}-\\u{1106F}\\u{110F0}-\\u{110F9}\\u{11136}-\\u{1113F}\\u{111D0}-\\u{111D9}\\u{111E1}-\\u{111F4}\\u{112F0}-\\u{112F9}\\u{11450}-\\u{11459}\\u{114D0}-\\u{114D9}\\u{11650}-\\u{11659}\\u{116C0}-\\u{116C9}\\u{116D0}-\\u{116E3}\\u{11730}-\\u{1173B}\\u{118E0}-\\u{118F2}\\u{11950}-\\u{11959}\\u{11BF0}-\\u{11BF9}\\u{11C50}-\\u{11C6C}\\u{11D50}-\\u{11D59}\\u{11DA0}-\\u{11DA9}\\u{11DE0}-\\u{11DE9}\\u{11F50}-\\u{11F59}\\u{11FC0}-\\u{11FD4}\\u{12400}-\\u{1246E}\\u{16130}-\\u{16139}\\u{16A60}-\\u{16A69}\\u{16AC0}-\\u{16AC9}\\u{16B50}-\\u{16B59}\\u{16B5B}-\\u{16B61}\\u{16D70}-\\u{16D79}\\u{16E80}-\\u{16E96}\\u{16FF4}-\\u{16FF6}\\u{1CCF0}-\\u{1CCF9}\\u{1D2C0}-\\u{1D2D3}\\u{1D2E0}-\\u{1D2F3}\\u{1D360}-\\u{1D378}\\u{1D7CE}-\\u{1D7FF}\\u{1E140}-\\u{1E149}\\u{1E2F0}-\\u{1E2F9}\\u{1E4F0}-\\u{1E4F9}\\u{1E5F1}-\\u{1E5FA}\\u{1E8C7}-\\u{1E8CF}\\u{1E950}-\\u{1E959}\\u{1EC71}-\\u{1ECAB}\\u{1ECAD}-\\u{1ECAF}\\u{1ECB1}-\\u{1ECB4}\\u{1ED01}-\\u{1ED2D}\\u{1ED2F}-\\u{1ED3D}\\u{1F100}-\\u{1F10C}\\u{1FBF0}-\\u{1FBF9}]+", "u")).filter(Boolean).join(' ');
1851
1919
  /** Words that ask a visitor to get in touch, which the site's form answers. */ const GET_IN_TOUCH_WORDS = /\b(?:contact|book|booking|call|quote|estimate|appointment|schedule|reserve|reservation|get in touch|request|visit|enquire|inquire|enquiry|inquiry|message|talk|consult|consultation|order|pre-?order|sign up|join|apply|start)\b/i;
@@ -3377,7 +3445,11 @@ const BUDGET_METRICS = [
3377
3445
  * which is what the re-ask asks for;
3378
3446
  * - `link-color-on-band` (5): a link or a button whose words are drawn in its
3379
3447
  * band's own family is given that family's contrast text as its `sx` color,
3380
- * which is what the re-ask asks for.
3448
+ * which is what the re-ask asks for;
3449
+ * - `page-text-on-band` (5): words on a band in a family's main or dark shade
3450
+ * whose `sx` color is a page text color (`text.secondary`) are given the
3451
+ * family's contrast text, and a List Item Text's secondary words there take
3452
+ * the row's own color (`secondaryColor: inherit`).
3381
3453
  *
3382
3454
  * A tree with nothing to settle comes back as the same object, so settling is
3383
3455
  * idempotent; a node that is changed is copied, never edited in place.
@@ -3500,6 +3572,21 @@ const BUDGET_METRICS = [
3500
3572
  color: `${family}.contrastText`
3501
3573
  });
3502
3574
  }
3575
+ // Rule 5: words on a band in the band's contrast text, and a list's secondary words in the row's own color.
3576
+ for (const { id, family, part } of pageTextOnBands({
3577
+ rootId: tree.rootId,
3578
+ nodes
3579
+ }, outputKind)){
3580
+ var _node_sx3;
3581
+ if (part === 'secondary') {
3582
+ setProp(id, 'secondaryColor', 'inherit');
3583
+ continue;
3584
+ }
3585
+ const node = edit(id);
3586
+ node.sx = _extends({}, (_node_sx3 = node.sx) != null ? _node_sx3 : {}, {
3587
+ color: `${family}.contrastText`
3588
+ });
3589
+ }
3503
3590
  }
3504
3591
  return copied.size ? _extends({}, tree, {
3505
3592
  nodes
@@ -3594,6 +3681,7 @@ const BUDGET_METRICS = [
3594
3681
  ...detectInlineForms(tree, outputKind),
3595
3682
  ...detectLiteralStyles(tree, outputKind),
3596
3683
  ...detectInvisibleLinks(tree, outputKind),
3684
+ ...detectPageTextOnBands(tree, outputKind),
3597
3685
  ...detectOffBrandEmail(tree, outputKind, context.brand),
3598
3686
  ...detectTypedData(tree),
3599
3687
  ...detectUnfilledInstances(tree, context),
@@ -4513,12 +4601,12 @@ const FORM_SECTION_NAME = /\bform\b|\bsign[- ]?up\b|\bsubscribe\b|\bnewsletter\b
4513
4601
  const paths = [];
4514
4602
  plan.create.forEach((entry, index)=>{
4515
4603
  if (entry.kind === 'theme-change') return;
4516
- if (hasLiteralColor(entry.why) || entry.fields.some(hasLiteralColor)) {
4604
+ if (proseHasLiteralColor(entry.why) || entry.fields.some(proseHasLiteralColor)) {
4517
4605
  paths.push(`create[${index}]`);
4518
4606
  }
4519
4607
  });
4520
4608
  for (const { section, path } of sectionPaths(plan)){
4521
- if (hasLiteralColor(section.name)) paths.push(path);
4609
+ if (proseHasLiteralColor(section.name)) paths.push(path);
4522
4610
  }
4523
4611
  return paths.length ? [
4524
4612
  {
@@ -4766,6 +4854,11 @@ const NEWSLETTER_NAME = /\bnewsletter\b|\bsubscribe\b|\bsign[- ]?up\b/i;
4766
4854
  ].includes(String(refKind(ref, plan, kinds))));
4767
4855
  if (bindsData) continue;
4768
4856
  if (section.items >= AI_TYPED_LIST_MIN_ITEMS) typed.push(path);
4857
+ // A form section COLLECTS what its dataset holds; it never copies it
4858
+ // (AGL-3864). A workspace whose other site made a "Consultation
4859
+ // requests" dataset refused a new law firm's "Consultation requests" form.
4860
+ const collects = FORM_SECTION_NAME.test(section.name) || section.uses.some((ref)=>refKind(ref, plan, kinds) === 'form');
4861
+ if (collects) continue;
4769
4862
  const match = data.find((row)=>aiNamesMatch(row.name, section.name));
4770
4863
  if (match) unbound.push({
4771
4864
  path,