@adia-ai/web-modules 0.8.35 → 0.8.37

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 (89) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +3 -3
  3. package/agent-admin/admin-roster/admin-roster.js +1 -1
  4. package/agent-admin/admin-settings/admin-settings.js +1 -1
  5. package/agent-admin/agent-admin/agent-admin.js +1 -1
  6. package/billing/billing-overview/billing-overview.a2ui.json +281 -0
  7. package/billing/billing-overview/billing-overview.class.js +838 -0
  8. package/billing/billing-overview/billing-overview.css +223 -0
  9. package/billing/billing-overview/billing-overview.js +16 -0
  10. package/billing/billing-overview/billing-overview.yaml +441 -0
  11. package/billing/index.js +21 -0
  12. package/billing/invoice-detail/invoice-detail.a2ui.json +276 -0
  13. package/billing/invoice-detail/invoice-detail.class.js +711 -0
  14. package/billing/invoice-detail/invoice-detail.css +305 -0
  15. package/billing/invoice-detail/invoice-detail.js +16 -0
  16. package/billing/invoice-detail/invoice-detail.yaml +411 -0
  17. package/billing/invoice-history/invoice-history.a2ui.json +315 -0
  18. package/billing/invoice-history/invoice-history.class.js +672 -0
  19. package/billing/invoice-history/invoice-history.css +130 -0
  20. package/billing/invoice-history/invoice-history.js +16 -0
  21. package/billing/invoice-history/invoice-history.yaml +398 -0
  22. package/billing/payment-method-form/payment-method-form.a2ui.json +310 -0
  23. package/billing/payment-method-form/payment-method-form.class.js +886 -0
  24. package/billing/payment-method-form/payment-method-form.css +149 -0
  25. package/billing/payment-method-form/payment-method-form.js +16 -0
  26. package/billing/payment-method-form/payment-method-form.yaml +430 -0
  27. package/billing/payment-method-list/payment-method-list.a2ui.json +283 -0
  28. package/billing/payment-method-list/payment-method-list.class.js +705 -0
  29. package/billing/payment-method-list/payment-method-list.css +128 -0
  30. package/billing/payment-method-list/payment-method-list.js +16 -0
  31. package/billing/payment-method-list/payment-method-list.yaml +355 -0
  32. package/billing/plan-picker/plan-picker.a2ui.json +349 -0
  33. package/billing/plan-picker/plan-picker.class.js +635 -0
  34. package/billing/plan-picker/plan-picker.css +227 -0
  35. package/billing/plan-picker/plan-picker.js +16 -0
  36. package/billing/plan-picker/plan-picker.yaml +453 -0
  37. package/chat/README.md +1 -1
  38. package/chat/chat-composer/chat-composer.js +2 -2
  39. package/chat/chat-empty/chat-empty.js +2 -2
  40. package/chat/chat-shell/chat-shell.js +4 -4
  41. package/chat/chat-sidebar/chat-sidebar.js +2 -2
  42. package/chat/chat-surfaces/chat-surfaces.js +2 -2
  43. package/chat/chat-thread/chat-thread.js +2 -2
  44. package/dashboard/dashboard-layout/dashboard-layout.a2ui.json +254 -0
  45. package/dashboard/dashboard-layout/dashboard-layout.css +190 -0
  46. package/dashboard/dashboard-layout/dashboard-layout.js +289 -0
  47. package/dashboard/dashboard-layout/dashboard-layout.yaml +374 -0
  48. package/dashboard/date-range-selector/date-range-selector.a2ui.json +236 -0
  49. package/dashboard/date-range-selector/date-range-selector.css +84 -0
  50. package/dashboard/date-range-selector/date-range-selector.js +686 -0
  51. package/dashboard/date-range-selector/date-range-selector.yaml +358 -0
  52. package/dashboard/index.js +14 -0
  53. package/dist/everything.min.js +1 -1
  54. package/editor/editor-canvas/editor-canvas.js +2 -2
  55. package/editor/editor-shell/editor-shell.js +2 -2
  56. package/editor/editor-sidebar/editor-sidebar.js +2 -2
  57. package/editor/editor-toolbar/editor-toolbar.js +2 -2
  58. package/feedback/confirm-dialog/confirm-dialog.a2ui.json +206 -0
  59. package/feedback/confirm-dialog/confirm-dialog.css +157 -0
  60. package/feedback/confirm-dialog/confirm-dialog.js +383 -0
  61. package/feedback/confirm-dialog/confirm-dialog.yaml +297 -0
  62. package/feedback/index.js +10 -0
  63. package/form/form-popover/form-popover.js +1 -1
  64. package/generative/index.d.ts +1 -1
  65. package/generative/index.js +2 -2
  66. package/onboarding/index.js +1 -0
  67. package/onboarding/onboarding-checklist/onboarding-checklist.a2ui.json +263 -0
  68. package/onboarding/onboarding-checklist/onboarding-checklist.css +157 -0
  69. package/onboarding/onboarding-checklist/onboarding-checklist.js +428 -0
  70. package/onboarding/onboarding-checklist/onboarding-checklist.yaml +236 -0
  71. package/package.json +99 -6
  72. package/runtime/a2ui-root/a2ui-root.js +3 -3
  73. package/runtime/gen-root/gen-root.js +5 -5
  74. package/settings/index.js +12 -0
  75. package/settings/integrations-page/integrations-page.a2ui.json +274 -0
  76. package/settings/integrations-page/integrations-page.css +177 -0
  77. package/settings/integrations-page/integrations-page.d.ts +77 -0
  78. package/settings/integrations-page/integrations-page.js +413 -0
  79. package/settings/integrations-page/integrations-page.yaml +317 -0
  80. package/settings/notification-preferences/notification-preferences.a2ui.json +245 -0
  81. package/settings/notification-preferences/notification-preferences.css +204 -0
  82. package/settings/notification-preferences/notification-preferences.js +622 -0
  83. package/settings/notification-preferences/notification-preferences.yaml +358 -0
  84. package/shell/admin-command/admin-command.js +2 -2
  85. package/shell/admin-shell/admin-shell.js +2 -2
  86. package/shell/admin-sidebar/admin-sidebar.js +2 -2
  87. package/shell/embed-shell/embed-shell.js +3 -3
  88. package/simple/simple-shell/simple-shell.js +1 -1
  89. package/theme/theme-panel/theme-panel.js +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-modules",
