anentrypoint-design 0.0.143 → 0.0.145

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.
@@ -14,7 +14,8 @@
14
14
  display: flex;
15
15
  align-items: center;
16
16
  justify-content: space-between;
17
- padding: 4px 10px;
17
+ gap: var(--space-2);
18
+ padding: var(--space-1) var(--space-2);
18
19
  background: var(--os-bg-2);
19
20
  font-family: var(--os-mono);
20
21
  font-size: 11px;
@@ -22,14 +23,30 @@
22
23
  text-transform: lowercase;
23
24
  flex: 0 0 auto;
24
25
  }
25
- .terminal-app-title { font-family: var(--os-mono); }
26
- .terminal-app-status { font-family: var(--os-mono); color: var(--os-fg-3); }
26
+ .terminal-app-title {
27
+ font-family: var(--os-mono);
28
+ min-width: 0;
29
+ overflow: hidden;
30
+ text-overflow: ellipsis;
31
+ white-space: nowrap;
32
+ }
33
+ .terminal-app-status {
34
+ font-family: var(--os-mono);
35
+ color: var(--os-fg-3);
36
+ flex: 0 0 auto;
37
+ overflow: hidden;
38
+ text-overflow: ellipsis;
39
+ white-space: nowrap;
40
+ }
27
41
  .terminal-app-slot {
28
42
  flex: 1 1 auto;
43
+ min-width: 0;
29
44
  min-height: 0;
30
45
  overflow: hidden;
31
46
  background: var(--os-bg-0);
47
+ position: relative;
32
48
  }
49
+ .terminal-app-slot > * { width: 100%; height: 100%; }
33
50
 
34
51
  /* ── browser-app ────────────────────────────────────────────────────── */
