create-ailk 0.13.0 → 0.14.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 (113) hide show
  1. package/README.md +12 -4
  2. package/component-catalog.json +247 -33
  3. package/component-catalog.md +10 -6
  4. package/dist/apply-design.d.ts +21 -2
  5. package/dist/apply-design.js +120 -19
  6. package/dist/cli.js +1 -0
  7. package/dist/design-compile.d.ts +70 -2
  8. package/dist/design-compile.js +97 -1
  9. package/dist/design-home.d.ts +74 -0
  10. package/dist/design-home.js +256 -0
  11. package/dist/design-package.d.ts +39 -2
  12. package/dist/design-package.js +223 -9
  13. package/dist/design-presets.d.ts +17 -1
  14. package/dist/design-presets.js +17 -5
  15. package/dist/design-scaffold.d.ts +6 -25
  16. package/dist/design-scaffold.js +26 -74
  17. package/dist/index.d.ts +1 -0
  18. package/dist/lib/design-checks.d.ts +12 -1
  19. package/dist/lib/design-checks.js +38 -2
  20. package/dist/lib/module-license-gate.d.ts +9 -0
  21. package/dist/lib/module-license-gate.js +18 -0
  22. package/dist/programmatic.js +70 -26
  23. package/dist/site-chrome.d.ts +38 -0
  24. package/dist/site-chrome.js +109 -2
  25. package/dist/site-fonts.d.ts +21 -0
  26. package/dist/site-fonts.js +54 -0
  27. package/dist/site-roster.d.ts +16 -0
  28. package/dist/site-roster.js +81 -0
  29. package/dist/starter-grid.js +15 -0
  30. package/dist/surfaces.js +12 -0
  31. package/dist/team-profiles.d.ts +29 -0
  32. package/dist/team-profiles.js +43 -0
  33. package/package.json +3 -3
  34. package/release-scope.json +1 -1
  35. package/site-templates/_base/content/en/TeamList/team.mdx +68 -0
  36. package/site-templates/_base/content/en/TeamMember/first-member.mdx +22 -0
  37. package/site-templates/_base/content/en/TeamMember/second-member.mdx +22 -0
  38. package/site-templates/_base/content/en/TeamMember/third-member.mdx +22 -0
  39. package/site-templates/designs/minimalism/DESIGN.md +164 -34
  40. package/site-templates/designs/minimalism/home/local-business-service.mdx +119 -0
  41. package/site-templates/designs/minimalism/home/organization-product.mdx +132 -0
  42. package/site-templates/designs/minimalism/home/organization-service.mdx +131 -0
  43. package/site-templates/designs/minimalism/home/person-service.mdx +101 -0
  44. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +34 -1
  45. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +20 -0
  46. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +34 -1
  47. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +22 -1
  48. package/site-templates/marketing-site-free/ailk-template.json +1 -1
  49. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +34 -1
  50. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +26 -7
  51. package/site-templates/shapes/local-business-service/ailk-template.json +1 -1
  52. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +34 -1
  53. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +26 -7
  54. package/site-templates/shapes/organization-service/ailk-template.json +1 -1
  55. package/templates/README.md +2 -0
  56. package/templates/apps/api/CLAUDE.md +4 -1
  57. package/templates/apps/mcp/package.json +1 -1
  58. package/templates/apps/web/CLAUDE.md +11 -0
  59. package/templates/apps/web/app/[locale]/(authed)/account/__tests__/settings.test.tsx +10 -0
  60. package/templates/apps/web/app/[locale]/(authed)/account/settings/__tests__/theme-modes.test.ts +42 -0
  61. package/templates/apps/web/app/[locale]/(authed)/account/settings/theme-modes.ts +8 -0
  62. package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +2 -2
  63. package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +2 -2
  64. package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +14 -1
  65. package/templates/apps/web/app/[locale]/contact/__tests__/site-contact-lines.test.ts +69 -0
  66. package/templates/apps/web/app/[locale]/contact/site-contact-lines.ts +64 -0
  67. package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +4 -4
  68. package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +15 -3
  69. package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +17 -6
  70. package/templates/apps/web/app/[locale]/for/__tests__/page-renderer-migration.test.tsx +14 -1
  71. package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +2 -2
  72. package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +4 -6
  73. package/templates/apps/web/app/[locale]/layout.tsx +156 -53
  74. package/templates/apps/web/app/[locale]/page.tsx +37 -0
  75. package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +2 -2
  76. package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +4 -6
  77. package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +15 -2
  78. package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +43 -6
  79. package/templates/apps/web/app/[locale]/services/page.tsx +14 -2
  80. package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +2 -2
  81. package/templates/apps/web/app/[locale]/team/[slug]/page.tsx +45 -0
  82. package/templates/apps/web/app/[locale]/team/__tests__/team-routes.test.tsx +155 -0
  83. package/templates/apps/web/app/[locale]/team/page.tsx +49 -0
  84. package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +2 -2
  85. package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +14 -1
  86. package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +2 -2
  87. package/templates/apps/web/app/not-found.tsx +47 -0
  88. package/templates/apps/web/lib/__tests__/profile-back-link.test.ts +95 -0
  89. package/templates/apps/web/lib/__tests__/site-theme-head.test.ts +70 -0
  90. package/templates/apps/web/lib/__tests__/site-theme.test.ts +64 -1
  91. package/templates/apps/web/lib/profile-back-link.ts +51 -0
  92. package/templates/apps/web/lib/site-chrome.ts +12 -0
  93. package/templates/apps/web/lib/site-fonts.ts +15 -0
  94. package/templates/apps/web/lib/site-logo.tsx +39 -1
  95. package/templates/apps/web/lib/site-theme-head.ts +33 -0
  96. package/templates/apps/web/lib/site-theme.ts +13 -1
  97. package/templates/apps/web/messages/en.json +7 -1
  98. package/templates/database/CHANGELOG.md +7 -0
  99. package/templates/database/package.json +1 -1
  100. package/versions.json +34 -34
  101. package/site-templates/designs/minimalism/sample/README.md +0 -48
  102. package/site-templates/designs/minimalism/sample/content/en/HomePage/home.mdx +0 -244
  103. package/site-templates/designs/minimalism/sample/public/avatar-placeholder-1.svg +0 -7
  104. package/site-templates/designs/minimalism/sample/public/avatar-placeholder-2.svg +0 -7
  105. package/site-templates/designs/minimalism/sample/public/avatar-placeholder-3.svg +0 -7
  106. package/site-templates/designs/minimalism/sample/public/avatar-placeholder-4.svg +0 -7
  107. package/site-templates/designs/minimalism/sample/public/avatar-placeholder-5.svg +0 -7
  108. package/site-templates/designs/minimalism/sample/public/avatar-placeholder-6.svg +0 -7
  109. package/site-templates/designs/minimalism/sample/public/hero-backdrop.svg +0 -17
  110. package/site-templates/designs/minimalism/sample/public/logo-placeholder-1.svg +0 -6
  111. package/site-templates/designs/minimalism/sample/public/logo-placeholder-2.svg +0 -6
  112. package/site-templates/designs/minimalism/sample/public/logo-placeholder-3.svg +0 -6
  113. package/site-templates/designs/minimalism/sample/public/wordmark-placeholder.svg +0 -28
