anentrypoint-design 0.0.322 → 0.0.324

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 (45) hide show
  1. package/README.md +22 -2
  2. package/app-shell.css +24 -4782
  3. package/colors_and_type.css +43 -0
  4. package/dist/247420.css +74 -3
  5. package/dist/247420.js +16 -16
  6. package/package.json +14 -8
  7. package/src/bootstrap.js +10 -1
  8. package/src/components/chat-message-parts.js +355 -0
  9. package/src/components/chat.js +23 -320
  10. package/src/components/data-density.js +15 -10
  11. package/src/components/files-modals.js +14 -2
  12. package/src/components/files.js +5 -1
  13. package/src/components/freddie/helpers.js +46 -8
  14. package/src/css/app-shell/base.css +157 -0
  15. package/src/css/app-shell/catalog-theme.css +144 -0
  16. package/src/css/app-shell/chat-basic.css +12 -0
  17. package/src/css/app-shell/chat-polish.css +459 -0
  18. package/src/css/app-shell/data-density.css +150 -0
  19. package/src/css/app-shell/files.css +709 -0
  20. package/src/css/app-shell/hero-content.css +407 -0
  21. package/src/css/app-shell/kits-appended.css +361 -0
  22. package/src/css/app-shell/loading-alerts.css +120 -0
  23. package/src/css/app-shell/panel-row.css +177 -0
  24. package/src/css/app-shell/primitives.css +197 -0
  25. package/src/css/app-shell/responsive.css +266 -0
  26. package/src/css/app-shell/responsive2-workspace.css +465 -0
  27. package/src/css/app-shell/row-print.css +75 -0
  28. package/src/css/app-shell/sidebar-misc.css +79 -0
  29. package/src/css/app-shell/states-interactions.css +696 -0
  30. package/src/css/app-shell/topbar.css +319 -0
  31. package/src/deck-stage.js +6 -4
  32. package/src/highlight.js +20 -4
  33. package/src/index.js +15 -5
  34. package/src/kits/os/freddie/pages-chat.js +1 -1
  35. package/src/kits/os/freddie/pages-core.js +1 -1
  36. package/src/kits/os/freddie/pages-os.js +1 -1
  37. package/src/kits/os/freddie/pages-tools.js +1 -1
  38. package/src/kits/os/wm.js +38 -0
  39. package/src/kits/slides/deck-stage-overlay.js +68 -0
  40. package/src/kits/slides/deck-stage-state.js +81 -0
  41. package/src/kits/slides/deck-stage-style.js +117 -0
  42. package/src/kits/slides/deck-stage.js +167 -0
  43. package/src/kits/slides/index.js +5 -0
  44. package/src/markdown.js +89 -11
  45. package/src/kits/os/freddie/helpers.js +0 -33
