@utopia-studio-design/design-system-cli 0.4.1 → 0.5.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 (125) hide show
  1. package/README.md +23 -0
  2. package/bin/utopia-ds-mcp.mjs +9 -2
  3. package/bin/utopia-ds.mjs +106 -8
  4. package/data/blocks/activity-feed/ActivityFeedBlock.tsx +255 -0
  5. package/data/blocks/activity-feed/README.md +16 -0
  6. package/data/blocks/activity-feed/activity-feed-contract.ts +96 -0
  7. package/data/blocks/activity-feed/activity-feed-fixture.ts +22 -0
  8. package/data/blocks/activity-feed/activity-feed.css +154 -0
  9. package/data/blocks/agent-status/AgentStatusBlock.tsx +313 -0
  10. package/data/blocks/agent-status/README.md +15 -0
  11. package/data/blocks/agent-status/agent-status-contract.ts +133 -0
  12. package/data/blocks/agent-status/agent-status-fixture.ts +79 -0
  13. package/data/blocks/agent-status/agent-status.css +216 -0
  14. package/data/blocks/analytics-dashboard/AnalyticsDashboardBlocks.tsx +107 -0
  15. package/data/blocks/analytics-dashboard/AnalyticsMetricBlocks.tsx +87 -0
  16. package/data/blocks/analytics-dashboard/README.md +17 -0
  17. package/data/blocks/analytics-dashboard/analytics-dashboard.css +92 -0
  18. package/data/blocks/calendar-application/CalendarApplicationBlocks.tsx +519 -0
  19. package/data/blocks/calendar-application/README.md +20 -0
  20. package/data/blocks/calendar-application/calendar-application.css +216 -0
  21. package/data/blocks/calendar-application/calendar-localization.ts +90 -0
  22. package/data/blocks/calendar-application/calendar-panel-contract.ts +72 -0
  23. package/data/blocks/dashboard-composer/CeramicPuckAdapter.tsx +380 -0
  24. package/data/blocks/dashboard-composer/DashboardComposerBlocks.tsx +337 -0
  25. package/data/blocks/dashboard-composer/README.md +16 -0
  26. package/data/blocks/dashboard-composer/RegistryDataBlocks.tsx +238 -0
  27. package/data/blocks/dashboard-composer/dashboard-composer.css +328 -0
  28. package/data/blocks/database-workspace/DatabaseWorkspaceBlocks.tsx +240 -0
  29. package/data/blocks/database-workspace/README.md +9 -0
  30. package/data/blocks/database-workspace/database-workspace.css +107 -0
  31. package/data/blocks/interaction-workbench/InteractionWorkbench.tsx +271 -0
  32. package/data/blocks/interaction-workbench/README.md +9 -0
  33. package/data/blocks/interaction-workbench/interaction-workbench.css +226 -0
  34. package/data/docs/calendar.md +164 -0
  35. package/data/docs/charts.md +95 -0
  36. package/data/docs/composition-registry.md +174 -0
  37. package/data/docs/dashboard-composer.md +94 -0
  38. package/data/docs/database.md +68 -0
  39. package/data/docs/examples/dashboard-layout.v1.json +65 -0
  40. package/data/docs/foundations.md +1 -1
  41. package/data/docs/interaction-foundation.md +109 -0
  42. package/data/docs/quick-start-ai.md +23 -1
  43. package/data/manifests/blocks.json +392 -0
  44. package/data/manifests/catalog.json +7 -4
  45. package/data/manifests/components.json +179 -0
  46. package/data/manifests/composition-registry.json +427 -0
  47. package/data/manifests/motion-profiles.json +1 -1
  48. package/data/manifests/patterns.json +113 -1
  49. package/data/manifests/templates.json +346 -0
  50. package/data/manifests/theme-renacore.json +142 -0
  51. package/data/manifests/themes.json +314 -28
  52. package/data/templates/analytics-dashboard/AnalyticsDashboardBlocks.tsx +107 -0
  53. package/data/templates/analytics-dashboard/AnalyticsMetricBlocks.tsx +87 -0
  54. package/data/templates/analytics-dashboard/README.md +6 -0
  55. package/data/templates/analytics-dashboard/analytics-dashboard.css +92 -0
  56. package/data/templates/analytics-dashboard/index.html +13 -0
  57. package/data/templates/analytics-dashboard/main.tsx +196 -0
  58. package/data/templates/analytics-dashboard/styles.css +120 -0
  59. package/data/templates/analytics-dashboard/template.manifest.json +17 -0
  60. package/data/templates/calendar-application/CalendarApplicationBlocks.tsx +519 -0
  61. package/data/templates/calendar-application/README.md +10 -0
  62. package/data/templates/calendar-application/calendar-application.css +216 -0
  63. package/data/templates/calendar-application/calendar-localization.ts +90 -0
  64. package/data/templates/calendar-application/index.html +14 -0
  65. package/data/templates/calendar-application/main.tsx +409 -0
  66. package/data/templates/calendar-application/styles.css +248 -0
  67. package/data/templates/calendar-application/template.manifest.json +27 -0
  68. package/data/templates/composition-registry-lab/README.md +9 -0
  69. package/data/templates/composition-registry-lab/index.html +14 -0
  70. package/data/templates/composition-registry-lab/main.tsx +217 -0
  71. package/data/templates/composition-registry-lab/sample-layout.json +63 -0
  72. package/data/templates/composition-registry-lab/styles.css +343 -0
  73. package/data/templates/composition-registry-lab/template.manifest.json +34 -0
  74. package/data/templates/dashboard-composer/ActivityFeedBlock.tsx +255 -0
  75. package/data/templates/dashboard-composer/AgentStatusBlock.tsx +313 -0
  76. package/data/templates/dashboard-composer/AnalyticsDashboardBlocks.tsx +107 -0
  77. package/data/templates/dashboard-composer/AnalyticsMetricBlocks.tsx +87 -0
  78. package/data/templates/dashboard-composer/CalendarApplicationBlocks.tsx +519 -0
  79. package/data/templates/dashboard-composer/CeramicPuckAdapter.tsx +380 -0
  80. package/data/templates/dashboard-composer/DashboardComposerBlocks.tsx +337 -0
  81. package/data/templates/dashboard-composer/DatabaseWorkspaceBlocks.tsx +240 -0
  82. package/data/templates/dashboard-composer/README.md +53 -0
  83. package/data/templates/dashboard-composer/RegistryDataBlocks.tsx +238 -0
  84. package/data/templates/dashboard-composer/activity-feed-contract.ts +96 -0
  85. package/data/templates/dashboard-composer/activity-feed-fixture.ts +22 -0
  86. package/data/templates/dashboard-composer/activity-feed.css +154 -0
  87. package/data/templates/dashboard-composer/agent-status-contract.ts +133 -0
  88. package/data/templates/dashboard-composer/agent-status-fixture.ts +79 -0
  89. package/data/templates/dashboard-composer/agent-status-lab/index.html +19 -0
  90. package/data/templates/dashboard-composer/agent-status-lab/main.tsx +151 -0
  91. package/data/templates/dashboard-composer/agent-status-lab/styles.css +139 -0
  92. package/data/templates/dashboard-composer/agent-status.css +216 -0
  93. package/data/templates/dashboard-composer/analytics-dashboard.css +92 -0
  94. package/data/templates/dashboard-composer/calendar-application.css +216 -0
  95. package/data/templates/dashboard-composer/calendar-localization.ts +90 -0
  96. package/data/templates/dashboard-composer/calendar-panel-contract.ts +72 -0
  97. package/data/templates/dashboard-composer/dashboard-composer.css +328 -0
  98. package/data/templates/dashboard-composer/database-workspace.css +107 -0
  99. package/data/templates/dashboard-composer/index.html +14 -0
  100. package/data/templates/dashboard-composer/main.tsx +550 -0
  101. package/data/templates/dashboard-composer/sample-layout.json +147 -0
  102. package/data/templates/dashboard-composer/styles.css +198 -0
  103. package/data/templates/dashboard-composer/template.manifest.json +34 -0
  104. package/data/templates/dashboard-composer/visual-editor/PuckEditorSurface.tsx +132 -0
  105. package/data/templates/dashboard-composer/visual-editor/VisualEditorApp.tsx +343 -0
  106. package/data/templates/dashboard-composer/visual-editor/index.html +17 -0
  107. package/data/templates/dashboard-composer/visual-editor/main.tsx +95 -0
  108. package/data/templates/dashboard-composer/visual-editor/styles.css +310 -0
  109. package/data/templates/database-workspace/DatabaseWorkspaceBlocks.tsx +240 -0
  110. package/data/templates/database-workspace/README.md +5 -0
  111. package/data/templates/database-workspace/database-workspace.css +107 -0
  112. package/data/templates/database-workspace/index.html +14 -0
  113. package/data/templates/database-workspace/main.tsx +247 -0
  114. package/data/templates/database-workspace/styles.css +121 -0
  115. package/data/templates/database-workspace/template.manifest.json +19 -0
  116. package/data/templates/interaction-lab/InteractionWorkbench.tsx +271 -0
  117. package/data/templates/interaction-lab/README.md +7 -0
  118. package/data/templates/interaction-lab/index.html +14 -0
  119. package/data/templates/interaction-lab/interaction-workbench.css +226 -0
  120. package/data/templates/interaction-lab/main.tsx +104 -0
  121. package/data/templates/interaction-lab/styles.css +224 -0
  122. package/data/templates/interaction-lab/template.manifest.json +36 -0
  123. package/lib/api.mjs +72 -5
  124. package/lib/composition-runtime.mjs +382 -0
  125. package/package.json +4 -1