package/README.md CHANGED
@@ -118,10 +118,18 @@ It changes how the site **looks**, never what it **is**. It writes only:
118
118
  - the `design`, `layout` and `theme` record in `.ailk-site-manifest.json`.
119
119
 
120
120
  It never adds, removes or renames a route or page, never touches a content
121
- field, and leaves every page's structured data unchanged. It prints the files
122
- it changed; running it again changes nothing. A site whose roster is the older
123
- root `TEMPLATE-MANIFEST.json` gets the look but no record, and the report says
124
- so.
121
+ field (except a placeholder home's sections, below), and leaves every other
122
+ page's structured data unchanged. It prints the files it changed; running it
123
+ again changes nothing. A site whose roster is the older root
124
+ `TEMPLATE-MANIFEST.json` gets the look but no record, and the report says so.
125
+
126
+ A design may also seed the home's sections — its home arc, one placeholder
127
+ home per shape (minimalism ships them) — while they are still a placeholder
128
+ home: the shape's own sections, or a design's arc of them. It never changes a
129
+ home whose sections were edited; it reports the home as kept and leaves it
130
+ byte-for-byte. A seeded home takes the design's looks; look values on the
131
+ sections it replaced are not kept. A design with no arc restores the shape's
132
+ own sections on a home that still wears another design's untouched arc.
125
133
 
126
134
  A design other than `standard` needs a Pro or Pro Plus key. The key is read
127
135
  from the site's own `ailk.key` (put one there with
@@ -17,7 +17,7 @@
17
17
  "importPath": "@working-theory/ui/blocks",
18
18
  "rootBarrel": "@working-theory/ui",
19
19
  "sourceRoot": "packages/ui/src/blocks",
20
- "count": 99
20
+ "count": 101
21
21
  },
22
22
  {
23
23
  "name": "chrome",
@@ -49,7 +49,7 @@
49
49
  "importPath": "@working-theory/templates/shells",
50
50
  "rootBarrel": "@working-theory/templates",
51
51
  "sourceRoot": "packages/templates/src/shells",
52
- "count": 6
52
+ "count": 8
53
53
  },
54
54
  {
55
55
  "name": "docs-blog-blocks",
@@ -1068,6 +1068,17 @@
1068
1068
  "descriptionGrade": "strong",
1069
1069
  "sectionType": null
1070
1070
  },
1071
+ {
1072
+ "name": "DisplayList",
1073
+ "tier": "blocks",
1074
+ "sourcePath": "packages/ui/src/blocks/DisplayList.tsx",
1075
+ "importPath": "@working-theory/ui/blocks",
1076
+ "exported": true,
1077
+ "description": "Centred display-size rows of short labels, each optionally a link, with no rules, cards or dividers between them — the bondcap.com \"what we offer\" list and its report archive grid.",
1078
+ "descriptionSource": "doc-comment",
1079
+ "descriptionGrade": "strong",
1080
+ "sectionType": null
1081
+ },
1071
1082
  {
1072
1083
  "name": "DistributionList",
1073
1084
  "tier": "blocks",
@@ -1618,6 +1629,17 @@
1618
1629
  "descriptionGrade": "weak",
1619
1630
  "sectionType": null
1620
1631
  },
