@ai-composer/themes 0.1.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.
- package/LICENSE +21 -0
- package/README.md +6 -0
- package/css/compact.css +10 -0
- package/css/dark.css +38 -0
- package/css/default.css +525 -0
- package/css/tokens.css +67 -0
- package/dist/css/compact.css +10 -0
- package/dist/css/dark.css +38 -0
- package/dist/css/default.css +525 -0
- package/dist/css/tokens.css +67 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/package.json +25 -0
- package/package.json +24 -0
- package/project.json +61 -0
- package/src/index.ts +64 -0
- package/tsconfig.json +15 -0
- package/tsconfig.lib.json +15 -0
- package/tsconfig.spec.json +16 -0
- package/vitest.config.ts +11 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/* Dark theme — override tokens only; structure comes from default.css.
|
|
2
|
+
Opt-in: set data-aic-theme="dark" on <html> (or any ancestor, or the
|
|
3
|
+
.aic-root element itself). Importing this file alone changes nothing.
|
|
4
|
+
The send button inverts: light circle, dark glyph. */
|
|
5
|
+
|
|
6
|
+
.aic-root[data-aic-theme='dark'],
|
|
7
|
+
[data-aic-theme='dark'] .aic-root {
|
|
8
|
+
--aic-background: #202024;
|
|
9
|
+
--aic-surface-raised: #2b2b31;
|
|
10
|
+
--aic-surface-hover: #35353c;
|
|
11
|
+
--aic-border: rgb(255 255 255 / 14%);
|
|
12
|
+
--aic-border-focus: #5ed6c0;
|
|
13
|
+
|
|
14
|
+
--aic-text: #f4f4f5;
|
|
15
|
+
--aic-text-muted: #a1a1aa;
|
|
16
|
+
--aic-text-placeholder: #565660;
|
|
17
|
+
|
|
18
|
+
--aic-accent: #fafafa;
|
|
19
|
+
--aic-accent-hover: #d4d4d8;
|
|
20
|
+
--aic-accent-contrast: #18181b;
|
|
21
|
+
--aic-accent-disabled: #3f3f46;
|
|
22
|
+
--aic-accent-disabled-contrast: #c4c4cc;
|
|
23
|
+
|
|
24
|
+
--aic-chip-background: #2b2b31;
|
|
25
|
+
--aic-chip-text: #d4d4d8;
|
|
26
|
+
--aic-chip-mention-background: #1c2c47;
|
|
27
|
+
--aic-chip-mention-text: #8cb4f8;
|
|
28
|
+
--aic-chip-command-background: #2e2246;
|
|
29
|
+
--aic-chip-command-text: #c4a8fb;
|
|
30
|
+
--aic-chip-variable-background: #3a2f16;
|
|
31
|
+
--aic-chip-variable-text: #ecc36b;
|
|
32
|
+
--aic-chip-hashtag-background: #14352a;
|
|
33
|
+
--aic-chip-hashtag-text: #7ed9a9;
|
|
34
|
+
|
|
35
|
+
--aic-shadow: 0 1px 2px rgb(0 0 0 / 40%), 0 4px 12px rgb(0 0 0 / 30%);
|
|
36
|
+
--aic-shadow-raised: 0 4px 6px -1px rgb(0 0 0 / 40%), 0 2px 4px -2px rgb(0 0 0 / 40%);
|
|
37
|
+
--aic-focus-ring: 0 0 0 3px rgb(94 214 192 / 18%);
|
|
38
|
+
}
|
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
/* Default theme — calm neutral composer (editor-area aesthetic).
|
|
2
|
+
Structure comes from core/dom (data-aic-*); every value flows from tokens.
|
|
3
|
+
Import order: tokens.css → default.css → (dark|compact).css → your overrides.
|
|
4
|
+
|
|
5
|
+
Modes are visually distinct:
|
|
6
|
+
compact — single-line pill, no chrome
|
|
7
|
+
chat — auto-growing multiline box, attachments row, circular send button
|
|
8
|
+
expanded — tall canvas with header, rich toolbar and footer
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
@import './tokens.css';
|
|
12
|
+
|
|
13
|
+
/* Scoped reset so min-/max-height math includes padding (height caps work). */
|
|
14
|
+
.aic-root,
|
|
15
|
+
.aic-root *,
|
|
16
|
+
.aic-root *::before,
|
|
17
|
+
.aic-root *::after {
|
|
18
|
+
box-sizing: border-box;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Mode presets hide slots with [hidden]; slot display rules (flex) must not
|
|
22
|
+
resurrect them. */
|
|
23
|
+
.aic-root [hidden] {
|
|
24
|
+
display: none !important;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* ------------------------------------------------------------------ root */
|
|
28
|
+
.aic-root {
|
|
29
|
+
position: relative;
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
min-width: 0;
|
|
33
|
+
background: var(--aic-background);
|
|
34
|
+
border: var(--aic-border-width) solid var(--aic-border);
|
|
35
|
+
border-radius: var(--aic-radius);
|
|
36
|
+
box-shadow: var(--aic-shadow);
|
|
37
|
+
font-family: var(--aic-font-family);
|
|
38
|
+
font-size: var(--aic-font-size);
|
|
39
|
+
color: var(--aic-text);
|
|
40
|
+
line-height: 1.6;
|
|
41
|
+
transition:
|
|
42
|
+
border-color var(--aic-transition),
|
|
43
|
+
box-shadow var(--aic-transition),
|
|
44
|
+
background-color var(--aic-transition);
|
|
45
|
+
/* Auto-height ceiling: grows with content up to this, then scrolls inside.
|
|
46
|
+
Modes retune it; values may use viewport units so the box never outgrows
|
|
47
|
+
the space actually available. */
|
|
48
|
+
--aic-input-max-height: 200px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.aic-root:focus-within {
|
|
52
|
+
border-color: var(--aic-border-focus);
|
|
53
|
+
box-shadow: var(--aic-focus-ring), var(--aic-shadow);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.aic-root[data-aic-disabled='true'] {
|
|
57
|
+
opacity: 0.55;
|
|
58
|
+
pointer-events: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.aic-body {
|
|
62
|
+
position: relative; /* anchor for custom-renderer suggestion popups */
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* --------------------------------------------------- input + popup anchor */
|
|
68
|
+
/* The wrapper occupies exactly the input's space; popups float out of it. */
|
|
69
|
+
.aic-input-wrap {
|
|
70
|
+
position: relative;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.aic-input-host {
|
|
74
|
+
display: block;
|
|
75
|
+
height: auto; /* auto-grow: the box expands with content */
|
|
76
|
+
padding: var(--aic-input-padding);
|
|
77
|
+
min-height: var(--aic-input-min-height);
|
|
78
|
+
max-height: var(--aic-input-max-height); /* cap: scroll once space runs out */
|
|
79
|
+
outline: none;
|
|
80
|
+
overflow-y: auto;
|
|
81
|
+
white-space: pre-wrap;
|
|
82
|
+
word-break: break-word;
|
|
83
|
+
line-height: 1.55;
|
|
84
|
+
caret-color: var(--aic-accent);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* placeholder — empty and unfocused. Clicking in (focus) clears it so the
|
|
88
|
+
caret stands alone; it returns as soon as the box is empty and blurred. */
|
|
89
|
+
.aic-input-host[data-aic-empty=''][data-placeholder]:not(:focus)::before {
|
|
90
|
+
content: attr(data-placeholder);
|
|
91
|
+
color: var(--aic-text-placeholder);
|
|
92
|
+
pointer-events: none;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* ------------------------------------------------------------- chips */
|
|
96
|
+
.aic-chip {
|
|
97
|
+
display: inline-flex;
|
|
98
|
+
align-items: center;
|
|
99
|
+
position: relative;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
background: var(--aic-chip-background);
|
|
102
|
+
color: var(--aic-chip-text);
|
|
103
|
+
border-radius: var(--aic-chip-radius);
|
|
104
|
+
margin: 0 1px;
|
|
105
|
+
padding: 1px 6px;
|
|
106
|
+
font-size: 0.875em;
|
|
107
|
+
font-weight: 500;
|
|
108
|
+
line-height: 1.5;
|
|
109
|
+
white-space: nowrap;
|
|
110
|
+
cursor: pointer;
|
|
111
|
+
user-select: none;
|
|
112
|
+
vertical-align: baseline;
|
|
113
|
+
transition:
|
|
114
|
+
background-color var(--aic-transition),
|
|
115
|
+
transform 150ms cubic-bezier(0.4, 0, 0.2, 1),
|
|
116
|
+
box-shadow var(--aic-transition);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.aic-chip:hover {
|
|
120
|
+
background: var(--aic-surface-hover);
|
|
121
|
+
box-shadow: 0 1px 4px rgb(0 0 0 / 8%);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.aic-chip:active {
|
|
125
|
+
transform: scale(0.93);
|
|
126
|
+
background: var(--aic-surface-hover);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* semantic tints per node type */
|
|
130
|
+
.aic-chip[data-aic-node='mention'] {
|
|
131
|
+
background: var(--aic-chip-mention-background);
|
|
132
|
+
color: var(--aic-chip-mention-text);
|
|
133
|
+
}
|
|
134
|
+
.aic-chip[data-aic-node='command'] {
|
|
135
|
+
background: var(--aic-chip-command-background);
|
|
136
|
+
color: var(--aic-chip-command-text);
|
|
137
|
+
}
|
|
138
|
+
.aic-chip[data-aic-node='variable'] {
|
|
139
|
+
background: var(--aic-chip-variable-background);
|
|
140
|
+
color: var(--aic-chip-variable-text);
|
|
141
|
+
}
|
|
142
|
+
.aic-chip[data-aic-node='custom'] {
|
|
143
|
+
background: var(--aic-chip-hashtag-background);
|
|
144
|
+
color: var(--aic-chip-hashtag-text);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* ------------------------------------------------------- suggestion popup */
|
|
148
|
+
/* True popup: absolutely positioned by the dom layer inside .aic-input-wrap.
|
|
149
|
+
It never reserves layout space. */
|
|
150
|
+
.aic-suggestions {
|
|
151
|
+
list-style: none;
|
|
152
|
+
box-sizing: border-box;
|
|
153
|
+
margin: 0;
|
|
154
|
+
min-width: 230px;
|
|
155
|
+
max-height: 260px;
|
|
156
|
+
padding: 6px;
|
|
157
|
+
background: var(--aic-background);
|
|
158
|
+
border: var(--aic-border-width) solid var(--aic-border);
|
|
159
|
+
border-radius: 12px;
|
|
160
|
+
box-shadow: var(--aic-shadow-raised);
|
|
161
|
+
overflow-y: auto;
|
|
162
|
+
overscroll-behavior: contain;
|
|
163
|
+
z-index: var(--aic-z-suggestions);
|
|
164
|
+
animation: aic-pop-in 140ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@keyframes aic-pop-in {
|
|
168
|
+
from {
|
|
169
|
+
opacity: 0;
|
|
170
|
+
transform: scale(0.97) translateY(2px);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.aic-suggestion {
|
|
175
|
+
display: flex;
|
|
176
|
+
flex-direction: column;
|
|
177
|
+
gap: 1px;
|
|
178
|
+
padding: 6px 10px;
|
|
179
|
+
border-radius: var(--aic-radius-sm);
|
|
180
|
+
cursor: pointer;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.aic-suggestion.aic-active,
|
|
184
|
+
.aic-suggestion:hover {
|
|
185
|
+
background: var(--aic-surface-raised);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.aic-suggestion-label {
|
|
189
|
+
font-weight: 500;
|
|
190
|
+
font-size: 0.9em;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.aic-suggestion-description {
|
|
194
|
+
color: var(--aic-text-muted);
|
|
195
|
+
font-size: 0.8em;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* Decorative keyboard-hints footer */
|
|
199
|
+
.aic-suggestion-footer {
|
|
200
|
+
display: flex;
|
|
201
|
+
align-items: center;
|
|
202
|
+
gap: 4px;
|
|
203
|
+
margin-top: 4px;
|
|
204
|
+
padding: 6px 10px 4px;
|
|
205
|
+
border-top: var(--aic-border-width) solid var(--aic-border);
|
|
206
|
+
color: var(--aic-text-placeholder);
|
|
207
|
+
font-size: 11.5px;
|
|
208
|
+
cursor: default;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.aic-suggestion-footer kbd {
|
|
212
|
+
font-family: var(--aic-font-family);
|
|
213
|
+
font-size: 10.5px;
|
|
214
|
+
line-height: 1;
|
|
215
|
+
padding: 2px 5px;
|
|
216
|
+
border: var(--aic-border-width) solid var(--aic-border);
|
|
217
|
+
border-bottom-width: 2px;
|
|
218
|
+
border-radius: 4px;
|
|
219
|
+
background: var(--aic-surface-raised);
|
|
220
|
+
color: var(--aic-text-muted);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.aic-suggestion-footer span {
|
|
224
|
+
flex: 1;
|
|
225
|
+
text-align: center;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.aic-suggestion-footer span::before {
|
|
229
|
+
content: '·';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* ------------------------------------------------------- attachments row */
|
|
233
|
+
.aic-attachments {
|
|
234
|
+
display: flex;
|
|
235
|
+
flex-wrap: wrap;
|
|
236
|
+
gap: 6px;
|
|
237
|
+
padding: var(--aic-input-padding) ;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.aic-attachment {
|
|
241
|
+
display: inline-flex;
|
|
242
|
+
align-items: center;
|
|
243
|
+
gap: 6px;
|
|
244
|
+
background: var(--aic-surface-raised);
|
|
245
|
+
border: none;
|
|
246
|
+
border-radius: 8px;
|
|
247
|
+
padding: 3px 8px;
|
|
248
|
+
font-size: 0.85em;
|
|
249
|
+
color: var(--aic-text);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.aic-attachment-remove {
|
|
253
|
+
display: inline-flex;
|
|
254
|
+
align-items: center;
|
|
255
|
+
justify-content: center;
|
|
256
|
+
border: none;
|
|
257
|
+
background: none;
|
|
258
|
+
color: var(--aic-text-muted);
|
|
259
|
+
cursor: pointer;
|
|
260
|
+
padding: 2px;
|
|
261
|
+
line-height: 0;
|
|
262
|
+
border-radius: 4px;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.aic-attachment-remove:hover {
|
|
266
|
+
color: var(--aic-text);
|
|
267
|
+
background: var(--aic-surface-hover);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* ------------------------------------------------------------ toolbar */
|
|
271
|
+
.aic-toolbar {
|
|
272
|
+
display: flex;
|
|
273
|
+
align-items: center;
|
|
274
|
+
justify-content: flex-end;
|
|
275
|
+
gap: 8px;
|
|
276
|
+
min-height: var(--aic-toolbar-height);
|
|
277
|
+
padding: 6px 12px 10px;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* Circular ghost icon buttons */
|
|
281
|
+
.aic-toolbar button {
|
|
282
|
+
min-width: 32px;
|
|
283
|
+
height: 32px;
|
|
284
|
+
padding: 0;
|
|
285
|
+
border: none;
|
|
286
|
+
border-radius: 999px;
|
|
287
|
+
background: transparent;
|
|
288
|
+
color: var(--aic-text-muted);
|
|
289
|
+
font-size: 1em;
|
|
290
|
+
line-height: 1;
|
|
291
|
+
cursor: pointer;
|
|
292
|
+
display: inline-flex;
|
|
293
|
+
align-items: center;
|
|
294
|
+
justify-content: center;
|
|
295
|
+
transition: background var(--aic-transition), color var(--aic-transition),
|
|
296
|
+
transform 100ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.aic-toolbar button svg {
|
|
300
|
+
display: block;
|
|
301
|
+
pointer-events: none;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.aic-toolbar button:hover:not(:disabled) {
|
|
305
|
+
background: var(--aic-surface-raised);
|
|
306
|
+
color: var(--aic-text);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.aic-toolbar button:active:not(:disabled) {
|
|
310
|
+
transform: scale(0.92);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.aic-toolbar button:disabled {
|
|
314
|
+
opacity: 0.4;
|
|
315
|
+
cursor: default;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.aic-toolbar button:focus-visible {
|
|
319
|
+
outline: 2px solid var(--aic-border-focus);
|
|
320
|
+
outline-offset: 1px;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* Send — the primary action: solid circle, inverted in dark themes */
|
|
324
|
+
.aic-toolbar button[data-aic-action='submit'] {
|
|
325
|
+
width: 36px;
|
|
326
|
+
min-width: 36px;
|
|
327
|
+
height: 36px;
|
|
328
|
+
padding: 0;
|
|
329
|
+
background: var(--aic-accent);
|
|
330
|
+
color: var(--aic-accent-contrast);
|
|
331
|
+
box-shadow: 0 1px 2px rgb(15 118 110 / 18%);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.aic-toolbar button[data-aic-action='submit']:hover:not(:disabled) {
|
|
335
|
+
background: var(--aic-accent-hover);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.aic-toolbar button[data-aic-action='submit']:active:not(:disabled) {
|
|
339
|
+
transform: scale(0.92);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.aic-toolbar button[data-aic-action='submit']:disabled {
|
|
343
|
+
background: var(--aic-accent-disabled);
|
|
344
|
+
color: var(--aic-accent-disabled-contrast);
|
|
345
|
+
opacity: 1;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/* Submit loading state */
|
|
349
|
+
.aic-spinner {
|
|
350
|
+
display: inline-block;
|
|
351
|
+
width: 14px;
|
|
352
|
+
height: 14px;
|
|
353
|
+
border: 2px solid currentColor;
|
|
354
|
+
border-right-color: transparent;
|
|
355
|
+
border-radius: 50%;
|
|
356
|
+
animation: aic-spin 0.7s linear infinite;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
@keyframes aic-spin {
|
|
360
|
+
to {
|
|
361
|
+
transform: rotate(360deg);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.aic-header,
|
|
366
|
+
.aic-footer {
|
|
367
|
+
padding: 8px 16px;
|
|
368
|
+
color: var(--aic-text-muted);
|
|
369
|
+
font-size: 0.9em;
|
|
370
|
+
}
|
|
371
|
+
.aic-header:is(:empty),
|
|
372
|
+
.aic-footer:is(:empty) {
|
|
373
|
+
display: none;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/* ======================================================================
|
|
377
|
+
MODES — visually distinct presets
|
|
378
|
+
====================================================================== */
|
|
379
|
+
|
|
380
|
+
/* COMPACT — inline composer (Copilot review-box style): one line with
|
|
381
|
+
[chips][input …][send] inside the pill. Wrapped/newline content is
|
|
382
|
+
detected (data-aic-multiline) — the composer then morphs into a rounded
|
|
383
|
+
box where the input takes the whole area, anchored top, and the controls
|
|
384
|
+
move to their own row below. Never clips text. */
|
|
385
|
+
.aic-root[data-aic-mode='compact'] {
|
|
386
|
+
--aic-radius: 999px;
|
|
387
|
+
--aic-input-padding: 6px 16px;
|
|
388
|
+
--aic-input-min-height: 34px;
|
|
389
|
+
--aic-input-max-height: 120px;
|
|
390
|
+
flex-direction: row;
|
|
391
|
+
align-items: center;
|
|
392
|
+
box-shadow: var(--aic-shadow);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.aic-root[data-aic-mode='compact'] .aic-body {
|
|
396
|
+
flex: 1;
|
|
397
|
+
min-width: 0;
|
|
398
|
+
flex-direction: row;
|
|
399
|
+
align-items: center;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.aic-root[data-aic-mode='compact'] .aic-input-wrap {
|
|
403
|
+
flex: 1;
|
|
404
|
+
min-width: 0;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.aic-root[data-aic-mode='compact'] .aic-attachments {
|
|
408
|
+
flex: none;
|
|
409
|
+
flex-wrap: nowrap;
|
|
410
|
+
gap: 4px;
|
|
411
|
+
padding: 0 0 0 10px;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.aic-root[data-aic-mode='compact'] .aic-toolbar {
|
|
415
|
+
flex: none;
|
|
416
|
+
min-height: 0;
|
|
417
|
+
gap: 0;
|
|
418
|
+
padding: 0 5px 0 0;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.aic-root[data-aic-mode='compact'] .aic-toolbar button {
|
|
422
|
+
width: 30px;
|
|
423
|
+
min-width: 30px;
|
|
424
|
+
height: 30px;
|
|
425
|
+
padding: 0;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.aic-root[data-aic-mode='compact'] .aic-toolbar button[data-aic-action='submit'] {
|
|
429
|
+
width: 30px;
|
|
430
|
+
min-width: 30px;
|
|
431
|
+
height: 30px;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/* Multiline — the input takes over: full area, top-anchored; chips and
|
|
435
|
+
controls move to their own rows (chat-like layout). The multiline flag
|
|
436
|
+
is mirrored onto the root as data-aic-multiline (plain attribute —
|
|
437
|
+
:has()-based rules are still dropped by some engine versions). */
|
|
438
|
+
.aic-root[data-aic-mode='compact'][data-aic-multiline] {
|
|
439
|
+
--aic-radius: 16px;
|
|
440
|
+
flex-direction: column;
|
|
441
|
+
align-items: stretch;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.aic-root[data-aic-mode='compact'][data-aic-multiline] .aic-body {
|
|
445
|
+
flex-direction: column;
|
|
446
|
+
align-items: stretch; /* reset the one-line `center` — input takes full width */
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.aic-root[data-aic-mode='compact'][data-aic-multiline] .aic-input-host {
|
|
450
|
+
min-height: 60px;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
.aic-root[data-aic-mode='compact'][data-aic-multiline] .aic-attachments {
|
|
454
|
+
flex-wrap: wrap;
|
|
455
|
+
padding: 10px 14px 0;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.aic-root[data-aic-mode='compact'][data-aic-multiline] .aic-toolbar {
|
|
459
|
+
padding: 4px 8px 8px;
|
|
460
|
+
justify-content: flex-end;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/* CHAT — auto-growing box: starts small, grows to a cap */
|
|
464
|
+
.aic-root[data-aic-mode='chat'] {
|
|
465
|
+
--aic-input-min-height: 28px;
|
|
466
|
+
--aic-radius: 16px;
|
|
467
|
+
--aic-input-max-height: min(200px, 55vh);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
@supports (height: 1dvh) {
|
|
471
|
+
.aic-root[data-aic-mode='chat'] {
|
|
472
|
+
--aic-input-max-height: min(200px, 55dvh);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.aic-root[data-aic-mode='chat'] .aic-input-host {
|
|
477
|
+
padding: 14px 16px 2px;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
.aic-root[data-aic-mode='chat'] .aic-toolbar {
|
|
481
|
+
border-top: none;
|
|
482
|
+
padding: 4px 8px 8px;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/* EXPANDED — a tall writing canvas with full chrome */
|
|
486
|
+
.aic-root[data-aic-mode='expanded'] {
|
|
487
|
+
--aic-radius: 20px;
|
|
488
|
+
--aic-input-min-height: 220px;
|
|
489
|
+
--aic-input-max-height: 60vh;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
@supports (height: 1dvh) {
|
|
493
|
+
.aic-root[data-aic-mode='expanded'] {
|
|
494
|
+
--aic-input-max-height: 60dvh;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.aic-root[data-aic-mode='expanded'] .aic-toolbar {
|
|
499
|
+
border-top: var(--aic-border-width) solid var(--aic-border);
|
|
500
|
+
justify-content: space-between;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.aic-root[data-aic-mode='expanded'] .aic-toolbar::before {
|
|
504
|
+
content: 'Expanded editor';
|
|
505
|
+
font-size: 0.8em;
|
|
506
|
+
color: var(--aic-text-placeholder);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/* ------------------------------------------------------ a11y preferences */
|
|
510
|
+
@media (prefers-reduced-motion: reduce) {
|
|
511
|
+
.aic-root,
|
|
512
|
+
.aic-root * {
|
|
513
|
+
transition: none !important;
|
|
514
|
+
animation: none !important;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
@media (prefers-contrast: more) {
|
|
519
|
+
.aic-root {
|
|
520
|
+
border-width: 2px;
|
|
521
|
+
}
|
|
522
|
+
.aic-suggestion.aic-active {
|
|
523
|
+
outline: 2px solid currentColor;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design tokens — the only styling contract. Every visual default flows from
|
|
3
|
+
* CSS custom properties; no hard-coded colors or dimensions in core/dom
|
|
4
|
+
* (ADR-0007). Applications override any token, any theme can replace any
|
|
5
|
+
* layer:
|
|
6
|
+
*
|
|
7
|
+
* core tokens → default theme → mode theme → app theme → component overrides
|
|
8
|
+
*
|
|
9
|
+
* Palette: neutral zinc scale, near-black primary action — the editor reads
|
|
10
|
+
* calm and framework-native instead of arriving with a brand color.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
:root {
|
|
14
|
+
/* surface */
|
|
15
|
+
--aic-background: #ffffff;
|
|
16
|
+
--aic-surface-raised: #f4f4f5;
|
|
17
|
+
--aic-surface-hover: #e4e4e7;
|
|
18
|
+
--aic-border: #e4e4e7;
|
|
19
|
+
--aic-border-focus: #0f766e;
|
|
20
|
+
|
|
21
|
+
/* text */
|
|
22
|
+
--aic-text: #18181b;
|
|
23
|
+
--aic-text-muted: #71717a;
|
|
24
|
+
--aic-text-placeholder: #a1a1aa;
|
|
25
|
+
|
|
26
|
+
/* primary action (send) */
|
|
27
|
+
--aic-accent: #0f766e;
|
|
28
|
+
--aic-accent-hover: #115e59;
|
|
29
|
+
--aic-accent-contrast: #f0fdfa;
|
|
30
|
+
--aic-accent-disabled: #dce8e5;
|
|
31
|
+
--aic-accent-disabled-contrast: #647b76;
|
|
32
|
+
|
|
33
|
+
/* chips — neutral base, semantic tint per node type */
|
|
34
|
+
--aic-chip-background: #f4f4f5;
|
|
35
|
+
--aic-chip-text: #3f3f46;
|
|
36
|
+
--aic-chip-radius: 4px;
|
|
37
|
+
--aic-chip-mention-background: #e8f1ff;
|
|
38
|
+
--aic-chip-mention-text: #1d5fd6;
|
|
39
|
+
--aic-chip-command-background: #f3ecfe;
|
|
40
|
+
--aic-chip-command-text: #7a3af0;
|
|
41
|
+
--aic-chip-variable-background: #fdf3d5;
|
|
42
|
+
--aic-chip-variable-text: #96660a;
|
|
43
|
+
--aic-chip-hashtag-background: #e5f8ed;
|
|
44
|
+
--aic-chip-hashtag-text: #177245;
|
|
45
|
+
|
|
46
|
+
/* geometry */
|
|
47
|
+
--aic-radius: 12px;
|
|
48
|
+
--aic-radius-sm: 8px;
|
|
49
|
+
--aic-border-width: 1px;
|
|
50
|
+
--aic-input-padding: 12px 16px;
|
|
51
|
+
--aic-input-min-height: 52px;
|
|
52
|
+
--aic-input-max-height: 40vh;
|
|
53
|
+
--aic-toolbar-height: 44px;
|
|
54
|
+
--aic-font-size: 15px;
|
|
55
|
+
--aic-font-family: inherit;
|
|
56
|
+
|
|
57
|
+
/* effects */
|
|
58
|
+
--aic-shadow: 0 1px 2px rgb(24 24 27 / 4%), 0 5px 16px rgb(24 24 27 / 7%);
|
|
59
|
+
--aic-shadow-raised: 0 4px 6px -1px rgb(0 0 0 / 10%), 0 2px 4px -2px rgb(0 0 0 / 10%);
|
|
60
|
+
--aic-focus-ring: 0 0 0 3px rgb(15 118 110 / 16%);
|
|
61
|
+
|
|
62
|
+
/* motion */
|
|
63
|
+
--aic-transition: 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
64
|
+
|
|
65
|
+
/* z-index scale */
|
|
66
|
+
--aic-z-suggestions: 30;
|
|
67
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ai-composer/themes — design tokens and theme presets.
|
|
3
|
+
*
|
|
4
|
+
* Import CSS by entry (package exports `./css/*`):
|
|
5
|
+
*
|
|
6
|
+
* import '@ai-composer/themes/css/tokens.css';
|
|
7
|
+
* import '@ai-composer/themes/css/default.css'; // structure, uses tokens
|
|
8
|
+
* import '@ai-composer/themes/css/dark.css'; // optional dark override
|
|
9
|
+
*
|
|
10
|
+
* Theme layers (ADR-0007):
|
|
11
|
+
* tokens → default → mode (compact) → app overrides → component overrides
|
|
12
|
+
*/
|
|
13
|
+
export declare const THEME_CSS_ENTRIES: readonly ["tokens", "default", "dark", "compact"];
|
|
14
|
+
export type ThemeCssEntry = (typeof THEME_CSS_ENTRIES)[number];
|
|
15
|
+
/** Programmatically resolve a CSS import specifier (e.g. for bundler-resolved dynamic imports). */
|
|
16
|
+
export declare function themeCss(entry: ThemeCssEntry): string;
|
|
17
|
+
/** Token names emitted by tokens.css — useful for docs tooling and lint rules. */
|
|
18
|
+
export declare const DESIGN_TOKENS: readonly ["--aic-background", "--aic-surface-raised", "--aic-surface-hover", "--aic-border", "--aic-border-focus", "--aic-text", "--aic-text-muted", "--aic-text-placeholder", "--aic-accent", "--aic-accent-hover", "--aic-accent-contrast", "--aic-accent-disabled", "--aic-chip-background", "--aic-chip-text", "--aic-chip-radius", "--aic-chip-mention-background", "--aic-chip-mention-text", "--aic-chip-command-background", "--aic-chip-command-text", "--aic-chip-variable-background", "--aic-chip-variable-text", "--aic-chip-hashtag-background", "--aic-chip-hashtag-text", "--aic-radius", "--aic-radius-sm", "--aic-border-width", "--aic-input-padding", "--aic-input-min-height", "--aic-input-max-height", "--aic-toolbar-height", "--aic-font-size", "--aic-font-family", "--aic-shadow", "--aic-shadow-raised", "--aic-focus-ring", "--aic-transition", "--aic-z-suggestions"];
|
|
19
|
+
export type DesignToken = (typeof DESIGN_TOKENS)[number];
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,iBAAiB,mDAAoD,CAAC;AAEnF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,mGAAmG;AACnG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAErD;AAED,kFAAkF;AAClF,eAAO,MAAM,aAAa,q2BAsChB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ai-composer/themes — design tokens and theme presets.
|
|
3
|
+
*
|
|
4
|
+
* Import CSS by entry (package exports `./css/*`):
|
|
5
|
+
*
|
|
6
|
+
* import '@ai-composer/themes/css/tokens.css';
|
|
7
|
+
* import '@ai-composer/themes/css/default.css'; // structure, uses tokens
|
|
8
|
+
* import '@ai-composer/themes/css/dark.css'; // optional dark override
|
|
9
|
+
*
|
|
10
|
+
* Theme layers (ADR-0007):
|
|
11
|
+
* tokens → default → mode (compact) → app overrides → component overrides
|
|
12
|
+
*/
|
|
13
|
+
export const THEME_CSS_ENTRIES = ['tokens', 'default', 'dark', 'compact'];
|
|
14
|
+
/** Programmatically resolve a CSS import specifier (e.g. for bundler-resolved dynamic imports). */
|
|
15
|
+
export function themeCss(entry) {
|
|
16
|
+
return `@ai-composer/themes/css/${entry}.css`;
|
|
17
|
+
}
|
|
18
|
+
/** Token names emitted by tokens.css — useful for docs tooling and lint rules. */
|
|
19
|
+
export const DESIGN_TOKENS = [
|
|
20
|
+
'--aic-background',
|
|
21
|
+
'--aic-surface-raised',
|
|
22
|
+
'--aic-surface-hover',
|
|
23
|
+
'--aic-border',
|
|
24
|
+
'--aic-border-focus',
|
|
25
|
+
'--aic-text',
|
|
26
|
+
'--aic-text-muted',
|
|
27
|
+
'--aic-text-placeholder',
|
|
28
|
+
'--aic-accent',
|
|
29
|
+
'--aic-accent-hover',
|
|
30
|
+
'--aic-accent-contrast',
|
|
31
|
+
'--aic-accent-disabled',
|
|
32
|
+
'--aic-chip-background',
|
|
33
|
+
'--aic-chip-text',
|
|
34
|
+
'--aic-chip-radius',
|
|
35
|
+
'--aic-chip-mention-background',
|
|
36
|
+
'--aic-chip-mention-text',
|
|
37
|
+
'--aic-chip-command-background',
|
|
38
|
+
'--aic-chip-command-text',
|
|
39
|
+
'--aic-chip-variable-background',
|
|
40
|
+
'--aic-chip-variable-text',
|
|
41
|
+
'--aic-chip-hashtag-background',
|
|
42
|
+
'--aic-chip-hashtag-text',
|
|
43
|
+
'--aic-radius',
|
|
44
|
+
'--aic-radius-sm',
|
|
45
|
+
'--aic-border-width',
|
|
46
|
+
'--aic-input-padding',
|
|
47
|
+
'--aic-input-min-height',
|
|
48
|
+
'--aic-input-max-height',
|
|
49
|
+
'--aic-toolbar-height',
|
|
50
|
+
'--aic-font-size',
|
|
51
|
+
'--aic-font-family',
|
|
52
|
+
'--aic-shadow',
|
|
53
|
+
'--aic-shadow-raised',
|
|
54
|
+
'--aic-focus-ring',
|
|
55
|
+
'--aic-transition',
|
|
56
|
+
'--aic-z-suggestions',
|
|
57
|
+
];
|
|
58
|
+
//# sourceMappingURL=index.js.map
|