35
52
  .browser-app {
@@ -43,15 +60,15 @@
43
60
  .browser-app-bar {
44
61
  display: flex;
45
62
  align-items: center;
46
- gap: 6px;
47
- padding: 6px 8px;
63
+ gap: var(--space-1);
64
+ padding: var(--space-1) var(--space-2);
48
65
  background: var(--os-bg-2);
49
66
  flex: 0 0 auto;
50
67
  }
51
68
  .browser-app-btn {
52
69
  height: 28px;
53
70
  min-width: 28px;
54
- padding: 0 8px;
71
+ padding: 0 var(--space-2);
55
72
  background: var(--os-bg-3);
56
73
  color: var(--os-fg);
57
74
  border: none;
@@ -61,10 +78,12 @@
61
78
  outline: none;
62
79
  }
63
80
  .browser-app-btn:hover { background: var(--os-accent-soft); }
81
+ .browser-app-btn:focus-visible { box-shadow: inset 0 0 0 1px var(--os-accent); }
64
82
  .browser-app-url {
65
83
  flex: 1 1 auto;
84
+ min-width: 0;
66
85
  height: 28px;
67
- padding: 0 10px;
86
+ padding: 0 var(--space-2);
68
87
  background: var(--os-bg-0);
69
88
  color: var(--os-fg);
70
89
  border: none;
@@ -75,15 +94,16 @@
75
94
  .browser-app-url:focus { box-shadow: inset 4px 0 0 var(--os-accent); }
76
95
  .browser-app-slot {
77
96
  flex: 1 1 auto;
97
+ min-width: 0;
78
98
  min-height: 0;
79
99
  overflow: hidden;
80
100
  background: var(--os-bg-0);
81
- display: flex;
101
+ position: relative;
82
102
  }
83
- .browser-app-slot > * { flex: 1 1 auto; min-width: 0; min-height: 0; }
103
+ .browser-app-slot > * { width: 100%; height: 100%; }
84
104
  .browser-app-status {
85
105
  flex: 0 0 auto;
86
- padding: 2px 10px;
106
+ padding: var(--space-1) var(--space-2);
87
107
  background: var(--os-bg-2);
88
108
  font: 11px var(--os-mono);
89
109
  color: var(--os-fg-3);
@@ -103,29 +123,33 @@
103
123
  .validator-app-head {
104
124
  display: flex;
105
125
  align-items: center;
106
- gap: 10px;
107
- padding: 6px 10px;
126
+ gap: var(--space-2);
127
+ padding: var(--space-1) var(--space-2);
108
128
  background: var(--os-bg-2);
109
129
  flex: 0 0 auto;
110
130
  }
111
131
  .validator-app-banner {
112
- padding: 2px 10px;
132
+ flex: 0 0 auto;
133
+ padding: 2px var(--space-2);
113
134
  border-radius: 999px;
114
135
  font: 11px var(--os-mono);
115
136
  text-transform: lowercase;
116
137
  background: var(--os-bg-3);
117
138
  color: var(--os-fg-2);
118
139
  }
119
- .validator-app-banner[data-state="pass"] { background: var(--os-accent-soft); color: var(--os-fg); }
140
+ .validator-app-banner[data-state="pending"] { background: var(--os-amber); color: var(--os-bg-0); }
141
+ .validator-app-banner[data-state="pass"] { background: var(--os-accent); color: var(--os-bg-0); }
120
142
  .validator-app-banner[data-state="fail"] { background: var(--os-red); color: var(--os-bg-0); }
121
143
  .validator-app-counts {
144
+ flex: 0 0 auto;
122
145
  font: 11px var(--os-mono);
123
146
  color: var(--os-fg-2);
124
147
  }
125
148
  .validator-app-rerun {
126
149
  margin-left: auto;
127
- height: 24px;
128
- padding: 0 10px;
150
+ flex: 0 0 auto;
151
+ height: var(--space-4);
152
+ padding: 0 var(--space-2);
129
153
  background: var(--os-bg-3);
130
154
  color: var(--os-fg);
131
155
  border: none;
@@ -138,9 +162,11 @@
138
162
  .validator-app-rerun:hover { background: var(--os-accent-soft); }
139
163
  .validator-app-slot {
140
164
  flex: 1 1 auto;
165
+ min-width: 0;
141
166
  min-height: 0;
142
167
  overflow: hidden;
143
168
  display: flex;
169
+ position: relative;
144
170
  background: var(--os-bg-0);
145
171
  }
146
172
  .validator-app-slot > * { flex: 1 1 auto; min-width: 0; min-height: 0; }
@@ -10,8 +10,11 @@ export function renderFilesApp(opts = {}) {
10
10
  node.dataset.component = 'files-app';
11
11
 
12
12
  let preview = null;
13
+ let selected = null;
13
14
  async function refresh() {
14
15
  const items = await list();
16
+ preview = null;
17
+ selected = null;
15
18
  node.innerHTML = '';
16
19
  const head = document.createElement('div');
17
20
  head.className = 'head';
@@ -21,7 +24,11 @@ export function renderFilesApp(opts = {}) {
21
24
  const row = document.createElement('div');
22
25
  row.className = 'row';
23
26
  row.textContent = p;
27
+ row.title = p;
24
28
  row.addEventListener('click', async () => {
29
+ if (selected) selected.classList.remove('selected');
30
+ selected = row;
31
+ row.classList.add('selected');
25
32
  const body = await readFile(p);
26
33
  if (preview) preview.remove();
27
34
  preview = document.createElement('pre');
@@ -3,49 +3,52 @@
3
3
  Table/Receipt/Hero/Row/EmptyState/Chip) that ship their own classes via
4
4
  247420.css. This file holds the freddie-specific chrome that AGENTS.md's
5
5
  inline-styles ban pushed out of freddie-dashboard.js and the freddie/* page
6
- modules. */
6
+ modules. Tokens follow the kit --os-* namespace plus the base --space-*/
7
+ --fs-* 8pt scale, with the var(--token, fallback) idiom so the kit's
8
+ standalone theme.css resolves cleanly. */
7
9
 
8
10
  .app-fd .fd-pre {
9
- font-family: var(--ff-mono, JetBrains Mono, monospace);
10
- font-size: 12px;
11
+ font-family: var(--os-mono, JetBrains Mono, monospace);
12
+ font-size: var(--fs-tiny, 12px);
11
13
  white-space: pre-wrap;
12
14
  word-break: break-all;
13
15
  margin: 0;
14
16
  max-height: 320px;
15
17
  overflow: auto;
16
- background: var(--panel-2, #DDD3BC);
17
- padding: 8px 10px;
18
- border-radius: var(--r-1, 6px);
18
+ background: var(--os-bg-2, #F0E9DA);
19
+ padding: var(--space-2, 8px) var(--space-3, 16px);
20
+ border-radius: var(--os-radius-sm, 6px);
19
21
  }
20
22
 
21
23
  .fd-root { height: 100%; overflow: hidden; display: flex; flex-direction: column; }
22
24
 
23
- .fd-btn-mini { padding: 2px 10px; font-size: 0.8em; }
25
+ .fd-btn-mini { padding: var(--space-1, 4px) var(--space-2, 8px); font-size: var(--fs-tiny, 12px); }
24
26
 
25
27
  /* chat composer fields */
26
- .fd-chat-form { display: flex; flex-direction: column; gap: var(--tool-gutter, 16px); }
27
- .fd-chat-row { display: flex; gap: var(--tool-gutter, 16px); flex-wrap: wrap; }
28
- .fd-chat-field { display: flex; flex-direction: column; gap: 4px; min-width: 120px; }
28
+ .fd-chat-form { display: flex; flex-direction: column; gap: var(--space-3, 16px); }
29
+ .fd-chat-row { display: flex; gap: var(--space-3, 16px); flex-wrap: wrap; }
30
+ .fd-chat-field { display: flex; flex-direction: column; gap: var(--space-1, 4px); min-width: 120px; }
29
31
  .fd-chat-field-grow { flex: 2; min-width: 140px; }
30
- .fd-chat-field > label { font-size: 0.75em; opacity: 0.7; letter-spacing: 0.05em; }
32
+ .fd-chat-field > label { font-family: var(--os-mono, JetBrains Mono, monospace); font-size: var(--fs-micro, 11px); color: var(--os-fg-3, #857B6C); letter-spacing: var(--tr-label, 0.10em); text-transform: uppercase; }
31
33
  .fd-chat-field > input { width: 100%; box-sizing: border-box; }
32
- .fd-chat-submit { display: flex; gap: var(--tool-gutter, 16px); align-items: flex-end; }
34
+ .fd-chat-submit { display: flex; gap: var(--space-3, 16px); align-items: flex-end; }
33
35
  .fd-chat-submit textarea { flex: 1; resize: none; min-height: 80px; }
34
36
  .fd-chat-submit > button { align-self: flex-end; }
35
37
 
36
38
  /* chatlog (legacy fd-chat-msgs container) */
37
39
  .fd-chatlog {
38
40
  max-height: 420px; overflow-y: auto;
39
- background: var(--panel-2, #DDD3BC);
40
- border-radius: 4px; padding: 4px; margin-top: 8px;
41
+ background: var(--os-bg-2, #F0E9DA);
42
+ border-radius: var(--os-radius-sm, 6px);
43
+ padding: var(--space-1, 4px); margin-top: var(--space-2, 8px);
41
44
  }
42
- .fd-chatlog-msg { padding: 6px 10px; background: var(--panel-2, #DDD3BC); white-space: pre-wrap; word-break: break-word; }
43
- .fd-chatlog-assistant { color: var(--panel-accent, #3F8A4A); }
44
- .fd-chatlog-tool { margin: 4px 0; padding: 4px 8px; background: var(--panel-3, #C9BDA0); border-radius: 4px; font-family: var(--ff-mono, JetBrains Mono, monospace); font-size: 0.85em; }
45
- .fd-chatlog-tool-sum { cursor: pointer; color: var(--warn, #FF6B4A); padding: 2px 0; }
46
- .fd-chatlog-tool-body { margin: 4px 0 0; white-space: pre-wrap; word-break: break-all; max-height: 200px; overflow-y: auto; }
45
+ .fd-chatlog-msg { padding: var(--space-1, 4px) var(--space-3, 16px); background: var(--os-bg-2, #F0E9DA); white-space: pre-wrap; word-break: break-word; }
46
+ .fd-chatlog-assistant { color: var(--os-accent, #3F8A4A); }
47
+ .fd-chatlog-tool { margin: var(--space-1, 4px) 0; padding: var(--space-1, 4px) var(--space-2, 8px); background: var(--os-bg-3, #E3DAC7); border-radius: var(--os-radius-sm, 6px); font-family: var(--os-mono, JetBrains Mono, monospace); font-size: var(--fs-tiny, 12px); }
48
+ .fd-chatlog-tool-sum { cursor: pointer; color: var(--os-red, #FF6B4A); padding: var(--space-1, 4px) 0; }
49
+ .fd-chatlog-tool-body { margin: var(--space-1, 4px) 0 0; white-space: pre-wrap; word-break: break-all; max-height: 200px; overflow-y: auto; }
47
50
 
48
51
  /* chip wraps (providers, env) */
49
- .fd-chip-wrap { display: flex; flex-wrap: wrap; gap: 6px; }
50
- .fd-chip-wrap-padded { padding: 8px 4px; }
52
+ .fd-chip-wrap { display: flex; flex-wrap: wrap; gap: var(--space-1, 4px); }
53
+ .fd-chip-wrap-padded { padding: var(--space-2, 8px) var(--space-1, 4px); }
51
54
  .fd-env-chip { cursor: pointer; }
@@ -6,24 +6,25 @@
6
6
  .launcher-dock {
7
7
  position: fixed;
8
8
  left: 0; top: 0; bottom: 0;
9
- width: 56px;
9
+ width: var(--os-rail-w, 56px);
10
10
  background: var(--os-bg-2);
11
11
  border: none;
12
12
  display: flex;
13
13
  flex-direction: column;
14
14
  align-items: center;
15
- padding: 8px 0;
16
- gap: 8px;
15
+ padding: var(--space-2, 8px) 0;
16
+ gap: var(--space-2, 8px);
17
17
  z-index: 10000;
18
18
  pointer-events: auto;
19
19
  font: 11px var(--os-mono);
20
20
  color: var(--os-fg);
21
+ overflow: hidden;
21
22
  }
22
23
 
23
24
  .launcher-btn {
24
25
  width: 40px; height: 40px;
25
26
  background: transparent;
26
- color: inherit;
27
+ color: var(--os-fg-2);
27
28
  cursor: pointer;
28
29
  border-radius: var(--os-radius-sm);
29
30
  display: flex;
@@ -31,31 +32,39 @@
31
32
  justify-content: center;
32
33
  padding: 0;
33
34
  font: inherit;
35
+ text-transform: lowercase;
34
36
  transition: background 80ms ease, color 80ms ease, box-shadow 80ms ease;
35
37
  }
36
38
  .launcher-btn:hover { background: var(--panel-hover, var(--os-bg-1)); color: var(--os-fg); }
39
+ .launcher-btn:active { background: var(--panel-select); }
37
40
  .launcher-btn.active {
38
41
  background: var(--panel-select, var(--os-accent-soft));
39
42
  color: var(--os-fg);
40
43
  box-shadow: inset 4px 0 0 var(--os-accent);
41
44
  }
42
- .launcher-add { font-size: 20px; }
45
+ .launcher-add { font-size: 20px; color: var(--os-fg-2); }
46
+ .launcher-add:hover { color: var(--os-accent); }
43
47
 
44
48
  .launcher-instances {
45
49
  display: flex;
46
50
  flex-direction: column;
47
51
  align-items: center;
48
52
  gap: 8px;
53
+ flex: 1 1 auto;
54
+ min-height: 0;
55
+ overflow-y: auto;
56
+ overflow-x: hidden;
57
+ width: 100%;
49
58
  }
50
59
 
51
60
  .launcher-row {
52
61
  display: flex;
53
62
  flex-direction: column;
54
63
  align-items: center;
55
- gap: 2px;
64
+ gap: var(--space-1, 4px);
56
65
  }
57
66
 
58
- .launcher-close { font-size: 11px; opacity: 0.7; width: 20px; height: 20px; }
59
- .launcher-close:hover { opacity: 1; }
67
+ .launcher-close { font-size: 11px; opacity: 0.7; width: 20px; height: 20px; color: var(--os-fg-3); }
68
+ .launcher-close:hover { opacity: 1; color: var(--os-red); }
60
69
 
61
- .launcher-dock + .wm-root { left: 56px !important; }
70
+ .launcher-dock + .wm-root { left: var(--os-rail-w, 56px) !important; }
@@ -104,10 +104,10 @@ html, body {
104
104
  background: var(--os-bg-1);
105
105
  border: none;
106
106
  border-radius: var(--r-3, 18px);
107
- padding: 8px;
107
+ padding: var(--space-2, 8px);
108
108
  min-width: 220px;
109
- top: calc(var(--os-bar-h) + 4px);
110
- left: 8px;
109
+ top: calc(var(--os-bar-h) + var(--space-1, 4px));
110
+ left: var(--space-2, 8px);
111
111
  z-index: 9500;
112
112
  display: none;
113
113
  flex-direction: column;
@@ -220,15 +220,15 @@ html, body {
220
220
 
221
221
  .os-side-rail {
222
222
  position: fixed;
223
- left: 0; top: 0; bottom: 0;
223
+ left: 0; top: var(--os-bar-h); bottom: var(--os-bar-h);
224
224
  width: var(--os-rail-w);
225
225
  background: var(--os-bg-2);
226
226
  border: none;
227
227
  display: none;
228
228
  flex-direction: column;
229
229
  align-items: center;
230
- padding: 12px 0;
231
- gap: 6px;
230
+ padding: var(--space-2, 8px) 0;
231
+ gap: var(--space-1, 4px);
232
232
  z-index: 9100;
233
233
  pointer-events: auto;
234
234
  }
@@ -266,7 +266,7 @@ html, body {
266
266
  .os-drawer.open { display: flex; opacity: 1; transform: translateY(0); }
267
267
  .os-drawer-head {
268
268
  display: flex; align-items: center; justify-content: space-between;
269
- padding: 12px 16px;
269
+ padding: var(--space-2, 8px) var(--space-3, 16px);
270
270
  border: none;
271
271
  height: 56px;
272
272
  box-sizing: border-box;
@@ -287,15 +287,15 @@ html, body {
287
287
  .os-drawer-grid {
288
288
  display: grid;
289
289
  grid-template-columns: repeat(3, 1fr);
290
- gap: 12px;
291
- padding: 16px;
290
+ gap: var(--space-3, 16px);
291
+ padding: var(--space-3, 16px);
292
292
  overflow-y: auto;
293
293
  flex: 1;
294
294
  align-content: start;
295
295
  }
296
296
  .os-drawer-tile {
297
- display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
298
- padding: 18px 8px;
297
+ display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2, 8px);
298
+ padding: var(--space-3, 16px) var(--space-2, 8px);
299
299
  background: var(--os-bg-1);
300
300
  border: none;
301
301
  color: var(--os-fg);
@@ -320,24 +320,26 @@ html, body {
320
320
  .os-instances .os-btn { flex: 0 0 auto; min-width: 36px; padding: 2px 8px; font-family: var(--os-mono); font-size: 11px; }
321
321
  .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)); }
322
322
  .os-menubar [data-role="home"] { display: none; }
323
- .os-root { position: fixed; inset: 0; display: flex; flex-direction: column; pointer-events: none; z-index: 8000; }
323
+ .os-root { position: fixed; inset: 0; display: flex; flex-direction: column; pointer-events: none; z-index: 9300; }
324
324
  .os-menubar, .os-taskbar { pointer-events: auto; flex: 0 0 auto; }
325
325
  .os-taskbar { margin-top: auto; }
326
326
  .wm-root { top: var(--os-bar-h) !important; bottom: var(--os-bar-h) !important; inset: var(--os-bar-h) 0 var(--os-bar-h) 0 !important; }
327
327
 
328
- .app-pane { padding: 16px 18px; font: 14px var(--os-font); color: var(--os-fg); line-height: 1.55; overflow: auto; height: 100%; box-sizing: border-box; background: var(--os-bg-1); }
329
- .app-pane h2 { margin: 0 0 10px 0; color: var(--os-fg); font-family: var(--os-display); font-size: 22px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.15; }
330
- .app-pane p { margin: 0 0 10px 0; color: var(--os-fg-2); }
331
- .app-pane ul { padding-left: 18px; margin: 6px 0 12px; color: var(--os-fg-2); }
332
- .app-pane li { padding: 2px 0; }
333
- .app-pane code { font: 12px var(--os-mono); background: var(--os-bg-2); padding: 1px 6px; border-radius: var(--r-1, 6px); color: var(--os-fg); }
328
+ .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); }
329
+ .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); }
330
+ .app-pane p { margin: 0 0 var(--space-2, 8px) 0; color: var(--os-fg-2); }
331
+ .app-pane ul { padding-left: var(--space-3, 16px); margin: var(--space-1, 4px) 0 var(--space-3, 16px); color: var(--os-fg-2); }
332
+ .app-pane li { padding: var(--space-1, 4px) 0; }
333
+ .app-pane code { font: var(--fs-tiny, 12px) var(--os-mono); background: var(--os-bg-2); padding: 1px 6px; border-radius: var(--r-1, 6px); color: var(--os-fg); }
334
334
  .app-pane a { color: var(--os-accent); text-decoration: none; }
335
335
  .app-pane a:hover { text-decoration: underline; text-underline-offset: 2px; }
336
- .app-pane .meta { color: var(--os-fg-3); font-size: 12px; }
337
- .app-pane.mono { font: 12.5px var(--os-mono); padding: 12px; background: var(--os-bg-1); }
338
- .app-pane.mono .row { padding: 5px 8px; cursor: pointer; border-radius: var(--r-1, 6px); }
336
+ .app-pane .meta { color: var(--os-fg-3); font-size: var(--fs-tiny, 12px); }
337
+ .app-pane.mono { font: var(--fs-tiny, 12px) var(--os-mono); padding: var(--space-2, 8px); background: var(--os-bg-1); }
338
+ .app-pane.mono[data-component="monitor-app"] { white-space: pre-wrap; line-height: 1.7; }
339
+ .app-pane.mono .row { padding: 4px 8px; cursor: pointer; border-radius: var(--r-1, 6px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
339
340
  .app-pane.mono .row:hover { background: var(--panel-hover, var(--os-bg-2)); }
340
- .app-pane.mono .head { color: var(--os-accent); margin-bottom: 8px; padding-bottom: 6px; font-weight: 600; letter-spacing: 0.02em; }
341
+ .app-pane.mono .row.selected { background: var(--panel-select, var(--os-accent-soft)); box-shadow: inset 4px 0 0 var(--os-accent); }
342
+ .app-pane.mono .head { color: var(--os-accent); margin-bottom: 8px; padding-bottom: 8px; font-weight: 600; letter-spacing: 0.02em; border-bottom: 1px solid var(--os-bg-3); }
341
343
  .app-pane.mono pre { background: var(--os-bg-2); padding: 10px 12px; margin: 8px 0 0 0; max-height: 220px; overflow: auto; white-space: pre-wrap; font: 11.5px var(--os-mono); border-radius: var(--r-1, 6px); color: var(--os-fg); border: none; }
342
344
  .app-shell-pane { margin: 0; padding: 8px; font: 12px var(--os-mono); color: var(--os-fg); background: var(--os-bg-0); height: 100%; overflow: auto; white-space: pre-wrap; box-sizing: border-box; }
343
345
  .app-canvas { width: 100%; height: 100%; background: var(--os-bg-0); display: block; cursor: default; }
@@ -354,10 +356,10 @@ html, body {
354
356
  @media (max-width: 1023px) and (min-width: 768px) {
355
357
  .os-side-rail { display: flex; }
356
358
  .wm-root { left: var(--os-rail-w) !important; }
357
- .os-menubar { padding-left: calc(var(--os-rail-w) + 8px); }
358
- .os-taskbar { padding-left: calc(var(--os-rail-w) + 8px); }
359
+ .os-menubar { padding-left: calc(var(--os-rail-w) + var(--space-2, 8px)); }
360
+ .os-taskbar { padding-left: calc(var(--os-rail-w) + var(--space-2, 8px)); }
359
361
  .os-menubar .os-instances { display: flex; }
360
- .os-menu { left: calc(var(--os-rail-w) + 8px); }
362
+ .os-menu { left: calc(var(--os-rail-w) + var(--space-2, 8px)); }
361
363
  }
362
364
 
363
365
  @media (max-width: 767px) {
@@ -18,7 +18,7 @@
18
18
  background: var(--os-bg-1);
19
19
  color: var(--os-fg);
20
20
  border: none;
21
- border-radius: var(--r-3, 18px);
21
+ border-radius: var(--os-radius, var(--r-2, 10px));
22
22
  display: flex;
23
23
  flex-direction: column;
24
24
  pointer-events: auto;
@@ -29,7 +29,7 @@
29
29
  .wm-bar {
30
30
  display: flex;
31
31
  align-items: center;
32
- padding: 6px 10px;
32
+ padding: 8px 12px;
33
33
  background: var(--os-bg-2);
34
34
  cursor: move;
35
35
  user-select: none;
@@ -39,14 +39,16 @@
39
39
  }
40
40
  .wm-title {
41
41
  flex: 1;
42
+ min-width: 0;
42
43
  font: 12px var(--os-font);
44
+ color: var(--os-fg-2);
43
45
  white-space: nowrap;
44
46
  overflow: hidden;
45
47
  text-overflow: ellipsis;
46
48
  text-transform: lowercase;
47
49
  }
48
50
 
49
- .wm-btns { display: flex; gap: 4px; }
51
+ .wm-btns { display: flex; gap: 6px; }
50
52
  .wm-btn {
51
53
  width: 22px;
52
54
  height: 22px;
@@ -60,10 +62,10 @@
60
62
  display: inline-flex;
61
63
  align-items: center;
62
64
  justify-content: center;
63
- border-radius: var(--r-1, 6px);
65
+ border-radius: var(--os-radius-sm, var(--r-1, 6px));
64
66
  transition: background 100ms ease, color 100ms ease;
65
67
  }
66
- .wm-btn:hover { background: var(--panel-hover, var(--os-bg-2)); color: var(--os-fg); }
68
+ .wm-btn:hover { background: var(--panel-hover, var(--os-bg-1)); color: var(--os-fg); }
67
69
 
68
70
  .wm-body {
69
71
  flex: 1;
@@ -76,8 +78,10 @@
76
78
  position: absolute;
77
79
  right: 0;
78
80
  bottom: 0;
79
- width: 14px;
80
- height: 14px;
81
+ width: 16px;
82
+ height: 16px;
83
+ padding: 2px;
84
+ box-sizing: border-box;
81
85
  cursor: nwse-resize;
82
86
  background: transparent;
83
87
  color: var(--os-fg-3);
@@ -89,6 +93,7 @@
89
93
  justify-content: flex-end;
90
94
  touch-action: none;
91
95
  }
96
+ .wm-resize:hover { opacity: 0.7; }
92
97
  .wm-resize::after { content: '\25E2'; }
93
98
 
94
99
  .wm-win.wm-min .wm-body,
package/src/kits/os/wm.js CHANGED
@@ -55,16 +55,20 @@ export function renderWindow(opts = {}) {
55
55
  maxBtn.addEventListener('click', e => { e.stopPropagation(); callbacks.onMaximize && callbacks.onMaximize(); });
56
56
  closeBtn.addEventListener('click', e => { e.stopPropagation(); callbacks.onClose && callbacks.onClose(); });
57
57
 
58
- el.addEventListener('pointerdown', () => callbacks.onFocus && callbacks.onFocus());
58
+ const focus = () => callbacks.onFocus && callbacks.onFocus();
59
+
60
+ el.addEventListener('pointerdown', () => focus());
59
61
 
60
62
  bar.addEventListener('pointerdown', e => {
61
63
  if (e.target.closest('.wm-btn')) return;
62
- callbacks.onFocus && callbacks.onFocus();
64
+ e.stopPropagation();
65
+ focus();
63
66
  if (callbacks.onDragStart) callbacks.onDragStart(e, { x: el.offsetLeft, y: el.offsetTop, w: el.offsetWidth, h: el.offsetHeight });
64
67
  });
65
68
 
66
69
  resize.addEventListener('pointerdown', e => {
67
- callbacks.onFocus && callbacks.onFocus();
70
+ e.stopPropagation();
71
+ focus();
68
72
  if (callbacks.onResizeStart) callbacks.onResizeStart(e, { x: el.offsetLeft, y: el.offsetTop, w: el.offsetWidth, h: el.offsetHeight });
69
73
  });
70
74
 
@@ -24,11 +24,28 @@ function updateEventListener(el, eventName, newHandler, oldHandler) {
24
24
  * @param key Property or attribute name
25
25
  * @param value New value to set
26
26
  */
27
+ function setPropOrFallback(el, key, value) {
28
+ // Some IDL attributes (e.g. <input>.list, .form, .labels, .validity) are
29
+ // read-only getters: assigning to them throws TypeError and aborts the diff.
30
+ // Fall back to setAttribute so the render survives.
31
+ try {
32
+ el[key] = value;
33
+ }
34
+ catch {
35
+ try {
36
+ if (value == null || value === false)
37
+ el.removeAttribute(key);
38
+ else
39
+ el.setAttribute(key, value === true ? "" : `${value}`);
40
+ }
41
+ catch { /* give up silently rather than break the whole tree */ }
42
+ }
43
+ }
27
44
  function updatePropOrAttr(el, key, value) {
28
45
  if (el instanceof HTMLElement) {
29
46
  if (key in el) {
30
47
  // Fast path: property exists on HTMLElement
31
- el[key] = value;
48
+ setPropOrFallback(el, key, value);
32
49
  return;
33
50
  }
34
51
  if (typeof value === "string") {
@@ -36,7 +53,7 @@ function updatePropOrAttr(el, key, value) {
36
53
  return;
37
54
  }
38
55
  // Fallback for non-string values on HTMLElement
39
- el[key] = value;
56
+ setPropOrFallback(el, key, value);
40
57
  return;
41
58
  }
42
59
  // SVG/Other namespace elements
@@ -55,7 +72,7 @@ function updatePropOrAttr(el, key, value) {
55
72
  el.setAttribute(key, value);
56
73
  }
57
74
  else {
58
- el[key] = value;
75
+ setPropOrFallback(el, key, value);
59
76
  }
60
77
  }
61
78
  /**