1632
+ {
1633
+ "name": "SlideAdvance",
1634
+ "tier": "blocks",
1635
+ "sourcePath": "packages/ui/src/blocks/SlideAdvance.tsx",
1636
+ "importPath": "@working-theory/ui/blocks",
1637
+ "exported": true,
1638
+ "description": "The deck's slide-advance control. One ghost Button holding a hairline chevron: a down chevron moves to the next slide, an up chevron to the first. A native button, so a click, Enter and Space all fire the same move, and nothing else listens: no wheel, touch, scroll or key handler is added, so native scroll-snap still settles every user scroll (the argument against a scroll-hijacking deck).",
1639
+ "descriptionSource": "doc-comment",
1640
+ "descriptionGrade": "strong",
1641
+ "sectionType": null
1642
+ },
1621
1643
  {
1622
1644
  "name": "SocialIcons",
1623
1645
  "tier": "blocks",
@@ -3004,6 +3026,28 @@
3004
3026
  "descriptionGrade": "strong",
3005
3027
  "sectionType": null
3006
3028
  },
3029
+ {
3030
+ "name": "DeckPresentation",
3031
+ "tier": "shells",
3032
+ "sourcePath": "packages/templates/src/shells/DeckPresentation.tsx",
3033
+ "importPath": "@working-theory/templates/shells",
3034
+ "exported": false,
3035
+ "description": "Internal client island for MarketingShell's `presentation` option. Not exported from the shells barrel (`./index.ts`) — MarketingShell renders it internally under `snap=\"mandatory\"` with `presentation`, beside DeckHeroObserver, whose idiom it follows: a zero-size anchor, no React state, and every write made through the DOM after hydration.",
3036
+ "descriptionSource": "doc-comment",
3037
+ "descriptionGrade": "strong",
3038
+ "sectionType": null
3039
+ },
3040
+ {
3041
+ "name": "DeckSlideAdvance",
3042
+ "tier": "shells",
3043
+ "sourcePath": "packages/templates/src/shells/DeckSlideAdvance.tsx",
3044
+ "importPath": "@working-theory/templates/shells",
3045
+ "exported": false,
3046
+ "description": "Internal client island that puts one working slide-advance button at the foot of every slide of MarketingShell's scroll-snap deck: down to the next slide, and up from the last slide back to the first.",
3047
+ "descriptionSource": "doc-comment",
3048
+ "descriptionGrade": "strong",
3049
+ "sectionType": null
3050
+ },
3007
3051
  {
3008
3052
  "name": "MarketingShell",
3009
3053
  "tier": "shells",
@@ -3571,7 +3615,8 @@
3571
3615
  "wash",
3572
3616
  "wash-secondary",
3573
3617
  "gradient-brand",
3574
- "gradient-dark"
3618
+ "gradient-dark",
3619
+ "solid-dark"
3575
3620
  ]
3576
3621
  },
3577
3622
  "quickSearch": {
@@ -4641,6 +4686,9 @@
4641
4686
  },
4642
4687
  "blurDataURL": {
4643
4688
  "type": "string"
4689
+ },
4690
+ "darkSrc": {
4691
+ "type": "string"
4644
4692
  }
4645
4693
  },
4646
4694
  "required": [
@@ -4908,7 +4956,8 @@
4908
4956
  "wash",
4909
4957
  "wash-secondary",
4910
4958
  "gradient-brand",
4911
- "gradient-dark"
4959
+ "gradient-dark",
4960
+ "solid-dark"
4912
4961
  ]
4913
4962
  },
4914
4963
  "headlineSize": {
@@ -4975,6 +5024,25 @@
4975
5024
  "href"
4976
5025
  ]
4977
5026
  }
5027
+ },
5028
+ "align": {
5029
+ "type": "string",
5030
+ "enum": [
5031
+ "start",
5032
+ "center"
5033
+ ]
5034
+ },
5035
+ "phoneColumns": {
5036
+ "anyOf": [
5037
+ {
5038
+ "type": "number",
5039
+ "const": 1
5040
+ },
5041
+ {
5042
+ "type": "number",
5043
+ "const": 2
5044
+ }
5045
+ ]
4978
5046
  }
4979
5047
  },
4980
5048
  "required": [
@@ -4992,7 +5060,9 @@
4992
5060
  "headlineSize",
4993
5061
  "numbered",
4994
5062
  "numberTone",
4995
- "itemTitleSize"
5063
+ "itemTitleSize",
5064
+ "align",
5065
+ "phoneColumns"
4996
5066
  ]
4997
5067
  },
4998
5068
  {
@@ -5010,7 +5080,8 @@
5010
5080
  "branded",
5011
5081
  "minimal",
5012
5082
  "tile",
5013
- "tiles"
5083
+ "tiles",
5084
+ "list"
5014
5085
  ]
5015
5086
  },