3
- "version": "0.8.35",
3
+ "version": "0.8.37",
4
4
  "description": "AdiaUI composite custom elements — shell, chat, editor, runtime clusters built from @adia-ai/web-components primitives. Subpath exports per cluster.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -231,6 +231,76 @@
231
231
  "types": "./css-module.d.ts",
232
232
  "default": "./agent-admin/*/*.css"
233
233
  },
234
+ "./billing": {
235
+ "types": "./billing/index.d.ts",
236
+ "import": "./billing/index.js",
237
+ "default": "./billing/index.js"
238
+ },
239
+ "./billing/*": {
240
+ "types": "./billing/*/*.d.ts",
241
+ "import": "./billing/*/*.js",
242
+ "default": "./billing/*/*.js"
243
+ },
244
+ "./billing/*.css": {
245
+ "types": "./css-module.d.ts",
246
+ "default": "./billing/*/*.css"
247
+ },
248
+ "./dashboard": {
249
+ "types": "./dashboard/index.d.ts",
250
+ "import": "./dashboard/index.js",
251
+ "default": "./dashboard/index.js"
252
+ },
253
+ "./dashboard/*": {
254
+ "types": "./dashboard/*/*.d.ts",
255
+ "import": "./dashboard/*/*.js",
256
+ "default": "./dashboard/*/*.js"
257
+ },
258
+ "./dashboard/*.css": {
259
+ "types": "./css-module.d.ts",
260
+ "default": "./dashboard/*/*.css"
261
+ },
262
+ "./feedback": {
263
+ "types": "./feedback/index.d.ts",
264
+ "import": "./feedback/index.js",
265
+ "default": "./feedback/index.js"
266
+ },
267
+ "./feedback/*": {
268
+ "types": "./feedback/*/*.d.ts",
269
+ "import": "./feedback/*/*.js",
270
+ "default": "./feedback/*/*.js"
271
+ },
272
+ "./feedback/*.css": {
273
+ "types": "./css-module.d.ts",
274
+ "default": "./feedback/*/*.css"
275
+ },
276
+ "./onboarding": {
277
+ "types": "./onboarding/index.d.ts",
278
+ "import": "./onboarding/index.js",
279
+ "default": "./onboarding/index.js"
280
+ },
281
+ "./onboarding/*": {
282
+ "types": "./onboarding/*/*.d.ts",
283
+ "import": "./onboarding/*/*.js",
284
+ "default": "./onboarding/*/*.js"
285
+ },
286
+ "./onboarding/*.css": {
287
+ "types": "./css-module.d.ts",
288
+ "default": "./onboarding/*/*.css"
289
+ },
290
+ "./settings": {
291
+ "types": "./settings/index.d.ts",
292
+ "import": "./settings/index.js",
293
+ "default": "./settings/index.js"
294
+ },
295
+ "./settings/*": {
296
+ "types": "./settings/*/*.d.ts",
297
+ "import": "./settings/*/*.js",
298
+ "default": "./settings/*/*.js"
299
+ },
300
+ "./settings/*.css": {
301
+ "types": "./css-module.d.ts",
302
+ "default": "./settings/*/*.css"
303
+ },
234
304
  "./package.json": "./package.json"