@@ -0,0 +1,226 @@
1
+ .interaction-workbench {
2
+ display: grid;
3
+ gap: var(--interaction-density-comfortable);
4
+ min-inline-size: 0;
5
+ padding: var(--space-4);
6
+ color: var(--foreground);
7
+ }
8
+
9
+ .interaction-workbench > header,
10
+ .interaction-panel-heading,
11
+ .interaction-resize {
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: space-between;
15
+ gap: var(--space-3);
16
+ }
17
+
18
+ .interaction-workbench h2,
19
+ .interaction-workbench h3,
20
+ .interaction-workbench p {
21
+ margin: 0;
22
+ }
23
+
24
+ .interaction-supporting,
25
+ .interaction-instruction {
26
+ color: var(--muted-foreground);
27
+ }
28
+
29
+ .interaction-supporting {
30
+ margin-block-start: var(--space-1);
31
+ }
32
+
33
+ .interaction-instruction {
34
+ max-inline-size: 62ch;
35
+ font-size: var(--font-size-small);
36
+ line-height: var(--line-height-body);
37
+ }
38
+
39
+ .interaction-step {
40
+ color: var(--muted-foreground);
41
+ font-size: var(--font-size-eyebrow);
42
+ font-weight: var(--font-weight-semibold);
43
+ letter-spacing: var(--tracking-eyebrow);
44
+ text-transform: uppercase;
45
+ }
46
+
47
+ .interaction-eyebrow {
48
+ color: var(--muted-foreground);
49
+ font-size: var(--font-size-eyebrow);
50
+ text-transform: uppercase;
51
+ letter-spacing: var(--tracking-eyebrow);
52
+ }
53
+
54
+ .interaction-history,
55
+ .interaction-current-actions > div {
56
+ display: flex;
57
+ gap: var(--space-1);
58
+ }
59
+
60
+ .interaction-layout {
61
+ display: grid;
62
+ grid-template-columns: minmax(0, 1fr) minmax(16rem, .75fr);
63
+ gap: var(--space-4);
64
+ min-inline-size: 0;
65
+ }
66
+
67
+ .interaction-panel {
68
+ display: grid;
69
+ align-content: start;
70
+ gap: var(--interaction-density-default);
71
+ min-inline-size: 0;
72
+ padding: var(--space-3);
73
+ border: var(--border-width-hairline) solid var(--border);
74
+ border-radius: var(--radius-surface);
75
+ background: var(--surface);
76
+ }
77
+
78
+ .interaction-panel > div:first-child h3 {
79
+ margin-block-start: var(--space-1);
80
+ }
81
+
82
+ .interaction-grid {
83
+ display: grid;
84
+ grid-template-columns: repeat(2, minmax(0, 1fr));
85
+ gap: var(--interaction-density-compact);
86
+ margin: 0;
87
+ padding: 0;
88
+ list-style: none;
89
+ }
90
+
91
+ .interaction-item-shell {
92
+ min-inline-size: 0;
93
+ }
94
+
95
+ .interaction-item {
96
+ border: var(--border-width-hairline) solid var(--border);
97
+ border-radius: var(--radius-control);
98
+ background: var(--background);
99
+ color: var(--foreground);
100
+ font: inherit;
101
+ }
102
+
103
+ .interaction-item {
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: space-between;
107
+ gap: var(--space-2);
108
+ min-block-size: var(--button-height);
109
+ min-inline-size: 0;
110
+ padding-inline: var(--space-3);
111
+ text-align: start;
112
+ cursor: grab;
113
+ }
114
+
115
+ .interaction-item[aria-pressed='true'] {
116
+ border-color: var(--interaction-selection-border);
117
+ background: var(--interaction-selection-surface);
118
+ }
119
+
120
+ .interaction-item[draggable='true']:active {
121
+ border-color: var(--interaction-drag-border);
122
+ background: var(--interaction-drag-surface);
123
+ }
124
+
125
+ .interaction-item:focus-visible,
126
+ .interaction-virtual-scroll:focus-visible,
127
+ .interaction-resize input:focus-visible {
128
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
129
+ outline-offset: var(--focus-ring-offset);
130
+ }
131
+
132
+ .interaction-current-actions {
133
+ display: flex;
134
+ align-items: center;
135
+ justify-content: space-between;
136
+ gap: var(--space-3);
137
+ min-inline-size: 0;
138
+ }
139
+
140
+ .interaction-current-actions > span {
141
+ color: var(--muted-foreground);
142
+ font-size: var(--font-size-small);
143
+ }
144
+
145
+ .interaction-current-actions button {
146
+ min-block-size: var(--interaction-target-min);
147
+ }
148
+
149
+ .interaction-resize {
150
+ flex-wrap: wrap;
151
+ }
152
+
153
+ .interaction-resize input {
154
+ inline-size: 100%;
155
+ }
156
+
157
+ .interaction-virtual-shell {
158
+ max-inline-size: 100%;
159
+ min-inline-size: 0;
160
+ }
161
+
162
+ .interaction-virtual-scroll {
163
+ block-size: 180px;
164
+ max-inline-size: 100%;
165
+ overflow: auto;
166
+ border: var(--border-width-hairline) solid var(--border);
167
+ background: var(--background);
168
+ }
169
+
170
+ .interaction-virtual-row {
171
+ position: absolute;
172
+ inset-inline: 0;
173
+ display: flex;
174
+ align-items: center;
175
+ block-size: 36px;
176
+ padding-inline: var(--space-3);
177
+ border-block-end: var(--border-width-hairline) solid var(--border);
178
+ }
179
+
180
+ .interaction-announcement {
181
+ min-block-size: var(--button-height);
182
+ padding: var(--space-3);
183
+ border-inline-start: var(--border-width-strong) solid var(--interaction-selection-border);
184
+ background: var(--interaction-selection-surface);
185
+ color: var(--foreground);
186
+ font-size: var(--font-size-small);
187
+ }
188
+
189
+ @media (max-width: 44rem) {
190
+ .interaction-workbench > header,
191
+ .interaction-layout {
192
+ grid-template-columns: 1fr;
193
+ }
194
+
195
+ .interaction-workbench > header {
196
+ display: grid;
197
+ }
198
+
199
+ .interaction-history {
200
+ inline-size: 100%;
201
+ }
202
+
203
+ .interaction-current-actions {
204
+ align-items: stretch;
205
+ flex-direction: column;
206
+ }
207
+
208
+ .interaction-current-actions > div {
209
+ display: grid;
210
+ grid-template-columns: repeat(2, minmax(0, 1fr));
211
+ }
212
+
213
+ .interaction-grid {
214
+ grid-template-columns: 1fr;
215
+ }
216
+ }
217
+
218
+ @media (prefers-reduced-motion: reduce) {
219
+ .interaction-workbench *,
220
+ .interaction-workbench *::before,
221
+ .interaction-workbench *::after {
222
+ scroll-behavior: auto;
223
+ transition-duration: 0ms;
224
+ animation-duration: 0ms;
225
+ }
226
+ }
@@ -0,0 +1,104 @@
1
+ import { StrictMode, useState } from 'react'
2
+ import { createRoot } from 'react-dom/client'
3
+ import { Button } from '@utopia-studio-design/design-system/Button'
4
+ import { useControllableState } from '@utopia-studio-design/design-system/Interaction'
5
+ import { InteractionWorkbench } from './InteractionWorkbench'
6
+ import '@utopia-studio-design/design-system/core.css'
7
+ import '@utopia-studio-design/design-system/themes/utopia-default.css'
8
+ import './styles.css'
9
+
10
+ const activeTheme = 'utopia-default'
11
+
12
+ function StateContractProbe() {
13
+ const [ownedValue, setOwnedValue] = useState('idle')
14
+ const [events, setEvents] = useState<string[]>([])
15
+ const [value, setValue] = useControllableState({
16
+ value: ownedValue,
17
+ defaultValue: 'default',
18
+ onChange: (next) => {
19
+ setEvents((current) => [...current, `change:${next}`])
20
+ setOwnedValue(next)
21
+ },
22
+ })
23
+
24
+ return (
25
+ <div className="state-contract-probe">
26
+ <div>
27
+ <p>Automatic contract check</p>
28
+ <h3>Controlled state ordering</h3>
29
+ </div>
30
+ <output aria-label="Current controlled value">{value}</output>
31
+ <div>
32
+ <Button size="sm" variant="outline" onClick={() => setValue('idle')}>Set same value</Button>
33
+ <Button size="sm" onClick={() => setValue('ready')}>Set next value</Button>
34
+ </div>
35
+ <output aria-label="Controlled change events">{events.join(',') || 'none'}</output>
36
+ </div>
37
+ )
38
+ }
39
+
40
+ function App() {
41
+ const [direction, setDirection] = useState<'ltr' | 'rtl'>('ltr')
42
+ const [dark, setDark] = useState(false)
43
+
44
+ return (
45
+ <main
46
+ id="main-content"
47
+ className="interaction-lab"
48
+ data-theme={activeTheme}
49
+ data-color-mode={dark ? 'dark' : 'light'}
50
+ dir={direction}
51
+ >
52
+ <header className="interaction-lab-header">
53
+ <div>
54
+ <p>Step 1 · Shared foundation</p>
55
+ <h1>Review the interaction foundation</h1>
56
+ <span>This is the behavior underneath future Charts, Database, and Calendar components—not a finished product component.</span>
57
+ </div>
58
+ <div className="interaction-lab-controls" aria-label="Preview controls">
59
+ <Button variant="outline" onClick={() => setDirection((value) => value === 'ltr' ? 'rtl' : 'ltr')}>
60
+ {direction === 'ltr' ? 'Test RTL' : 'Test LTR'}
61
+ </Button>
62
+ <Button variant="outline" onClick={() => setDark((value) => !value)}>
63
+ {dark ? 'Use light mode' : 'Use dark mode'}
64
+ </Button>
65
+ </div>
66
+ </header>
67
+
68
+ <section className="review-guide" aria-labelledby="review-guide-title">
69
+ <div className="review-guide-intro">
70
+ <p>What am I reviewing?</p>
71
+ <h2 id="review-guide-title">Four interactions in about one minute</h2>
72
+ <span>If each task feels predictable and the page never overflows, the shared foundation is ready for the next component family.</span>
73
+ </div>
74
+ <ol className="review-checklist">
75
+ <li><strong>Select</strong><span>Click a stage, or focus it and press Space.</span></li>
76
+ <li><strong>Move and undo</strong><span>Drag a stage or use − / +, then choose Undo.</span></li>
77
+ <li><strong>Stress the list</strong><span>Resize and scroll the 1,000-record preview.</span></li>
78
+ <li><strong>Check direction</strong><span>Switch to RTL and use the arrow keys again.</span></li>
79
+ </ol>
80
+ </section>
81
+
82
+ <nav className="foundation-roadmap" aria-label="Complex component delivery order">
83
+ <span data-current="true">1. Interaction foundation</span>
84
+ <span>2. Charts</span>
85
+ <span>3. Database</span>
86
+ <span>4. Calendar</span>
87
+ </nav>
88
+
89
+ <InteractionWorkbench direction={direction} />
90
+
91
+ <details className="developer-evidence">
92
+ <summary>Developer evidence: controlled state event ordering</summary>
93
+ <p>This automated fixture verifies that setting the same value emits no change and the next value emits exactly once.</p>
94
+ <StateContractProbe />
95
+ </details>
96
+ </main>
97
+ )
98
+ }
99
+
100
+ createRoot(document.getElementById('root')!).render(
101
+ <StrictMode>
102
+ <App />
103
+ </StrictMode>,
104
+ )
@@ -0,0 +1,224 @@
1
+ @import './interaction-workbench.css';
2
+
3
+ * {
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ html,
8
+ body,
9
+ #root {
10
+ min-block-size: 100%;
11
+ margin: 0;
12
+ }
13
+
14
+ body {
15
+ background: var(--background);
16
+ color: var(--foreground);
17
+ font-family: var(--font-sans);
18
+ }
19
+
20
+ .skip-link {
21
+ position: fixed;
22
+ inset-block-start: var(--space-2);
23
+ inset-inline-start: var(--space-2);
24
+ z-index: var(--z-modal);
25
+ translate: 0 -200%;
26
+ }
27
+
28
+ .skip-link:focus {
29
+ translate: 0;
30
+ }
31
+
32
+ .interaction-lab {
33
+ min-block-size: 100vh;
34
+ padding: var(--page-gutter);
35
+ background: var(--background);
36
+ color: var(--foreground);
37
+ }
38
+
39
+ .interaction-lab-header {
40
+ display: flex;
41
+ align-items: end;
42
+ justify-content: space-between;
43
+ gap: var(--space-6);
44
+ max-inline-size: var(--container-standard);
45
+ margin-inline: auto;
46
+ padding-block: var(--space-8);
47
+ border-block-end: var(--border-width-hairline) solid var(--border);
48
+ }
49
+
50
+ .interaction-lab-header > div:first-child {
51
+ display: grid;
52
+ gap: var(--space-2);
53
+ max-inline-size: 48rem;
54
+ }
55
+
56
+ .interaction-lab-header h1,
57
+ .interaction-lab-header p {
58
+ margin: 0;
59
+ }
60
+
61
+ .interaction-lab-header p,
62
+ .interaction-lab-header span {
63
+ color: var(--muted-foreground);
64
+ }
65
+
66
+ .review-guide {
67
+ display: grid;
68
+ grid-template-columns: minmax(16rem, .7fr) minmax(0, 1.3fr);
69
+ gap: var(--space-6);
70
+ max-inline-size: var(--container-standard);
71
+ margin: var(--space-6) auto 0;
72
+ padding: var(--space-6);
73
+ border: var(--border-width-hairline) solid var(--border);
74
+ background: var(--surface);
75
+ }
76
+
77
+ .review-guide-intro {
78
+ display: grid;
79
+ align-content: start;
80
+ gap: var(--space-2);
81
+ }
82
+
83
+ .review-guide-intro h2,
84
+ .review-guide-intro p {
85
+ margin: 0;
86
+ }
87
+
88
+ .review-guide-intro p {
89
+ color: var(--muted-foreground);
90
+ font-size: var(--font-size-eyebrow);
91
+ font-weight: var(--font-weight-semibold);
92
+ letter-spacing: var(--tracking-eyebrow);
93
+ text-transform: uppercase;
94
+ }
95
+
96
+ .review-guide-intro span,
97
+ .review-checklist span,
98
+ .developer-evidence > p {
99
+ color: var(--muted-foreground);
100
+ line-height: var(--line-height-body);
101
+ }
102
+
103
+ .review-checklist {
104
+ display: grid;
105
+ grid-template-columns: repeat(2, minmax(0, 1fr));
106
+ gap: var(--space-2);
107
+ margin: 0;
108
+ padding: 0;
109
+ list-style: none;
110
+ counter-reset: review-task;
111
+ }
112
+
113
+ .review-checklist li {
114
+ display: grid;
115
+ align-content: start;
116
+ gap: var(--space-1);
117
+ min-block-size: 7rem;
118
+ padding: var(--space-3);
119
+ border: var(--border-width-hairline) solid var(--border);
120
+ background: var(--background);
121
+ counter-increment: review-task;
122
+ }
123
+
124
+ .review-checklist strong::before {
125
+ content: counter(review-task) ". ";
126
+ color: var(--muted-foreground);
127
+ }
128
+
129
+ .foundation-roadmap {
130
+ display: grid;
131
+ grid-template-columns: repeat(4, minmax(0, 1fr));
132
+ max-inline-size: var(--container-standard);
133
+ margin: var(--space-4) auto 0;
134
+ border-block: var(--border-width-hairline) solid var(--border);
135
+ }
136
+
137
+ .foundation-roadmap span {
138
+ padding: var(--space-3);
139
+ color: var(--muted-foreground);
140
+ font-size: var(--font-size-small);
141
+ text-align: center;
142
+ }
143
+
144
+ .foundation-roadmap span[data-current='true'] {
145
+ background: var(--interaction-selection-surface);
146
+ color: var(--foreground);
147
+ font-weight: var(--font-weight-semibold);
148
+ }
149
+
150
+ .interaction-lab-controls {
151
+ display: flex;
152
+ flex-wrap: wrap;
153
+ gap: var(--space-2);
154
+ }
155
+
156
+ .interaction-workbench {
157
+ max-inline-size: var(--container-standard);
158
+ margin-inline: auto;
159
+ }
160
+
161
+ .developer-evidence {
162
+ max-inline-size: var(--container-standard);
163
+ margin: var(--space-4) auto;
164
+ padding: var(--space-4);
165
+ border: var(--border-width-hairline) solid var(--border);
166
+ background: var(--surface);
167
+ }
168
+
169
+ .developer-evidence summary {
170
+ cursor: pointer;
171
+ font-weight: var(--font-weight-semibold);
172
+ }
173
+
174
+ .state-contract-probe {
175
+ display: grid;
176
+ grid-template-columns: minmax(0, 1fr) auto auto minmax(8rem, auto);
177
+ align-items: center;
178
+ gap: var(--space-3);
179
+ margin-block-start: var(--space-3);
180
+ padding-block-start: var(--space-3);
181
+ border-block-start: var(--border-width-hairline) solid var(--border);
182
+ }
183
+
184
+ .state-contract-probe h3,
185
+ .state-contract-probe p {
186
+ margin: 0;
187
+ }
188
+
189
+ .state-contract-probe p {
190
+ color: var(--muted-foreground);
191
+ font-size: var(--font-size-small);
192
+ }
193
+
194
+ .state-contract-probe > div {
195
+ display: flex;
196
+ flex-wrap: wrap;
197
+ gap: var(--space-2);
198
+ }
199
+
200
+ @media (max-width: 44rem) {
201
+ .interaction-lab-header {
202
+ align-items: start;
203
+ flex-direction: column;
204
+ }
205
+
206
+ .review-guide,
207
+ .review-checklist,
208
+ .foundation-roadmap,
209
+ .state-contract-probe {
210
+ grid-template-columns: 1fr;
211
+ }
212
+
213
+ .review-guide {
214
+ padding: var(--space-4);
215
+ }
216
+
217
+ .review-checklist li {
218
+ min-block-size: auto;
219
+ }
220
+
221
+ .foundation-roadmap span {
222
+ text-align: start;
223
+ }
224
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "id": "template-interaction-lab",
3
+ "name": "Interaction Lab",
4
+ "category": "development-tool",
5
+ "status": "available",
6
+ "purpose": "A runnable contract lab for developing and verifying Ceramic complex components.",
7
+ "packageImport": "@utopia-studio-design/design-system",
8
+ "sourcePath": "templates/interaction-lab/main.tsx",
9
+ "entryPath": "templates/interaction-lab/index.html",
10
+ "requiredTokens": [
11
+ "interaction-density-*",
12
+ "interaction-focus",
13
+ "interaction-selection-*",
14
+ "interaction-drag-*",
15
+ "visualization-*",
16
+ "temporal-*"
17
+ ],
18
+ "features": {
19
+ "selection": true,
20
+ "keyboardNavigation": true,
21
+ "pointerDrag": true,
22
+ "touchAlternatives": true,
23
+ "resize": true,
24
+ "virtualization": true,
25
+ "undoRedo": true,
26
+ "rtl": true,
27
+ "reducedMotion": true,
28
+ "responsiveMinimum": "320px"
29
+ },
30
+ "translations": {
31
+ "ar": {
32
+ "name": "مختبر التفاعل",
33
+ "purpose": "مختبر قابل للتشغيل للتحقق من عقود التفاعل المشتركة في Ceramic."
34
+ }
35
+ }
36
+ }