5016
5087
  "tileHover": {
@@ -5177,7 +5248,15 @@
5177
5248
  "wash",
5178
5249
  "wash-secondary",
5179
5250
  "gradient-brand",
5180
- "gradient-dark"
5251
+ "gradient-dark",
5252
+ "solid-dark"
5253
+ ]
5254
+ },
5255
+ "itemStyle": {
5256
+ "type": "string",
5257
+ "enum": [
5258
+ "card",
5259
+ "plain"
5181
5260
  ]
5182
5261
  }
5183
5262
  },
@@ -5193,7 +5272,8 @@
5193
5272
  "columns",
5194
5273
  "separation",
5195
5274
  "gap",
5196
- "surface"
5275
+ "surface",
5276
+ "itemStyle"
5197
5277
  ]
5198
5278
  },
5199
5279
  {
@@ -5214,7 +5294,9 @@
5214
5294
  "wide",
5215
5295
  "narrow",
5216
5296
  "media-left",
5217
- "media-right"
5297
+ "media-right",
5298
+ "statement",
5299
+ "profile"
5218
5300
  ]
5219
5301
  },
5220
5302
  "headline": {
@@ -5381,7 +5463,8 @@
5381
5463
  "wash",
5382
5464
  "wash-secondary",
5383
5465
  "gradient-brand",
5384
- "gradient-dark"
5466
+ "gradient-dark",
5467
+ "solid-dark"
5385
5468
  ]
5386
5469
  },
5387
5470
  "align": {
@@ -5391,12 +5474,27 @@
5391
5474
  "center"
5392
5475
  ]
5393
5476
  },
5477
+ "alignMobile": {
5478
+ "type": "string",
5479
+ "enum": [
5480
+ "start",
5481
+ "center"
5482
+ ]
5483
+ },
5394
5484
  "fill": {
5395
5485
  "type": "string",
5396
5486
  "enum": [
5397
5487
  "natural",
5398
5488
  "viewport"
5399
5489
  ]
5490
+ },
5491
+ "actionStyle": {
5492
+ "type": "string",
5493
+ "enum": [
5494
+ "buttons",
5495
+ "one-button",
5496
+ "links"
5497
+ ]
5400
5498
  }
5401
5499
  }
5402
5500
  },
@@ -5408,7 +5506,9 @@
5408
5506
  "glow",
5409
5507
  "surface",
5410
5508
  "align",
5411
- "fill"
5509
+ "alignMobile",
5510
+ "fill",
5511
+ "actionStyle"
5412
5512
  ]
5413
5513
  },
5414
5514
  {
@@ -5541,7 +5641,8 @@
5541
5641
  "wash",
5542
5642
  "wash-secondary",
5543
5643
  "gradient-brand",
5544
- "gradient-dark"
5644
+ "gradient-dark",
5645
+ "solid-dark"
5545
5646
  ]
5546
5647
  },
5547
5648
  "headlineSize": {
@@ -5741,7 +5842,8 @@
5741
5842
  "wash",
5742
5843
  "wash-secondary",
5743
5844
  "gradient-brand",
5744
- "gradient-dark"
5845
+ "gradient-dark",
5846
+ "solid-dark"
5745
5847
  ]
5746
5848
  },
5747
5849
  "headlineSize": {
@@ -5752,6 +5854,13 @@
5752
5854
  "display",
5753
5855
  "heading-3"
5754
5856
  ]
5857
+ },
5858
+ "align": {
5859
+ "type": "string",
5860
+ "enum": [
5861
+ "start",
5862
+ "center"
5863
+ ]
5755
5864
  }
5756
5865
  }
5757
5866
  },
@@ -5766,7 +5875,8 @@
5766
5875
  "answerSize",
5767
5876
  "dividerTone",
5768
5877
  "surface",
5769
- "headlineSize"
5878
+ "headlineSize",
5879
+ "align"
5770
5880
  ]
5771
5881
  },
5772
5882
  {
@@ -6100,7 +6210,8 @@
6100
6210
  "wash",
6101
6211
  "wash-secondary",
6102
6212
  "gradient-brand",
6103
- "gradient-dark"
6213
+ "gradient-dark",
6214
+ "solid-dark"
6104
6215
  ]
6105
6216
  },
6106
6217
  "headlineSize": {
@@ -6111,6 +6222,13 @@
6111
6222
  "display",
6112
6223
  "heading-3"
6113
6224
  ]
6225
+ },
6226
+ "align": {
6227
+ "type": "string",
6228
+ "enum": [
6229
+ "start",
6230
+ "center"
6231
+ ]
6114
6232
  }
6115
6233
  },
6116
6234
  "required": [
@@ -6126,7 +6244,8 @@
6126
6244
  "separation",
6127
6245
  "gap",
6128
6246
  "surface",
6129
- "headlineSize"
6247
+ "headlineSize",
6248
+ "align"
6130
6249
  ]
6131
6250
  },
6132
6251
  {
@@ -6244,7 +6363,8 @@
6244
6363
  "wash",
6245
6364
  "wash-secondary",
6246
6365
  "gradient-brand",
6247
- "gradient-dark"
6366
+ "gradient-dark",
6367
+ "solid-dark"
6248
6368
  ]
6249
6369
  }
6250
6370
  },
@@ -6902,7 +7022,8 @@
6902
7022
  "wash",
6903
7023
  "wash-secondary",
6904
7024
  "gradient-brand",