235
305
  },
236
306
  "files": [
@@ -271,6 +341,29 @@
271
341
  "!agent-admin/**/*.examples.html",
272
342
  "!agent-admin/**/*.examples.js",
273
343
  "!agent-admin/**/*.html",
344
+ "billing/",
345
+ "!billing/**/*.examples.html",
346
+ "!billing/**/*.examples.js",
347
+ "!billing/**/*.examples.md",
348
+ "!billing/**/*.html",
349
+ "dashboard/",
350
+ "!dashboard/**/*.examples.html",
351
+ "!dashboard/**/*.examples.js",
352
+ "!dashboard/**/*.examples.md",
353
+ "!dashboard/**/*.html",
354
+ "feedback/",
355
+ "!feedback/**/*.examples.html",
356
+ "!feedback/**/*.examples.js",
357
+ "!feedback/**/*.examples.md",
358
+ "!feedback/**/*.html",
359
+ "onboarding/",
360
+ "!onboarding/**/*.examples.html",
361
+ "!onboarding/**/*.examples.js",
362
+ "!onboarding/**/*.html",
363
+ "settings/",
364
+ "!settings/**/*.examples.html",
365
+ "!settings/**/*.examples.js",
366
+ "!settings/**/*.html",
274
367
  "!**/*.test.js",
275
368
  "index.js",
276
369
  "css-module.d.ts",
@@ -296,11 +389,11 @@
296
389
  "./simple/**/*.js"
297
390
  ],
298
391
  "peerDependencies": {
299
- "@adia-ai/web-components": "0.8.35",
300
- "@adia-ai/a2ui-runtime": "0.8.35",
301
- "@adia-ai/llm": "0.8.35",
302
- "@adia-ai/agent": "0.8.35",
303
- "@adia-ai/persona": "0.8.35"
392
+ "@adia-ai/web-components": "0.8.37",
393
+ "@adia-ai/a2ui": "0.8.37",
394
+ "@adia-ai/llm": "0.8.37",
395
+ "@adia-ai/agent": "0.8.37",
396
+ "@adia-ai/persona": "0.8.37"
304
397
  },
