anentrypoint-design 0.0.414 → 0.0.415
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/dist/247420.js +62 -12
- package/dist/app-shell.css +40 -594
- package/dist/colors_and_type.css +607 -47
- package/dist/index.html +227 -277
- package/dist/preview/buttons.html +39 -28
- package/dist/preview/colors-core.html +18 -8
- package/dist/preview/colors-lore.html +26 -17
- package/dist/preview/colors-semantic.html +24 -18
- package/dist/preview/dateline.html +6 -5
- package/dist/preview/dropzone.html +4 -3
- package/dist/preview/file-grid.html +10 -9
- package/dist/preview/file-row.html +14 -13
- package/dist/preview/file-toolbar.html +4 -3
- package/dist/preview/file-viewer.html +4 -3
- package/dist/preview/header.html +26 -24
- package/dist/preview/icons-unicode.html +8 -5
- package/dist/preview/index-row.html +17 -9
- package/dist/preview/inputs.html +4 -3
- package/dist/preview/manifesto.html +34 -17
- package/dist/preview/motion-default.js +77 -57
- package/dist/preview/rules.html +4 -3
- package/dist/preview/spacing.html +13 -12
- package/dist/preview/stamps-lore.html +5 -4
- package/dist/preview/stamps.html +4 -3
- package/dist/preview/theme-ink.html +7 -6
- package/dist/preview/type-display.html +14 -5
- package/dist/preview/type-mono.html +6 -5
- package/dist/preview/type-prose.html +12 -10
- package/dist/preview/type-scale.html +4 -3
- package/dist/preview/wordmarks.html +10 -7
- package/dist/site/content/globals/site.yaml +5 -3
- package/dist/site/content/pages/freddie.yaml +2 -2
- package/dist/site/content/pages/home.yaml +55 -55
- package/dist/site/theme.mjs +96 -348
- package/dist/slides/index.html +13 -13
- package/dist/src/bootstrap.js +10 -1
- package/dist/src/components/chat.js +43 -195
- package/dist/src/components/community.js +18 -166
- package/dist/src/components/content.js +30 -210
- package/dist/src/components/files-modals.js +14 -106
- package/dist/src/components/files.js +15 -116
- package/dist/src/components/freddie/helpers.js +53 -8
- package/dist/src/components/freddie.js +35 -25
- package/dist/src/components/shell.js +16 -114
- package/dist/src/components/theme-toggle.js +69 -25
- package/dist/src/components.js +92 -13
- package/dist/src/deck-stage.js +6 -4
- package/dist/src/highlight.js +51 -7
- package/dist/src/index.js +58 -12
- package/dist/src/kits/os/about-app.js +2 -3
- package/dist/src/kits/os/app-panes.css +46 -70
- package/dist/src/kits/os/browser-app.js +28 -1
- package/dist/src/kits/os/files-app.js +7 -0
- package/dist/src/kits/os/freddie/pages-chat.js +90 -75
- package/dist/src/kits/os/freddie/pages-core.js +9 -9
- package/dist/src/kits/os/freddie/pages-os.js +8 -8
- package/dist/src/kits/os/freddie/pages-tools.js +14 -14
- package/dist/src/kits/os/freddie/routes.js +21 -19
- package/dist/src/kits/os/freddie-dashboard.css +42 -21
- package/dist/src/kits/os/freddie-dashboard.js +6 -6
- package/dist/src/kits/os/icons.js +38 -16
- package/dist/src/kits/os/index.js +11 -0
- package/dist/src/kits/os/launcher.css +26 -10
- package/dist/src/kits/os/launcher.js +3 -0
- package/dist/src/kits/os/shell.js +72 -108
- package/dist/src/kits/os/terminal-app.js +1 -1
- package/dist/src/kits/os/theme.css +1330 -150
- package/dist/src/kits/os/wm.css +68 -15
- package/dist/src/kits/os/wm.js +93 -17
- package/dist/src/markdown.js +121 -12
- package/dist/src/motion.js +18 -2
- package/dist/src/page-html.js +62 -134
- package/dist/src/theme.js +106 -13
- package/dist/src/web-components/ds-chat.js +80 -9
- package/dist/ui_kits/aicat/app.js +54 -6
- package/dist/ui_kits/aicat/index.html +2 -0
- package/dist/ui_kits/blog/index.html +33 -17
- package/dist/ui_kits/chat/app.js +90 -22
- package/dist/ui_kits/chat/index.html +2 -0
- package/dist/ui_kits/community/app.js +86 -24
- package/dist/ui_kits/community/index.html +1 -0
- package/dist/ui_kits/dashboard/app.js +123 -34
- package/dist/ui_kits/dashboard/index.html +1 -0
- package/dist/ui_kits/docs/index.html +43 -33
- package/dist/ui_kits/error_404/app.js +78 -23
- package/dist/ui_kits/file_browser/README.md +1 -1
- package/dist/ui_kits/file_browser/app.js +45 -10
- package/dist/ui_kits/file_browser/index.html +1 -0
- package/dist/ui_kits/gallery/app.js +130 -51
- package/dist/ui_kits/homepage/app.js +156 -138
- package/dist/ui_kits/project_page/app.js +142 -125
- package/dist/ui_kits/project_page/index.html +2 -1
- package/dist/ui_kits/search/app.js +52 -15
- package/dist/ui_kits/settings/app.js +166 -39
- package/dist/ui_kits/signin/app.js +175 -49
- package/dist/ui_kits/signin/index.html +1 -0
- package/dist/ui_kits/slide_deck/app.js +83 -49
- package/dist/ui_kits/system_primer/app.js +57 -40
- package/dist/ui_kits/terminal/app.js +160 -43
- package/package.json +1 -1
- package/src/page-html/client-script.js +40 -11
- package/src/page-html/page-styles.js +22 -1
|
@@ -1,26 +1,45 @@
|
|
|
1
|
+
/* Fonts are declared once in the canonical theme (colors_and_type.css /
|
|
2
|
+
vendor/fonts.css), which every .ds-247420 consumer loads first. No @import
|
|
3
|
+
here — a second Inter-only import risked a weight-set FOUT mismatch. */
|
|
4
|
+
|
|
5
|
+
/* The OS shell namespaces its surfaces as --os-* but those are pure ALIASES of
|
|
6
|
+
the canonical semantic tokens from colors_and_type.css. colors_and_type.css
|
|
7
|
+
is always loaded before this sheet for any .ds-247420 consumer, so the
|
|
8
|
+
canonical tokens are guaranteed present and the alias fallbacks are dropped —
|
|
9
|
+
a fallback here would silently re-introduce theme drift (a baked light value
|
|
10
|
+
that ignores [data-theme="ink"]). One theme drives both token namespaces. */
|
|
1
11
|
:root {
|
|
2
|
-
--
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
--
|
|
6
|
-
--os-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
--os-
|
|
11
|
-
--os-
|
|
12
|
-
--os-
|
|
13
|
-
--os-
|
|
14
|
-
--os-
|
|
15
|
-
--os-
|
|
16
|
-
--os-
|
|
12
|
+
/* --ff-ui is the OS-shell alias for the canonical body font; --ff-display
|
|
13
|
+
and --ff-mono are already canonical (colors_and_type.css), referenced
|
|
14
|
+
directly below — do not self-redefine them here (cycle). */
|
|
15
|
+
--ff-ui: var(--ff-body);
|
|
16
|
+
/* --os-accent is used predominantly as TEXT/icon/border in the OS chrome,
|
|
17
|
+
so it tracks the readable --accent-ink tone (the electric lead is too
|
|
18
|
+
light for text on paper). --os-accent-fill is the saturated lead for the
|
|
19
|
+
rare solid fill; --os-accent-soft is the tint. */
|
|
20
|
+
--os-accent: var(--accent-ink);
|
|
21
|
+
--os-accent-fill: var(--accent);
|
|
22
|
+
--os-accent-2: var(--accent-bright, var(--accent));
|
|
23
|
+
--os-accent-soft: var(--accent-tint);
|
|
24
|
+
--os-bg-0: var(--bg);
|
|
25
|
+
--os-bg-1: var(--bg-2);
|
|
26
|
+
--os-bg-2: var(--bg-3);
|
|
27
|
+
--os-bg-3: var(--panel-3);
|
|
28
|
+
--os-fg: var(--fg);
|
|
29
|
+
--os-fg-2: var(--fg-2);
|
|
30
|
+
--os-fg-3: var(--fg-3);
|
|
31
|
+
--os-red: var(--warn);
|
|
32
|
+
--os-amber: var(--sun);
|
|
33
|
+
--os-green: var(--green);
|
|
34
|
+
--os-radius: var(--r-2);
|
|
35
|
+
--os-radius-sm: var(--r-1);
|
|
17
36
|
--os-bar-h: 44px;
|
|
18
37
|
--os-bar-h-mobile: 52px;
|
|
19
38
|
--os-rail-w: 64px;
|
|
20
39
|
--os-tap: 44px;
|
|
21
|
-
--os-font: var(--ff-ui
|
|
22
|
-
--os-display: var(--ff-display
|
|
23
|
-
--os-mono: var(--ff-mono
|
|
40
|
+
--os-font: var(--ff-ui);
|
|
41
|
+
--os-display: var(--ff-display);
|
|
42
|
+
--os-mono: var(--ff-mono);
|
|
24
43
|
}
|
|
25
44
|
|
|
26
45
|
html, body {
|
|
@@ -32,13 +51,15 @@ html, body {
|
|
|
32
51
|
}
|
|
33
52
|
|
|
34
53
|
.os-menubar, .os-taskbar {
|
|
35
|
-
background: var(--os-bg-2);
|
|
54
|
+
background: color-mix(in oklab, var(--os-bg-2) 88%, transparent);
|
|
55
|
+
backdrop-filter: blur(10px);
|
|
56
|
+
-webkit-backdrop-filter: blur(10px);
|
|
36
57
|
border: none;
|
|
37
58
|
color: var(--os-fg);
|
|
38
|
-
font:
|
|
59
|
+
font: var(--fs-tiny) var(--os-font);
|
|
39
60
|
height: var(--os-bar-h);
|
|
40
|
-
padding: 0
|
|
41
|
-
gap:
|
|
61
|
+
padding: 0 var(--space-2-75);
|
|
62
|
+
gap: var(--space-1-75);
|
|
42
63
|
box-shadow: none;
|
|
43
64
|
display: flex;
|
|
44
65
|
align-items: center;
|
|
@@ -48,17 +69,22 @@ html, body {
|
|
|
48
69
|
.os-menubar > *, .os-taskbar > * { flex-shrink: 0; }
|
|
49
70
|
.os-menubar .os-spacer { flex: 1 1 auto; min-width: 0; }
|
|
50
71
|
.os-menubar .os-tray { margin-left: auto; }
|
|
72
|
+
/* Many open windows must scroll within the bar, not overflow it. Mobile
|
|
73
|
+
already had this; promote it to all widths so a crowded desktop taskbar
|
|
74
|
+
scrolls horizontally instead of pushing buttons off-screen. */
|
|
75
|
+
.os-taskbar { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
|
|
76
|
+
.os-taskbar::-webkit-scrollbar { display: none; }
|
|
51
77
|
|
|
52
78
|
.os-brand {
|
|
53
79
|
color: var(--os-fg);
|
|
54
80
|
font-family: var(--os-display);
|
|
55
81
|
font-weight: 700;
|
|
56
82
|
letter-spacing: -0.01em;
|
|
57
|
-
font-size:
|
|
83
|
+
font-size: var(--fs-sm);
|
|
58
84
|
margin-right: 14px;
|
|
59
85
|
display: inline-flex;
|
|
60
86
|
align-items: center;
|
|
61
|
-
gap:
|
|
87
|
+
gap: var(--space-2);
|
|
62
88
|
text-transform: lowercase;
|
|
63
89
|
}
|
|
64
90
|
.os-brand::before {
|
|
@@ -77,12 +103,12 @@ html, body {
|
|
|
77
103
|
cursor: pointer;
|
|
78
104
|
font: inherit;
|
|
79
105
|
font-family: var(--os-font);
|
|
80
|
-
font-size:
|
|
81
|
-
border-radius: 999px;
|
|
106
|
+
font-size: var(--fs-tiny);
|
|
107
|
+
border-radius: var(--r-pill, 999px);
|
|
82
108
|
transition: background 80ms ease, color 80ms ease;
|
|
83
109
|
display: inline-flex;
|
|
84
110
|
align-items: center;
|
|
85
|
-
gap:
|
|
111
|
+
gap: var(--space-1-75);
|
|
86
112
|
outline: none;
|
|
87
113
|
text-transform: lowercase;
|
|
88
114
|
}
|
|
@@ -97,42 +123,59 @@ html, body {
|
|
|
97
123
|
background: var(--os-bg-1);
|
|
98
124
|
border: none;
|
|
99
125
|
border-radius: var(--r-3, 18px);
|
|
100
|
-
padding: 8px;
|
|
126
|
+
padding: var(--space-2, 8px);
|
|
101
127
|
min-width: 220px;
|
|
102
|
-
top: calc(var(--os-bar-h) + 4px);
|
|
103
|
-
left: 8px;
|
|
104
|
-
z-index:
|
|
128
|
+
top: calc(var(--os-bar-h) + var(--space-1, 4px));
|
|
129
|
+
left: var(--space-2, 8px);
|
|
130
|
+
z-index: var(--z-dropdown);
|
|
105
131
|
display: none;
|
|
106
132
|
flex-direction: column;
|
|
107
|
-
gap:
|
|
133
|
+
gap: var(--space-hair);
|
|
108
134
|
pointer-events: auto;
|
|
135
|
+
/* Long app registries must scroll, not extend past the viewport. */
|
|
136
|
+
max-height: calc(100vh - var(--os-bar-h) - 16px);
|
|
137
|
+
max-height: calc(100dvh - var(--os-bar-h) - env(safe-area-inset-top, 0px) - 16px);
|
|
138
|
+
overflow-y: auto;
|
|
139
|
+
overscroll-behavior: contain;
|
|
109
140
|
}
|
|
110
141
|
.os-menu.open { display: flex; }
|
|
111
142
|
.os-menu .os-btn {
|
|
112
143
|
width: 100%;
|
|
113
144
|
text-align: left;
|
|
114
145
|
border-radius: var(--os-radius-sm);
|
|
115
|
-
padding:
|
|
146
|
+
padding: var(--space-2) var(--space-2-5);
|
|
116
147
|
color: var(--os-fg);
|
|
117
148
|
justify-content: flex-start;
|
|
118
149
|
}
|
|
119
150
|
.os-menu .os-btn:hover { background: var(--panel-hover, var(--os-bg-2)); color: var(--os-fg); }
|
|
120
151
|
|
|
152
|
+
/* Collapsible "System" apps group inside the apps menu. thebird's os-shell.js
|
|
153
|
+
* builds the group structurally and toggles only the list's display; the static
|
|
154
|
+
* layout (column flow + indent + arrow alignment) lives here so no visual rule
|
|
155
|
+
* leaks back into thebird JS (zero-design-CSS contract). */
|
|
156
|
+
.os-menu-group { display: flex; flex-direction: column; gap: var(--space-hair); }
|
|
157
|
+
.os-menu-system-toggle { display: flex; align-items: center; gap: var(--space-1-75); }
|
|
158
|
+
.os-menu-system-arrow { display: inline-flex; align-items: center; transition: transform 120ms ease; }
|
|
159
|
+
.os-menu-system-arrow .ds-icon { width: 14px; height: 14px; }
|
|
160
|
+
.os-menu-system-list { display: none; flex-direction: column; padding-left: 14px; }
|
|
161
|
+
.os-menu-system-toggle[aria-expanded="true"] + .os-menu-system-list { display: flex; }
|
|
162
|
+
@media (prefers-reduced-motion: reduce) { .os-menu-system-arrow { transition: none; } }
|
|
163
|
+
|
|
121
164
|
.os-clock {
|
|
122
165
|
color: var(--os-fg-2);
|
|
123
166
|
font-variant-numeric: tabular-nums;
|
|
124
167
|
font-family: var(--os-mono);
|
|
125
|
-
padding: 0
|
|
126
|
-
font-size:
|
|
168
|
+
padding: 0 var(--space-2-5);
|
|
169
|
+
font-size: var(--fs-micro);
|
|
127
170
|
}
|
|
128
171
|
|
|
129
172
|
.os-task {
|
|
130
173
|
border: none;
|
|
131
174
|
background: var(--os-bg-1);
|
|
132
175
|
color: var(--os-fg-2);
|
|
133
|
-
border-radius: 999px;
|
|
134
|
-
padding:
|
|
135
|
-
font-size:
|
|
176
|
+
border-radius: var(--r-pill, 999px);
|
|
177
|
+
padding: var(--space-1-75) 14px;
|
|
178
|
+
font-size: var(--fs-micro);
|
|
136
179
|
font-family: var(--os-font);
|
|
137
180
|
transition: background 80ms ease, color 80ms ease, box-shadow 80ms ease;
|
|
138
181
|
max-width: 200px;
|
|
@@ -143,7 +186,10 @@ html, body {
|
|
|
143
186
|
text-overflow: ellipsis;
|
|
144
187
|
text-transform: lowercase;
|
|
145
188
|
}
|
|
189
|
+
.os-task { min-height: 28px; }
|
|
146
190
|
.os-task:hover { background: var(--panel-hover, var(--os-bg-2)); color: var(--os-fg); }
|
|
191
|
+
/* Empty taskbar reads as an intentional strip, not a stray blurred bar. */
|
|
192
|
+
.os-task-empty { font-size: var(--fs-nano); color: var(--os-fg-3); padding: 0 var(--space-2-5); font-family: var(--os-font); }
|
|
147
193
|
.os-task.focused {
|
|
148
194
|
background: var(--panel-select, var(--os-accent-soft));
|
|
149
195
|
color: var(--os-fg);
|
|
@@ -151,78 +197,93 @@ html, body {
|
|
|
151
197
|
box-shadow: inset 4px 0 0 var(--os-accent);
|
|
152
198
|
}
|
|
153
199
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
200
|
+
/* Window-chrome overrides of wm.css.
|
|
201
|
+
*
|
|
202
|
+
* wm.css is loaded by the consumer as a SEPARATE raw sheet (it is not part of
|
|
203
|
+
* the dist bundle), so its load order relative to this file is not guaranteed.
|
|
204
|
+
* These rules therefore carry the `.ds-247420` scope class: at (0,2,0) they
|
|
205
|
+
* beat wm.css's bare (0,1,0) `.wm-*` rules on SPECIFICITY, which is order-
|
|
206
|
+
* independent — replacing the `!important` wall that previously did the same
|
|
207
|
+
* job by force. Do not un-scope these; the scope IS the override mechanism. */
|
|
208
|
+
.ds-247420 .wm-win {
|
|
209
|
+
background: var(--os-bg-1);
|
|
210
|
+
border: none;
|
|
211
|
+
border-radius: var(--r-3);
|
|
212
|
+
box-shadow: none;
|
|
159
213
|
overflow: hidden;
|
|
160
214
|
}
|
|
161
|
-
.wm-win.wm-focused {
|
|
162
|
-
border: none
|
|
163
|
-
box-shadow: inset
|
|
215
|
+
.ds-247420 .wm-win.wm-focused {
|
|
216
|
+
border: none;
|
|
217
|
+
box-shadow: inset var(--space-1) 0 0 var(--os-accent);
|
|
164
218
|
}
|
|
165
219
|
|
|
166
|
-
.wm-bar {
|
|
167
|
-
background: var(--os-bg-2)
|
|
168
|
-
border: none
|
|
169
|
-
padding:
|
|
170
|
-
gap:
|
|
220
|
+
.ds-247420 .wm-bar {
|
|
221
|
+
background: var(--os-bg-2);
|
|
222
|
+
border: none;
|
|
223
|
+
padding: var(--space-2) var(--space-2-75);
|
|
224
|
+
gap: var(--space-2-5);
|
|
171
225
|
}
|
|
172
|
-
.wm-title {
|
|
173
|
-
font:
|
|
174
|
-
color: var(--os-fg-2)
|
|
226
|
+
.ds-247420 .wm-title {
|
|
227
|
+
font: var(--fs-tiny) var(--os-font);
|
|
228
|
+
color: var(--os-fg-2);
|
|
175
229
|
letter-spacing: 0.005em;
|
|
176
230
|
text-align: center;
|
|
177
231
|
font-weight: 600;
|
|
178
232
|
text-transform: lowercase;
|
|
179
233
|
}
|
|
180
|
-
.wm-btns { gap:
|
|
181
|
-
.wm-btn {
|
|
182
|
-
width: 22px
|
|
183
|
-
height: 22px
|
|
184
|
-
border-radius: var(--r-1
|
|
185
|
-
border: none
|
|
186
|
-
background: var(--os-bg-3)
|
|
187
|
-
color: var(--os-fg-2)
|
|
188
|
-
padding: 0
|
|
234
|
+
.ds-247420 .wm-btns { gap: var(--space-1-75); order: -1; }
|
|
235
|
+
.ds-247420 .wm-btn {
|
|
236
|
+
width: 22px;
|
|
237
|
+
height: 22px;
|
|
238
|
+
border-radius: var(--r-1);
|
|
239
|
+
border: none;
|
|
240
|
+
background: var(--os-bg-3);
|
|
241
|
+
color: var(--os-fg-2);
|
|
242
|
+
padding: 0;
|
|
189
243
|
cursor: pointer;
|
|
190
|
-
font: 600
|
|
191
|
-
line-height: 1
|
|
192
|
-
display: inline-flex
|
|
244
|
+
font: 600 var(--fs-micro) var(--os-mono);
|
|
245
|
+
line-height: 1;
|
|
246
|
+
display: inline-flex;
|
|
193
247
|
align-items: center;
|
|
194
248
|
justify-content: center;
|
|
195
249
|
transition: background 100ms ease, color 100ms ease;
|
|
196
250
|
}
|
|
197
|
-
.wm-btn:hover { background: var(--panel-hover, var(--os-bg-2))
|
|
251
|
+
.ds-247420 .wm-btn:hover { background: var(--panel-hover, var(--os-bg-2)); color: var(--os-fg); }
|
|
198
252
|
|
|
199
|
-
.wm-resize {
|
|
200
|
-
background: transparent
|
|
201
|
-
width: 14px
|
|
202
|
-
height: 14px
|
|
253
|
+
.ds-247420 .wm-resize {
|
|
254
|
+
background: transparent;
|
|
255
|
+
width: 14px;
|
|
256
|
+
height: 14px;
|
|
203
257
|
color: var(--os-fg-3);
|
|
204
258
|
opacity: 0.4;
|
|
205
|
-
font: 10px var(--os-mono);
|
|
206
|
-
display: flex;
|
|
207
|
-
align-items: flex-end;
|
|
208
|
-
justify-content: flex-end;
|
|
209
|
-
line-height: 1;
|
|
210
259
|
}
|
|
211
|
-
.
|
|
212
|
-
.wm-
|
|
260
|
+
/* Resize grip via CSS gradient (matches wm.css); no decorative content glyph. */
|
|
261
|
+
.wm-resize::after {
|
|
262
|
+
content: '';
|
|
263
|
+
position: absolute;
|
|
264
|
+
right: 3px;
|
|
265
|
+
bottom: 3px;
|
|
266
|
+
width: 8px;
|
|
267
|
+
height: 8px;
|
|
268
|
+
background:
|
|
269
|
+
linear-gradient(135deg, transparent 0 45%, currentColor 45% 55%, transparent 55% 100%),
|
|
270
|
+
linear-gradient(135deg, transparent 0 70%, currentColor 70% 80%, transparent 80% 100%);
|
|
271
|
+
}
|
|
272
|
+
.ds-247420 .wm-body { background: var(--os-bg-1); }
|
|
213
273
|
|
|
214
274
|
.os-side-rail {
|
|
215
275
|
position: fixed;
|
|
216
|
-
left: 0; top:
|
|
217
|
-
|
|
276
|
+
left: 0; top: var(--os-bar-h); bottom: var(--os-bar-h);
|
|
277
|
+
padding-left: env(safe-area-inset-left, 0px);
|
|
278
|
+
width: calc(var(--os-rail-w) + env(safe-area-inset-left, 0px));
|
|
218
279
|
background: var(--os-bg-2);
|
|
219
280
|
border: none;
|
|
220
281
|
display: none;
|
|
221
282
|
flex-direction: column;
|
|
222
283
|
align-items: center;
|
|
223
|
-
padding:
|
|
224
|
-
gap:
|
|
225
|
-
z-index:
|
|
284
|
+
padding: var(--space-2, 8px) 0;
|
|
285
|
+
gap: var(--space-1, 4px);
|
|
286
|
+
z-index: var(--z-dock);
|
|
226
287
|
pointer-events: auto;
|
|
227
288
|
}
|
|
228
289
|
.os-rail-btn {
|
|
@@ -246,7 +307,7 @@ html, body {
|
|
|
246
307
|
position: fixed;
|
|
247
308
|
inset: 0;
|
|
248
309
|
background: var(--os-bg-0);
|
|
249
|
-
z-index:
|
|
310
|
+
z-index: var(--z-modal);
|
|
250
311
|
pointer-events: auto;
|
|
251
312
|
display: none;
|
|
252
313
|
flex-direction: column;
|
|
@@ -259,13 +320,13 @@ html, body {
|
|
|
259
320
|
.os-drawer.open { display: flex; opacity: 1; transform: translateY(0); }
|
|
260
321
|
.os-drawer-head {
|
|
261
322
|
display: flex; align-items: center; justify-content: space-between;
|
|
262
|
-
padding:
|
|
323
|
+
padding: var(--space-2, 8px) var(--space-3, 16px);
|
|
263
324
|
border: none;
|
|
264
325
|
height: 56px;
|
|
265
326
|
box-sizing: border-box;
|
|
266
327
|
background: var(--os-bg-2);
|
|
267
328
|
}
|
|
268
|
-
.os-drawer-title { color: var(--os-fg); font-family: var(--os-display); font-size:
|
|
329
|
+
.os-drawer-title { color: var(--os-fg); font-family: var(--os-display); font-size: var(--fs-xl); font-weight: 700; letter-spacing: -0.01em; text-transform: lowercase; }
|
|
269
330
|
.os-drawer-close {
|
|
270
331
|
width: 44px; height: 44px;
|
|
271
332
|
border: none; background: transparent;
|
|
@@ -279,20 +340,24 @@ html, body {
|
|
|
279
340
|
.os-drawer-close .ic svg { width: 22px; height: 22px; fill: none; stroke: currentColor; }
|
|
280
341
|
.os-drawer-grid {
|
|
281
342
|
display: grid;
|
|
282
|
-
grid-template-columns: repeat(
|
|
283
|
-
gap:
|
|
284
|
-
padding: 16px;
|
|
343
|
+
grid-template-columns: repeat(auto-fill, minmax(clamp(92px, 24vw, 140px), 1fr));
|
|
344
|
+
gap: var(--space-3, 16px);
|
|
345
|
+
padding: var(--space-3, 16px);
|
|
285
346
|
overflow-y: auto;
|
|
286
347
|
flex: 1;
|
|
287
348
|
align-content: start;
|
|
349
|
+
max-width: 720px;
|
|
350
|
+
margin: 0 auto;
|
|
351
|
+
width: 100%;
|
|
352
|
+
box-sizing: border-box;
|
|
288
353
|
}
|
|
289
354
|
.os-drawer-tile {
|
|
290
|
-
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
|
|
291
|
-
padding:
|
|
355
|
+
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2, 8px);
|
|
356
|
+
padding: var(--space-3, 16px) var(--space-2, 8px);
|
|
292
357
|
background: var(--os-bg-1);
|
|
293
358
|
border: none;
|
|
294
359
|
color: var(--os-fg);
|
|
295
|
-
font:
|
|
360
|
+
font: var(--fs-tiny) var(--os-font);
|
|
296
361
|
min-height: 100px;
|
|
297
362
|
cursor: pointer;
|
|
298
363
|
transition: background 80ms ease;
|
|
@@ -307,62 +372,72 @@ html, body {
|
|
|
307
372
|
.os-drawer-tile .lbl { color: var(--os-fg); font-weight: 600; }
|
|
308
373
|
|
|
309
374
|
.os-spacer { flex: 1 1 auto; }
|
|
310
|
-
.os-tray { display: flex; align-items: center; gap:
|
|
311
|
-
.os-instances { display: flex; gap:
|
|
375
|
+
.os-tray { display: flex; align-items: center; gap: var(--space-1-75); }
|
|
376
|
+
.os-instances { display: flex; gap: var(--space-1); margin-left: var(--space-2); flex: 0 1 40vw; max-width: 40vw; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; padding: 0 var(--space-1); -webkit-mask-image: linear-gradient(to right, transparent, black 12px, black calc(100% - 12px), transparent); mask-image: linear-gradient(to right, transparent, black 12px, black calc(100% - 12px), transparent); }
|
|
312
377
|
.os-instances::-webkit-scrollbar { height: 4px; }
|
|
313
|
-
.os-instances .os-btn { flex: 0 0 auto; min-width: 36px; padding:
|
|
378
|
+
.os-instances .os-btn { flex: 0 0 auto; min-width: 36px; padding: var(--space-hair) var(--space-2); font-family: var(--os-mono); font-size: var(--fs-nano); }
|
|
314
379
|
.os-instances .os-btn.active { background: var(--panel-select, var(--os-accent-soft)); color: var(--os-fg); border-color: var(--panel-accent, var(--os-accent)); box-shadow: inset 0 0 0 1px var(--panel-accent, var(--os-accent)); }
|
|
315
380
|
.os-menubar [data-role="home"] { display: none; }
|
|
316
|
-
.os-root { position: fixed; inset: 0; display: flex; flex-direction: column; pointer-events: none; z-index:
|
|
381
|
+
.os-root { position: fixed; inset: 0; display: flex; flex-direction: column; pointer-events: none; z-index: calc(var(--z-dock) + 2); }
|
|
317
382
|
.os-menubar, .os-taskbar { pointer-events: auto; flex: 0 0 auto; }
|
|
318
383
|
.os-taskbar { margin-top: auto; }
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
.
|
|
324
|
-
|
|
325
|
-
.app-pane
|
|
326
|
-
.app-pane
|
|
384
|
+
/* Desktop default: the window layer sits BETWEEN the menubar and taskbar.
|
|
385
|
+
* Scoped (0,2,0) to beat wm.css's bare `.wm-root{inset:0}` by specificity
|
|
386
|
+
* rather than `!important`. The brand "bars overlay" block further below
|
|
387
|
+
* re-asserts inset:0 for .ds-247420 at equal specificity + later source order. */
|
|
388
|
+
.ds-247420 .wm-root { inset: var(--os-bar-h) 0 var(--os-bar-h) 0; }
|
|
389
|
+
|
|
390
|
+
.app-pane { padding: var(--space-3, 16px); font: var(--fs-sm, 14px) var(--os-font); color: var(--os-fg); line-height: var(--lh-base, 1.55); overflow: auto; height: 100%; box-sizing: border-box; background: var(--os-bg-1); }
|
|
391
|
+
.app-pane h2 { margin: 0 0 var(--space-2, 8px) 0; color: var(--os-fg); font-family: var(--os-display); font-size: var(--fs-xl, 21px); font-weight: 700; letter-spacing: -0.01em; line-height: var(--lh-snug, 1.2); }
|
|
392
|
+
.app-pane p { margin: 0 0 var(--space-2, 8px) 0; color: var(--os-fg-2); }
|
|
393
|
+
.app-pane ul { padding-left: var(--space-3, 16px); margin: var(--space-1, 4px) 0 var(--space-3, 16px); color: var(--os-fg-2); }
|
|
394
|
+
.app-pane li { padding: var(--space-1, 4px) 0; }
|
|
395
|
+
.app-pane code { font: var(--fs-tiny, 12px) var(--os-mono); background: var(--os-bg-2); padding: 1px var(--space-1-75); border-radius: var(--r-1, 6px); color: var(--os-fg); }
|
|
327
396
|
.app-pane a { color: var(--os-accent); text-decoration: none; }
|
|
328
397
|
.app-pane a:hover { text-decoration: underline; text-underline-offset: 2px; }
|
|
329
|
-
.app-pane .meta { color: var(--os-fg-3); font-size: 12px; }
|
|
330
|
-
.app-pane.mono { font:
|
|
331
|
-
.app-pane.mono
|
|
398
|
+
.app-pane .meta { color: var(--os-fg-3); font-size: var(--fs-tiny, 12px); }
|
|
399
|
+
.app-pane.mono { font: var(--fs-tiny, 12px) var(--os-mono); padding: var(--space-2, 8px); background: var(--os-bg-1); }
|
|
400
|
+
.app-pane.mono[data-component="monitor-app"] { white-space: pre-wrap; line-height: 1.7; }
|
|
401
|
+
.app-pane.mono .row { padding: var(--space-1) var(--space-2); cursor: pointer; border-radius: var(--r-1, 6px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
332
402
|
.app-pane.mono .row:hover { background: var(--panel-hover, var(--os-bg-2)); }
|
|
333
|
-
.app-pane.mono .
|
|
334
|
-
.app-pane.mono
|
|
335
|
-
.app-
|
|
403
|
+
.app-pane.mono .row.selected { background: var(--panel-select, var(--os-accent-soft)); box-shadow: inset 4px 0 0 var(--os-accent); }
|
|
404
|
+
.app-pane.mono .head { color: var(--os-accent); margin-bottom: var(--space-2); padding-bottom: var(--space-2); font-weight: 600; letter-spacing: 0.02em; border-bottom: 1px solid var(--os-bg-3); }
|
|
405
|
+
.app-pane.mono pre { background: var(--os-bg-2); padding: var(--space-2-5) var(--space-2-75); margin: var(--space-2) 0 0 0; max-height: 220px; overflow: auto; white-space: pre-wrap; font: var(--fs-nano) var(--os-mono); border-radius: var(--r-1, 6px); color: var(--os-fg); border: none; }
|
|
406
|
+
.app-shell-pane { margin: 0; padding: var(--space-2); font: var(--fs-micro) var(--os-mono); color: var(--os-fg); background: var(--os-bg-0); height: 100%; overflow: auto; white-space: pre-wrap; box-sizing: border-box; }
|
|
336
407
|
.app-canvas { width: 100%; height: 100%; background: var(--os-bg-0); display: block; cursor: default; }
|
|
337
|
-
.app-canvas.x-display { background: #0b0d10; }
|
|
408
|
+
.app-canvas.x-display { background: #0b0d10; } /* intentional: fake CRT/terminal black screen, not a theme surface */
|
|
338
409
|
.app-frame { width: 100%; height: 100%; border: 0; background: var(--os-bg-0); }
|
|
339
410
|
.app-iframe { width: 100%; height: 100%; border: 0; display: block; }
|
|
340
|
-
.app-iframe.web { background: #ffffff; }
|
|
341
|
-
.app-text-cursor {
|
|
342
|
-
|
|
411
|
+
.app-iframe.web { background: #ffffff; } /* intentional: white canvas for embedded external web content that expects white */
|
|
412
|
+
.app-text-cursor { }
|
|
413
|
+
|
|
414
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
415
|
+
.app-text-cursor { animation: app-cursor-blink 0.5s step-end infinite; }
|
|
416
|
+
@keyframes app-cursor-blink { 50% { opacity: 0; } }
|
|
417
|
+
}
|
|
343
418
|
@media (max-width: 1023px) and (min-width: 768px) {
|
|
344
419
|
.os-side-rail { display: flex; }
|
|
345
|
-
.wm-root { left: var(--os-rail-w)
|
|
346
|
-
.os-menubar { padding-left: calc(var(--os-rail-w) + 8px); }
|
|
347
|
-
.os-taskbar { padding-left: calc(var(--os-rail-w) + 8px); }
|
|
420
|
+
.ds-247420 .wm-root { left: calc(var(--os-rail-w) + env(safe-area-inset-left, 0px)); }
|
|
421
|
+
.os-menubar { padding-left: calc(var(--os-rail-w) + env(safe-area-inset-left, 0px) + var(--space-2, 8px)); }
|
|
422
|
+
.os-taskbar { padding-left: calc(var(--os-rail-w) + env(safe-area-inset-left, 0px) + var(--space-2, 8px)); }
|
|
348
423
|
.os-menubar .os-instances { display: flex; }
|
|
349
|
-
.os-menu { left: calc(var(--os-rail-w) + 8px); }
|
|
424
|
+
.os-menu { left: calc(var(--os-rail-w) + env(safe-area-inset-left, 0px) + var(--space-2, 8px)); }
|
|
350
425
|
}
|
|
351
426
|
|
|
352
427
|
@media (max-width: 767px) {
|
|
353
428
|
:root { --os-bar-h: var(--os-bar-h-mobile); }
|
|
354
429
|
body { overscroll-behavior: none; }
|
|
355
|
-
.os-menubar [data-role="home"] { display: inline-flex; min-width: var(--os-tap); min-height: var(--os-tap); padding: 0
|
|
430
|
+
.os-menubar [data-role="home"] { display: inline-flex; min-width: var(--os-tap); min-height: var(--os-tap); padding: 0 var(--space-2-75); }
|
|
356
431
|
.os-menubar [data-role="home"] .ic svg { width: 22px; height: 22px; }
|
|
357
|
-
.os-menubar { font-size:
|
|
432
|
+
.os-menubar { font-size: var(--fs-xs); padding: env(safe-area-inset-top, 0) max(8px, env(safe-area-inset-right, 0px)) 0 max(8px, env(safe-area-inset-left, 0px)); height: calc(var(--os-bar-h) + env(safe-area-inset-top, 0)); }
|
|
358
433
|
.os-menubar [data-role="apps"] { display: none; }
|
|
359
|
-
.os-menubar .os-brand { font-size:
|
|
434
|
+
.os-menubar .os-brand { font-size: var(--fs-tiny); margin-right: var(--space-1-75); }
|
|
360
435
|
.os-menubar [data-role="add"] { display: none; }
|
|
361
436
|
.os-menubar .os-instances { display: none; }
|
|
362
437
|
.os-clock { display: none; }
|
|
363
438
|
.os-taskbar {
|
|
364
|
-
padding: 6px 8px calc(6px + env(safe-area-inset-bottom, 0));
|
|
365
|
-
gap:
|
|
439
|
+
padding: 6px max(8px, env(safe-area-inset-right, 0px)) calc(6px + env(safe-area-inset-bottom, 0)) max(8px, env(safe-area-inset-left, 0px));
|
|
440
|
+
gap: var(--space-1-75);
|
|
366
441
|
overflow-x: auto;
|
|
367
442
|
overflow-y: hidden;
|
|
368
443
|
flex-wrap: nowrap;
|
|
@@ -376,37 +451,1142 @@ html, body {
|
|
|
376
451
|
min-width: 120px;
|
|
377
452
|
min-height: 44px;
|
|
378
453
|
max-width: none;
|
|
379
|
-
padding:
|
|
454
|
+
padding: var(--space-2-5) 14px;
|
|
380
455
|
scroll-snap-align: start;
|
|
381
|
-
font-size:
|
|
456
|
+
font-size: var(--fs-tiny);
|
|
382
457
|
}
|
|
383
|
-
.os-task.focused { background: var(--panel-select, var(--os-accent-soft)); box-shadow: inset
|
|
384
|
-
.os-side-rail { display: none
|
|
385
|
-
.os-menu { left:
|
|
386
|
-
.wm-root {
|
|
387
|
-
|
|
388
|
-
bottom: calc(var(--os-bar-h) + env(safe-area-inset-bottom, 0)) !important;
|
|
389
|
-
inset: calc(var(--os-bar-h) + env(safe-area-inset-top, 0)) 0 calc(var(--os-bar-h) + env(safe-area-inset-bottom, 0)) 0 !important;
|
|
458
|
+
.os-task.focused { background: var(--panel-select, var(--os-accent-soft)); box-shadow: inset var(--space-1) 0 0 var(--os-accent); }
|
|
459
|
+
.os-side-rail { display: none; }
|
|
460
|
+
.os-menu { left: var(--space-2); right: var(--space-2); min-width: 0; top: calc(var(--os-bar-h) + env(safe-area-inset-top, 0) + var(--space-1)); }
|
|
461
|
+
.ds-247420 .wm-root {
|
|
462
|
+
inset: calc(var(--os-bar-h) + env(safe-area-inset-top, 0)) 0 calc(var(--os-bar-h) + env(safe-area-inset-bottom, 0)) 0;
|
|
390
463
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
464
|
+
/* LOAD-BEARING !important: wm.css's own mobile block declares
|
|
465
|
+
* `.wm-win{left/top/width/height: ... !important}` (wm.css:157-165). An
|
|
466
|
+
* !important declaration can only be beaten by another !important one, so
|
|
467
|
+
* scoping alone cannot win here — these five must keep the flag. The
|
|
468
|
+
* non-!important properties in this rule do not, and were dropped. */
|
|
469
|
+
.ds-247420 .wm-win {
|
|
470
|
+
position: absolute;
|
|
471
|
+
left: 0 !important;
|
|
472
|
+
top: 0 !important;
|
|
473
|
+
width: 100% !important;
|
|
474
|
+
height: 100% !important;
|
|
475
|
+
border: none;
|
|
476
|
+
/* bare 0, not --r-0 (4px): a full-screen window has square corners.
|
|
477
|
+
* The radius lint intentionally does not flag unitless zero. */
|
|
478
|
+
border-radius: 0;
|
|
479
|
+
box-shadow: none;
|
|
398
480
|
}
|
|
399
|
-
.wm-bar {
|
|
400
|
-
padding:
|
|
401
|
-
height: 36px
|
|
402
|
-
gap:
|
|
403
|
-
cursor: default
|
|
404
|
-
touch-action: pan-y
|
|
481
|
+
.ds-247420 .wm-bar {
|
|
482
|
+
padding: var(--space-1-75) var(--space-2-5);
|
|
483
|
+
height: 36px;
|
|
484
|
+
gap: var(--space-1-75);
|
|
485
|
+
cursor: default;
|
|
486
|
+
touch-action: pan-y;
|
|
405
487
|
pointer-events: none;
|
|
406
488
|
}
|
|
407
|
-
.wm-bar .wm-title { pointer-events: auto; font-size:
|
|
408
|
-
.wm-bar .wm-btns { pointer-events: auto; }
|
|
409
|
-
.wm-btns .wm-btn:nth-child(1), .wm-btns .wm-btn:nth-child(2) { display: none
|
|
410
|
-
.wm-btns .wm-btn:nth-child(3) { width: 44px
|
|
411
|
-
.wm-resize { display: none
|
|
489
|
+
.ds-247420 .wm-bar .wm-title { pointer-events: auto; font-size: var(--fs-tiny); }
|
|
490
|
+
.ds-247420 .wm-bar .wm-btns { pointer-events: auto; }
|
|
491
|
+
.ds-247420 .wm-btns .wm-btn:nth-child(1), .ds-247420 .wm-btns .wm-btn:nth-child(2) { display: none; }
|
|
492
|
+
.ds-247420 .wm-btns .wm-btn:nth-child(3) { width: 44px; height: 44px; border-radius: var(--r-1); background: var(--os-bg-3); color: var(--os-fg); }
|
|
493
|
+
.ds-247420 .wm-resize, .ds-247420 .wm-edge { display: none; }
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/* ---- data-attr theme/accent: deferred to the canonical theme ----
|
|
497
|
+
* The OS shell no longer redefines surface or accent colors per theme. The
|
|
498
|
+
* --os-* aliases above consume the canonical semantic tokens (--bg/--fg/
|
|
499
|
+
* --accent), and colors_and_type.css already drives [data-theme] (paper/ink/
|
|
500
|
+
* auto, with color-scheme + --danger tuning) and [data-accent] (green/purple/
|
|
501
|
+
* mascot). Re-declaring the os surface or accent tokens per theme here only
|
|
502
|
+
* re-introduced drift (ink vs canonical ink; purple vs canonical purple).
|
|
503
|
+
* Density bar-height is genuinely OS-shell-specific, so it stays;
|
|
504
|
+
* --os-accent-tint maps to the canonical accent tint. */
|
|
505
|
+
:root { --os-accent-tint: var(--accent-tint); }
|
|
506
|
+
:root[data-density="compact"] { --os-bar-h: 28px; --os-tile-pad: 6px; --os-gap: 6px; }
|
|
507
|
+
:root[data-density="comfortable"] { --os-bar-h: 36px; --os-tile-pad: 10px; --os-gap: 10px; }
|
|
508
|
+
:root[data-density="spacious"] { --os-bar-h: 44px; --os-tile-pad: 14px; --os-gap: 14px; }
|
|
509
|
+
|
|
510
|
+
/* ============================================================
|
|
511
|
+
* thebird brand layer (migrated from thebird's local thebird-brand.css
|
|
512
|
+
* 2026-05-26). thebird ships ZERO design CSS — every rule below lives here
|
|
513
|
+
* upstream and is delivered via the published package. Scoped to .ds-247420
|
|
514
|
+
* (thebird's OS root carries that class). Brand identity: Inter + green accent
|
|
515
|
+
* + uniform 34px bars + Windows-style right-side window controls.
|
|
516
|
+
*
|
|
517
|
+
* NOTE: this no longer globally overrides --paper. A global :root override
|
|
518
|
+
* silently mutated the base theme for EVERY portfolio consumer (canonical
|
|
519
|
+
* --paper is #F6F5F1; thebird wanted #F5F0E4). The warm-paper variant is now a
|
|
520
|
+
* named preset [data-theme="thebird"] a consumer opts into, leaving the base
|
|
521
|
+
* theme untouched. The [data-theme="thebird"] COLOR preset now lives in the
|
|
522
|
+
* canonical colors_and_type.css (a first-class swappable theme); only the
|
|
523
|
+
* OS-shell chrome (bar geometry, typography alias) stays here scoped to
|
|
524
|
+
* .ds-247420.
|
|
525
|
+
* ============================================================ */
|
|
526
|
+
.ds-247420 {
|
|
527
|
+
--ff-ui: var(--ff-body);
|
|
528
|
+
/* uniform bar height: 22px button + 6px+6px padding = 34px.
|
|
529
|
+
* LOAD-BEARING !important: `:root[data-density="compact"|"comfortable"|
|
|
530
|
+
* "spacious"]` (this file, "data-attr theme/accent" block above) redefines
|
|
531
|
+
* --os-bar-h at (0,2,0) — HIGHER than this rule's (0,1,0) — on the same
|
|
532
|
+
* <html> element. Without the flag the density presets silently override
|
|
533
|
+
* the brand's uniform 34px bar geometry. */
|
|
534
|
+
--os-bar-h: 34px !important;
|
|
535
|
+
--os-bar-h-mobile: 34px !important;
|
|
536
|
+
--os-dock-h: 34px !important;
|
|
537
|
+
/* Brand identity, scoped so it never leaks to other portfolio consumers.
|
|
538
|
+
* The base theme's auto/paper/ink presets let --accent drift to the bright
|
|
539
|
+
* --green-2 (#3A9A34) in ink mode; thebird's brand accent is the deep green
|
|
540
|
+
* #247420 (--green) in EVERY resolved mode, and its paper is the warm
|
|
541
|
+
* #F5F0E4 variant. Re-assert both here rather than forcing the consumer to
|
|
542
|
+
* opt into [data-theme="thebird"], which the OS boots past with
|
|
543
|
+
* data-theme="auto". --accent-bright is pinned too so the ink-mode
|
|
544
|
+
* --accent: var(--accent-bright, ...) chain still resolves to brand green.
|
|
545
|
+
* LOAD-BEARING !important: colors_and_type.css defines --accent on
|
|
546
|
+
* `[data-accent="acid"|"green"|...]` and `[data-theme="ink"]` — attribute
|
|
547
|
+
* selectors at (0,1,0), the SAME specificity as this `.ds-247420` class
|
|
548
|
+
* rule, on the same <html> element. colors_and_type.css is always loaded
|
|
549
|
+
* first, but equal specificity + later source order would still let a
|
|
550
|
+
* [data-accent] preset win. The flag is the only thing pinning brand green. */
|
|
551
|
+
--accent: var(--green) !important;
|
|
552
|
+
--accent-bright: var(--green) !important;
|
|
553
|
+
--paper: #F5F0E4;
|
|
554
|
+
}
|
|
555
|
+
/* Window titlebar matches the 34px bar height; clamp so menubar/taskbar/titlebar
|
|
556
|
+
* heights are uniform. */
|
|
557
|
+
.ds-247420 .wm-bar { height: 34px; min-height: 34px; box-sizing: border-box; padding-top: var(--space-1); padding-bottom: var(--space-1); }
|
|
558
|
+
/* Bars overlay windows: .wm-root fills full viewport, menubar/taskbar paint on top.
|
|
559
|
+
* Tilde key hides them via .bars-hidden on <html>.
|
|
560
|
+
* Wins over the desktop `.ds-247420 .wm-root{inset:var(--os-bar-h)...}` above by
|
|
561
|
+
* equal specificity + later source order (both are now (0,2,0)) — no flag needed. */
|
|
562
|
+
.ds-247420 .wm-root { inset: 0; }
|
|
563
|
+
/* With bars overlaying the wm-root, a maximized window's 34px titlebar would
|
|
564
|
+
* sit exactly under the 34px menubar (untappable) and its body under the
|
|
565
|
+
* taskbar; keep maximized windows between the bars on desktop/tablet. The
|
|
566
|
+
* mobile band re-asserts its own contract in the responsive layer below. */
|
|
567
|
+
@media (min-width: 768px) {
|
|
568
|
+
/* LOAD-BEARING !important: wm.css declares `.wm-win.wm-max{top:0!important;
|
|
569
|
+
* height:100%!important}` (wm.css:137-143). Only another !important can beat
|
|
570
|
+
* an !important, regardless of specificity. */
|
|
571
|
+
.ds-247420 .wm-win.wm-max {
|
|
572
|
+
top: var(--os-bar-h) !important;
|
|
573
|
+
height: calc(100% - (var(--os-bar-h) * 2)) !important;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
/* Instance filtering hides off-instance windows via class, not inline style.
|
|
577
|
+
* LOAD-BEARING !important: must beat wm.css's `.wm-win.wm-max{...!important}`
|
|
578
|
+
* geometry and any display set by the window's own state classes — a hidden
|
|
579
|
+
* window must stay hidden no matter which layout rule matched it. */
|
|
580
|
+
.ds-247420 .wm-win.wm-inst-hidden,
|
|
581
|
+
.wm-win.wm-inst-hidden { display: none !important; }
|
|
582
|
+
/* LOAD-BEARING !important: `.os-menubar`/`.os-taskbar` carry `display:flex`
|
|
583
|
+
* from rules at equal-or-higher specificity in this sheet and in the responsive
|
|
584
|
+
* bands below; the tilde-key hide must beat all of them unconditionally. */
|
|
585
|
+
html.bars-hidden .os-menubar,
|
|
586
|
+
html.bars-hidden .os-taskbar { display: none !important; }
|
|
587
|
+
.ds-247420 .os-task { border-radius: var(--r-pill, 999px); }
|
|
588
|
+
.os-brand { font-family: var(--ff-display); font-weight: 700; }
|
|
589
|
+
|
|
590
|
+
/* thebird windows use Windows/Linux-style right-side controls (upstream theme
|
|
591
|
+
* sets .wm-btns order:-1 for a macOS look; thebird overrides to natural DOM
|
|
592
|
+
* order so controls render on the right). */
|
|
593
|
+
.ds-247420 .wm-btns { order: 0; }
|
|
594
|
+
|
|
595
|
+
/* OS-shell z-index layering: .os-root above .wm-root so its .os-menu dropdowns
|
|
596
|
+
* paint above windows. */
|
|
597
|
+
.ds-247420 .os-root { z-index: calc(var(--z-dock) + 2); }
|
|
598
|
+
.ds-247420 .os-menubar { z-index: calc(var(--z-dock) + 1); position: relative; }
|
|
599
|
+
.ds-247420 .os-taskbar { z-index: calc(var(--z-dock) + 1); position: relative; }
|
|
600
|
+
.ds-247420 .os-menu { z-index: var(--z-dropdown); }
|
|
601
|
+
.ds-247420 .wm-root { z-index: var(--z-window); }
|
|
602
|
+
.ds-247420 .launcher-dock { z-index: var(--z-dock); }
|
|
603
|
+
|
|
604
|
+
/* Touch/gesture hardening. */
|
|
605
|
+
html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-text-size-adjust: 100%; }
|
|
606
|
+
.ds-247420 .os-root, .ds-247420 .wm-root { touch-action: none; }
|
|
607
|
+
.ds-247420 .wm-body { overscroll-behavior: contain; touch-action: auto; }
|
|
608
|
+
.ds-247420 .wm-bar, .ds-247420 .wm-resize { -webkit-touch-callout: none; user-select: none; }
|
|
609
|
+
.ds-247420 .os-menubar, .ds-247420 .os-taskbar, .ds-247420 .launcher-dock { user-select: none; -webkit-user-select: none; }
|
|
610
|
+
|
|
611
|
+
/* Aero-snap drag preview. */
|
|
612
|
+
.ds-247420 .wm-snap-preview {
|
|
613
|
+
position: fixed;
|
|
614
|
+
pointer-events: none;
|
|
615
|
+
display: none;
|
|
616
|
+
z-index: calc(var(--z-window) + 1);
|
|
617
|
+
background: color-mix(in oklab, var(--os-accent) 20%, transparent);
|
|
618
|
+
border: 2px solid var(--os-accent);
|
|
619
|
+
border-radius: var(--r-0);
|
|
620
|
+
/* Animate only geometry, never `all` — `transition: all` animated display/
|
|
621
|
+
* opacity too, producing a one-frame ghost on show (jank-pass fix). */
|
|
622
|
+
transition: left 80ms ease, top 80ms ease, width 80ms ease, height 80ms ease;
|
|
623
|
+
}
|
|
624
|
+
@media (prefers-reduced-motion: reduce) {
|
|
625
|
+
.ds-247420 .wm-snap-preview { transition: none; }
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/* Alt+Tab window switcher overlay. */
|
|
629
|
+
.ds-247420 .wm-switcher {
|
|
630
|
+
position: fixed;
|
|
631
|
+
left: 50%;
|
|
632
|
+
top: 50%;
|
|
633
|
+
transform: translate(-50%, -50%);
|
|
634
|
+
padding: var(--space-3) var(--space-3-5);
|
|
635
|
+
background: var(--os-bg-2);
|
|
636
|
+
border: 1px solid var(--os-accent);
|
|
637
|
+
border-radius: var(--r-0);
|
|
638
|
+
z-index: var(--z-modal);
|
|
639
|
+
font-family: var(--ff-ui);
|
|
640
|
+
color: var(--os-fg);
|
|
641
|
+
min-width: 280px;
|
|
642
|
+
box-shadow: var(--shadow-overlay);
|
|
643
|
+
}
|
|
644
|
+
.ds-247420 .wm-switcher-item {
|
|
645
|
+
padding: var(--space-2) var(--space-2-75);
|
|
646
|
+
border-radius: var(--r-0);
|
|
647
|
+
display: flex;
|
|
648
|
+
align-items: center;
|
|
649
|
+
gap: var(--space-2-5);
|
|
650
|
+
}
|
|
651
|
+
.ds-247420 .wm-switcher-item.active {
|
|
652
|
+
background: var(--os-accent);
|
|
653
|
+
color: var(--paper);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/* freddie-chat font family (upstream still ships Nunito; brand is Inter). */
|
|
657
|
+
.ds-247420 freddie-chat,
|
|
658
|
+
.ds-247420 freddie-chat .chat-bubble,
|
|
659
|
+
.ds-247420 freddie-chat .chat-meta,
|
|
660
|
+
.ds-247420 freddie-chat .chat-head {
|
|
661
|
+
font-family: var(--ff-ui);
|
|
412
662
|
}
|
|
663
|
+
.ds-247420 freddie-chat .chat-bubble pre,
|
|
664
|
+
.ds-247420 freddie-chat .chat-bubble code {
|
|
665
|
+
font-family: var(--ff-mono, ui-monospace, Menlo, Consolas, monospace);
|
|
666
|
+
}
|
|
667
|
+
.ds-247420 freddie-chat .chat-head {
|
|
668
|
+
font-family: var(--ff-display, system-ui, sans-serif);
|
|
669
|
+
font-weight: 700;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/* Session-switch crossfade. */
|
|
673
|
+
.ds-247420 .wm-win { transition: opacity 140ms ease; }
|
|
674
|
+
.tb-switching .ds-247420 .wm-win { opacity: 0.4; }
|
|
675
|
+
@media (prefers-reduced-motion: reduce) {
|
|
676
|
+
.ds-247420 .wm-win { transition: none; }
|
|
677
|
+
.tb-switching .ds-247420 .wm-win { opacity: 1; }
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/* ---- Session-UX surfaces: chips + modals + empty state ---- */
|
|
681
|
+
.ds-247420 .os-instances { display: flex; gap: var(--space-1-75); align-items: center; flex: 0 1 auto; min-width: 0; height: var(--os-bar-h, 34px); overflow-x: auto; overflow-y: hidden; padding: 0 var(--space-1); scrollbar-width: none; }
|
|
682
|
+
.ds-247420 .os-instances::-webkit-scrollbar { display: none; }
|
|
683
|
+
|
|
684
|
+
.ds-247420 .tb-sess-chip {
|
|
685
|
+
display: inline-flex; align-items: center; gap: var(--space-1-75);
|
|
686
|
+
height: 22px; padding: 0 var(--space-1-75) 0 var(--space-2);
|
|
687
|
+
border-radius: var(--r-pill, 999px);
|
|
688
|
+
background: color-mix(in oklab, var(--fg) 6%, transparent);
|
|
689
|
+
color: var(--fg);
|
|
690
|
+
font-family: var(--ff-ui); font-size: var(--fs-nano); font-weight: 500;
|
|
691
|
+
cursor: pointer;
|
|
692
|
+
border: 1px solid transparent;
|
|
693
|
+
transition: background 120ms ease, border-color 120ms ease;
|
|
694
|
+
user-select: none; flex: 0 0 auto;
|
|
695
|
+
}
|
|
696
|
+
.ds-247420 .tb-sess-chip:hover { background: color-mix(in oklab, var(--fg) 12%, transparent); }
|
|
697
|
+
.ds-247420 .tb-sess-chip.active {
|
|
698
|
+
background: color-mix(in oklab, var(--os-accent) 18%, transparent);
|
|
699
|
+
border-color: var(--os-accent);
|
|
700
|
+
color: var(--fg);
|
|
701
|
+
}
|
|
702
|
+
.ds-247420 .tb-sess-chip.active .tb-sess-dot { background: var(--os-accent); box-shadow: 0 0 0 2px color-mix(in oklab, var(--os-accent) 30%, transparent); }
|
|
703
|
+
.ds-247420 .tb-sess-dot { width: 6px; height: 6px; border-radius: 50%; background: color-mix(in oklab, var(--fg) 40%, transparent); flex: 0 0 6px; }
|
|
704
|
+
.ds-247420 .tb-sess-label { max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
705
|
+
.ds-247420 .tb-sess-badge {
|
|
706
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
707
|
+
min-width: 16px; height: 14px; padding: 0 var(--space-1);
|
|
708
|
+
border-radius: var(--r-0);
|
|
709
|
+
background: color-mix(in oklab, var(--fg) 14%, transparent);
|
|
710
|
+
font-size: var(--fs-pico); font-weight: 600; line-height: 1;
|
|
711
|
+
}
|
|
712
|
+
.ds-247420 .tb-sess-chip.active .tb-sess-badge { background: color-mix(in oklab, var(--os-accent) 30%, transparent); }
|
|
713
|
+
.ds-247420 .tb-sess-x {
|
|
714
|
+
width: 16px; height: 16px; line-height: 14px; text-align: center;
|
|
715
|
+
border: 0; padding: 0; background: transparent;
|
|
716
|
+
border-radius: 50%; cursor: pointer; color: inherit;
|
|
717
|
+
font-size: var(--fs-xs); font-weight: 600;
|
|
718
|
+
opacity: 0.55; transition: opacity 120ms ease, background 120ms ease;
|
|
719
|
+
}
|
|
720
|
+
.ds-247420 .tb-sess-chip:hover .tb-sess-x { opacity: 1; }
|
|
721
|
+
.ds-247420 .tb-sess-x:hover { background: color-mix(in oklab, var(--danger) 30%, transparent); color: var(--on-color); }
|
|
722
|
+
|
|
723
|
+
.ds-247420 .tb-sess-add {
|
|
724
|
+
display: inline-flex; align-items: center; gap: var(--space-1);
|
|
725
|
+
height: 22px; padding: 0 var(--space-2-5);
|
|
726
|
+
border: 1px dashed color-mix(in oklab, var(--fg) 30%, transparent);
|
|
727
|
+
background: transparent;
|
|
728
|
+
border-radius: var(--r-pill, 999px);
|
|
729
|
+
font-family: var(--ff-ui); font-size: var(--fs-nano); font-weight: 500;
|
|
730
|
+
color: var(--fg);
|
|
731
|
+
cursor: pointer;
|
|
732
|
+
margin-left: var(--space-1-75);
|
|
733
|
+
transition: border-color 120ms ease, background 120ms ease;
|
|
734
|
+
}
|
|
735
|
+
.ds-247420 .tb-sess-add:hover {
|
|
736
|
+
border-color: var(--os-accent);
|
|
737
|
+
background: color-mix(in oklab, var(--os-accent) 8%, transparent);
|
|
738
|
+
}
|
|
739
|
+
.ds-247420 .tb-sess-add-plus { font-size: var(--fs-tiny); line-height: 1; }
|
|
740
|
+
.ds-247420 .tb-sess-add-lbl { line-height: 1; }
|
|
741
|
+
|
|
742
|
+
.tb-sess-overlay {
|
|
743
|
+
position: fixed; inset: 0; z-index: var(--z-modal);
|
|
744
|
+
background: var(--scrim);
|
|
745
|
+
display: flex; align-items: center; justify-content: center;
|
|
746
|
+
animation: tb-sess-fade 120ms ease;
|
|
747
|
+
}
|
|
748
|
+
@keyframes tb-sess-fade { from { opacity: 0; } to { opacity: 1; } }
|
|
749
|
+
.tb-sess-modal {
|
|
750
|
+
background: var(--bg);
|
|
751
|
+
color: var(--fg);
|
|
752
|
+
border-radius: var(--r-1);
|
|
753
|
+
box-shadow: var(--shadow-overlay);
|
|
754
|
+
min-width: 320px; max-width: 480px;
|
|
755
|
+
border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
|
|
756
|
+
overflow: hidden;
|
|
757
|
+
font-family: var(--ff-ui);
|
|
758
|
+
}
|
|
759
|
+
.tb-sess-modal-head { display: flex; align-items: center; justify-content: space-between; padding: var(--space-2-75) var(--space-3); border-bottom: 1px solid color-mix(in oklab, var(--fg) 8%, transparent); }
|
|
760
|
+
.tb-sess-modal-title { font-weight: 600; font-size: var(--fs-xs); }
|
|
761
|
+
.tb-sess-modal-x { background: transparent; border: 0; font-size: var(--fs-xl); line-height: 1; cursor: pointer; color: inherit; padding: 0 var(--space-1); }
|
|
762
|
+
.tb-sess-modal-body { padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
|
|
763
|
+
.tb-sess-modal-lbl { font-size: var(--fs-nano); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; opacity: 0.7; }
|
|
764
|
+
.tb-sess-modal-input {
|
|
765
|
+
width: 100%; box-sizing: border-box;
|
|
766
|
+
height: 32px; padding: 0 var(--space-2-5);
|
|
767
|
+
border: 1px solid color-mix(in oklab, var(--fg) 20%, transparent);
|
|
768
|
+
border-radius: var(--r-0);
|
|
769
|
+
background: color-mix(in oklab, var(--fg) 6%, var(--bg));
|
|
770
|
+
color: inherit;
|
|
771
|
+
font-family: inherit; font-size: var(--fs-tiny);
|
|
772
|
+
}
|
|
773
|
+
.tb-sess-modal-input:focus { outline: none; border-color: var(--os-accent); box-shadow: 0 0 0 3px color-mix(in oklab, var(--os-accent) 20%, transparent); }
|
|
774
|
+
.tb-sess-modal-hint { font-size: var(--fs-nano); opacity: 0.7; }
|
|
775
|
+
.tb-sess-modal-msg { font-size: var(--fs-tiny); }
|
|
776
|
+
.tb-sess-modal-foot { display: flex; justify-content: flex-end; gap: var(--space-2); padding: var(--space-2-75) var(--space-3); border-top: 1px solid color-mix(in oklab, var(--fg) 8%, transparent); }
|
|
777
|
+
.tb-sess-modal-btn {
|
|
778
|
+
height: 28px; padding: 0 14px;
|
|
779
|
+
border-radius: var(--r-0); border: 1px solid color-mix(in oklab, var(--fg) 20%, transparent);
|
|
780
|
+
background: transparent; color: inherit;
|
|
781
|
+
font-family: inherit; font-size: var(--fs-micro); font-weight: 500; cursor: pointer;
|
|
782
|
+
transition: background 120ms ease, border-color 120ms ease;
|
|
783
|
+
}
|
|
784
|
+
.tb-sess-modal-btn:hover { background: color-mix(in oklab, var(--fg) 6%, transparent); }
|
|
785
|
+
.tb-sess-modal-btn.primary { background: var(--os-accent); color: var(--on-color); border-color: var(--os-accent); }
|
|
786
|
+
.tb-sess-modal-btn.primary:hover { background: color-mix(in oklab, var(--os-accent) 80%, var(--ink)); }
|
|
787
|
+
.tb-sess-modal-btn.danger { background: var(--danger); color: var(--on-color); border-color: var(--danger); }
|
|
788
|
+
.tb-sess-modal-btn.danger:hover { background: color-mix(in oklab, var(--danger) 80%, var(--ink)); }
|
|
789
|
+
|
|
790
|
+
.tb-sess-empty {
|
|
791
|
+
position: fixed; inset: 0; z-index: var(--z-window);
|
|
792
|
+
display: flex; align-items: center; justify-content: center;
|
|
793
|
+
pointer-events: none;
|
|
794
|
+
}
|
|
795
|
+
.tb-sess-empty-card {
|
|
796
|
+
pointer-events: auto;
|
|
797
|
+
background: var(--bg);
|
|
798
|
+
color: var(--fg);
|
|
799
|
+
border: 1px solid color-mix(in oklab, var(--fg) 14%, transparent);
|
|
800
|
+
border-radius: var(--r-2);
|
|
801
|
+
box-shadow: var(--shadow-3);
|
|
802
|
+
padding: var(--space-5) 40px; text-align: center;
|
|
803
|
+
font-family: var(--ff-ui);
|
|
804
|
+
max-width: 420px;
|
|
805
|
+
}
|
|
806
|
+
.tb-sess-empty-title { font-size: var(--fs-lg); font-weight: 600; margin-bottom: var(--space-1-75); }
|
|
807
|
+
.tb-sess-empty-sub { font-size: var(--fs-tiny); opacity: 0.7; margin-bottom: var(--space-3-5); }
|
|
808
|
+
.tb-sess-empty-cta {
|
|
809
|
+
height: 40px; padding: 0 var(--space-4);
|
|
810
|
+
background: var(--os-accent); color: var(--on-color);
|
|
811
|
+
border: 0; border-radius: var(--r-pill, 999px);
|
|
812
|
+
font-family: inherit; font-size: var(--fs-xs); font-weight: 600;
|
|
813
|
+
cursor: pointer;
|
|
814
|
+
transition: transform 120ms ease, box-shadow 120ms ease;
|
|
815
|
+
}
|
|
816
|
+
.tb-sess-empty-cta:hover { transform: translateY(-1px); box-shadow: 0 4px 16px color-mix(in oklab, var(--os-accent) 40%, transparent); }
|
|
817
|
+
|
|
818
|
+
/* ---- Workspaces app — full-window session manager card grid ---- */
|
|
819
|
+
.ds-247420 .tb-sessions-app { display: flex; flex-direction: column; height: 100%; font-family: var(--ff-ui); color: var(--fg); background: var(--bg); }
|
|
820
|
+
.ds-247420 .tb-sessions-bar { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2-5) 14px; border-bottom: 1px solid color-mix(in oklab, var(--fg) 10%, transparent); }
|
|
821
|
+
.ds-247420 .tb-sessions-title { font-weight: 600; font-size: var(--fs-xs); }
|
|
822
|
+
.ds-247420 .tb-sessions-count { font-size: var(--fs-micro); opacity: 0.6; margin-left: var(--space-1); }
|
|
823
|
+
.ds-247420 .tb-sessions-spacer { flex: 1; }
|
|
824
|
+
.ds-247420 .tb-sessions-btn { height: 28px; padding: 0 var(--space-2-75); border-radius: var(--r-0); border: 1px solid color-mix(in oklab, var(--fg) 20%, transparent); background: transparent; color: inherit; font-size: var(--fs-micro); font-weight: 500; cursor: pointer; font-family: inherit; }
|
|
825
|
+
.ds-247420 .tb-sessions-btn:hover { background: color-mix(in oklab, var(--fg) 6%, transparent); }
|
|
826
|
+
.ds-247420 .tb-sessions-btn.primary { background: var(--os-accent); color: var(--on-color); border-color: var(--os-accent); }
|
|
827
|
+
.ds-247420 .tb-sessions-btn.danger { background: var(--danger); color: var(--on-color); border-color: var(--danger); }
|
|
828
|
+
.ds-247420 .tb-sessions-btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
829
|
+
.ds-247420 .tb-sessions-grid { flex: 1; overflow: auto; padding: 14px; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--space-2-75); align-content: start; }
|
|
830
|
+
.ds-247420 .tb-sessions-card { padding: var(--space-2-75); border-radius: var(--r-1, 10px); border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent); background: color-mix(in oklab, var(--fg) 3%, transparent); display: flex; flex-direction: column; gap: var(--space-2); transition: border-color 120ms ease, transform 120ms ease; }
|
|
831
|
+
.ds-247420 .tb-sessions-card:hover { border-color: var(--os-accent); }
|
|
832
|
+
.ds-247420 .tb-sessions-card.active { border-color: var(--os-accent); box-shadow: 0 0 0 2px color-mix(in oklab, var(--os-accent) 30%, transparent); }
|
|
833
|
+
.ds-247420 .tb-sessions-card-head { display: flex; align-items: center; gap: var(--space-2); }
|
|
834
|
+
.ds-247420 .tb-sessions-card-check { width: 14px; height: 14px; cursor: pointer; flex: 0 0 14px; }
|
|
835
|
+
.ds-247420 .tb-sessions-card-name { font-weight: 600; font-size: var(--fs-tiny); flex: 1; outline: none; padding: var(--space-hair) var(--space-1); border-radius: var(--r-0); }
|
|
836
|
+
.ds-247420 .tb-sessions-card-name[contenteditable="true"] { background: color-mix(in oklab, var(--fg) 8%, transparent); }
|
|
837
|
+
.ds-247420 .tb-sessions-card-id { font-family: var(--os-mono, monospace); font-size: var(--fs-pico); opacity: 0.5; }
|
|
838
|
+
.ds-247420 .tb-sessions-card-stats { font-size: var(--fs-nano); opacity: 0.7; display: flex; gap: var(--space-2-75); }
|
|
839
|
+
.ds-247420 .tb-sessions-card-actions { display: flex; gap: var(--space-1-75); margin-top: var(--space-1); }
|
|
840
|
+
.ds-247420 .tb-sessions-card-actions button { flex: 1; height: 24px; font-size: var(--fs-nano); padding: 0 var(--space-2); border-radius: var(--r-0); border: 1px solid color-mix(in oklab, var(--fg) 16%, transparent); background: transparent; color: inherit; cursor: pointer; font-family: inherit; }
|
|
841
|
+
.ds-247420 .tb-sessions-card-actions button:hover { background: color-mix(in oklab, var(--fg) 6%, transparent); }
|
|
842
|
+
.ds-247420 .tb-sessions-card-actions button.danger:hover { background: var(--danger); color: var(--on-color); border-color: var(--danger); }
|
|
843
|
+
.ds-247420 .tb-sessions-empty-mid { padding: 40px; text-align: center; opacity: 0.6; font-size: var(--fs-tiny); }
|
|
844
|
+
|
|
845
|
+
/* ---- prefers-contrast: more — strengthen borders + focus so the translucent
|
|
846
|
+
chrome stays legible under forced/high-contrast user settings. ---- */
|
|
847
|
+
@media (prefers-contrast: more) {
|
|
848
|
+
.ds-247420 .wm-win { border-color: var(--fg); }
|
|
849
|
+
.ds-247420 .wm-bar { border-bottom: 1px solid var(--fg); }
|
|
850
|
+
.ds-247420 .os-menubar,
|
|
851
|
+
.ds-247420 .os-taskbar { border-color: var(--fg); }
|
|
852
|
+
.ds-247420 .tb-sess-chip,
|
|
853
|
+
.ds-247420 .tb-sessions-card,
|
|
854
|
+
.ds-247420 .tb-sessions-btn { border-color: var(--fg); }
|
|
855
|
+
.ds-247420 :focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/* ---- print: a web-OS desktop has no meaningful print form. Suppress the
|
|
859
|
+
live chrome so a Ctrl+P does not waste pages on translucent panels. ---- */
|
|
860
|
+
/* LOAD-BEARING !important throughout this block. Print must defeat two things
|
|
861
|
+
* no selector can outrank: (1) wm.css's `.wm-win.wm-max{left/top/width/height
|
|
862
|
+
* !important}` and its mobile `.wm-win{...!important}` band, and (2) the
|
|
863
|
+
* INLINE styles createWM()/renderWindow() write directly onto .wm-win/.wm-canvas
|
|
864
|
+
* for drag, resize and pan (element style attribute beats every stylesheet
|
|
865
|
+
* rule). Flattening the desktop to static flow for print is only possible by
|
|
866
|
+
* force. Do not remove. */
|
|
867
|
+
@media print {
|
|
868
|
+
.os-menubar, .os-taskbar, .wm-snap-preview,
|
|
869
|
+
.tb-sess-overlay, .tb-switching, .wm-switcher { display: none !important; }
|
|
870
|
+
.wm-root, .wm-canvas { position: static !important; transform: none !important; overflow: visible !important; }
|
|
871
|
+
.wm-win { position: static !important; box-shadow: none !important; border: 1px solid var(--fg) !important; page-break-inside: avoid; margin: 0 0 var(--space-2-75); width: auto !important; height: auto !important; }
|
|
872
|
+
.wm-win.wm-min { display: none !important; }
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/* ============================================================================
|
|
876
|
+
* Relocated from thebird (2026-05-30) — moves design CSS out of docs/*.js
|
|
877
|
+
* modules to enforce the zero-design-CSS-in-thebird rule.
|
|
878
|
+
* Source files: docs/chat-config.js, docs/fsbrowse-app.js, docs/wm.js,
|
|
879
|
+
* docs/apps.js (todo-app), docs/freddie-keys.js.
|
|
880
|
+
* ============================================================================ */
|
|
881
|
+
|
|
882
|
+
/* ---- chat-config strip (was: docs/chat-config.js ensureStyles) ---- */
|
|
883
|
+
.ds-247420 .wm-body:has(> .freddie-chat-wrap) { display: flex; flex-direction: column; padding: 0; }
|
|
884
|
+
.ds-247420 .freddie-chat-wrap { position: absolute; inset: 0; display: flex; flex-direction: column; min-height: 0; }
|
|
885
|
+
.ds-247420 .freddie-chat-wrap > freddie-chat { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
|
|
886
|
+
.ds-247420 .cc-strip { flex: 0 0 auto; font-size: var(--fs-micro); border-bottom: 1px solid color-mix(in oklab, var(--fg) 16%, transparent); }
|
|
887
|
+
.ds-247420 .cc-toggle { all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: .4em; padding: .35em .7em; color: var(--fg, inherit); opacity: .75; }
|
|
888
|
+
.ds-247420 .cc-toggle:hover { opacity: 1; }
|
|
889
|
+
.ds-247420 .cc-toggle.cc-open { opacity: 1; font-weight: 600; }
|
|
890
|
+
.ds-247420 .cc-body { padding: .5em .7em .7em; display: flex; flex-direction: column; gap: .5em; max-height: 42vh; max-height: 42dvh; overflow: auto; }
|
|
891
|
+
.ds-247420 .cc-body[hidden] { display: none; }
|
|
892
|
+
.ds-247420 .cc-row { display: flex; gap: .6em; flex-wrap: wrap; }
|
|
893
|
+
.ds-247420 .cc-row > .cc-field { flex: 1 1 140px; min-width: 0; }
|
|
894
|
+
.ds-247420 .cc-field { display: flex; flex-direction: column; gap: .2em; }
|
|
895
|
+
.ds-247420 .cc-field-label { font-size: var(--fs-nano); opacity: .65; text-transform: lowercase; }
|
|
896
|
+
.ds-247420 .cc-strip select,
|
|
897
|
+
.ds-247420 .cc-strip input { font: inherit; font-size: var(--fs-micro); padding: .3em .4em; width: 100%; box-sizing: border-box; background: var(--panel-1, transparent); color: var(--fg, inherit); border: 1px solid color-mix(in oklab, var(--fg) 18%, transparent); border-radius: var(--r-0); }
|
|
898
|
+
.ds-247420 .cc-acp-mode-wrap { display: flex; align-items: center; gap: .4em; }
|
|
899
|
+
.ds-247420 .cc-acp-mode-wrap select { flex: 1; }
|
|
900
|
+
.ds-247420 .cc-acp-status { opacity: .5; font-size: var(--fs-tiny); }
|
|
901
|
+
.ds-247420 .cc-acp-status.cc-reachable { opacity: 1; color: var(--os-accent, #247420); }
|
|
902
|
+
.ds-247420 .cc-details > summary { cursor: pointer; opacity: .7; padding: .2em 0; }
|
|
903
|
+
.ds-247420 .cc-skills,
|
|
904
|
+
.ds-247420 .cc-plugins { display: flex; flex-wrap: wrap; gap: .3em .8em; padding: .3em 0; }
|
|
905
|
+
.ds-247420 .cc-check { display: inline-flex; align-items: center; gap: .3em; cursor: pointer; }
|
|
906
|
+
.ds-247420 .cc-check input { width: auto; }
|
|
907
|
+
.ds-247420 .cc-empty { opacity: .5; font-style: italic; }
|
|
908
|
+
|
|
909
|
+
/* ---- fsbrowse files app (was: docs/fsbrowse-app.js ensureStyles) ---- */
|
|
910
|
+
.ds-247420 .fsb-root { position: absolute; inset: 0; display: flex; flex-direction: column; min-height: 0; font-size: var(--fs-tiny); color: var(--fg, inherit); }
|
|
911
|
+
.ds-247420 .fsb-bar { flex: 0 0 auto; display: flex; align-items: center; gap: .4em; padding: .45em .6em; border-bottom: 1px solid color-mix(in oklab, var(--fg) 16%, transparent); flex-wrap: wrap; }
|
|
912
|
+
.ds-247420 .fsb-crumbs { flex: 1; display: flex; align-items: center; gap: .2em; min-width: 0; overflow: auto; white-space: nowrap; }
|
|
913
|
+
.ds-247420 .fsb-crumb { cursor: pointer; opacity: .75; text-decoration: none; color: inherit; }
|
|
914
|
+
.ds-247420 .fsb-crumb:hover { opacity: 1; text-decoration: underline; }
|
|
915
|
+
.ds-247420 .fsb-crumb-sep { opacity: .4; }
|
|
916
|
+
.ds-247420 .fsb-btn { all: unset; cursor: pointer; padding: .3em .55em; border: 1px solid color-mix(in oklab, var(--fg) 18%, transparent); border-radius: var(--r-0); opacity: .85; }
|
|
917
|
+
.ds-247420 .fsb-btn:hover { opacity: 1; background: color-mix(in oklab, var(--fg) 6%, transparent); }
|
|
918
|
+
.ds-247420 .fsb-list { flex: 1; min-height: 0; overflow: auto; padding: .3em 0; }
|
|
919
|
+
.ds-247420 .fsb-row { display: flex; align-items: center; gap: .6em; padding: .35em .7em; cursor: pointer; border: 0; }
|
|
920
|
+
.ds-247420 .fsb-row:hover { background: color-mix(in oklab, var(--fg) 6%, transparent); }
|
|
921
|
+
.ds-247420 .fsb-row:focus-visible { outline: 2px solid var(--os-accent); outline-offset: -2px; background: color-mix(in oklab, var(--fg) 6%, transparent); }
|
|
922
|
+
.ds-247420 .fsb-icon { width: 1.3em; text-align: center; flex: 0 0 auto; }
|
|
923
|
+
.ds-247420 .fsb-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
924
|
+
.ds-247420 .fsb-size { opacity: .55; font-size: var(--fs-nano); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
|
|
925
|
+
.ds-247420 .fsb-actions { display: flex; gap: .3em; flex: 0 0 auto; opacity: 0; }
|
|
926
|
+
/* Reveal row actions on hover OR keyboard focus-within OR coarse-pointer (touch),
|
|
927
|
+
* so they aren't hover-only dead controls for keyboard/touch users. */
|
|
928
|
+
.ds-247420 .fsb-row:hover .fsb-actions,
|
|
929
|
+
.ds-247420 .fsb-row:focus-within .fsb-actions { opacity: 1; }
|
|
930
|
+
@media (hover: none) { .ds-247420 .fsb-actions { opacity: 1; } }
|
|
931
|
+
.ds-247420 .fsb-act { all: unset; cursor: pointer; padding: .1em .35em; border-radius: var(--r-0); opacity: .7; font-size: var(--fs-micro); }
|
|
932
|
+
.ds-247420 .fsb-act:hover { opacity: 1; background: color-mix(in oklab, var(--fg) 12%, transparent); }
|
|
933
|
+
.ds-247420 .fsb-empty { opacity: .5; padding: 1.5em; text-align: center; font-style: italic; }
|
|
934
|
+
.ds-247420 .fsb-view { flex: 1; min-height: 0; overflow: auto; margin: 0; padding: .7em; white-space: pre-wrap; word-break: break-word; font: var(--fs-micro)/1.5 var(--os-mono, ui-monospace, monospace); background: var(--panel-1, transparent); }
|
|
935
|
+
.ds-247420 .fsb-dropping { outline: 2px dashed var(--os-accent, #247420); outline-offset: -6px; }
|
|
936
|
+
|
|
937
|
+
/* ---- wm canvas (infinite zoom/pan surface — was: docs/desktop-camera.js canvas.style.cssText) ----
|
|
938
|
+
* .wm-root is the fixed clipping viewport; .wm-canvas is the inner transformed
|
|
939
|
+
* layer that carries translate()/scale() updates per camera tick. Compositor-
|
|
940
|
+
* promoted via will-change:transform so per-frame pan/zoom does GPU-only work. */
|
|
941
|
+
.ds-247420 .wm-canvas { position: absolute; inset: 0; transform-origin: 0 0; will-change: transform; }
|
|
942
|
+
|
|
943
|
+
/* ---- wm context menu (was: docs/wm.js showWindowMenu cssText) ---- */
|
|
944
|
+
/* No var() fallbacks here: colors_and_type.css is guaranteed loaded first for
|
|
945
|
+
* every .ds-247420 consumer (see the file header), and the old `#1a1a1a` /
|
|
946
|
+
* `#fff` fallbacks were baked DARK values that would have rendered white text
|
|
947
|
+
* on a near-white panel in paper mode had they ever fired. */
|
|
948
|
+
.ds-247420 .wm-context-menu { position: fixed; background: var(--panel-2); border: 1px solid color-mix(in oklab, var(--fg) 18%, transparent); border-radius: var(--r-0); z-index: var(--z-dropdown); font-family: var(--ff-ui); color: var(--fg); min-width: 140px; box-shadow: 0 var(--space-2) var(--space-5) rgba(0, 0, 0, .35); padding: var(--space-1); }
|
|
949
|
+
.ds-247420 .wm-context-menu-item { display: block; width: 100%; padding: 7px var(--space-2-5); border: none; border-radius: var(--r-0); background: none; color: inherit; font-family: inherit; text-align: left; cursor: pointer; font-size: var(--fs-tiny); }
|
|
950
|
+
.ds-247420 .wm-context-menu-item:hover { background: color-mix(in oklab, var(--fg) 8%, transparent); }
|
|
951
|
+
|
|
952
|
+
/* ---- todo app (was: docs/apps.js todo-app cssText) ---- */
|
|
953
|
+
.ds-247420 .tb-todo-bar { display: flex; gap: var(--space-1-75); margin-bottom: var(--space-2); }
|
|
954
|
+
.ds-247420 .tb-todo-input { flex: 1; padding: var(--space-1-5) var(--space-2); border: 1px solid color-mix(in oklab, var(--fg) 18%, transparent); border-radius: var(--r-0); font: inherit; background: var(--panel-1, transparent); color: var(--fg, inherit); }
|
|
955
|
+
.ds-247420 .tb-todo-list { list-style: none; padding: 0; margin: var(--space-1-75) 0; }
|
|
956
|
+
.ds-247420 .tb-todo-footer { display: flex; gap: var(--space-2); align-items: center; margin-top: var(--space-1-75); font-size: var(--fs-nano); }
|
|
957
|
+
.ds-247420 .tb-todo-status { margin-top: var(--space-2-5); font-size: var(--fs-nano); color: color-mix(in oklab, var(--fg) 55%, transparent); padding: var(--space-1-75) var(--space-2); background: var(--panel-1, transparent); border-radius: var(--r-0); min-height: 14px; }
|
|
958
|
+
.ds-247420 .tb-todo-item { display: flex; gap: var(--space-2); align-items: center; padding: var(--space-1-5) var(--space-1-75); border-bottom: 1px solid color-mix(in oklab, var(--fg) 8%, transparent); }
|
|
959
|
+
.ds-247420 .tb-todo-text { flex: 1; }
|
|
960
|
+
.ds-247420 .tb-todo-text.is-done { text-decoration: line-through; color: color-mix(in oklab, var(--fg) 45%, transparent); }
|
|
961
|
+
.ds-247420 .tb-todo-del { padding: var(--space-hair) var(--space-2); }
|
|
962
|
+
|
|
963
|
+
/* ---- freddie keys panel (was: docs/freddie-keys.js cssText) ---- */
|
|
964
|
+
.ds-247420 .fk-root { padding: var(--space-2-75); overflow: auto; height: 100%; font-family: var(--os-mono, monospace); font-size: var(--fs-micro); }
|
|
965
|
+
.ds-247420 .fk-status { margin-top: var(--space-2); color: color-mix(in oklab, var(--fg) 60%, transparent); min-height: 1.2em; }
|
|
966
|
+
.ds-247420 .fk-row { display: grid; grid-template-columns: 140px 1fr auto auto; gap: var(--space-1-75); align-items: center; margin: var(--space-hair) 0; }
|
|
967
|
+
.ds-247420 .fk-input { font-family: var(--os-mono, monospace); font-size: var(--fs-nano); padding: var(--space-hair) var(--space-1); }
|
|
968
|
+
.ds-247420 .fk-title { font-weight: 600; margin-bottom: var(--space-2); }
|
|
969
|
+
.ds-247420 .fk-nim-wrap { display: flex; gap: var(--space-1-75); align-items: center; margin: var(--space-1) 0 var(--space-2-5) 0; }
|
|
970
|
+
.ds-247420 .fk-nim-in { font-family: var(--os-mono, monospace); font-size: var(--fs-nano); padding: var(--space-hair) var(--space-1); flex: 1; }
|
|
971
|
+
.ds-247420 .fk-badge { font-size: var(--fs-pico); padding: var(--space-hair) var(--space-1-75); border: 1px solid color-mix(in oklab, var(--fg) 18%, transparent); border-radius: var(--r-hair); color: var(--os-accent, #247420); }
|
|
972
|
+
.ds-247420 .fk-agent-title,
|
|
973
|
+
.ds-247420 .fk-host-title { margin-top: 14px; font-size: var(--fs-nano); color: color-mix(in oklab, var(--fg) 60%, transparent); }
|
|
974
|
+
.ds-247420 .fk-summary { font-size: var(--fs-pico); color: color-mix(in oklab, var(--fg) 60%, transparent); margin: var(--space-1-75) 0; }
|
|
975
|
+
|
|
976
|
+
/* ============================================================================
|
|
977
|
+
* Freddie chat redesign (2026-05-30) — extends ds-chat / freddie-chat with
|
|
978
|
+
* agent-loop chrome: tool-call cards, thinking indicator, system/centered
|
|
979
|
+
* roles, suggestion chips on empty state, cancel-while-generating button.
|
|
980
|
+
* Drives the {role: 'tool'|'system'|'thinking'} + parts:[{kind:'tool'|...}]
|
|
981
|
+
* shape that freddie's agent machine now produces.
|
|
982
|
+
* ============================================================================ */
|
|
983
|
+
|
|
984
|
+
/* Centered chrome for system/tool/thinking — full row, no avatar column. */
|
|
985
|
+
.ds-247420 .chat-msg.centered { grid-template-columns: 1fr; padding: var(--space-1) 12%; }
|
|
986
|
+
.ds-247420 .chat-msg.centered .chat-stack { align-items: center; }
|
|
987
|
+
.ds-247420 .chat-msg.system .chat-bubble { background: transparent; border: 0; font-style: italic; opacity: 0.65; font-size: var(--fs-micro); padding: var(--space-1) var(--space-2); text-align: center; max-width: 100%; }
|
|
988
|
+
|
|
989
|
+
/* Tool-call card — collapsible details with status icon + name + label. */
|
|
990
|
+
.ds-247420 .chat-tool { display: block; background: var(--panel-1, color-mix(in oklab, var(--fg) 4%, transparent)); border: 1px solid color-mix(in oklab, var(--fg) 14%, transparent); border-radius: var(--r-0); padding: 0; max-width: min(640px, 92%); overflow: hidden; font-size: var(--fs-micro); }
|
|
991
|
+
.ds-247420 .chat-tool[open] { background: var(--panel-1, color-mix(in oklab, var(--fg) 6%, transparent)); }
|
|
992
|
+
.ds-247420 .chat-tool.tool-error { border-color: color-mix(in oklab, var(--danger, #c0392b) 60%, transparent); }
|
|
993
|
+
.ds-247420 .chat-tool.tool-done { border-color: color-mix(in oklab, var(--os-accent, #247420) 35%, transparent); }
|
|
994
|
+
.ds-247420 .chat-tool-head { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1-75) var(--space-2-5); cursor: pointer; list-style: none; user-select: none; }
|
|
995
|
+
.ds-247420 .chat-tool-head::-webkit-details-marker { display: none; }
|
|
996
|
+
.ds-247420 .chat-tool-icon { display: inline-flex; width: 14px; height: 14px; align-items: center; justify-content: center; font-family: var(--os-mono, monospace); font-size: var(--fs-micro); opacity: 0.7; }
|
|
997
|
+
.ds-247420 .chat-tool.tool-error .chat-tool-icon { color: var(--danger, #c0392b); opacity: 1; }
|
|
998
|
+
.ds-247420 .chat-tool.tool-done .chat-tool-icon { color: var(--os-accent, #247420); opacity: 1; }
|
|
999
|
+
.ds-247420 .chat-tool.tool-running .chat-tool-icon { animation: chat-spin 1.4s linear infinite; }
|
|
1000
|
+
@keyframes chat-spin { to { transform: rotate(360deg); } }
|
|
1001
|
+
.ds-247420 .chat-tool-name { font-family: var(--os-mono, monospace); font-weight: 600; font-size: var(--fs-micro); }
|
|
1002
|
+
.ds-247420 .chat-tool-label { opacity: 0.7; font-size: var(--fs-nano); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1003
|
+
.ds-247420 .chat-tool-status { font-size: var(--fs-pico); opacity: 0.55; text-transform: uppercase; letter-spacing: 0.05em; margin-left: auto; }
|
|
1004
|
+
.ds-247420 .chat-tool-body { padding: var(--space-1) var(--space-2-5) var(--space-2-5); display: flex; flex-direction: column; gap: var(--space-2); border-top: 1px solid color-mix(in oklab, var(--fg) 8%, transparent); }
|
|
1005
|
+
.ds-247420 .chat-tool-section { display: flex; flex-direction: column; gap: var(--space-half); }
|
|
1006
|
+
.ds-247420 .chat-tool-section-label { font-size: var(--fs-pico); opacity: 0.5; text-transform: lowercase; letter-spacing: 0.05em; }
|
|
1007
|
+
.ds-247420 .chat-tool-pre { margin: 0; padding: var(--space-1-75) var(--space-2); background: color-mix(in oklab, var(--fg) 4%, transparent); border-radius: var(--r-0); max-height: 200px; overflow: auto; font: var(--fs-nano)/1.45 var(--os-mono, ui-monospace, monospace); white-space: pre-wrap; word-break: break-word; }
|
|
1008
|
+
.ds-247420 .chat-tool-pre.is-error { color: var(--danger, #c0392b); }
|
|
1009
|
+
|
|
1010
|
+
/* Thinking indicator — typing dots + label, transient (assistant-side). */
|
|
1011
|
+
.ds-247420 .chat-thinking { display: inline-flex; align-items: center; gap: var(--space-2); background: transparent; border: 0; padding: var(--space-1) var(--space-2); opacity: 0.7; font-size: var(--fs-micro); }
|
|
1012
|
+
.ds-247420 .chat-thinking-dots { display: inline-flex; gap: var(--space-half); }
|
|
1013
|
+
.ds-247420 .chat-thinking-dots span { width: 5px; height: 5px; border-radius: 50%; background: var(--fg); opacity: 0.4; animation: chat-thinking-bounce 1.2s infinite ease-in-out; }
|
|
1014
|
+
.ds-247420 .chat-thinking-dots span:nth-child(2) { animation-delay: 0.15s; }
|
|
1015
|
+
.ds-247420 .chat-thinking-dots span:nth-child(3) { animation-delay: 0.3s; }
|
|
1016
|
+
@keyframes chat-thinking-bounce { 0%, 80%, 100% { transform: scale(0.8); opacity: 0.4; } 40% { transform: scale(1); opacity: 1; } }
|
|
1017
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1018
|
+
.ds-247420 .chat-thinking-dots span { animation: none; opacity: 0.7; }
|
|
1019
|
+
.ds-247420 .chat-tool.tool-running .chat-tool-icon { animation: none; }
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
/* Empty-state suggestion chips — clickable prompts. */
|
|
1023
|
+
.ds-247420 .chat-empty-suggestions { display: flex; flex-wrap: wrap; gap: var(--space-1-75); justify-content: center; margin-top: var(--space-2-75); max-width: 480px; }
|
|
1024
|
+
.ds-247420 .chat-empty-suggestion { all: unset; cursor: pointer; font-size: var(--fs-micro); padding: var(--space-1-75) var(--space-2-5); border: 1px solid color-mix(in oklab, var(--fg) 18%, transparent); border-radius: var(--r-pill, 999px); background: var(--panel-1, transparent); transition: background 120ms ease, border-color 120ms ease; }
|
|
1025
|
+
.ds-247420 .chat-empty-suggestion:hover { background: color-mix(in oklab, var(--os-accent, #247420) 10%, transparent); border-color: var(--os-accent, #247420); }
|
|
1026
|
+
.ds-247420 .chat-empty-suggestion:focus-visible { outline: 2px solid var(--os-accent, #247420); outline-offset: 2px; }
|
|
1027
|
+
|
|
1028
|
+
/* Cancel-while-generating button replaces send. */
|
|
1029
|
+
.ds-247420 .chat-composer .send.cancel { background: var(--danger); color: var(--on-color); }
|
|
1030
|
+
.ds-247420 .chat-composer .send.cancel:hover { background: color-mix(in oklab, var(--danger, #c0392b) 80%, black); }
|
|
1031
|
+
|
|
1032
|
+
/* ============================================================================
|
|
1033
|
+
* Jank pass 2 (2026-05-30) — outer-layer scroll containment + iframe gesture
|
|
1034
|
+
* blocking + backdrop blur. Compositor-promotion on .wm-win drag/resize was
|
|
1035
|
+
* already addressed in pass 1 (commit 7e057b6); these are the rules pass 1
|
|
1036
|
+
* did not surface.
|
|
1037
|
+
* ============================================================================ */
|
|
1038
|
+
|
|
1039
|
+
/* Scroll containment on the desktop frame too — pass 1 only set
|
|
1040
|
+
* overscroll-behavior on .wm-body. Touch-trackpad two-finger pan over the
|
|
1041
|
+
* desktop could leak to document.body in some Chromium versions, briefly
|
|
1042
|
+
* rubber-banding the page while the camera also panned. */
|
|
1043
|
+
.ds-247420 .wm-root,
|
|
1044
|
+
.ds-247420 .wm-canvas { overscroll-behavior: contain; }
|
|
1045
|
+
|
|
1046
|
+
/* Block iframe pointer-events while a wm window is being dragged/resized so
|
|
1047
|
+
* mid-gesture cursor crossings into an iframe child don't swallow the drag
|
|
1048
|
+
* (the iframe captures pointerover and the outer wm pointermove stops firing).
|
|
1049
|
+
* .wm-dragging / .wm-resizing classes are toggled by docs/wm.js for gesture
|
|
1050
|
+
* duration only. */
|
|
1051
|
+
.ds-247420 .wm-dragging iframe,
|
|
1052
|
+
.ds-247420 .wm-resizing iframe,
|
|
1053
|
+
.ds-247420 body:has(.wm-win.wm-dragging) iframe,
|
|
1054
|
+
.ds-247420 body:has(.wm-win.wm-resizing) iframe { pointer-events: none; }
|
|
1055
|
+
|
|
1056
|
+
/* Subtle backdrop blur behind modal overlays — depth cue without compounding
|
|
1057
|
+
* paint cost since the blur layer is GPU-composited. Respect reduced-motion
|
|
1058
|
+
* by falling back to plain dim. */
|
|
1059
|
+
.ds-247420 .tb-sess-overlay { backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
|
|
1060
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1061
|
+
.ds-247420 .tb-sess-overlay { backdrop-filter: none; -webkit-backdrop-filter: none; }
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
/* -----------------------------------------------------------------------
|
|
1065
|
+
* Freddie chat — jank pass 3 (2026-05-31)
|
|
1066
|
+
* Pins layout, spacing, focus, scrollbar, role-distinct bubbles, focus ring,
|
|
1067
|
+
* overflow-wrap, empty-state typography, composer chrome, suggestion list.
|
|
1068
|
+
* Visual code lives in this kit; thebird only wires state.
|
|
1069
|
+
* ----------------------------------------------------------------------- */
|
|
1070
|
+
|
|
1071
|
+
.ds-247420 freddie-chat,
|
|
1072
|
+
.ds-247420 ds-chat,
|
|
1073
|
+
.ds-247420 freddie-chat.chat,
|
|
1074
|
+
.ds-247420 ds-chat.chat {
|
|
1075
|
+
display: flex;
|
|
1076
|
+
flex-direction: column;
|
|
1077
|
+
min-height: 0;
|
|
1078
|
+
height: 100%;
|
|
1079
|
+
overflow: hidden;
|
|
1080
|
+
/* zero the legacy `.chat` card treatment (app-shell.css chat-polish.css,
|
|
1081
|
+
which the bundle scopes to `.ds-247420 .chat` = (0,2,0)) leaking onto the
|
|
1082
|
+
host element, which also carries the `.chat` class. The
|
|
1083
|
+
`freddie-chat.chat` / `ds-chat.chat` compound selectors here are (0,2,1) —
|
|
1084
|
+
strictly higher — so these win on SPECIFICITY alone, independent of which
|
|
1085
|
+
sheet loads first. That is why no !important is needed. */
|
|
1086
|
+
margin: 0;
|
|
1087
|
+
padding: 0;
|
|
1088
|
+
gap: 0;
|
|
1089
|
+
max-width: none;
|
|
1090
|
+
background: transparent;
|
|
1091
|
+
border-radius: 0;
|
|
1092
|
+
}
|
|
1093
|
+
.ds-247420 freddie-chat > .chat,
|
|
1094
|
+
.ds-247420 ds-chat > .chat {
|
|
1095
|
+
flex: 1 1 auto;
|
|
1096
|
+
min-height: 0;
|
|
1097
|
+
display: flex;
|
|
1098
|
+
flex-direction: column;
|
|
1099
|
+
overflow: hidden;
|
|
1100
|
+
margin: 0;
|
|
1101
|
+
padding: 0;
|
|
1102
|
+
gap: 0;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
.ds-247420 .chat-head {
|
|
1106
|
+
display: flex;
|
|
1107
|
+
align-items: center;
|
|
1108
|
+
gap: var(--space-2);
|
|
1109
|
+
padding: var(--space-2) var(--space-2-75);
|
|
1110
|
+
border-bottom: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
|
|
1111
|
+
min-height: 38px;
|
|
1112
|
+
flex: 0 0 auto;
|
|
1113
|
+
background: var(--panel-0, transparent);
|
|
1114
|
+
}
|
|
1115
|
+
.ds-247420 .chat-head .dot {
|
|
1116
|
+
width: 8px;
|
|
1117
|
+
height: 8px;
|
|
1118
|
+
border-radius: 50%;
|
|
1119
|
+
background: var(--os-accent, #247420);
|
|
1120
|
+
flex-shrink: 0;
|
|
1121
|
+
}
|
|
1122
|
+
.ds-247420 .chat-head .ds-chat-title {
|
|
1123
|
+
font-size: var(--fs-tiny);
|
|
1124
|
+
font-weight: 600;
|
|
1125
|
+
margin: 0;
|
|
1126
|
+
white-space: nowrap;
|
|
1127
|
+
overflow: hidden;
|
|
1128
|
+
text-overflow: ellipsis;
|
|
1129
|
+
flex-shrink: 0;
|
|
1130
|
+
}
|
|
1131
|
+
.ds-247420 .chat-head .sub {
|
|
1132
|
+
font-size: var(--fs-micro);
|
|
1133
|
+
opacity: 0.7;
|
|
1134
|
+
white-space: nowrap;
|
|
1135
|
+
overflow: hidden;
|
|
1136
|
+
text-overflow: ellipsis;
|
|
1137
|
+
min-width: 0;
|
|
1138
|
+
flex: 1 1 auto;
|
|
1139
|
+
}
|
|
1140
|
+
.ds-247420 .chat-head .spread { flex: 0; }
|
|
1141
|
+
|
|
1142
|
+
.ds-247420 .chat-thread {
|
|
1143
|
+
flex: 1 1 auto;
|
|
1144
|
+
min-height: 0;
|
|
1145
|
+
overflow-y: auto;
|
|
1146
|
+
overflow-x: hidden;
|
|
1147
|
+
padding: var(--space-2-75);
|
|
1148
|
+
display: flex;
|
|
1149
|
+
flex-direction: column;
|
|
1150
|
+
gap: var(--space-1-75);
|
|
1151
|
+
scrollbar-width: thin;
|
|
1152
|
+
scrollbar-color: color-mix(in oklab, var(--fg) 22%, transparent) transparent;
|
|
1153
|
+
scroll-behavior: smooth;
|
|
1154
|
+
overscroll-behavior: contain;
|
|
1155
|
+
}
|
|
1156
|
+
.ds-247420 .chat-thread::-webkit-scrollbar { width: 8px; }
|
|
1157
|
+
.ds-247420 .chat-thread::-webkit-scrollbar-track { background: transparent; }
|
|
1158
|
+
.ds-247420 .chat-thread::-webkit-scrollbar-thumb {
|
|
1159
|
+
background: color-mix(in oklab, var(--fg) 18%, transparent);
|
|
1160
|
+
border-radius: var(--r-0);
|
|
1161
|
+
}
|
|
1162
|
+
.ds-247420 .chat-thread::-webkit-scrollbar-thumb:hover {
|
|
1163
|
+
background: color-mix(in oklab, var(--fg) 30%, transparent);
|
|
1164
|
+
}
|
|
1165
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1166
|
+
.ds-247420 .chat-thread { scroll-behavior: auto; }
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
.ds-247420 .chat-msg {
|
|
1170
|
+
display: grid;
|
|
1171
|
+
grid-template-columns: 28px 1fr;
|
|
1172
|
+
gap: var(--space-2);
|
|
1173
|
+
align-items: start;
|
|
1174
|
+
}
|
|
1175
|
+
.ds-247420 .chat-msg.you {
|
|
1176
|
+
grid-template-columns: 1fr 28px;
|
|
1177
|
+
justify-items: end;
|
|
1178
|
+
}
|
|
1179
|
+
.ds-247420 .chat-msg.you .chat-stack { align-items: flex-end; }
|
|
1180
|
+
.ds-247420 .chat-msg.centered {
|
|
1181
|
+
grid-template-columns: 1fr;
|
|
1182
|
+
justify-items: center;
|
|
1183
|
+
padding: var(--space-hair) 12%;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
.ds-247420 .chat-avatar {
|
|
1187
|
+
width: 28px;
|
|
1188
|
+
height: 28px;
|
|
1189
|
+
border-radius: 50%;
|
|
1190
|
+
background: color-mix(in oklab, var(--os-accent, #247420) 18%, transparent);
|
|
1191
|
+
color: var(--fg);
|
|
1192
|
+
display: inline-flex;
|
|
1193
|
+
align-items: center;
|
|
1194
|
+
justify-content: center;
|
|
1195
|
+
font-size: var(--fs-micro);
|
|
1196
|
+
font-weight: 600;
|
|
1197
|
+
text-transform: lowercase;
|
|
1198
|
+
flex-shrink: 0;
|
|
1199
|
+
user-select: none;
|
|
1200
|
+
}
|
|
1201
|
+
.ds-247420 .chat-msg.you .chat-avatar {
|
|
1202
|
+
background: var(--os-accent, #247420);
|
|
1203
|
+
color: var(--on-color);
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
.ds-247420 .chat-stack {
|
|
1207
|
+
display: flex;
|
|
1208
|
+
flex-direction: column;
|
|
1209
|
+
gap: var(--space-half);
|
|
1210
|
+
min-width: 0;
|
|
1211
|
+
align-items: flex-start;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
.ds-247420 .chat-bubble {
|
|
1215
|
+
background: var(--panel-1, color-mix(in oklab, var(--fg) 5%, transparent));
|
|
1216
|
+
color: var(--fg);
|
|
1217
|
+
border: 1px solid color-mix(in oklab, var(--fg) 8%, transparent);
|
|
1218
|
+
border-radius: var(--r-1);
|
|
1219
|
+
padding: var(--space-2) var(--space-2-75);
|
|
1220
|
+
font-size: var(--fs-xs);
|
|
1221
|
+
line-height: 1.5;
|
|
1222
|
+
max-width: min(720px, 86%);
|
|
1223
|
+
overflow-wrap: anywhere;
|
|
1224
|
+
word-break: break-word;
|
|
1225
|
+
}
|
|
1226
|
+
.ds-247420 .chat-msg.you .chat-bubble {
|
|
1227
|
+
background: var(--os-accent, #247420);
|
|
1228
|
+
color: var(--on-color);
|
|
1229
|
+
border-color: color-mix(in oklab, var(--os-accent, #247420) 60%, black);
|
|
1230
|
+
border-bottom-right-radius: 4px;
|
|
1231
|
+
}
|
|
1232
|
+
.ds-247420 .chat-msg.them .chat-bubble {
|
|
1233
|
+
border-bottom-left-radius: 4px;
|
|
1234
|
+
}
|
|
1235
|
+
.ds-247420 .chat-bubble + .chat-bubble { margin-top: var(--space-1); }
|
|
1236
|
+
.ds-247420 .chat-bubble pre,
|
|
1237
|
+
.ds-247420 .chat-bubble code { font-family: var(--os-mono, ui-monospace, monospace); font-size: var(--fs-micro); }
|
|
1238
|
+
.ds-247420 .chat-bubble pre {
|
|
1239
|
+
margin: var(--space-1-75) 0 0;
|
|
1240
|
+
padding: var(--space-2) var(--space-2-5);
|
|
1241
|
+
background: color-mix(in oklab, var(--fg) 6%, transparent);
|
|
1242
|
+
border-radius: var(--r-0);
|
|
1243
|
+
max-height: 320px;
|
|
1244
|
+
overflow: auto;
|
|
1245
|
+
white-space: pre;
|
|
1246
|
+
scrollbar-width: thin;
|
|
1247
|
+
}
|
|
1248
|
+
.ds-247420 .chat-msg.you .chat-bubble pre {
|
|
1249
|
+
background: color-mix(in oklab, black 25%, transparent);
|
|
1250
|
+
color: var(--on-color);
|
|
1251
|
+
}
|
|
1252
|
+
.ds-247420 .chat-bubble a {
|
|
1253
|
+
color: inherit;
|
|
1254
|
+
text-decoration: underline;
|
|
1255
|
+
text-decoration-thickness: 1px;
|
|
1256
|
+
text-underline-offset: 2px;
|
|
1257
|
+
overflow-wrap: anywhere;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
.ds-247420 .chat-meta {
|
|
1261
|
+
font-size: var(--fs-nano);
|
|
1262
|
+
opacity: 0.55;
|
|
1263
|
+
display: inline-flex;
|
|
1264
|
+
align-items: center;
|
|
1265
|
+
gap: var(--space-1-75);
|
|
1266
|
+
padding: 0 var(--space-1);
|
|
1267
|
+
}
|
|
1268
|
+
.ds-247420 .chat-msg.you .chat-meta { flex-direction: row-reverse; }
|
|
1269
|
+
|
|
1270
|
+
.ds-247420 .chat-empty {
|
|
1271
|
+
flex: 1 1 auto;
|
|
1272
|
+
display: flex;
|
|
1273
|
+
flex-direction: column;
|
|
1274
|
+
align-items: center;
|
|
1275
|
+
justify-content: center;
|
|
1276
|
+
text-align: center;
|
|
1277
|
+
padding: var(--space-5) var(--space-4);
|
|
1278
|
+
color: var(--fg);
|
|
1279
|
+
gap: var(--space-1);
|
|
1280
|
+
}
|
|
1281
|
+
.ds-247420 .chat-empty-title {
|
|
1282
|
+
font-size: var(--fs-lg);
|
|
1283
|
+
font-weight: 600;
|
|
1284
|
+
margin: 0;
|
|
1285
|
+
letter-spacing: -0.01em;
|
|
1286
|
+
}
|
|
1287
|
+
.ds-247420 .chat-empty-sub {
|
|
1288
|
+
font-size: var(--fs-tiny);
|
|
1289
|
+
opacity: 0.65;
|
|
1290
|
+
margin: 0;
|
|
1291
|
+
max-width: 420px;
|
|
1292
|
+
line-height: 1.5;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
.ds-247420 .chat-composer {
|
|
1296
|
+
display: flex;
|
|
1297
|
+
flex-direction: column;
|
|
1298
|
+
gap: var(--space-1-75);
|
|
1299
|
+
padding: var(--space-2) var(--space-2-5);
|
|
1300
|
+
border-top: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
|
|
1301
|
+
background: var(--panel-0, transparent);
|
|
1302
|
+
flex: 0 0 auto;
|
|
1303
|
+
}
|
|
1304
|
+
.ds-247420 .chat-composer textarea {
|
|
1305
|
+
font: var(--fs-xs)/1.45 var(--os-ui, system-ui), sans-serif;
|
|
1306
|
+
background: var(--panel-1, color-mix(in oklab, var(--fg) 5%, transparent));
|
|
1307
|
+
color: var(--fg);
|
|
1308
|
+
border: 1px solid color-mix(in oklab, var(--fg) 14%, transparent);
|
|
1309
|
+
border-radius: var(--r-0);
|
|
1310
|
+
padding: var(--space-2) var(--space-2-5);
|
|
1311
|
+
resize: none;
|
|
1312
|
+
outline: none;
|
|
1313
|
+
width: 100%;
|
|
1314
|
+
min-height: 40px;
|
|
1315
|
+
max-height: 200px;
|
|
1316
|
+
box-sizing: border-box;
|
|
1317
|
+
transition: border-color 120ms ease;
|
|
1318
|
+
}
|
|
1319
|
+
.ds-247420 .chat-composer textarea:hover {
|
|
1320
|
+
border-color: color-mix(in oklab, var(--fg) 22%, transparent);
|
|
1321
|
+
}
|
|
1322
|
+
.ds-247420 .chat-composer textarea:focus-visible {
|
|
1323
|
+
outline: 2px solid var(--os-accent, #247420);
|
|
1324
|
+
outline-offset: 0;
|
|
1325
|
+
border-color: color-mix(in oklab, var(--os-accent, #247420) 60%, transparent);
|
|
1326
|
+
}
|
|
1327
|
+
.ds-247420 .chat-composer-toolbar {
|
|
1328
|
+
display: flex;
|
|
1329
|
+
align-items: center;
|
|
1330
|
+
gap: var(--space-1);
|
|
1331
|
+
}
|
|
1332
|
+
.ds-247420 .composer-btn {
|
|
1333
|
+
all: unset;
|
|
1334
|
+
cursor: pointer;
|
|
1335
|
+
display: inline-flex;
|
|
1336
|
+
align-items: center;
|
|
1337
|
+
justify-content: center;
|
|
1338
|
+
width: 32px;
|
|
1339
|
+
height: 32px;
|
|
1340
|
+
border-radius: var(--r-0);
|
|
1341
|
+
color: var(--fg);
|
|
1342
|
+
opacity: 0.65;
|
|
1343
|
+
transition: background-color 120ms ease, opacity 120ms ease;
|
|
1344
|
+
}
|
|
1345
|
+
.ds-247420 .composer-btn:hover {
|
|
1346
|
+
background: color-mix(in oklab, var(--fg) 6%, transparent);
|
|
1347
|
+
opacity: 1;
|
|
1348
|
+
}
|
|
1349
|
+
.ds-247420 .composer-btn:focus-visible {
|
|
1350
|
+
outline: 2px solid var(--os-accent, #247420);
|
|
1351
|
+
outline-offset: 2px;
|
|
1352
|
+
opacity: 1;
|
|
1353
|
+
}
|
|
1354
|
+
.ds-247420 .chat-composer .send {
|
|
1355
|
+
all: unset;
|
|
1356
|
+
cursor: pointer;
|
|
1357
|
+
margin-left: auto;
|
|
1358
|
+
width: 36px;
|
|
1359
|
+
height: 32px;
|
|
1360
|
+
border-radius: var(--r-0);
|
|
1361
|
+
background: var(--os-accent, #247420);
|
|
1362
|
+
color: var(--on-color);
|
|
1363
|
+
display: inline-flex;
|
|
1364
|
+
align-items: center;
|
|
1365
|
+
justify-content: center;
|
|
1366
|
+
transition: background 120ms ease, transform 60ms ease;
|
|
1367
|
+
}
|
|
1368
|
+
.ds-247420 .chat-composer .send:hover {
|
|
1369
|
+
background: color-mix(in oklab, var(--os-accent, #247420) 88%, black);
|
|
1370
|
+
}
|
|
1371
|
+
.ds-247420 .chat-composer .send:active { transform: scale(0.96); }
|
|
1372
|
+
.ds-247420 .chat-composer .send:focus-visible {
|
|
1373
|
+
outline: 2px solid var(--os-accent, #247420);
|
|
1374
|
+
outline-offset: 2px;
|
|
1375
|
+
}
|
|
1376
|
+
.ds-247420 .chat-composer .send:disabled,
|
|
1377
|
+
.ds-247420 .chat-composer .send[disabled] {
|
|
1378
|
+
opacity: 0.35;
|
|
1379
|
+
cursor: not-allowed;
|
|
1380
|
+
background: color-mix(in oklab, var(--fg) 25%, transparent);
|
|
1381
|
+
}
|
|
1382
|
+
.ds-247420 .chat-composer.is-disabled {
|
|
1383
|
+
opacity: .55;
|
|
1384
|
+
pointer-events: none;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
.ds-247420 .ds-icon { --ds-icon-stroke: 1.7; }
|
|
1388
|
+
|
|
1389
|
+
.ds-247420 .aicat-face {
|
|
1390
|
+
font-family: var(--os-mono, ui-monospace, monospace);
|
|
1391
|
+
font-size: var(--fs-nano);
|
|
1392
|
+
line-height: 1.2;
|
|
1393
|
+
margin: 0;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
/* gm memory browser — recall hits rendered as interactive, prunable cards
|
|
1397
|
+
(thebird's gm app, docs/apps.js recall panel). */
|
|
1398
|
+
.ds-247420 .gm-recall-hits {
|
|
1399
|
+
display: flex;
|
|
1400
|
+
flex-direction: column;
|
|
1401
|
+
gap: var(--space-1-75);
|
|
1402
|
+
margin: var(--space-2) 0;
|
|
1403
|
+
}
|
|
1404
|
+
.ds-247420 .gm-recall-hit {
|
|
1405
|
+
border: 1px solid color-mix(in oklab, var(--fg) 14%, transparent);
|
|
1406
|
+
border-radius: var(--r-0);
|
|
1407
|
+
padding: var(--space-2) var(--space-2-5);
|
|
1408
|
+
background: color-mix(in oklab, var(--bg) 92%, var(--fg) 2%);
|
|
1409
|
+
}
|
|
1410
|
+
.ds-247420 .gm-recall-hit.is-pruned {
|
|
1411
|
+
opacity: 0.45;
|
|
1412
|
+
text-decoration: line-through;
|
|
1413
|
+
}
|
|
1414
|
+
.ds-247420 .gm-recall-meta {
|
|
1415
|
+
font-family: var(--os-mono, ui-monospace, monospace);
|
|
1416
|
+
font-size: var(--fs-nano);
|
|
1417
|
+
color: color-mix(in oklab, var(--fg) 60%, transparent);
|
|
1418
|
+
margin-bottom: var(--space-1);
|
|
1419
|
+
}
|
|
1420
|
+
.ds-247420 .gm-recall-text {
|
|
1421
|
+
font-size: var(--fs-tiny);
|
|
1422
|
+
line-height: 1.4;
|
|
1423
|
+
white-space: pre-wrap;
|
|
1424
|
+
word-break: break-word;
|
|
1425
|
+
}
|
|
1426
|
+
.ds-247420 .gm-recall-acts {
|
|
1427
|
+
display: flex;
|
|
1428
|
+
justify-content: flex-end;
|
|
1429
|
+
margin-top: var(--space-1-75);
|
|
1430
|
+
}
|
|
1431
|
+
.ds-247420 .gm-recall-forget {
|
|
1432
|
+
font-size: var(--fs-nano);
|
|
1433
|
+
padding: var(--space-hair) var(--space-2);
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
/* ============================================================
|
|
1437
|
+
* thebird RESPONSIVE PERFECTION layer (desk / tablet / mobile).
|
|
1438
|
+
* Appended LAST so the .ds-247420-scoped rules here win by SOURCE ORDER at
|
|
1439
|
+
* equal (0,2,0) specificity over the earlier brand overrides
|
|
1440
|
+
* (.ds-247420 .wm-root{inset:0} at the "bars overlay" block,
|
|
1441
|
+
* .ds-247420 .wm-bar{height:34px}, the unconditional
|
|
1442
|
+
* .ds-247420 .os-instances{display:flex}) that were silently defeating the
|
|
1443
|
+
* @media(max-width:767px)/(768-1023px) contracts. Every rule below is a
|
|
1444
|
+
* measured fix for a confirmed responsive-audit finding.
|
|
1445
|
+
*
|
|
1446
|
+
* Because every competing rule is now equally scoped, source order alone
|
|
1447
|
+
* decides — so this layer needs no !important except where it must beat
|
|
1448
|
+
* wm.css's own !important declarations or wm.js's inline styles.
|
|
1449
|
+
*
|
|
1450
|
+
* View classes: desktop >1023px (free-float windows, full menubar);
|
|
1451
|
+
* tablet 768..1023px (side-rail, wm-root left-offset); mobile <=767px AND
|
|
1452
|
+
* short landscape phones (full-screen windows, collapsed menubar, bottom
|
|
1453
|
+
* scroll-snap taskbar). Touch sizing is driven by (pointer:coarse) so it
|
|
1454
|
+
* also covers the landscape-phone band that width-only queries miss.
|
|
1455
|
+
* ============================================================ */
|
|
1456
|
+
|
|
1457
|
+
/* --- mobile bar height: the kit intends a touch-friendly 52px; the brand
|
|
1458
|
+
* layer pinned --os-bar-h-mobile to 34px which left no room for 44px tap
|
|
1459
|
+
* targets in the bar. Restore 52px on mobile/touch. --- */
|
|
1460
|
+
@media (max-width: 767px), (max-height: 500px) and (orientation: landscape) {
|
|
1461
|
+
/* LOAD-BEARING !important: same reason as the brand block's --os-bar-h —
|
|
1462
|
+
* `:root[data-density="…"]` redefines --os-bar-h at (0,2,0), higher than
|
|
1463
|
+
* this (0,1,0) class rule on the same <html> element. */
|
|
1464
|
+
.ds-247420 { --os-bar-h-mobile: 52px !important; --os-bar-h: 52px !important; }
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
/* --- mobile + landscape-phone full-screen windows. The earlier
|
|
1468
|
+
* .ds-247420 .wm-root{inset:0!important} forced windows over the bars so the
|
|
1469
|
+
* titlebar close button landed under the menubar (occluded, untappable) and
|
|
1470
|
+
* window content underlapped the taskbar. Re-assert the bar-inset at scoped
|
|
1471
|
+
* specificity so windows sit BETWEEN the bars. --- */
|
|
1472
|
+
@media (max-width: 767px), (max-height: 500px) and (orientation: landscape) {
|
|
1473
|
+
.ds-247420 .wm-root {
|
|
1474
|
+
inset: calc(var(--os-bar-h) + env(safe-area-inset-top, 0px)) 0
|
|
1475
|
+
calc(var(--os-bar-h) + env(safe-area-inset-bottom, 0px)) 0;
|
|
1476
|
+
}
|
|
1477
|
+
/* LOAD-BEARING !important on the geometry four: wm.css's mobile band
|
|
1478
|
+
* (wm.css:157-165) declares left/top/width/height with !important, and
|
|
1479
|
+
* wm.js writes left/top/width/height as INLINE styles during drag/resize.
|
|
1480
|
+
* Neither can be beaten by specificity — only by !important. The remaining
|
|
1481
|
+
* properties here need no flag. */
|
|
1482
|
+
.ds-247420 .wm-win {
|
|
1483
|
+
position: absolute;
|
|
1484
|
+
left: 0 !important; top: 0 !important;
|
|
1485
|
+
width: 100% !important; height: 100% !important;
|
|
1486
|
+
border: none;
|
|
1487
|
+
/* bare 0: full-screen window has square corners (not --r-0's 4px) */
|
|
1488
|
+
border-radius: 0;
|
|
1489
|
+
box-shadow: none;
|
|
1490
|
+
}
|
|
1491
|
+
/* titlebar must host a 44px close button -> 44px bar (beats the 34px brand
|
|
1492
|
+
* clamp by later source order at equal specificity) */
|
|
1493
|
+
.ds-247420 .wm-bar {
|
|
1494
|
+
height: 44px; min-height: 44px;
|
|
1495
|
+
padding: 0 var(--space-2-5); align-items: center;
|
|
1496
|
+
pointer-events: none;
|
|
1497
|
+
}
|
|
1498
|
+
.ds-247420 .wm-bar .wm-title { pointer-events: auto; }
|
|
1499
|
+
.ds-247420 .wm-bar .wm-btns { pointer-events: auto; }
|
|
1500
|
+
/* hide min+max on mobile full-screen; keep close at 44x44 fully inside the bar */
|
|
1501
|
+
.ds-247420 .wm-btns .wm-btn:nth-child(1),
|
|
1502
|
+
.ds-247420 .wm-btns .wm-btn:nth-child(2) { display: none; }
|
|
1503
|
+
/* LOAD-BEARING !important on width/height: wm.css's `@media (pointer:coarse)`
|
|
1504
|
+
* sets `.wm-btn{min-width:44px;min-height:44px}` and this must also beat the
|
|
1505
|
+
* (0,3,0) `.ds-247420 .wm-btns .wm-btn` coarse-pointer rule below, which is
|
|
1506
|
+
* later in source order. Colors/radius need no flag. */
|
|
1507
|
+
.ds-247420 .wm-btns .wm-btn:nth-child(3) {
|
|
1508
|
+
width: 44px !important; height: 44px !important;
|
|
1509
|
+
border-radius: var(--r-1);
|
|
1510
|
+
background: var(--os-bg-3); color: var(--os-fg);
|
|
1511
|
+
}
|
|
1512
|
+
.ds-247420 .wm-resize, .ds-247420 .wm-edge { display: none; }
|
|
1513
|
+
/* collapse the menubar workspace cluster on mobile. `.os-menubar
|
|
1514
|
+
* .os-instances` is (0,3,0) here, beating the unconditional (0,2,0)
|
|
1515
|
+
* `.ds-247420 .os-instances{display:flex}` on specificity. */
|
|
1516
|
+
.ds-247420 .os-menubar .os-instances,
|
|
1517
|
+
.ds-247420 .os-instances { display: none; }
|
|
1518
|
+
.ds-247420 .os-menubar [data-role="add"],
|
|
1519
|
+
.ds-247420 .tb-sess-add { display: none; }
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
/* --- landscape-phone (short + wide + touch): also hide the side-rail that the
|
|
1523
|
+
* 768-1023 tablet band would otherwise show, and force the mobile menubar. --- */
|
|
1524
|
+
@media (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
|
|
1525
|
+
.ds-247420 .os-side-rail { display: none; }
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
/* --- tablet (768..1023): the side-rail offset for .wm-root was defeated by
|
|
1529
|
+
* the scoped inset:0; re-asserted here at equal (0,2,0) specificity but later
|
|
1530
|
+
* source order, which is enough now that the earlier rule is also scoped.
|
|
1531
|
+
* `inset` alone carries the left offset — the separate `left` declaration it
|
|
1532
|
+
* used to be paired with was redundant with this shorthand. --- */
|
|
1533
|
+
@media (min-width: 768px) and (max-width: 1023px) {
|
|
1534
|
+
.ds-247420 .wm-root {
|
|
1535
|
+
inset: 0 0 0 var(--os-rail-w);
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
/* --- universal touch tap-target floor (pointer:coarse covers tablets AND
|
|
1540
|
+
* landscape phones that width-only queries miss). Every interactive control
|
|
1541
|
+
* the audit measured below 44px is lifted to the --os-tap (44px) token. --- */
|
|
1542
|
+
@media (pointer: coarse) {
|
|
1543
|
+
/* window chrome */
|
|
1544
|
+
.ds-247420 .wm-btns .wm-btn { min-width: var(--os-tap, 44px); min-height: var(--os-tap, 44px); }
|
|
1545
|
+
.ds-247420 .wm-resize { width: var(--os-tap, 44px); height: var(--os-tap, 44px); }
|
|
1546
|
+
/* taskbar tasks (also widen and snap on the whole touch band, not mobile-only) */
|
|
1547
|
+
.ds-247420 .os-task {
|
|
1548
|
+
min-height: var(--os-tap, 44px); min-width: 120px;
|
|
1549
|
+
padding: var(--space-2-5) 14px; scroll-snap-align: start;
|
|
1550
|
+
}
|
|
1551
|
+
.ds-247420 .os-taskbar { scroll-snap-type: x proximity; }
|
|
1552
|
+
/* menubar workspace controls (when shown on tablet) */
|
|
1553
|
+
.ds-247420 .os-menubar .tb-sess-x { min-width: var(--os-tap, 44px); min-height: var(--os-tap, 44px); }
|
|
1554
|
+
.ds-247420 .tb-sess-chip { min-height: var(--os-tap, 44px); }
|
|
1555
|
+
.ds-247420 .tb-sess-add { min-height: var(--os-tap, 44px); }
|
|
1556
|
+
/* modal controls */
|
|
1557
|
+
.ds-247420 .tb-sess-modal-input { height: var(--os-tap, 44px); min-height: var(--os-tap, 44px); }
|
|
1558
|
+
.ds-247420 .tb-sess-modal-btn { min-height: var(--os-tap, 44px); }
|
|
1559
|
+
.ds-247420 .tb-sess-modal-x { min-width: var(--os-tap, 44px); min-height: var(--os-tap, 44px); }
|
|
1560
|
+
/* files-app rows + per-row actions */
|
|
1561
|
+
.ds-247420 .fsb-row { min-height: var(--os-tap, 44px); }
|
|
1562
|
+
.ds-247420 .fsb-act {
|
|
1563
|
+
min-width: var(--os-tap, 44px); min-height: var(--os-tap, 44px);
|
|
1564
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
1565
|
+
}
|
|
1566
|
+
/* chat composer controls */
|
|
1567
|
+
.ds-247420 .chat-composer .send { width: var(--os-tap, 44px); height: var(--os-tap, 44px); }
|
|
1568
|
+
.ds-247420 .cc-toggle { min-height: var(--os-tap, 44px); }
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
/* --- files-app row actions must reveal on coarse pointers too (the existing
|
|
1572
|
+
* trigger keyed only on hover:none, which fails on hybrid touch+hover
|
|
1573
|
+
* tablets that also report a hover-capable pointer). --- */
|
|
1574
|
+
@media (hover: none), (pointer: coarse) {
|
|
1575
|
+
.ds-247420 .fsb-actions { opacity: 1; }
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
/* --- modals: a content-tall card had no max-height and the overlay did not
|
|
1579
|
+
* scroll, so the footer (primary action) was stranded off-canvas. Cap the
|
|
1580
|
+
* card to the visible viewport, scroll the body, honor safe-area. --- */
|
|
1581
|
+
.ds-247420 .tb-sess-overlay {
|
|
1582
|
+
overflow-y: auto;
|
|
1583
|
+
padding: max(12px, env(safe-area-inset-top, 0px)) max(12px, env(safe-area-inset-right, 0px))
|
|
1584
|
+
max(12px, env(safe-area-inset-bottom, 0px)) max(12px, env(safe-area-inset-left, 0px));
|
|
1585
|
+
}
|
|
1586
|
+
.ds-247420 .tb-sess-modal { max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px); display: flex; flex-direction: column; }
|
|
1587
|
+
.ds-247420 .tb-sess-modal-body { overflow-y: auto; min-height: 0; }
|
|
1588
|
+
|
|
1589
|
+
/* --- browser-pane: the generic .app-pane 16px prose padding stranded the
|
|
1590
|
+
* iframe 16px on every side; the browser pane is full-bleed. --- */
|
|
1591
|
+
/* (0,3,0) beats the generic `.app-pane` (0,1,0) prose padding on specificity. */
|
|
1592
|
+
.ds-247420 .app-pane.browser-app { padding: 0; }
|