6905
- "gradient-dark"
7025
+ "gradient-dark",
7026
+ "solid-dark"
6906
7027
  ]
6907
7028
  },
6908
7029
  "keyPointsPanel": {
@@ -7135,7 +7256,8 @@
7135
7256
  "wash",
7136
7257
  "wash-secondary",
7137
7258
  "gradient-brand",
7138
- "gradient-dark"
7259
+ "gradient-dark",
7260
+ "solid-dark"
7139
7261
  ]
7140
7262
  },
7141
7263
  "chips": {
@@ -7157,6 +7279,21 @@
7157
7279
  },
7158
7280
  "imagerySlot": {
7159
7281
  "type": "boolean"
7282
+ },
7283
+ "align": {
7284
+ "type": "string",
7285
+ "enum": [
7286
+ "start",
7287
+ "center"
7288
+ ]
7289
+ },
7290
+ "actionStyle": {
7291
+ "type": "string",
7292
+ "enum": [
7293
+ "buttons",
7294
+ "one-button",
7295
+ "links"
7296
+ ]
7160
7297
  }
7161
7298
  },
7162
7299
  "required": [
@@ -7167,7 +7304,9 @@
7167
7304
  "schemaError": null,
7168
7305
  "look": [
7169
7306
  "variant",
7170
- "surface"
7307
+ "surface",
7308
+ "align",
7309
+ "actionStyle"
7171
7310
  ]
7172
7311
  },
7173
7312
  {
@@ -7231,7 +7370,8 @@
7231
7370
  "type": "string",
7232
7371
  "enum": [
7233
7372
  "color",
7234
- "monochrome"
7373
+ "monochrome",
7374
+ "silhouette"
7235
7375
  ]
7236
7376
  },
7237
7377
  "logoSize": {
@@ -7249,7 +7389,8 @@
7249
7389
  "wash",
7250
7390
  "wash-secondary",
7251
7391
  "gradient-brand",
7252
- "gradient-dark"
7392
+ "gradient-dark",
7393
+ "solid-dark"
7253
7394
  ]
7254
7395
  },
7255
7396
  "actions": {
@@ -7292,6 +7433,57 @@
7292
7433
  "href"
7293
7434
  ]
7294
7435
  }
7436
+ },
7437
+ "columns": {
7438
+ "anyOf": [
7439
+ {
7440
+ "type": "number",
7441
+ "const": 3
7442
+ },
7443
+ {
7444
+ "type": "number",
7445
+ "const": 4
7446
+ },
7447
+ {
7448
+ "type": "number",
7449
+ "const": 5
7450
+ },
7451
+ {
7452
+ "type": "number",
7453
+ "const": 6
7454
+ }
7455
+ ]
7456
+ },
7457
+ "phoneColumns": {
7458
+ "anyOf": [
7459
+ {
7460
+ "type": "number",
7461
+ "const": 1
7462
+ },
7463
+ {
7464
+ "type": "number",
7465
+ "const": 2
7466
+ },
7467
+ {
7468
+ "type": "number",
7469
+ "const": 3
7470
+ }
7471
+ ]
7472
+ },
7473
+ "motion": {
7474
+ "type": "string",
7475
+ "enum": [
7476
+ "static",
7477
+ "scroll"
7478
+ ]
7479
+ },
7480
+ "actionStyle": {
7481
+ "type": "string",
7482
+ "enum": [
7483
+ "buttons",
7484
+ "one-button",
7485
+ "links"
7486
+ ]
7295
7487
  }
7296
7488
  },
7297
7489
  "required": [
@@ -7304,7 +7496,11 @@
7304
7496
  "layout",
7305
7497
  "treatment",
7306
7498
  "logoSize",
7307
- "surface"
7499
+ "surface",
7500
+ "columns",
7501
+ "phoneColumns",
7502
+ "motion",
7503
+ "actionStyle"
7308
7504
  ]
7309
7505
  },
7310
7506
  {
@@ -7593,7 +7789,8 @@
7593
7789
  "wash",
7594
7790
  "wash-secondary",
7595
7791
  "gradient-brand",
7596
- "gradient-dark"
7792
+ "gradient-dark",
7793
+ "solid-dark"
7597
7794
  ]
7598
7795
  }
7599
7796
  },
@@ -8616,7 +8813,8 @@
8616
8813
  "enum": [
8617
8814
  "with-small-images",
8618
8815
  "with-large-images",
8619
- "with-side-images"
8816
+ "with-side-images",
8817
+ "with-portraits"
8620
8818
  ]
8621
8819
  },
8622
8820
  "avatarSize": {
@@ -8681,7 +8879,8 @@
8681
8879
  "wash",
8682
8880
  "wash-secondary",
8683
8881
  "gradient-brand",
8684
- "gradient-dark"
8882
+ "gradient-dark",
8883
+ "solid-dark"
8685
8884
  ]
8686
8885
  },
8687
8886
  "actions": {
@@ -8724,6 +8923,14 @@
8724
8923
  "href"
8725
8924
  ]
8726
8925
  }
8926
+ },
8927
+ "actionStyle": {
8928
+ "type": "string",
8929
+ "enum": [
8930
+ "buttons",
8931
+ "one-button",
8932
+ "links"
8933
+ ]
8727
8934
  }