305
398
  "publishConfig": {
306
399
  "access": "public",
@@ -25,8 +25,8 @@
25
25
  * doc-replaced — fired after a full doc reset + replay (author-driven mode)
26
26
  */
27
27
 
28
- import { defineIfFree } from '../../../web-components/core/register.js';
29
- import { UIElement } from '../../../web-components/core/element.js';
28
+ import { defineIfFree } from '@adia-ai/web-components/core/register';
29
+ import { UIElement } from '@adia-ai/web-components/core/element';
30
30
  import {
31
31
  A2UIRenderer,
32
32
  registry,
@@ -34,7 +34,7 @@ import {
34
34
  wsStream,
35
35
  jsonlStream,
36
36
  mcpStream,
37
- } from '@adia-ai/a2ui-runtime';
37
+ } from '@adia-ai/a2ui';
38
38
 
39
39
  class A2UIRoot extends UIElement {
40
40
  static properties = {
@@ -1,8 +1,8 @@
1
- import { defineIfFree } from '../../../web-components/core/register.js';
2
- import { UIElement } from '../../../web-components/core/element.js';
3
- import '../../../web-components/components/chat-thread/chat-thread.js';
4
- import '../../../web-components/components/canvas/canvas.js';
5
- import '../../../web-components/components/inspector/inspector.js';
1
+ import { defineIfFree } from '@adia-ai/web-components/core/register';
2
+ import { UIElement } from '@adia-ai/web-components/core/element';
3
+ import '@adia-ai/web-components/components/chat-thread';
4
+ import '@adia-ai/web-components/components/canvas';
5
+ import '@adia-ai/web-components/components/inspector';
6
6
 
7
7
  /**
8
8
  * <gen-root> — Composition shell for chat + canvas generative UI.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @adia-ai/web-modules/settings — cluster barrel.
3
+ *
4
+ * Settings-tier composites consumed by the settings shell. Each
5
+ * composite is a data-driven page-level surface that replaces a
6
+ * hand-rolled HTML template in the consuming app.
7
+ *
8
+ * SPEC-063 — integrations-page-ui (searchable integration-card grid).
9
+ * SPEC-064 — notification-preferences-ui (notification × channels matrix).
10
+ */
11
+ export { UIIntegrationsPage } from './integrations-page/integrations-page.js';
12
+ export { UINotificationPreferences } from './notification-preferences/notification-preferences.js';
@@ -0,0 +1,274 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://adiaui.dev/a2ui/v0_9/components/IntegrationsPage.json",
4
+ "title": "IntegrationsPage",
5
+ "description": "Module-tier Settings page composite — a searchable, category-grouped\ngrid of <integration-card-ui> tiles (SPEC-062). Owns the\n`integrations` array, the search-filter state, the category /\nstatus grouping, the responsive grid breakpoints, and the empty-state\ncopy. Card-level events (`connect` / `configure` / `disconnect` /\n`retry`) bubble up unchanged with `provider` in detail; the page also\nemits `search` (debounced) and a top-bar `filter-change` when the\nuser picks a status chip.\n\nLives in `packages/web-modules/settings/integrations-page/` per the\nthree-tier architecture — composes multiple primitives, holds layout\nresponsibility, consumed by the settings shell. Replaces the\nhand-rolled `settings/integrations` HTML template per consumer.\n\nSpec: .claude/docs/specs/implementation-ready/SPEC-063-integrations-page.md\n",
6
+ "type": "object",
7
+ "allOf": [
8
+ {
9
+ "$ref": "common_types.json#/$defs/ComponentCommon"
10
+ },
11
+ {
12
+ "$ref": "common_types.json#/$defs/CatalogComponentCommon"
13
+ }
14
+ ],
15
+ "properties": {
16
+ "component": {
17
+ "const": "IntegrationsPage"
18
+ },
19
+ "group-by": {
20
+ "description": "How to bucket cards into sections. `category` groups by the per-item\n`category` key; `status` groups by connection state; `none` renders\na single ungrouped grid.\n",
21
+ "type": "string",
22
+ "enum": [
23
+ "category",
24
+ "status",
25
+ "none"
26
+ ],
27
+ "default": "category"
28
+ },
29
+ "integrations": {
30
+ "description": "Array of integration descriptors — each item conforms to the\nSPEC-062 <integration-card-ui> prop shape:\n`{ provider, name, logo?, description?, status, category?,\nerror-message? }`. Empty array renders the empty-state slot.\n",
31
+ "$ref": "common_types.json#/$defs/DynamicStringList"
32
+ },
33
+ "loading": {
34
+ "description": "Renders a skeleton grid (6 tiles) instead of cards. Driven by the\nconsumer while the integrations payload is in flight.\n",
35
+ "$ref": "common_types.json#/$defs/DynamicBoolean"
36
+ },
37
+ "search-placeholder": {
38
+ "description": "Placeholder copy for the built-in search input. Defaults to\n\"Search integrations\".\n",
39
+ "type": "string",
40
+ "default": "Search integrations"
41
+ },
42
+ "status-filter": {
43
+ "description": "Optional status filter — restricts the visible cards to one status.\n`all` (default) shows everything; the rest restrict to that status\nbucket. Reflects so consumers can deep-link.\n",
44
+ "$ref": "common_types.json#/$defs/DynamicString"
45
+ }
46
+ },
47
+ "required": [
48
+ "component",
49
+ "integrations"
50
+ ],
51
+ "unevaluatedProperties": false,
52
+ "x-adiaui": {
53
+ "anti_patterns": [
54
+ {
55
+ "fix": "{\"component\": \"IntegrationsPage\", \"integrations\": [\n {\"provider\": \"slack\", \"name\": \"Slack\", \"status\": \"available\"}\n]}\n",
56
+ "why": "Slotted cards are ignored — the page generates cards from the\n`integrations` prop. The page renders empty.\n",
57
+ "wrong": "{\"component\": \"IntegrationsPage\", \"children\": [\n {\"component\": \"IntegrationCard\", \"provider\": \"slack\", \"name\": \"Slack\"}\n]}\n"
58
+ },
59
+ {
60
+ "fix": "{\"component\": \"IntegrationsPage\", \"integrations\": [\n {\"provider\": \"slack\", \"name\": \"Slack\", \"status\": \"available\"}\n]}\n",
61
+ "why": "Re-implements the page composite with primitives. Loses search,\ngrouping, and empty-state semantics.\n",
62
+ "wrong": "{\"component\": \"Page\", \"children\": [\n {\"component\": \"Grid\", \"children\": [\n {\"component\": \"IntegrationCard\", \"provider\": \"slack\", \"name\": \"Slack\"}\n ]}\n]}\n"
63
+ }
64
+ ],
65
+ "category": "container",
66
+ "composes": [
67
+ "integration-card-ui",
68
+ "grid-ui",
69
+ "search-ui",
70
+ "segmented-ui",
71
+ "segment-ui",
72
+ "text-ui"
73
+ ],
74
+ "events": {
75
+ "configure": {
76
+ "description": "Bubbled from a child <integration-card-ui> while `status=\"connected\"`.",
77
+ "detail": {
78
+ "provider": {
79
+ "description": "The provider key of the card that fired.",
80
+ "type": "string"
81
+ }
82
+ }
83
+ },
84
+ "connect": {
85
+ "description": "Bubbled from a child <integration-card-ui> when its primary button is pressed while `status=\"available\"`.",
86
+ "detail": {
87
+ "provider": {
88
+ "description": "The provider key of the card that fired.",
89
+ "type": "string"
90
+ }
91
+ }
92
+ },
93
+ "disconnect": {
94
+ "description": "Bubbled from a child card's overflow menu disconnect item.",
95
+ "detail": {
96
+ "provider": {
97
+ "description": "The provider key of the card that fired.",
98
+ "type": "string"
99
+ }
100
+ }
101
+ },
102
+ "filter-change": {
103
+ "description": "User clicked a status filter chip in the top bar.",
104
+ "detail": {
105
+ "status": {
106
+ "description": "The newly-selected status filter (`all` resets).",
107
+ "type": "string"
108
+ }
109
+ }
110
+ },
111
+ "retry": {
112
+ "description": "Bubbled from a child <integration-card-ui> while `status=\"error\"`.",
113
+ "detail": {
114
+ "provider": {
115
+ "description": "The provider key of the card that fired.",
116
+ "type": "string"
117
+ }
118
+ }
119
+ },
120
+ "search": {
121
+ "description": "Debounced search input change.",
122
+ "detail": {
123
+ "query": {
124
+ "description": "The current search query (lower-cased, trimmed).",
125
+ "type": "string"
126
+ }
127
+ }
128
+ }
129
+ },
130
+ "examples": [
131
+ {
132
+ "description": "Full integrations page grouped by category (default).",
133
+ "a2ui": "[\n {\n \"id\": \"page\",\n \"component\": \"IntegrationsPage\",\n \"group-by\": \"category\",\n \"integrations\": [\n {\"provider\": \"slack\", \"name\": \"Slack\", \"logo\": \"/integrations/slack.svg\",\n \"description\": \"Notifications and replies in channels.\",\n \"status\": \"connected\", \"category\": \"Communication\"},\n {\"provider\": \"github\", \"name\": \"GitHub\", \"logo\": \"/integrations/github.svg\",\n \"description\": \"Sync issues and pull requests.\",\n \"status\": \"available\", \"category\": \"Developer Tools\"},\n {\"provider\": \"stripe\", \"name\": \"Stripe\", \"logo\": \"/integrations/stripe.svg\",\n \"description\": \"Charge customers and reconcile invoices.\",\n \"status\": \"error\", \"category\": \"Payments\",\n \"error-message\": \"Token expired — re-authenticate.\"}\n ]\n }\n]\n",
134
+ "name": "category-grouped"
135
+ },
136
+ {
137
+ "description": "Loading state — 6 skeleton tiles, no cards.",
138
+ "a2ui": "[{\"id\": \"page\", \"component\": \"IntegrationsPage\", \"loading\": true}]\n",
139
+ "name": "loading-skeleton"
140
+ },
141
+ {
142
+ "description": "Empty state — no integrations available.",
143
+ "a2ui": "[{\"id\": \"page\", \"component\": \"IntegrationsPage\", \"integrations\": []}]\n",
144
+ "name": "empty-data"
145
+ }
146
+ ],
147
+ "keywords": [
148
+ "integrations",
149
+ "integration",
150
+ "settings",
151
+ "settings-page",
152
+ "connections",
153
+ "third-party",
154
+ "oauth",
155
+ "providers",
156
+ "app-directory",
157
+ "marketplace"
158
+ ],
159
+ "name": "UIIntegrationsPage",
160
+ "related": [
161
+ "IntegrationCard",
162
+ "Grid",
163
+ "Search",
164
+ "Segmented",
165
+ "Page"
166
+ ],
167
+ "slots": {
168
+ "empty": {
169
+ "description": "Optional override for the empty-state copy. When supplied, replaces\nthe built-in \"No integrations match\" / \"No integrations available\"\nmessages.\n"
170
+ },
171
+ "header": {
172
+ "description": "Optional page header (kicker / title / subtitle). Overrides the\ndefault rendering — when supplied the composite stamps no\nbuilt-in heading.\n"
173
+ }
174
+ },
175
+ "states": [
176
+ {
177
+ "description": "Default; renders all groups matching the current filter.",
178
+ "name": "idle"
179
+ },
180
+ {
181
+ "description": "Skeleton grid; cards hidden.",
182
+ "attribute": "loading",
183
+ "name": "loading"
184
+ },
185
+ {
186
+ "description": "Search query yields zero cards.",
187
+ "attribute": "data-empty-search",
188
+ "name": "empty-search"
189
+ },
190
+ {
191
+ "description": "`integrations` array is empty.",
192
+ "attribute": "data-empty-data",
193
+ "name": "empty-data"
194
+ }
195
+ ],
196
+ "status": "stable",
197
+ "synonyms": {
198
+ "integrations": [
199
+ "integration",
200
+ "connections",
201
+ "apps",
202
+ "providers"
203
+ ],
204
+ "marketplace": [
205
+ "integrations",
206
+ "app-directory",
207
+ "apps"
208
+ ],
209
+ "oauth": [
210
+ "integration",
211
+ "connection",
212
+ "auth"
213
+ ],
214
+ "settings": [
215
+ "settings",
216
+ "account",
217
+ "admin"
218
+ ]
219
+ },
220
+ "tag": "integrations-page-ui",
221
+ "tokens": {
222
+ "--integrations-page-bg": {
223
+ "description": "Page background. Defaults to `var(--a-bg)`.",
224
+ "default": "var(--a-bg)"
225
+ },
226
+ "--integrations-page-card-gap": {
227
+ "description": "Gap inside the grid between cards.",
228
+ "default": "var(--a-space-4)"
229
+ },
230
+ "--integrations-page-fg": {
231
+ "description": "Primary foreground. Defaults to `var(--a-fg)`.",
232
+ "default": "var(--a-fg)"
233
+ },
234
+ "--integrations-page-fg-muted": {
235
+ "description": "Secondary foreground for empty-state copy + section meta.",
236
+ "default": "var(--a-fg-muted)"
237
+ },
238
+ "--integrations-page-gap": {
239
+ "description": "Vertical gap between toolbar / sections / empty-state.",
240
+ "default": "var(--a-space-5)"
241
+ },
242
+ "--integrations-page-grid-min": {
243
+ "description": "Minimum card width for the auto-fill grid track.",
244
+ "default": "var(--a-space-12)"
245
+ },
246
+ "--integrations-page-px": {
247
+ "description": "Horizontal padding around the page.",
248
+ "default": "var(--a-space-5)"
249
+ },
250
+ "--integrations-page-py": {
251
+ "description": "Vertical padding around the page.",
252
+ "default": "var(--a-space-5)"
253
+ },
254
+ "--integrations-page-section-gap": {
255
+ "description": "Vertical gap between sibling category sections.",
256
+ "default": "var(--a-space-6)"
257
+ },
258
+ "--integrations-page-section-heading-fg": {
259
+ "description": "Section heading color.",
260
+ "default": "var(--a-fg-strong)"
261
+ },
262
+ "--integrations-page-section-heading-size": {
263
+ "description": "Section heading font size.",
264
+ "default": "var(--a-ui-sm)"
265
+ },
266
+ "--integrations-page-section-heading-weight": {
267
+ "description": "Section heading font weight.",
268
+ "default": "var(--a-weight-medium)"
269
+ }
270
+ },
271
+ "traits": [],
272
+ "version": 1
273
+ }
274
+ }
@@ -0,0 +1,177 @@
1
+ /* ═══════════════════════════════════════════════════════════════
2
+ integrations-page-ui — Module CSS
3
+
4
+ Two-block @scope:
5
+ Block 1 — TOKENS (:where(:scope))
6
+ Block 2 — BASE (:scope + descendant rules)
7
+
8
+ Tokens consumed (substrate):
9
+ --a-bg, --a-fg, --a-fg-muted, --a-fg-strong,
10
+ --a-border-subtle, --a-bg-muted, --a-radius-md,
11
+ --a-space-1, --a-space-2, --a-space-3, --a-space-4,
12
+ --a-space-5, --a-space-6, --a-space-7, --a-space-12,
13
+ --a-ui-sm, --a-text-lg, --a-weight-medium
14
+
15
+ Composition note: layout + spacing only; child primitives
16
+ (search-ui, segmented-ui, grid-ui, integration-card-ui, text-ui)
17
+ carry their own chrome via their own scoped stylesheets.
18
+ ═══════════════════════════════════════════════════════════════ */
19
+
20
+ @scope (integrations-page-ui) {
21
+
22
+ /* ── Block 1: TOKENS ────────────────────────────────────────── */
23
+
24
+ :where(:scope) {
25
+ --integrations-page-bg: var(--md-sys-color-neutral-background);
26
+ --integrations-page-fg: var(--md-sys-color-neutral-on-surface);
27
+ --integrations-page-fg-muted: var(--a-fg-muted);
28
+ --integrations-page-px: var(--a-space-5);
29
+ --integrations-page-py: var(--a-space-5);
30
+ --integrations-page-gap: var(--a-space-5);
31
+ --integrations-page-section-gap: var(--a-space-6);
32
+ --integrations-page-card-gap: var(--a-space-4);
33
+ --integrations-page-grid-min: var(--a-space-12);
34
+ --integrations-page-section-heading-fg: var(--a-fg-strong);
35
+ --integrations-page-section-heading-size: var(--a-ui-sm);
36
+ --integrations-page-section-heading-weight: var(--a-weight-medium);
37
+ }
38
+
39
+ /* ── Block 2: BASE ──────────────────────────────────────────── */
40
+
41
+ :scope {
42
+ box-sizing: border-box;
43
+ display: grid;
44
+ gap: var(--integrations-page-gap);
45
+ padding:
46
+ var(--integrations-page-py)
47
+ var(--integrations-page-px);
48
+ background: var(--integrations-page-bg);
49
+ color: var(--integrations-page-fg);
50
+ width: 100%;
51
+ min-width: 0;
52
+ }
53
+
54
+ /* ── Header ─────────────────────────────────────────────────── */
55
+ :scope > [data-part="header"] {
56
+ display: flex;
57
+ align-items: baseline;
58
+ justify-content: space-between;
59
+ gap: var(--a-space-3);
60
+ flex-wrap: wrap;
61
+ }
62
+
63
+ :scope > [data-part="header"] > [data-part="title"] {
64
+ margin: 0;
65
+ font-size: var(--a-text-lg);
66
+ font-weight: var(--a-weight-medium);
67
+ color: var(--integrations-page-section-heading-fg);
68
+ }
69
+
70
+ /* ── Toolbar (search + status filter) ───────────────────────── */
71
+ :scope > [data-part="toolbar"] {
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: space-between;
75
+ gap: var(--a-space-3);
76
+ flex-wrap: wrap;
77
+ }
78
+
79
+ :scope > [data-part="toolbar"] > [data-part="search"] {
80
+ flex: 1 1 auto;
81
+ min-width: 0;
82
+ max-width: 100%;
83
+ }
84
+
85
+ :scope > [data-part="toolbar"] > [data-part="filter"] {
86
+ flex: 0 0 auto;
87
+ }
88
+
89
+ /* ── Sections wrapper ──────────────────────────────────────── */
90
+ /* Descendant (not child) combinator: the conditional render branch
91
+ (sections / skeleton / empty) is wrapped by the template engine in a
92
+ <span style="display:contents">, so `:scope > [data-part]` never matches
93
+ (display:contents doesn't collapse the parent→child relationship for
94
+ selector matching). The static header/toolbar above stay `:scope >`. */
95
+ :scope [data-part="sections"] {
96
+ display: grid;
97
+ gap: var(--integrations-page-section-gap);
98
+ }
99
+
100
+ :scope [data-part="section"] {
101
+ display: grid;
102
+ gap: var(--integrations-page-card-gap);
103
+ }
104
+
105
+ :scope [data-part="section-heading"] {
106
+ color: var(--integrations-page-section-heading-fg);
107
+ font-size: var(--integrations-page-section-heading-size);
108
+ font-weight: var(--integrations-page-section-heading-weight);
109
+ text-transform: uppercase;
110
+ letter-spacing: 0.04em;
111
+ }
112
+
113
+ /* group-by="none" — single ungrouped grid, no heading slot needed */
114
+ :scope[group-by="none"] [data-part="section-heading"] {
115
+ display: none;
116
+ }
117
+
118
+ /* ── Skeleton tiles (loading state) ─────────────────────────── */
119
+ :scope [data-part="skeleton"] {
120
+ display: block;
121
+ }
122
+
123
+ :scope [data-part="skeleton-tile"] {
124
+ display: block;
125
+ min-height: var(--a-space-12);
126
+ border: 1px solid var(--md-sys-color-neutral-outline-variant);
127
+ border-radius: var(--a-radius-md);
128
+ background: linear-gradient(
129
+ 90deg,
130
+ var(--a-bg-muted) 0%,
131
+ var(--md-sys-color-neutral-background) 50%,
132
+ var(--a-bg-muted) 100%
133
+ );
134
+ background-size: 200% 100%;
135
+ animation: integrations-page-shimmer 1.4s ease-in-out infinite;
136
+ }
137
+
138
+ @keyframes integrations-page-shimmer {
139
+ 0% { background-position: 100% 0; }
140
+ 100% { background-position: -100% 0; }
141
+ }
142
+
143
+ /* Cards in skeleton state dim further to communicate "not ready" */
144
+ :scope[loading] integration-card-ui {
145
+ opacity: 0.5;
146
+ pointer-events: none;
147
+ }
148
+
149
+ /* ── Empty state ───────────────────────────────────────────── */
150
+ :scope [data-part="empty"] {
151
+ display: grid;
152
+ gap: var(--a-space-2);
153
+ place-items: center;
154
+ text-align: center;
155
+ padding: var(--a-space-6) var(--a-space-4);
156
+ border: 1px dashed var(--md-sys-color-neutral-outline-variant);
157
+ border-radius: var(--a-radius-md);
158
+ background: var(--a-bg-muted);
159
+ color: var(--integrations-page-fg-muted);
160
+ }
161
+
162
+ :scope [data-part="empty"] [data-part="empty-heading"] {
163
+ color: var(--integrations-page-fg);
164
+ }
165
+
166
+ /* ── Responsive — single column at narrow viewports ─────────── */
167
+ @media (max-width: 480px) {
168
+ :scope > [data-part="toolbar"] {
169
+ flex-direction: column;
170
+ align-items: stretch;
171
+ }
172
+ :scope > [data-part="toolbar"] > [data-part="filter"] {
173
+ width: 100%;
174
+ overflow-x: auto;
175
+ }
176
+ }
177
+ }