@@ -0,0 +1,361 @@
1
+ /* == appended: popovers-files == */
2
+ /* FilePreviewMedia controls row — spacing + coarse-pointer tap floor */
3
+ .ds-preview-media-controls {
4
+ display: flex;
5
+ align-items: center;
6
+ gap: var(--space-2);
7
+ flex-wrap: wrap;
8
+ }
9
+ @media (hover: none), (pointer: coarse) {
10
+ .ds-preview-media-controls .chat-code-copy,
11
+ .chat-code-copy-head {
12
+ min-height: 44px;
13
+ min-width: 44px;
14
+ }
15
+ }
16
+
17
+ /* == appended: ui-kits == */
18
+ /* ============================================================
19
+ ui_kit responsive helpers (kits-grids sweep) */
20
+ .ds-section-pad { padding: clamp(6px, 1.2vw, 16px); }
21
+ .ds-panel-gap { margin: var(--space-2) 0; }
22
+ .ds-panel-duo { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin: var(--space-2) 0; }
23
+ @media (max-width: 760px) {
24
+ .ds-panel-duo { grid-template-columns: 1fr; }
25
+ }
26
+ /* wide dense rows/tables scroll inside their panel, never the page */
27
+ .ds-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
28
+
29
+ /* --- slide deck ------------------------------------------- */
30
+ .ds-deck-stage {
31
+ aspect-ratio: 16 / 9;
32
+ width: 100%;
33
+ max-width: min(1100px, 100%);
34
+ margin: var(--space-3) auto;
35
+ background: var(--bg-2);
36
+ border-radius: var(--r-2);
37
+ padding: clamp(16px, 5vw, 64px);
38
+ box-sizing: border-box;
39
+ display: flex;
40
+ overflow: hidden;
41
+ container-type: inline-size; /* cqw units track the stage, not the viewport */
42
+ }
43
+ @media (max-height: 500px) and (orientation: landscape) {
44
+ .ds-deck-stage {
45
+ max-height: calc(100vh - 140px);
46
+ max-height: calc(100dvh - 140px);
47
+ aspect-ratio: auto;
48
+ }
49
+ }
50
+ .ds-deck-slide { flex: 1; display: flex; min-width: 0; }
51
+ .ds-deck-controls {
52
+ display: flex; align-items: center; justify-content: center; gap: 14px;
53
+ padding: 8px; font-family: var(--ff-mono); font-size: var(--fs-sm);
54
+ }
55
+ .ds-deck-count { color: var(--fg-3); }
56
+ @media (pointer: coarse) {
57
+ .ds-deck-controls .btn { min-height: 44px; min-width: 44px; }
58
+ }
59
+ .ds-slide-eyebrow {
60
+ font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.1em;
61
+ text-transform: uppercase; color: var(--fg-3); margin-bottom: clamp(12px, 2.5cqw, 24px);
62
+ }
63
+ .ds-slide-col { display: flex; flex-direction: column; justify-content: center; gap: clamp(12px, 2.5cqw, 24px); min-width: 0; }
64
+ .ds-slide-col--start { align-items: flex-start; }
65
+ .ds-slide-col--narrow { max-width: 38ch; }
66
+ .ds-slide-col--quote { max-width: 42ch; }
67
+ .ds-slide-hero {
68
+ font-size: clamp(var(--fs-h2), 6cqw, var(--fs-hero));
69
+ line-height: var(--lh-tight); letter-spacing: var(--tr-tight); font-weight: 600;
70
+ color: var(--slide-accent, var(--accent-ink));
71
+ overflow-wrap: anywhere;
72
+ }
73
+ .ds-slide-h1 {
74
+ font-size: clamp(var(--fs-h3), 4.5cqw, var(--fs-h1));
75
+ line-height: var(--lh-snug); color: var(--fg); font-weight: 500; min-width: 0;
76
+ }
77
+ .ds-slide-h1--lead { margin-bottom: 12px; }
78
+ .ds-slide-quote-body {
79
+ font-size: clamp(var(--fs-lg), 3.5cqw, var(--fs-h2));
80
+ line-height: var(--lh-snug); color: var(--fg); font-weight: 400; font-style: italic;
81
+ }
82
+ .ds-slide-cite { font-family: var(--ff-mono); font-size: var(--fs-sm); color: var(--fg-3); }
83
+ .ds-slide-bullet {
84
+ display: flex; gap: clamp(8px, 2vw, 18px); align-items: baseline;
85
+ border-bottom: 1px solid var(--rule); padding: 12px 0; flex-wrap: wrap;
86
+ }
87
+ .ds-slide-bullet-key {
88
+ flex: 0 1 clamp(56px, 18%, 100px); min-width: 0;
89
+ font-family: var(--ff-mono); font-size: var(--fs-sm);
90
+ color: var(--slide-accent, var(--accent-ink));
91
+ }
92
+ .ds-slide-bullet-val { color: var(--fg-2); font-size: var(--fs-lg); min-width: 0; }
93
+ .ds-slide-split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(12px, 3vw, 32px); margin-top: 12px; }
94
+ @media (max-width: 760px) {
95
+ .ds-slide-split { grid-template-columns: 1fr; }
96
+ }
97
+ .ds-slide-split-cell {
98
+ padding: 18px; background: var(--bg-2); border-radius: var(--r-2);
99
+ color: var(--fg-2); font-size: var(--fs-lg); line-height: var(--lh-base); min-width: 0;
100
+ }
101
+ .ds-slide-split-cell--accent { border-left: 3px solid var(--slide-accent, var(--accent)); }
102
+
103
+ /* --- error 404 --------------------------------------------- */
104
+ .ds-err-hero {
105
+ padding: clamp(16px, 5vw, 36px) clamp(12px, 4vw, 22px);
106
+ text-align: center; display: flex; flex-direction: column; gap: 14px; align-items: center;
107
+ }
108
+ .ds-err-numeral {
109
+ font-family: var(--ff-mono); font-size: clamp(56px, 20vw, 120px);
110
+ line-height: 1; color: var(--panel-text-3); letter-spacing: -0.03em;
111
+ }
112
+ .ds-err-path {
113
+ display: inline-flex; gap: 6px; align-items: baseline; flex-wrap: wrap; max-width: 100%;
114
+ font-family: var(--ff-mono); font-size: 13px; color: var(--panel-text-2);
115
+ background: var(--panel-1); padding: 6px 12px; border-radius: var(--r-0);
116
+ overflow-wrap: anywhere; word-break: break-all;
117
+ }
118
+
119
+ /* --- gallery ------------------------------------------------ */
120
+ .ds-tile-grid {
121
+ padding: clamp(8px, 2.5vw, 16px);
122
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); gap: 8px;
123
+ }
124
+ .ds-tile-grid--tight { grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); }
125
+ .ds-swatch-grid {
126
+ padding: clamp(8px, 2.5vw, 16px);
127
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr)); gap: 12px;
128
+ }
129
+ .ds-gallery-tile {
130
+ cursor: pointer; display: flex; flex-direction: column; gap: 6px;
131
+ padding: 12px; border-radius: var(--r-1); min-height: clamp(120px, 18vw, 160px);
132
+ border: 0; text-align: left; font: inherit; color: inherit;
133
+ background: var(--tile-tone, var(--panel-1));
134
+ transition: transform var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
135
+ }
136
+ /* Flat tonal fill only (house style: no bespoke tile chrome, no borders — see
137
+ .ds-feature above), so the hover affordance is a lift, matching the same
138
+ translateY + shadow idiom .chat-msg:hover .chat-bubble already uses. */
139
+ .ds-gallery-tile:hover { transform: translateY(-2px); box-shadow: 0 2px 8px color-mix(in oklab, var(--fg) 10%, transparent); }
140
+ .ds-gallery-tile:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
141
+ .ds-gallery-tile--tight { min-height: clamp(96px, 14vw, 120px); }
142
+ .ds-lightbox {
143
+ position: fixed; inset: 0; background: var(--scrim);
144
+ display: flex; align-items: center; justify-content: center;
145
+ padding: clamp(12px, 4vw, 32px);
146
+ padding-bottom: max(clamp(12px, 4vw, 32px), env(safe-area-inset-bottom));
147
+ z-index: 50;
148
+ }
149
+ .ds-lightbox-card {
150
+ background: var(--panel-0); border-radius: var(--r-2); padding: clamp(16px, 4vw, 28px);
151
+ width: min(520px, 100%); min-width: 0;
152
+ max-height: calc(100vh - 24px);
153
+ max-height: calc(100dvh - 24px);
154
+ overflow: auto;
155
+ display: flex; flex-direction: column; gap: 14px;
156
+ }
157
+ .ds-lightbox-preview {
158
+ padding: clamp(16px, 6vw, 36px); border-radius: var(--r-1); text-align: center;
159
+ font-family: var(--ff-mono); white-space: pre-line; font-size: clamp(16px, 5vw, 24px);
160
+ background: var(--tile-tone, var(--panel-1));
161
+ }
162
+
163
+ /* --- search ------------------------------------------------- */
164
+ .ds-topbar-search { width: min(280px, 100%); min-width: 0; flex: 1 1 clamp(140px, 30vw, 280px); }
165
+ @media (max-width: 480px) {
166
+ .ds-topbar-search { flex-basis: 100%; }
167
+ }
168
+ .ds-empty-state { padding: clamp(16px, 5vw, 24px); text-align: center; color: var(--panel-text-3); }
169
+ .ds-empty-state-glyph { font-size: clamp(24px, 6vw, 32px); }
170
+ .ds-empty-state-msg { margin: 6px 0; }
171
+ .ds-empty-state-hint { margin: 0; font-size: var(--fs-sm); }
172
+
173
+ /* --- system primer ------------------------------------------ */
174
+ .ds-swatch-grid-sm {
175
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(110px, 100%), 1fr));
176
+ gap: 12px; padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px);
177
+ }
178
+ .ds-swatch-grid-lg { grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); }
179
+ .ds-swatch-col { display: flex; flex-direction: column; gap: 6px; }
180
+ .ds-swatch-chip { height: 48px; border-radius: var(--r-1); border: 1px solid var(--rule); background: var(--swatch, var(--panel-1)); }
181
+ .ds-swatch-chip--big { height: 64px; }
182
+ .ds-swatch-name { font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
183
+ .ds-type-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 14px; }
184
+ .ds-type-row {
185
+ display: flex; align-items: baseline; gap: 14px;
186
+ border-bottom: 1px solid var(--rule); padding-bottom: 8px; flex-wrap: wrap;
187
+ }
188
+ .ds-type-row-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
189
+ .ds-type-sample {
190
+ min-width: 0; overflow-wrap: anywhere; line-height: var(--lh-tight); color: var(--fg);
191
+ font-size: var(--sample-size, var(--fs-body));
192
+ }
193
+ .ds-prim-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 18px; }
194
+ .ds-prim-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
195
+ .ds-prim-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
196
+
197
+ /* == appended: content-site == */
198
+ /* Home landing wrappers (site/theme.mjs) — replace banned inline styles. */
199
+ .ds-home-hero-wrap { padding: 0 var(--space-2, 8px); }
200
+ .ds-home-panel { margin: var(--space-2, 8px); }
201
+ @media (max-width: 480px) {
202
+ .ds-home-panel { margin: var(--space-1, 4px) 0; }
203
+ }
204
+ /* Home landing section tablist (site/theme.mjs Tabs()) — bare .tabs had no
205
+ rule anywhere, so the four links rendered as unstyled inline text jammed
206
+ together with no separation. Mirror the topbar nav pill-tab treatment. */
207
+ .tabs[role="tablist"] {
208
+ display: flex;
209
+ flex-wrap: wrap;
210
+ gap: var(--space-1, 4px);
211
+ font-size: var(--fs-sm);
212
+ }
213
+ .tabs[role="tablist"] a {
214
+ display: flex;
215
+ align-items: center;
216
+ gap: var(--space-1, 4px);
217
+ padding: var(--space-2, 8px) var(--space-3, 12px);
218
+ border-radius: var(--r-pill);
219
+ color: var(--fg-2);
220
+ transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease),
221
+ transform var(--dur-base) var(--ease-spring);
222
+ }
223
+ .tabs[role="tablist"] a:hover { background: var(--bg-2); color: var(--fg); transform: translateY(-1px); }
224
+ .tabs[role="tablist"] a.active {
225
+ color: var(--accent-ink);
226
+ background: color-mix(in oklab, var(--accent) 16%, transparent);
227
+ box-shadow: inset 0 -2px 0 0 var(--accent);
228
+ font-weight: 600;
229
+ }
230
+ .ds-quickstart {
231
+ padding: var(--space-3, 16px) var(--space-4, 24px);
232
+ display: flex;
233
+ flex-direction: column;
234
+ gap: var(--space-1-75, 6px);
235
+ }
236
+ /* Table() scroll containment — wide tables scroll inside their own box,
237
+ never the page body. */
238
+ .ds-table-wrap {
239
+ overflow-x: auto;
240
+ -webkit-overflow-scrolling: touch;
241
+ max-width: 100%;
242
+ }
243
+ .ds-table-wrap > table { min-width: 100%; }
244
+
245
+
246
+ /* == appended: settings kit cleanup == */
247
+ /* == appended: settings kit == */
248
+ .ds-settings-main { padding: var(--space-2, 8px); }
249
+ .ds-settings-body { padding: 14px 18px; }
250
+ .ds-settings-body-stack { display: flex; flex-direction: column; gap: var(--space-2-5, 10px); }
251
+ .ds-field-block { margin: var(--space-2-5, 10px) 0; }
252
+ .ds-field-eyebrow {
253
+ font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em;
254
+ text-transform: uppercase; color: var(--panel-text-3);
255
+ }
256
+ .ds-hint-sm { font-size: 12px; color: var(--panel-text-2); }
257
+ .ds-note-quiet { margin: 0; color: var(--panel-text-2); }
258
+ .ds-btn-row { display: flex; gap: var(--space-2, 8px); flex-wrap: wrap; }
259
+ .ds-btn-row-tight { gap: var(--space-1-75, 6px); }
260
+ .ds-key-input { flex: 1 1 160px; min-width: 0; font-family: var(--ff-mono); }
261
+ .ds-toggle-btn { min-width: 78px; }
262
+ .ds-toggle-label { margin-left: var(--space-2, 8px); color: inherit; opacity: 0.7; }
263
+ .ds-btn-warn { color: var(--warn); }
264
+ /* Raw --mascot text measures 3.11:1 on paper (fails 4.5:1); --mascot-deep is
265
+ the text-safe tone, same accent/accent-ink split used everywhere else. */
266
+ .ds-btn-mascot { color: var(--mascot-deep); }
267
+ .ds-savebar {
268
+ position: sticky; bottom: 8px; display: flex; align-items: center;
269
+ justify-content: flex-end; gap: 8px; flex-wrap: wrap; padding: 10px;
270
+ background: var(--panel-2); border-radius: var(--r-1); margin: 8px 0;
271
+ }
272
+ .ds-savebar-note { flex: 1 1 160px; min-width: 0; color: var(--panel-text-2); }
273
+ .ds-settings-modal { min-width: min(320px, calc(100vw - 32px)); max-width: 480px; }
274
+ .ds-modal-body-form { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
275
+ .ds-modal-note { margin: 0 0 8px; color: var(--panel-text-2); font-size: 14px; }
276
+ .ds-draft-preview {
277
+ background: var(--panel-1); padding: 12px; border-radius: var(--r-0);
278
+ font-size: 13px; color: var(--panel-text-2); max-height: 120px;
279
+ overflow-y: auto; font-family: var(--ff-mono); overflow-wrap: anywhere;
280
+ }
281
+ .ds-modal-actions { display: flex; gap: 8px; margin-top: 12px; justify-content: space-between; flex-wrap: wrap; }
282
+
283
+ /* == appended: signin kit cleanup == */
284
+ /* -- signin kit (ui_kits/signin) -- */
285
+ .ds-auth-wrap { padding: var(--space-2, 8px); display: flex; flex-direction: column; align-items: center; }
286
+ .ds-auth-col { width: 100%; max-width: 440px; display: flex; flex-direction: column; gap: 8px; margin: clamp(12px, 4vw, 24px) 0; min-width: 0; }
287
+ .ds-auth-form { padding: clamp(12px, 3vw, 18px); display: flex; flex-direction: column; gap: 10px; }
288
+ .ds-auth-sent { align-items: center; text-align: center; }
289
+ .ds-auth-sent-glyph { font-size: 32px; color: var(--panel-accent); }
290
+ .ds-auth-sent-title { margin: 0; font-weight: 600; }
291
+ .ds-auth-sent-sub { margin: 0; color: var(--panel-text-2); overflow-wrap: anywhere; }
292
+ .ds-auth-field { display: flex; flex-direction: column; gap: 4px; }
293
+ .ds-auth-field-label { font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--panel-text-3); }
294
+ .ds-auth-row-between { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
295
+ .ds-auth-remember { display: flex; align-items: center; gap: 6px; cursor: pointer; }
296
+ .ds-auth-remember-text { color: var(--panel-text-2); font-size: 13px; }
297
+ .ds-auth-forgot { font-size: 13px; }
298
+ .ds-auth-error { padding: 8px 10px; background: var(--panel-1); border-radius: var(--r-0); color: var(--danger); font-size: 13px; overflow-wrap: anywhere; }
299
+ .ds-auth-providers { display: flex; gap: 8px; flex-wrap: wrap; }
300
+ .ds-auth-provider-btn { flex: 1 1 100px; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px; }
301
+ .ds-auth-provider-btn--loading { opacity: 0.7; pointer-events: none; }
302
+ .ds-auth-provider-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); display: inline-flex; }
303
+ .ds-auth-modes { display: flex; justify-content: center; gap: 14px; margin-top: 8px; font-size: 13px; flex-wrap: wrap; }
304
+ .ds-auth-mode-link { color: var(--panel-text-3); text-decoration: none; }
305
+ .ds-auth-mode-link--active { color: var(--panel-text); text-decoration: underline; }
306
+ .ds-auth-fineprint { text-align: center; font-size: 12px; color: var(--panel-text-3); margin: 6px 0; }
307
+
308
+ /* == appended: gallery-misc kit cleanup == */
309
+ /* --- shared helpers (converted from inline styles) --- */
310
+ .ds-m0 { margin: 0; }
311
+ .ds-text-2 { color: var(--panel-text-2); }
312
+ .ds-text-3 { color: var(--panel-text-3); }
313
+ .ds-kit-head { display: flex; align-items: center; justify-content: space-between; gap: clamp(8px, 2vw, 16px); flex-wrap: wrap; }
314
+
315
+ /* --- gallery kit --- */
316
+ .ds-tile-cap { flex: 1; display: flex; align-items: center; justify-content: center; font-family: var(--ff-mono); white-space: pre-line; color: var(--panel-text-2); font-size: 18px; min-width: 0; text-align: center; }
317
+ .ds-tile-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; flex-wrap: wrap; min-width: 0; }
318
+ .ds-tile-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); }
319
+ .ds-tile-label { color: var(--panel-text); overflow-wrap: anywhere; }
320
+ .ds-gal-swatch { height: 64px; border-radius: var(--r-0); background: var(--swatch, var(--panel-1)); }
321
+ .ds-gal-swatch-meta { display: flex; justify-content: space-between; gap: 6px; flex-wrap: wrap; font-family: var(--ff-mono); font-size: 11px; min-width: 0; }
322
+ .ds-gal-swatch-name { color: var(--panel-text); }
323
+ .ds-gal-swatch-hint { color: var(--panel-text-3); overflow-wrap: anywhere; }
324
+ .ds-lightbox-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
325
+ .ds-lightbox-tag { font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--panel-text-3); }
326
+
327
+ /* --- error_404 kit --- */
328
+ .ds-err-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }
329
+ .ds-err-chips { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }
330
+
331
+ /* == appended: terminal-capp kit cleanup == */
332
+ /* --- terminal kit ------------------------------------------ */
333
+ .ds-section-pad-sm { padding: 8px; }
334
+ .ds-kit-head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
335
+ .ds-cli-cmt .cmd { color: var(--fg-3); }
336
+ .ds-cli-out .cmd { color: var(--fg-2); }
337
+ .ds-cli-ok .prompt, .ds-cli-ok .cmd { color: var(--accent-ink); }
338
+ .ds-cli-warn .prompt, .ds-cli-warn .cmd { color: var(--mascot-deep); }
339
+ .ds-cli-log .prompt { color: var(--fg-3); }
340
+ .ds-cli-log .cmd { color: var(--fg-2); font-family: var(--ff-mono); }
341
+ .ds-term-body { padding: 14px 18px; display: flex; flex-direction: column; gap: 4px; background: var(--bg-2); border-radius: var(--r-1); }
342
+ .ds-term-body--tall { min-height: 280px; }
343
+ .ds-term-input-row { margin-top: 6px; }
344
+ .ds-term-input { flex: 1; min-width: 0; background: transparent; border: 0; outline: 0; font-family: var(--ff-mono); font-size: 13px; color: var(--fg); }
345
+ /* full-viewport render root (community-app) */
346
+ .ds-root-viewport { height: 100vh; height: 100dvh; }
347
+
348
+ /* --- chat kit: widescreen detail pane -----------------------
349
+ .chat itself stays single-column (shared component, untouched) and
350
+ stretches full-width on ultrawide via the existing .app-main > .chat
351
+ max-width:none rule above (~L380) — that's fine for a bare thread, but
352
+ it leaves a lone thread column growing to 1400px+ with no other use of
353
+ the extra width. This wrapper adds a persistent "thread info" rail once
354
+ there is room to spare, instead of just widening the message column. */
355
+ .ds-chat-layout { display: flex; flex-direction: column; flex: 1; min-height: 0; gap: var(--space-3); }
356
+ .ds-chat-layout > .chat { min-width: 0; }
357
+ .ds-chat-detail { display: none; }
358
+ @media (min-width: 1100px) {
359
+ .ds-chat-layout { display: grid; grid-template-columns: minmax(0, 1fr) 280px; align-items: start; gap: var(--space-4); }
360
+ .ds-chat-detail { display: block; position: sticky; top: 0; }
361
+ }
@@ -0,0 +1,120 @@
1
+
2
+ /* ============================================================
3
+ Spinner — animated loading indicator
4
+ ============================================================ */
5
+ .ds-spinner {
6
+ display: inline-flex;
7
+ gap: 4px;
8
+ align-items: center;
9
+ height: 16px;
10
+ }
11
+ .ds-spinner span {
12
+ width: 4px;
13
+ height: 4px;
14
+ border-radius: 50%;
15
+ background: var(--accent);
16
+ }
17
+ @media (prefers-reduced-motion: no-preference) {
18
+ .ds-spinner span { animation: ds-bounce 1.4s infinite ease-in-out; }
19
+ .ds-spinner span:nth-child(1) { animation-delay: 0s; }
20
+ .ds-spinner span:nth-child(2) { animation-delay: 0.18s; }
21
+ .ds-spinner span:nth-child(3) { animation-delay: 0.36s; }
22
+ }
23
+
24
+ .ds-spinner-lg { height: 24px; gap: 6px; }
25
+ .ds-spinner-lg span { width: 6px; height: 6px; }
26
+
27
+ .ds-spinner-sm { height: 12px; gap: 2px; }
28
+ .ds-spinner-sm span { width: 2px; height: 2px; }
29
+
30
+ .ds-spinner-xs { height: 8px; gap: 1px; }
31
+ .ds-spinner-xs span { width: 1.5px; height: 1.5px; }
32
+
33
+ .ds-spinner-xl { height: 32px; gap: 8px; }
34
+ .ds-spinner-xl span { width: 8px; height: 8px; }
35
+
36
+ @keyframes ds-bounce {
37
+ 0%, 80%, 100% { transform: translateY(0); }
38
+ 40% { transform: translateY(-8px); }
39
+ }
40
+
41
+ /* ============================================================
42
+ Skeleton — animated loading placeholder
43
+ ============================================================ */
44
+ .ds-skeleton-group {
45
+ display: flex;
46
+ flex-direction: column;
47
+ gap: var(--space-2);
48
+ }
49
+ .ds-skeleton {
50
+ background: linear-gradient(90deg, var(--bg-2) 25%, var(--bg-3) 50%, var(--bg-2) 75%);
51
+ background-size: 200% 100%;
52
+ animation: ds-shimmer 1.5s infinite;
53
+ border-radius: var(--r-1);
54
+ }
55
+
56
+ @keyframes ds-shimmer {
57
+ 0% { background-position: 200% 0; }
58
+ 100% { background-position: -200% 0; }
59
+ }
60
+
61
+ /* ============================================================
62
+ Alert — contextual message banner
63
+ ============================================================ */
64
+ .ds-alert {
65
+ display: flex;
66
+ gap: var(--space-3);
67
+ align-items: flex-start;
68
+ padding: var(--space-3) var(--space-4);
69
+ border-radius: var(--r-1);
70
+ background: var(--panel-1);
71
+ border: 1px solid var(--rule-strong);
72
+ color: var(--fg);
73
+ }
74
+
75
+ .ds-alert-info { --alert-tone: var(--sky); }
76
+ .ds-alert-success { --alert-tone: var(--green); }
77
+ .ds-alert-warn { --alert-tone: var(--amber); }
78
+ .ds-alert-error { --alert-tone: var(--warn); }
79
+
80
+ .ds-alert-icon {
81
+ flex-shrink: 0;
82
+ color: var(--alert-tone);
83
+ font-weight: 600;
84
+ min-width: 20px;
85
+ text-align: center;
86
+ }
87
+
88
+ .ds-alert-content {
89
+ flex: 1;
90
+ display: flex;
91
+ flex-direction: column;
92
+ gap: 4px;
93
+ }
94
+
95
+ .ds-alert-title {
96
+ font-weight: 500;
97
+ font-size: var(--fs-sm);
98
+ }
99
+
100
+ .ds-alert-message {
101
+ font-size: var(--fs-sm);
102
+ color: var(--fg-2);
103
+ }
104
+ .ds-alert-retry { margin-top: var(--space-2); }
105
+
106
+ .ds-alert-dismiss {
107
+ flex-shrink: 0;
108
+ background: none;
109
+ border: none;
110
+ cursor: pointer;
111
+ color: var(--fg-3);
112
+ padding: 0;
113
+ font-size: 14px;
114
+ line-height: 1;
115
+ min-width: 20px;
116
+ text-align: center;
117
+ transition: color var(--dur-snap) var(--ease);
118
+ }
119
+ .ds-alert-dismiss:hover { color: var(--fg); }
120
+
@@ -0,0 +1,177 @@
1
+ /* ============================================================
2
+ Panel — soft tonal container, no border decoration
3
+ ============================================================ */
4
+ .panel {
5
+ background: var(--panel-1, var(--bg-2));
6
+ border: var(--bw-hair) solid var(--rule);
7
+ border-radius: var(--r-2);
8
+ margin: 0 0 var(--space-4);
9
+ padding: var(--space-3);
10
+ position: relative;
11
+ /* Crisp, restrained elevation — a hairline border does the edge definition;
12
+ the shadow only adds a whisper of lift, not a soft glow-card float. */
13
+ box-shadow: var(--shadow-1);
14
+ transition: box-shadow var(--dur-base) var(--ease-spring), border-color var(--dur-snap) var(--ease),
15
+ transform var(--dur-base) var(--ease-spring);
16
+ }
17
+ /* Editorial accent spine — an opt-in printed-ink rule down the left edge that
18
+ reads as a magazine pull-quote bar, not a glow card. */
19
+ .panel.panel-spine {
20
+ border-radius: 0 var(--r-2) var(--r-2) 0;
21
+ padding-left: calc(var(--space-3) + var(--bw-chunk));
22
+ }
23
+ .panel.panel-spine::before {
24
+ content: ''; position: absolute; left: 0; top: 0; bottom: 0;
25
+ width: var(--bw-chunk); background: var(--accent);
26
+ border-radius: var(--bw-chunk) 0 0 var(--bw-chunk);
27
+ }
28
+ .panel.panel-inline { background: var(--bg-2); padding: var(--space-3) var(--space-3); }
29
+ .panel.panel-wide { background: transparent; box-shadow: none; border: none; }
30
+ /* Dense panel — a compact container for app surfaces (inspector sections,
31
+ sidebars) that want the .panel look without the roomy 16px pad + 24px stack
32
+ gap. Tighter corner + padding + head, so it sits between .panel and the
33
+ flush editor .ds-ep-panel. */
34
+ .panel.panel--dense {
35
+ padding: var(--space-2); margin-bottom: var(--space-2-75);
36
+ border-radius: var(--r-1);
37
+ }
38
+ .panel.panel--dense .panel-head { padding: var(--space-1-5) var(--space-2); }
39
+ .panel.panel--dense .panel-body { padding: var(--space-1-5) var(--space-2) var(--space-2); }
40
+ .panel.panel--dense .panel-body > * + * { margin-top: var(--space-2); }
41
+ .panel-head {
42
+ display: flex; align-items: baseline; justify-content: space-between;
43
+ /* Shares the .panel-body 16px side padding so the caps label and the body
44
+ rows sit on ONE left axis (the old 24/32 padding was authored for the
45
+ pre-padding .panel-wide era and indented the label 16px past its content). */
46
+ padding: var(--space-2) var(--space-3);
47
+ font-size: var(--fs-tiny); font-weight: 600;
48
+ color: var(--fg-3);
49
+ letter-spacing: var(--tr-caps); text-transform: uppercase;
50
+ }
51
+ .panel.panel-wide .panel-head { padding-left: 0; padding-right: 0; }
52
+ .panel-head > :last-child {
53
+ font-weight: 500; color: var(--fg-3);
54
+ font-family: var(--ff-mono); letter-spacing: 0;
55
+ }
56
+ .panel-body { padding: var(--space-2) var(--space-3) var(--space-3); }
57
+ .panel-body > * { margin: 0; }
58
+ .panel-body > * + * { margin-top: var(--space-3); }
59
+ .panel.panel-wide .panel-body { padding: 0; }
60
+
61
+ /* ============================================================
62
+ Row — primary list pattern. Indicator rail on the left,
63
+ no hairlines between rows.
64
+ ============================================================ */
65
+ .row {
66
+ display: grid;
67
+ grid-template-columns: minmax(80px, 12ch) minmax(0, 1fr) auto;
68
+ gap: var(--space-3);
69
+ align-items: baseline;
70
+ /* App density is the BASE: a list row is quiet working chrome, so it defaults
71
+ to the compact 12px/16px rhythm (density-scaled) rather than the old
72
+ 16px/24px marketing padding. .row--lede restores the roomier marketing
73
+ voice for editorial index pages. */
74
+ padding: calc(var(--space-2-75) * var(--density)) var(--space-3);
75
+ background: var(--bg);
76
+ border-radius: var(--r-1);
77
+ color: var(--fg);
78
+ position: relative;
79
+ /* Only background + the leading rail animate; padding/size never change on
80
+ interaction, so they are deliberately absent (a padding transition here was
81
+ dead and misleading). */
82
+ transition: background var(--dur-snap) var(--ease), box-shadow var(--dur-base) var(--ease-spring);
83
+ }
84
+ .row + .row { margin-top: 2px; }
85
+ /* Interactive rows (anchor/button wrappers) get a hairline lift on hover,
86
+ matching the btn/panel elevation language — non-interactive rows (plain
87
+ divs used as static list items) are unaffected since the selector needs a
88
+ real interactive role. */
89
+ a.row:hover, button.row:hover, .row[role="button"]:hover {
90
+ box-shadow: var(--shadow-1);
91
+ }
92
+ /* `detail` drops to its own full-width line. The row is a grid, so span every
93
+ track (grid-column 1/-1); flex-basis:100% covers the flex-row fallback. */
94
+ .ds-row-detail {
95
+ white-space: pre-wrap;
96
+ font-family: var(--ff-mono);
97
+ font-size: var(--fs-sm);
98
+ line-height: var(--lh-snug);
99
+ margin-top: var(--space-2);
100
+ padding: 10px 12px;
101
+ background: var(--bg);
102
+ border-radius: var(--r-1);
103
+ overflow-x: auto;
104
+ flex-basis: 100%;
105
+ grid-column: 1 / -1;
106
+ }
107
+ .row::before {
108
+ content: '';
109
+ position: absolute; left: 7px; top: 0; bottom: 0; width: 3px;
110
+ margin: auto 0;
111
+ height: 0; /* collapsed by default; reveals from centre */
112
+ background: var(--rule-strong);
113
+ border-radius: var(--r-pill);
114
+ opacity: 0;
115
+ transition: height var(--dur-base) var(--ease), opacity var(--dur-snap) var(--ease), background var(--dur-snap) var(--ease);
116
+ }
117
+ /* A clickable row (onClick -> role=button, or a link row) is interactive, so it
118
+ carries a pointer cursor; without this the click affordance is invisible. */
119
+ .row[role="button"], a.row { cursor: pointer; }
120
+ /* Hover reveals the rail (grows from centre) only on interactive rows — a static
121
+ row should not signal an affordance it does not have. */
122
+ .row[role="button"]:hover, a.row:hover { background: var(--bg-2); }
123
+ .row[role="button"]:hover::before, a.row:hover::before { height: 56%; opacity: 1; }
124
+ /* Editorial hover-reveal — the row's meta (cta) slides toward the lead accent
125
+ and nudges right, the printed-index "open ->" affordance. */
126
+ .row .meta { transition: color var(--dur-base) var(--ease), transform var(--dur-base) var(--ease-spring); }
127
+ a.row:hover .meta, .row[role="button"]:hover .meta { color: var(--accent-ink); transform: translateX(3px); }
128
+ .row.active { background: color-mix(in oklab, var(--accent) 10%, var(--bg-2)); }
129
+ .row.active::before { height: 64%; opacity: 1; background: var(--accent); }
130
+ .row.active .title { color: var(--accent-ink); }
131
+ .row.row-state-disabled { opacity: 0.5; pointer-events: none; }
132
+ .row.row-state-error { background: color-mix(in oklab, var(--flame) 10%, var(--bg-2)); }
133
+ .row.row-state-error::before { height: 64%; opacity: 1; background: var(--flame); }
134
+ /* rail tones — a persistent status colour on the leading rail (the ::before
135
+ bar). Always shown (a status indicator, not a hover affordance). Active/error
136
+ still win via their own rules below in source order. */
137
+ .row.rail-green::before,
138
+ .row.rail-purple::before,
139
+ .row.rail-flame::before { height: 56%; opacity: 1; }
140
+ .row.rail-green::before { background: var(--accent-ink); }
141
+ .row.rail-purple::before { background: var(--purple-2); }
142
+ .row.rail-flame::before { background: var(--flame); }
143
+ /* Differentiate the rail by SHAPE, not hue alone (color-blind safety): error
144
+ reads as a taller solid bar, subagent as a dashed/gapped fill, ok stays the
145
+ short solid bar. Paired with the sr-only status word emitted by Row(). */
146
+ .row.rail-flame::before { height: 64%; }
147
+ .row.rail-purple::before { background: repeating-linear-gradient(var(--purple-2) 0 4px, transparent 4px 7px); }
148
+ .row-grid { /* explicit grid-template-columns set inline */ }
149
+ /* A row with no leading code/index drops the empty first column so the title
150
+ takes the full width instead of wrapping in the narrow code gutter. */
151
+ .row.row-nocode { grid-template-columns: minmax(0, 1fr) auto; }
152
+
153
+ .row .code { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }
154
+ /* Title defaults to the quiet app voice (fs-sm/500) — the 18px/600 marketing
155
+ voice is now opt-in via .row--lede. */
156
+ .row .title { font-family: var(--ff-body); font-weight: 500; font-size: var(--fs-sm); line-height: var(--lh-snug); display: flex; align-items: baseline; gap: var(--space-2-5); flex-wrap: wrap; min-width: 0; }
157
+ .row .title .sub { font-family: var(--ff-body); font-weight: 400; font-size: var(--fs-sm); color: var(--fg-3); }
158
+ /* Marketing/editorial index row — restores the roomier padding + larger title
159
+ the default carried before app-scale became the base. */
160
+ .row--lede { padding: var(--space-3) var(--space-4); }
161
+ .row--lede .title { font-size: var(--fs-lg); font-weight: 600; }
162
+ /* App typescale: list rows are quiet working chrome (the 18px/600 default is a
163
+ marketing-surface voice). One size for ALL app list rows - matches
164
+ .ds-file-row/.ds-session-title at fs-sm/500; values mirror the kit's own
165
+ mobile block below. Marketing pages without data-typescale keep the default. */
166
+ [data-typescale="app"] .row { padding: 12px 16px; }
167
+ [data-typescale="app"] .row .title { font-size: var(--fs-sm); font-weight: 500; }
168
+ .row .sub { font-family: var(--ff-body); font-weight: 400; font-size: var(--fs-sm); color: var(--fg-3); }
169
+ /* Context-pane cwd fact reads as a path (like .ds-dash-cwd/.ds-session-agent/
170
+ .ds-dash-model) -- scoped to that one row so no other Row .sub is affected. */
171
+ .ds-context-cwd-row .row .sub { font-family: var(--ff-mono); }
172
+ .row .meta { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; align-self: center; }
173
+ /* WorksList meta pairs a label with a disclosure chevron, inline-aligned. */
174
+ .ds-works-meta { display: inline-flex; align-items: center; gap: .4em; }
175
+
176
+ a.row { text-decoration: none; }
177
+