8728
8935
  },
8729
8936
  "required": [
@@ -8741,7 +8948,8 @@
8741
8948
  "separation",
8742
8949
  "gap",
8743
8950
  "phoneColumns",
8744
- "surface"
8951
+ "surface",
8952
+ "actionStyle"
8745
8953
  ]
8746
8954
  },
8747
8955
  {
@@ -9313,7 +9521,8 @@
9313
9521
  "wash",
9314
9522
  "wash-secondary",
9315
9523
  "gradient-brand",
9316
- "gradient-dark"
9524
+ "gradient-dark",
9525
+ "solid-dark"
9317
9526
  ]
9318
9527
  },
9319
9528
  "successRedirect": {
@@ -10288,7 +10497,8 @@
10288
10497
  "wash",
10289
10498
  "wash-secondary",
10290
10499
  "gradient-brand",
10291
- "gradient-dark"
10500
+ "gradient-dark",
10501
+ "solid-dark"
10292
10502
  ]
10293
10503
  },
10294
10504
  "provider": {
@@ -10711,7 +10921,8 @@
10711
10921
  "wash",
10712
10922
  "wash-secondary",
10713
10923
  "gradient-brand",
10714
- "gradient-dark"
10924
+ "gradient-dark",
10925
+ "solid-dark"
10715
10926
  ]
10716
10927
  }
10717
10928
  },
@@ -11148,7 +11359,8 @@
11148
11359
  "wash",
11149
11360
  "wash-secondary",
11150
11361
  "gradient-brand",
11151
- "gradient-dark"
11362
+ "gradient-dark",
11363
+ "solid-dark"
11152
11364
  ]
11153
11365
  }
11154
11366
  },
@@ -11224,7 +11436,8 @@
11224
11436
  "type": "string",
11225
11437
  "enum": [
11226
11438
  "cards",
11227
- "list"
11439
+ "list",
11440
+ "archive"
11228
11441
  ]
11229
11442
  },
11230
11443
  "tone": {
@@ -11293,7 +11506,8 @@
11293
11506
  "wash",
11294
11507
  "wash-secondary",
11295
11508
  "gradient-brand",
11296
- "gradient-dark"
11509
+ "gradient-dark",
11510
+ "solid-dark"
11297
11511
  ]
11298
11512
  }
11299
11513
  },
@@ -15,13 +15,13 @@ The component inventory of `@working-theory/ui` and the shells of `@working-theo
15
15
  3. Check the Primitives, Panels and Shells tables too — a low-level control, a collapsible layout container, or a route-level frame lives there, not under Sections or Blocks.
16
16
  4. Only then build. If you do build, you are declaring the capability is genuinely absent.
17
17
 
18
- Inventory: **307 component files** across 16 tiers — 55 sections, 99 blocks, 18 chrome, 79 primitives, 6 panels, 6 shells, 5 docs-blog-blocks, 1 docs-blog-chrome, 2 docs-blog-shells, 2 scheduling-sections, 5 scheduling-blocks, 5 signal-collectors-sections, 9 signal-collectors-blocks, 2 commerce-sections, 12 commerce-blocks, 1 commerce-panels. 304 distinct names: `SchedulerEmbed`, `Separator`, `Tabs` exist in more than one tier as genuinely different components, listed once per tier with its own source path.
18
+ Inventory: **311 component files** across 16 tiers — 55 sections, 101 blocks, 18 chrome, 79 primitives, 6 panels, 8 shells, 5 docs-blog-blocks, 1 docs-blog-chrome, 2 docs-blog-shells, 2 scheduling-sections, 5 scheduling-blocks, 5 signal-collectors-sections, 9 signal-collectors-blocks, 2 commerce-sections, 12 commerce-blocks, 1 commerce-panels. 308 distinct names: `SchedulerEmbed`, `Separator`, `Tabs` exist in more than one tier as genuinely different components, listed once per tier with its own source path.
19
19
 
20
- Description coverage: **303/307** components carry a capability description derived from source — 44 from the section registry's hand-authored when-to-use text, 228 from the component's own doc-comment header, 31 from its tier barrel's roster line. **4** have none; they are listed under [Undescribed components](#undescribed-components) rather than given a sentence invented from their name.
20
+ Description coverage: **307/311** components carry a capability description derived from source — 44 from the section registry's hand-authored when-to-use text, 232 from the component's own doc-comment header, 31 from its tier barrel's roster line. **4** have none; they are listed under [Undescribed components](#undescribed-components) rather than given a sentence invented from their name.
21
21
 
22
- Of those, **272** are *strong* — a capability sentence you could match a requirement against — and **31** are *weak*: either one short clause, or a long one that spends itself on wiring (client boundaries, class names, which primitives it composes) instead of on what the thing is for. Weak rows are marked `(weak)` and listed in full under [Weak descriptions](#weak-descriptions). Coverage is 99%, but **findable-without-luck coverage is 89%**.
22
+ Of those, **276** are *strong* — a capability sentence you could match a requirement against — and **31** are *weak*: either one short clause, or a long one that spends itself on wiring (client boundaries, class names, which primitives it composes) instead of on what the thing is for. Weak rows are marked `(weak)` and listed in full under [Weak descriptions](#weak-descriptions). Coverage is 99%, but **findable-without-luck coverage is 89%**.
23
23
 
24
- Per tier, strong out of total: **Sections** 54/55 · **Blocks** 93/99 · **Chrome** 10/18 · **Primitives** 64/79 (4 undescribed) · **Panels** 5/6 · **Shells** 5/6 · **Docs + Blog Blocks** 5/5 · **Docs + Blog Chrome** 1/1 · **Docs + Blog Shells** 0/2 · **Scheduling Sections** 2/2 · **Scheduling Blocks** 5/5 · **Signal-Collectors Sections** 5/5 · **Signal-Collectors Blocks** 8/9 · **Commerce Sections** 2/2 · **Commerce Blocks** 12/12 · **Commerce Panels** 1/1. A tier low on this line is a tier where a capability search is most likely to come up empty on something that exists.
24
+ Per tier, strong out of total: **Sections** 54/55 · **Blocks** 95/101 · **Chrome** 10/18 · **Primitives** 64/79 (4 undescribed) · **Panels** 5/6 · **Shells** 7/8 · **Docs + Blog Blocks** 5/5 · **Docs + Blog Chrome** 1/1 · **Docs + Blog Shells** 0/2 · **Scheduling Sections** 2/2 · **Scheduling Blocks** 5/5 · **Signal-Collectors Sections** 5/5 · **Signal-Collectors Blocks** 8/9 · **Commerce Sections** 2/2 · **Commerce Blocks** 12/12 · **Commerce Panels** 1/1. A tier low on this line is a tier where a capability search is most likely to come up empty on something that exists.
25
25
 
26
26
  That grade is **mechanical**. It counts what it can measure — how much a description adds beyond the component's own name, how much of it is spent on wiring, whether the extraction came out damaged — and it cannot tell a fluent paragraph about the wrong subject from a useful one. A person reading these tables will find more rows unusable than the weak count admits. Treat it as a floor on the problem, not a measurement of it, and read the source before concluding a capability is absent.
27
27
 
@@ -119,7 +119,7 @@ Import: `import { X } from "@working-theory/ui/sections";` (or from the `@workin
119
119
 
