anentrypoint-design 0.0.144 → 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.
@@ -60,15 +60,15 @@
60
60
  .browser-app-bar {
61
61
  display: flex;
62
62
  align-items: center;
63
- gap: 6px;
64
- padding: 6px 8px;
63
+ gap: var(--space-1);
64
+ padding: var(--space-1) var(--space-2);
65
65
  background: var(--os-bg-2);
66
66
  flex: 0 0 auto;
67
67
  }
68
68
  .browser-app-btn {
69
69
  height: 28px;
70
70
  min-width: 28px;
71
- padding: 0 8px;
71
+ padding: 0 var(--space-2);
72
72
  background: var(--os-bg-3);
73
73
  color: var(--os-fg);
74
74
  border: none;
@@ -78,10 +78,12 @@
78
78
  outline: none;
79
79
  }
80
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); }
81
82
  .browser-app-url {
82
83
  flex: 1 1 auto;
84
+ min-width: 0;
83
85
  height: 28px;
84
- padding: 0 10px;
86
+ padding: 0 var(--space-2);
85
87
  background: var(--os-bg-0);
86
88
  color: var(--os-fg);
87
89
  border: none;
@@ -92,15 +94,16 @@
92
94
  .browser-app-url:focus { box-shadow: inset 4px 0 0 var(--os-accent); }
93
95
  .browser-app-slot {
94
96
  flex: 1 1 auto;
97
+ min-width: 0;
95
98
  min-height: 0;
96
99
  overflow: hidden;
97
100
  background: var(--os-bg-0);
98
- display: flex;
101
+ position: relative;
99
102
  }
100
- .browser-app-slot > * { flex: 1 1 auto; min-width: 0; min-height: 0; }
103
+ .browser-app-slot > * { width: 100%; height: 100%; }
101
104
  .browser-app-status {
102
105
  flex: 0 0 auto;
103
- padding: 2px 10px;
106
+ padding: var(--space-1) var(--space-2);
104
107
  background: var(--os-bg-2);
105
108
  font: 11px var(--os-mono);
106
109
  color: var(--os-fg-3);
@@ -120,29 +123,33 @@
120
123
  .validator-app-head {
121
124
  display: flex;
122
125
  align-items: center;
123
- gap: 10px;
124
- padding: 6px 10px;
126
+ gap: var(--space-2);
127
+ padding: var(--space-1) var(--space-2);
125
128
  background: var(--os-bg-2);
126
129
  flex: 0 0 auto;
127
130
  }
128
131
  .validator-app-banner {
129
- padding: 2px 10px;
132
+ flex: 0 0 auto;
133
+ padding: 2px var(--space-2);
130
134
  border-radius: 999px;
131
135
  font: 11px var(--os-mono);
132
136
  text-transform: lowercase;
133
137
  background: var(--os-bg-3);
134
138
  color: var(--os-fg-2);
135
139
  }
136
- .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); }
137
142
  .validator-app-banner[data-state="fail"] { background: var(--os-red); color: var(--os-bg-0); }
138
143
  .validator-app-counts {
144
+ flex: 0 0 auto;
139
145
  font: 11px var(--os-mono);
140
146
  color: var(--os-fg-2);
141
147
  }
142
148
  .validator-app-rerun {
143
149
  margin-left: auto;
144
- height: 24px;
145
- padding: 0 10px;
150
+ flex: 0 0 auto;
151
+ height: var(--space-4);
152
+ padding: 0 var(--space-2);
146
153
  background: var(--os-bg-3);
147
154
  color: var(--os-fg);
148
155
  border: none;
@@ -155,9 +162,11 @@
155
162
  .validator-app-rerun:hover { background: var(--os-accent-soft); }
156
163
  .validator-app-slot {
157
164
  flex: 1 1 auto;
165
+ min-width: 0;
158
166
  min-height: 0;
159
167
  overflow: hidden;
160
168
  display: flex;
169
+ position: relative;
161
170
  background: var(--os-bg-0);
162
171
  }
163
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
  /**