120
120
  ---
121
121
 
122
- ## Blocks (99)
122
+ ## Blocks (101)
123
123
 
124
124
  Intermediate composition tiles — the pieces sections are built from. Compose primitives and panels; never import a section.
125
125
 
@@ -158,6 +158,7 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
158
158
  | `DescriptionList` | Semantic <dl> of aligned term/definition rows (rows + inline layouts). A semantic <dl> rendering label/value rows from an `items` prop. Each item is a <dt> (muted term) paired with a <dd> (value). The value is a ReactNode, so callers compose richer values (spans, lists, mono text) inside it. | `import { DescriptionList } from "@working-theory/ui/blocks"` |
159
159
  | `DetailCard` | The collapsible console / data-panel card: a composable card with a header (title + optional actions + collapse toggle), an optional tab bar, a body slot, and an optional footer. The "deferred SidePanel DetailCard" from, built as a general content card any console / detail view can compose without inventing its own card structure. | `import { DetailCard } from "@working-theory/ui/blocks"` |
160
160
  | `DetailHeader` | The entity-bearing sibling of PageHeader: a Breadcrumb wayfinding trail above an EntityHeader identity row, plus a forwarded actions slot. | `import { DetailHeader } from "@working-theory/ui/blocks"` |
161
+ | `DisplayList` | Centred display-size rows of short labels, each optionally a link, with no rules, cards or dividers between them — the bondcap.com "what we offer" list and its report archive grid. | `import { DisplayList } from "@working-theory/ui/blocks"` |
161
162
  | `DistributionList` | Per-option answer-share list over the Progress primitive. One question's answer distribution: a title, an "answered" count line, and one row per declared option (a label, a pre-formatted share `display` string, and a `Progress` bar). `display` is pre-formatted by the caller (Rule 10 — this block never formats numbers itself); `share` drives the `Progress` fill, scaled to the primitive's 0–100 range. | `import { DistributionList } from "@working-theory/ui/blocks"` |
162
163
  | `EntityHeader` | The single identity-row source: an optional leading avatar, a title/name (Heading), an optional subtitle/meta line (Text), an optional type-badge slot above the title, and an optional trailing actions slot. | `import { EntityHeader } from "@working-theory/ui/blocks"` |
163
164
  | `FaqItem` | Q&A pair block for FAQ section families (expanded + accordion). Defaults reproduce the current render except the deliberate item-spacing-asymmetry fix. | `import { FaqItem } from "@working-theory/ui/blocks"` |
@@ -208,6 +209,7 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
208
209
  | `SectionHeader` | Alignment-parameterized section header (eyebrow/subtitle/description/supportLink). The same component serves two ranks (headingLevel="section" \| "subsection") and three alignments (align="start" \| "center" \| "end"). It knows nothing about columns/splits/carousels — it is width-flexible and fills whatever container the section places it in. | `import { SectionHeader } from "@working-theory/ui/blocks"` |
209
210
  | `ShareBar` | The reader-facing counterpart to DocsActionBar. Both surfaces share the same SplitButton *affordance + slot* (outline variant, right-justified on the post title row) but fill it with different actions: DocsActionBar carries the AI-ingestion set (Copy page + Open in …), ShareBar carries the social-share set (X · LinkedIn · Bluesky · Copy link). One primitive, two configs. | `import { ShareBar } from "@working-theory/ui/blocks"` |
210
211
  | `SinglePriceCard` | 2-column split card for the Pricing 'single-price-with-details' variant. *(weak)* | `import { SinglePriceCard } from "@working-theory/ui/blocks"` |
212
+ | `SlideAdvance` | The deck's slide-advance control. One ghost Button holding a hairline chevron: a down chevron moves to the next slide, an up chevron to the first. A native button, so a click, Enter and Space all fire the same move, and nothing else listens: no wheel, touch, scroll or key handler is added, so native scroll-snap still settles every user scroll (the argument against a scroll-hijacking deck). | `import { SlideAdvance } from "@working-theory/ui/blocks"` |
211
213
  | `SocialIcons` | Horizontal row of social icon links. Renders brand icons (via Icon primitive + simple-icons paths) inside accessible Link primitives. Each platform link gets an aria-label. Shared by company-mission, simple-centered, and newsletter-below footer variants, and composed by TeamMemberCard for member social links. *(weak)* | `import { SocialIcons } from "@working-theory/ui/blocks"` |
212
214
  | `SortableList` | The one @dnd-kit/sortable reorder block: mouse, touch and keyboard drag behind a six-dot grip, announced, controlled. `@dnd-kit/sortable` wrapped ONCE behind our six-dot grip. The ONLY file in the monorepo that imports `@dnd-kit/*` — enforced by tests/architecture/no-dnd-kit-outside-sortablelist.test.ts (SD-2). | `import { SortableList } from "@working-theory/ui/blocks"` |
213
215
  | `StatTicker` | Static, horizontally overflow-scrollable workspace stat strip with an optional trailing CTA; no auto-scroll marquee (ploy-capture recomposition). The Overview stat strip captured off ploy.ai (behavior spec: -2, — `overview-ticker` "-viewport"/"-track"/"-segment"/"-value"/"-cta"). | `import { StatTicker } from "@working-theory/ui/blocks"` |
@@ -365,7 +367,7 @@ Import: `import { X } from "@working-theory/ui/panels";` (or from the `@working-
365
367
 
366
368
  ---
367
369
 
368
- ## Shells (6)
370
+ ## Shells (8)
369
371
 
370
372
  Route-level slot-frames — the outermost layout a page is placed into. They supply geometry and slots (nav / sidebar / main / footer), not content: you inject the real Nav, Footer and sidebar. A different package from every tier above: `@working-theory/templates`.
371
373
 
@@ -377,6 +379,8 @@ Import: `import { X } from "@working-theory/templates/shells";` (or from the `@w
377
379
  | `AppShell` | Shared authed-app base frame. Layout ownership: AppShell is the SINGLE owner of the authed sidebar frame layout. The `sidebar` prop is CONTENT (e.g. a <SidebarNav>), never a layout component. Do NOT pass SidebarShell or FixedPanel as the sidebar — that nests two incompatible layout systems (a fixed-width shell vs a variable-width panel). | `import { AppShell } from "@working-theory/templates/shells"` |
378
380
  | `AuthShell` | The frame the five auth pages (/sign-in, /sign-up, /forgot-password, /reset-password, /verify-email) share: a brand mark top-start, one centered content column, and a slim footer. No nav — an auth page has nothing to navigate to, and the marketing Nav is exactly what this shell exists to replace on those routes. | `import { AuthShell } from "@working-theory/templates/shells"` |
379
381
  | `DeckHeroObserver` | Internal client island for MarketingShell's `deckHero` option. | internal — compose from `packages/templates/src/shells/DeckHeroObserver.tsx` |
382
+ | `DeckPresentation` | Internal client island for MarketingShell's `presentation` option. Not exported from the shells barrel (`./index.ts`) — MarketingShell renders it internally under `snap="mandatory"` with `presentation`, beside DeckHeroObserver, whose idiom it follows: a zero-size anchor, no React state, and every write made through the DOM after hydration. | internal — compose from `packages/templates/src/shells/DeckPresentation.tsx` |
383
+ | `DeckSlideAdvance` | Internal client island that puts one working slide-advance button at the foot of every slide of MarketingShell's scroll-snap deck: down to the next slide, and up from the last slide back to the first. | internal — compose from `packages/templates/src/shells/DeckSlideAdvance.tsx` |
380
384
  | `MarketingShell` | Public-facing marketing site **slot-frame**. Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* (top + bottom) and *where sections go* (the body), owning **geometry only**. Chrome (Nav/Footer) and sections **fill** the slots — nothing is baked into the component. See (first instance). *(weak)* | `import { MarketingShell } from "@working-theory/templates/shells"` |
381
385
  | `SignedInShell` | Every AILK signed-in area runs on this frame: the admin app's workspace (AppFrame supplies its switcher, Library and gating as content) and a site's own /account area. | `import { SignedInShell } from "@working-theory/templates/shells"` |
382
386